{"version":3,"sources":["../../../../src/server/requests-auth-methods/jwt.ts"],"sourcesContent":["import type { IncomingHttpHeaders } from 'node:http2'\n\nimport cookie from '@fastify/cookie'\nimport jwt from 'jsonwebtoken'\n\nimport { BaseRequestAuthMethod } from './base'\nimport { NotAuthenticatedError, TokenExpired } from '../../errors'\n\nexport interface BaseJwtRequestAuthMethodOptions {\n\tsigningKey: string\n\tstorageTTL: number\n\tstoragePrefix?: string\n\tenforceSingleSession?: boolean\n}\n\nexport abstract class BaseJwtRequestAuthMethod<T extends { id: string }> extends BaseRequestAuthMethod<T> {\n\tprotected readonly options: BaseJwtRequestAuthMethodOptions\n\tprotected abstract parseHeader(headers: IncomingHttpHeaders): Promise<string>\n\tprotected abstract store(key: string, token: string, ttl: number): Promise<void>\n\tprotected abstract retrieve(key: string): Promise<string | null>\n\tprotected abstract delete(key: string): Promise<void>\n\n\tconstructor(options: BaseJwtRequestAuthMethodOptions) {\n\t\tsuper()\n\t\tthis.options = options\n\t}\n\n\t#getKey(userId: string) {\n\t\treturn `${this.options.storagePrefix ?? ''}${userId}`\n\t}\n\n\tasync createToken(payload: T) {\n\t\tconst token = jwt.sign(payload, this.options.signingKey, { expiresIn: this.options.storageTTL })\n\t\tawait this.store(this.#getKey(payload.id), token, this.options.storageTTL)\n\t\treturn token\n\t}\n\n\tasync parse(headers: IncomingHttpHeaders) {\n\t\ttry {\n\t\t\tconst token = await this.parseHeader(headers)\n\t\t\tconst user = jwt.verify(token, this.options.signingKey) as T\n\t\t\tif (!user) throw new NotAuthenticatedError()\n\n\t\t\tif (this.options.enforceSingleSession) {\n\t\t\t\tconst cachedToken = await this.retrieve(this.#getKey(user.id))\n\t\t\t\tif (token && token !== cachedToken) throw new TokenExpired()\n\t\t\t}\n\n\t\t\treturn user\n\t\t} catch (err) {\n\t\t\tif (err instanceof TokenExpired) throw err\n\t\t\tif (err instanceof jwt.TokenExpiredError) throw new TokenExpired(undefined, err)\n\t\t\telse throw new NotAuthenticatedError(undefined, err)\n\t\t}\n\t}\n\n\tasync retrieveFor(userId: string) {\n\t\treturn this.retrieve(this.#getKey(userId))\n\t}\n\n\tasync deleteFor(userId: string) {\n\t\tawait this.delete(this.#getKey(userId))\n\t}\n}\n\ninterface BaseJwtHeaderRequestAuthMethodOptions<T extends string> extends BaseJwtRequestAuthMethodOptions {\n\theaderName: T\n}\n\nexport abstract class BaseJwtHeaderRequestAuthMethod<T extends { id: string }, Name extends string = string> extends BaseJwtRequestAuthMethod<T> {\n\tprotected readonly options: BaseJwtHeaderRequestAuthMethodOptions<Name>\n\n\tconstructor(options: BaseJwtHeaderRequestAuthMethodOptions<Name>) {\n\t\tsuper(options)\n\t\tthis.options = options\n\t}\n\n\tasync parseHeader(headers: IncomingHttpHeaders) {\n\t\tconst value = headers[this.options.headerName]\n\t\tif (!value || typeof value !== 'string') throw new NotAuthenticatedError()\n\t\treturn value.startsWith('Bearer ') ? value.slice(7) : value\n\t}\n\n\trouteSecuritySchemeName() {\n\t\treturn this.options.headerName\n\t}\n}\n\ninterface BaseJwtCookieRequestAuthMethodOptions<T extends string> extends BaseJwtRequestAuthMethodOptions {\n\tcookieName: T\n}\n\nexport abstract class BaseJwtCookieRequestAuthMethod<T extends { id: string }, Name extends string = string> extends BaseJwtRequestAuthMethod<T> {\n\tprotected readonly options: BaseJwtCookieRequestAuthMethodOptions<Name>\n\n\tconstructor(options: BaseJwtCookieRequestAuthMethodOptions<Name>) {\n\t\tsuper(options)\n\t\tthis.options = options\n\t}\n\n\tasync parseHeader(headers: IncomingHttpHeaders) {\n\t\tconst cookies = cookie.parse(headers.cookie || '') ?? {}\n\t\tconst value = cookies[this.options.cookieName]\n\t\tif (!value || typeof value !== 'string') throw new NotAuthenticatedError()\n\t\treturn value\n\t}\n\n\trouteSecuritySchemeName() {\n\t\treturn `cookie:${this.options.cookieName}`\n\t}\n}\n"],"mappings":"AAEA,OAAOA,MAAY,kBACnB,OAAOC,MAAS,eAEhB,OAAS,yBAAAC,MAA6B,SACtC,OAAS,yBAAAC,EAAuB,gBAAAC,MAAoB,eAS7C,MAAeC,UAA2DH,CAAyB,CACtF,QAMnB,YAAYI,EAA0C,CACrD,MAAM,EACN,KAAK,QAAUA,CAChB,CAEAC,GAAQC,EAAgB,CACvB,MAAO,GAAG,KAAK,QAAQ,eAAiB,EAAE,GAAGA,CAAM,EACpD,CAEA,MAAM,YAAYC,EAAY,CAC7B,MAAMC,EAAQT,EAAI,KAAKQ,EAAS,KAAK,QAAQ,WAAY,CAAE,UAAW,KAAK,QAAQ,UAAW,CAAC,EAC/F,aAAM,KAAK,MAAM,KAAKF,GAAQE,EAAQ,EAAE,EAAGC,EAAO,KAAK,QAAQ,UAAU,EAClEA,CACR,CAEA,MAAM,MAAMC,EAA8B,CACzC,GAAI,CACH,MAAMD,EAAQ,MAAM,KAAK,YAAYC,CAAO,EACtCC,EAAOX,EAAI,OAAOS,EAAO,KAAK,QAAQ,UAAU,EACtD,GAAI,CAACE,EAAM,MAAM,IAAIT,EAErB,GAAI,KAAK,QAAQ,qBAAsB,CACtC,MAAMU,EAAc,MAAM,KAAK,SAAS,KAAKN,GAAQK,EAAK,EAAE,CAAC,EAC7D,GAAIF,GAASA,IAAUG,EAAa,MAAM,IAAIT,CAC/C,CAEA,OAAOQ,CACR,OAASE,EAAK,CACb,MAAIA,aAAeV,EAAoBU,EACnCA,aAAeb,EAAI,kBAAyB,IAAIG,EAAa,OAAWU,CAAG,EACpE,IAAIX,EAAsB,OAAWW,CAAG,CACpD,CACD,CAEA,MAAM,YAAYN,EAAgB,CACjC,OAAO,KAAK,SAAS,KAAKD,GAAQC,CAAM,CAAC,CAC1C,CAEA,MAAM,UAAUA,EAAgB,CAC/B,MAAM,KAAK,OAAO,KAAKD,GAAQC,CAAM,CAAC,CACvC,CACD,CAMO,MAAeO,UAA+FV,CAA4B,CAC7H,QAEnB,YAAYC,EAAsD,CACjE,MAAMA,CAAO,EACb,KAAK,QAAUA,CAChB,CAEA,MAAM,YAAYK,EAA8B,CAC/C,MAAMK,EAAQL,EAAQ,KAAK,QAAQ,UAAU,EAC7C,GAAI,CAACK,GAAS,OAAOA,GAAU,SAAU,MAAM,IAAIb,EACnD,OAAOa,EAAM,WAAW,SAAS,EAAIA,EAAM,MAAM,CAAC,EAAIA,CACvD,CAEA,yBAA0B,CACzB,OAAO,KAAK,QAAQ,UACrB,CACD,CAMO,MAAeC,UAA+FZ,CAA4B,CAC7H,QAEnB,YAAYC,EAAsD,CACjE,MAAMA,CAAO,EACb,KAAK,QAAUA,CAChB,CAEA,MAAM,YAAYK,EAA8B,CAE/C,MAAMK,GADUhB,EAAO,MAAMW,EAAQ,QAAU,EAAE,GAAK,CAAC,GACjC,KAAK,QAAQ,UAAU,EAC7C,GAAI,CAACK,GAAS,OAAOA,GAAU,SAAU,MAAM,IAAIb,EACnD,OAAOa,CACR,CAEA,yBAA0B,CACzB,MAAO,UAAU,KAAK,QAAQ,UAAU,EACzC,CACD","names":["cookie","jwt","BaseRequestAuthMethod","NotAuthenticatedError","TokenExpired","BaseJwtRequestAuthMethod","options","#getKey","userId","payload","token","headers","user","cachedToken","err","BaseJwtHeaderRequestAuthMethod","value","BaseJwtCookieRequestAuthMethod"]}