better-auth
Version:
The most comprehensive authentication framework for TypeScript.
1 lines • 5.74 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugins/bearer/index.ts"],"sourcesContent":["import type { BetterAuthPlugin } from \"@better-auth/core\";\nimport { createAuthMiddleware } from \"@better-auth/core/api\";\nimport { createHMAC } from \"@better-auth/utils/hmac\";\nimport { serializeSignedCookie } from \"better-call\";\nimport { parseSetCookieHeader } from \"../../cookies\";\n\nexport interface BearerOptions {\n\t/**\n\t * If true, only signed tokens\n\t * will be converted to session\n\t * cookies\n\t *\n\t * @default false\n\t */\n\trequireSignature?: boolean | undefined;\n}\n\n/**\n * Converts bearer token to session cookie\n */\nexport const bearer = (options?: BearerOptions | undefined) => {\n\treturn {\n\t\tid: \"bearer\",\n\t\thooks: {\n\t\t\tbefore: [\n\t\t\t\t{\n\t\t\t\t\tmatcher(context) {\n\t\t\t\t\t\treturn Boolean(\n\t\t\t\t\t\t\tcontext.request?.headers.get(\"authorization\") ||\n\t\t\t\t\t\t\t\tcontext.headers?.get(\"authorization\"),\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t\thandler: createAuthMiddleware(async (c) => {\n\t\t\t\t\t\tconst token =\n\t\t\t\t\t\t\tc.request?.headers.get(\"authorization\")?.replace(\"Bearer \", \"\") ||\n\t\t\t\t\t\t\tc.headers?.get(\"Authorization\")?.replace(\"Bearer \", \"\");\n\t\t\t\t\t\tif (!token) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlet signedToken = \"\";\n\t\t\t\t\t\tif (token.includes(\".\")) {\n\t\t\t\t\t\t\tsignedToken = token.replace(\"=\", \"\");\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (options?.requireSignature) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsignedToken = (\n\t\t\t\t\t\t\t\tawait serializeSignedCookie(\"\", token, c.context.secret)\n\t\t\t\t\t\t\t).replace(\"=\", \"\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst decodedToken = decodeURIComponent(signedToken);\n\t\t\t\t\t\t\tconst isValid = await createHMAC(\n\t\t\t\t\t\t\t\t\"SHA-256\",\n\t\t\t\t\t\t\t\t\"base64urlnopad\",\n\t\t\t\t\t\t\t).verify(\n\t\t\t\t\t\t\t\tc.context.secret,\n\t\t\t\t\t\t\t\tdecodedToken.split(\".\")[0]!,\n\t\t\t\t\t\t\t\tdecodedToken.split(\".\")[1]!,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (!isValid) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst existingHeaders = (c.request?.headers ||\n\t\t\t\t\t\t\tc.headers) as Headers;\n\t\t\t\t\t\tconst headers = new Headers({\n\t\t\t\t\t\t\t...Object.fromEntries(existingHeaders?.entries()),\n\t\t\t\t\t\t});\n\t\t\t\t\t\theaders.append(\n\t\t\t\t\t\t\t\"cookie\",\n\t\t\t\t\t\t\t`${c.context.authCookies.sessionToken.name}=${signedToken}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcontext: {\n\t\t\t\t\t\t\t\theaders,\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},\n\t\t\t],\n\t\t\tafter: [\n\t\t\t\t{\n\t\t\t\t\tmatcher(context) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t\thandler: createAuthMiddleware(async (ctx) => {\n\t\t\t\t\t\tconst setCookie = ctx.context.responseHeaders?.get(\"set-cookie\");\n\t\t\t\t\t\tif (!setCookie) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst parsedCookies = parseSetCookieHeader(setCookie);\n\t\t\t\t\t\tconst cookieName = ctx.context.authCookies.sessionToken.name;\n\t\t\t\t\t\tconst sessionCookie = parsedCookies.get(cookieName);\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!sessionCookie ||\n\t\t\t\t\t\t\t!sessionCookie.value ||\n\t\t\t\t\t\t\tsessionCookie[\"max-age\"] === 0\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst token = sessionCookie.value;\n\t\t\t\t\t\tconst exposedHeaders =\n\t\t\t\t\t\t\tctx.context.responseHeaders?.get(\n\t\t\t\t\t\t\t\t\"access-control-expose-headers\",\n\t\t\t\t\t\t\t) || \"\";\n\t\t\t\t\t\tconst headersSet = new Set(\n\t\t\t\t\t\t\texposedHeaders\n\t\t\t\t\t\t\t\t.split(\",\")\n\t\t\t\t\t\t\t\t.map((header) => header.trim())\n\t\t\t\t\t\t\t\t.filter(Boolean),\n\t\t\t\t\t\t);\n\t\t\t\t\t\theadersSet.add(\"set-auth-token\");\n\t\t\t\t\t\tctx.setHeader(\"set-auth-token\", token);\n\t\t\t\t\t\tctx.setHeader(\n\t\t\t\t\t\t\t\"Access-Control-Expose-Headers\",\n\t\t\t\t\t\t\tArray.from(headersSet).join(\", \"),\n\t\t\t\t\t\t);\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\toptions,\n\t} satisfies BetterAuthPlugin;\n};\n"],"mappings":";;;;;;;;;;AAoBA,MAAa,UAAU,YAAwC;AAC9D,QAAO;EACN,IAAI;EACJ,OAAO;GACN,QAAQ,CACP;IACC,QAAQ,SAAS;AAChB,YAAO,QACN,QAAQ,SAAS,QAAQ,IAAI,gBAAgB,IAC5C,QAAQ,SAAS,IAAI,gBAAgB,CACtC;;IAEF,SAAS,qBAAqB,OAAO,MAAM;KAC1C,MAAM,QACL,EAAE,SAAS,QAAQ,IAAI,gBAAgB,EAAE,QAAQ,WAAW,GAAG,IAC/D,EAAE,SAAS,IAAI,gBAAgB,EAAE,QAAQ,WAAW,GAAG;AACxD,SAAI,CAAC,MACJ;KAGD,IAAI,cAAc;AAClB,SAAI,MAAM,SAAS,IAAI,CACtB,eAAc,MAAM,QAAQ,KAAK,GAAG;UAC9B;AACN,UAAI,SAAS,iBACZ;AAED,qBACC,MAAM,sBAAsB,IAAI,OAAO,EAAE,QAAQ,OAAO,EACvD,QAAQ,KAAK,GAAG;;AAEnB,SAAI;MACH,MAAM,eAAe,mBAAmB,YAAY;AASpD,UAAI,CARY,MAAM,WACrB,WACA,iBACA,CAAC,OACD,EAAE,QAAQ,QACV,aAAa,MAAM,IAAI,CAAC,IACxB,aAAa,MAAM,IAAI,CAAC,GACxB,CAEA;aAEM;AACP;;KAED,MAAM,kBAAmB,EAAE,SAAS,WACnC,EAAE;KACH,MAAM,UAAU,IAAI,QAAQ,EAC3B,GAAG,OAAO,YAAY,iBAAiB,SAAS,CAAC,EACjD,CAAC;AACF,aAAQ,OACP,UACA,GAAG,EAAE,QAAQ,YAAY,aAAa,KAAK,GAAG,cAC9C;AACD,YAAO,EACN,SAAS,EACR,SACA,EACD;MACA;IACF,CACD;GACD,OAAO,CACN;IACC,QAAQ,SAAS;AAChB,YAAO;;IAER,SAAS,qBAAqB,OAAO,QAAQ;KAC5C,MAAM,YAAY,IAAI,QAAQ,iBAAiB,IAAI,aAAa;AAChE,SAAI,CAAC,UACJ;KAED,MAAM,gBAAgB,qBAAqB,UAAU;KACrD,MAAM,aAAa,IAAI,QAAQ,YAAY,aAAa;KACxD,MAAM,gBAAgB,cAAc,IAAI,WAAW;AACnD,SACC,CAAC,iBACD,CAAC,cAAc,SACf,cAAc,eAAe,EAE7B;KAED,MAAM,QAAQ,cAAc;KAC5B,MAAM,iBACL,IAAI,QAAQ,iBAAiB,IAC5B,gCACA,IAAI;KACN,MAAM,aAAa,IAAI,IACtB,eACE,MAAM,IAAI,CACV,KAAK,WAAW,OAAO,MAAM,CAAC,CAC9B,OAAO,QAAQ,CACjB;AACD,gBAAW,IAAI,iBAAiB;AAChC,SAAI,UAAU,kBAAkB,MAAM;AACtC,SAAI,UACH,iCACA,MAAM,KAAK,WAAW,CAAC,KAAK,KAAK,CACjC;MACA;IACF,CACD;GACD;EACD;EACA"}