better-auth
Version:
The most comprehensive authentication framework for TypeScript.
1 lines • 5.66 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugins/custom-session/index.ts"],"sourcesContent":["import type {\n\tBetterAuthOptions,\n\tBetterAuthPlugin,\n\tGenericEndpointContext,\n} from \"@better-auth/core\";\nimport {\n\tcreateAuthEndpoint,\n\tcreateAuthMiddleware,\n} from \"@better-auth/core/api\";\nimport * as z from \"zod\";\nimport { getSession } from \"../../api\";\nimport type { InferSession, InferUser } from \"../../types\";\nimport { getEndpointResponse } from \"../../utils/plugin-helper\";\n\nconst getSessionQuerySchema = z.optional(\n\tz.object({\n\t\t/**\n\t\t * If cookie cache is enabled, it will disable the cache\n\t\t * and fetch the session from the database\n\t\t */\n\t\tdisableCookieCache: z\n\t\t\t.boolean()\n\t\t\t.meta({\n\t\t\t\tdescription: \"Disable cookie cache and fetch session from database\",\n\t\t\t})\n\t\t\t.or(z.string().transform((v) => v === \"true\"))\n\t\t\t.optional(),\n\t\tdisableRefresh: z\n\t\t\t.boolean()\n\t\t\t.meta({\n\t\t\t\tdescription:\n\t\t\t\t\t\"Disable session refresh. Useful for checking session status, without updating the session\",\n\t\t\t})\n\t\t\t.optional(),\n\t}),\n);\n\nexport type CustomSessionPluginOptions = {\n\t/**\n\t * This option is used to determine if the list-device-sessions endpoint should be mutated to the custom session data.\n\t * @default false\n\t */\n\tshouldMutateListDeviceSessionsEndpoint?: boolean | undefined;\n};\n\nexport const customSession = <\n\tReturns extends Record<string, any>,\n\tO extends BetterAuthOptions = BetterAuthOptions,\n>(\n\tfn: (\n\t\tsession: {\n\t\t\tuser: InferUser<O>;\n\t\t\tsession: InferSession<O>;\n\t\t},\n\t\tctx: GenericEndpointContext,\n\t) => Promise<Returns>,\n\toptions?: O | undefined,\n\tpluginOptions?: CustomSessionPluginOptions | undefined,\n) => {\n\treturn {\n\t\tid: \"custom-session\",\n\t\thooks: {\n\t\t\tafter: [\n\t\t\t\t{\n\t\t\t\t\tmatcher: (ctx) =>\n\t\t\t\t\t\tctx.path === \"/multi-session/list-device-sessions\" &&\n\t\t\t\t\t\t(pluginOptions?.shouldMutateListDeviceSessionsEndpoint ?? false),\n\t\t\t\t\thandler: createAuthMiddleware(async (ctx) => {\n\t\t\t\t\t\tconst response = await getEndpointResponse<[]>(ctx);\n\t\t\t\t\t\tif (!response) return;\n\t\t\t\t\t\tconst newResponse = await Promise.all(\n\t\t\t\t\t\t\tresponse.map(async (v) => await fn(v, ctx)),\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn ctx.json(newResponse);\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\tendpoints: {\n\t\t\tgetSession: createAuthEndpoint(\n\t\t\t\t\"/get-session\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\tquery: getSessionQuerySchema,\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\tCUSTOM_SESSION: true,\n\t\t\t\t\t\topenapi: {\n\t\t\t\t\t\t\tdescription: \"Get custom session data\",\n\t\t\t\t\t\t\tresponses: {\n\t\t\t\t\t\t\t\t\"200\": {\n\t\t\t\t\t\t\t\t\tdescription: \"Success\",\n\t\t\t\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: \"array\",\n\t\t\t\t\t\t\t\t\t\t\t\tnullable: true,\n\t\t\t\t\t\t\t\t\t\t\t\titems: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$ref: \"#/components/schemas/Session\",\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\trequireHeaders: true,\n\t\t\t\t},\n\t\t\t\tasync (ctx): Promise<Returns | null> => {\n\t\t\t\t\tconst session = await getSession()({\n\t\t\t\t\t\t...ctx,\n\t\t\t\t\t\tasResponse: false,\n\t\t\t\t\t\theaders: ctx.headers,\n\t\t\t\t\t\treturnHeaders: true,\n\t\t\t\t\t}).catch((e) => {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t});\n\t\t\t\t\tif (!session?.response) {\n\t\t\t\t\t\treturn ctx.json(null);\n\t\t\t\t\t}\n\t\t\t\t\tconst fnResult = await fn(session.response as any, ctx);\n\n\t\t\t\t\tconst setCookie = session.headers.get(\"set-cookie\");\n\t\t\t\t\tif (setCookie) {\n\t\t\t\t\t\tctx.setHeader(\"set-cookie\", setCookie);\n\t\t\t\t\t\tsession.headers.delete(\"set-cookie\");\n\t\t\t\t\t}\n\n\t\t\t\t\tsession.headers.forEach((value, key) => {\n\t\t\t\t\t\tctx.setHeader(key, value);\n\t\t\t\t\t});\n\t\t\t\t\treturn ctx.json(fnResult);\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\t$Infer: {\n\t\t\tSession: {} as Awaited<ReturnType<typeof fn>>,\n\t\t},\n\t\toptions: pluginOptions,\n\t} satisfies BetterAuthPlugin;\n};\n"],"mappings":";;;;;;;AAcA,MAAM,wBAAwB,EAAE,SAC/B,EAAE,OAAO;CAKR,oBAAoB,EAClB,SAAS,CACT,KAAK,EACL,aAAa,wDACb,CAAC,CACD,GAAG,EAAE,QAAQ,CAAC,WAAW,MAAM,MAAM,OAAO,CAAC,CAC7C,UAAU;CACZ,gBAAgB,EACd,SAAS,CACT,KAAK,EACL,aACC,6FACD,CAAC,CACD,UAAU;CACZ,CAAC,CACF;AAUD,MAAa,iBAIZ,IAOA,SACA,kBACI;AACJ,QAAO;EACN,IAAI;EACJ,OAAO,EACN,OAAO,CACN;GACC,UAAU,QACT,IAAI,SAAS,0CACZ,eAAe,0CAA0C;GAC3D,SAAS,qBAAqB,OAAO,QAAQ;IAC5C,MAAM,WAAW,MAAM,oBAAwB,IAAI;AACnD,QAAI,CAAC,SAAU;IACf,MAAM,cAAc,MAAM,QAAQ,IACjC,SAAS,IAAI,OAAO,MAAM,MAAM,GAAG,GAAG,IAAI,CAAC,CAC3C;AACD,WAAO,IAAI,KAAK,YAAY;KAC3B;GACF,CACD,EACD;EACD,WAAW,EACV,YAAY,mBACX,gBACA;GACC,QAAQ;GACR,OAAO;GACP,UAAU;IACT,gBAAgB;IAChB,SAAS;KACR,aAAa;KACb,WAAW,EACV,OAAO;MACN,aAAa;MACb,SAAS,EACR,oBAAoB,EACnB,QAAQ;OACP,MAAM;OACN,UAAU;OACV,OAAO,EACN,MAAM,gCACN;OACD,EACD,EACD;MACD,EACD;KACD;IACD;GACD,gBAAgB;GAChB,EACD,OAAO,QAAiC;GACvC,MAAM,UAAU,MAAM,YAAY,CAAC;IAClC,GAAG;IACH,YAAY;IACZ,SAAS,IAAI;IACb,eAAe;IACf,CAAC,CAAC,OAAO,MAAM;AACf,WAAO;KACN;AACF,OAAI,CAAC,SAAS,SACb,QAAO,IAAI,KAAK,KAAK;GAEtB,MAAM,WAAW,MAAM,GAAG,QAAQ,UAAiB,IAAI;GAEvD,MAAM,YAAY,QAAQ,QAAQ,IAAI,aAAa;AACnD,OAAI,WAAW;AACd,QAAI,UAAU,cAAc,UAAU;AACtC,YAAQ,QAAQ,OAAO,aAAa;;AAGrC,WAAQ,QAAQ,SAAS,OAAO,QAAQ;AACvC,QAAI,UAAU,KAAK,MAAM;KACxB;AACF,UAAO,IAAI,KAAK,SAAS;IAE1B,EACD;EACD,QAAQ,EACP,SAAS,EAAE,EACX;EACD,SAAS;EACT"}