better-auth
Version:
The most comprehensive authentication framework for TypeScript.
1 lines • 6.98 kB
Source Map (JSON)
{"version":3,"file":"cookie-utils.mjs","names":["result: string[]","trimmed","attrObj: CookieAttributes"],"sources":["../../src/cookies/cookie-utils.ts"],"sourcesContent":["interface CookieAttributes {\n\tvalue: string;\n\t\"max-age\"?: number | undefined;\n\texpires?: Date | undefined;\n\tdomain?: string | undefined;\n\tpath?: string | undefined;\n\tsecure?: boolean | undefined;\n\thttponly?: boolean | undefined;\n\tsamesite?: (\"strict\" | \"lax\" | \"none\") | undefined;\n\t[key: string]: any;\n}\n\nexport const SECURE_COOKIE_PREFIX = \"__Secure-\";\nexport const HOST_COOKIE_PREFIX = \"__Host-\";\n\n/**\n * Remove __Secure- or __Host- prefix from cookie name.\n */\nexport function stripSecureCookiePrefix(cookieName: string): string {\n\tif (cookieName.startsWith(SECURE_COOKIE_PREFIX)) {\n\t\treturn cookieName.slice(SECURE_COOKIE_PREFIX.length);\n\t}\n\tif (cookieName.startsWith(HOST_COOKIE_PREFIX)) {\n\t\treturn cookieName.slice(HOST_COOKIE_PREFIX.length);\n\t}\n\treturn cookieName;\n}\n\n/**\n * Split `Set-Cookie` header, handling commas in `Expires` dates.\n */\nexport function splitSetCookieHeader(setCookie: string): string[] {\n\tif (!setCookie) return [];\n\n\tconst result: string[] = [];\n\tlet current = \"\";\n\tlet i = 0;\n\n\twhile (i < setCookie.length) {\n\t\tconst c = setCookie[i];\n\n\t\tif (c === \",\") {\n\t\t\tconst lower = current.toLowerCase();\n\t\t\tif (lower.includes(\"expires=\") && !lower.includes(\"gmt\")) {\n\t\t\t\tcurrent += c;\n\t\t\t\ti++;\n\t\t\t} else {\n\t\t\t\tconst trimmed = current.trim();\n\t\t\t\tif (trimmed) {\n\t\t\t\t\tresult.push(trimmed);\n\t\t\t\t}\n\t\t\t\tcurrent = \"\";\n\t\t\t\ti++;\n\t\t\t\tif (i < setCookie.length && setCookie[i] === \" \") {\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tcurrent += c;\n\t\ti++;\n\t}\n\n\tconst trimmed = current.trim();\n\tif (trimmed) {\n\t\tresult.push(trimmed);\n\t}\n\n\treturn result;\n}\n\nexport function parseSetCookieHeader(\n\tsetCookie: string,\n): Map<string, CookieAttributes> {\n\tconst cookies = new Map<string, CookieAttributes>();\n\tconst cookieArray = splitSetCookieHeader(setCookie);\n\n\tcookieArray.forEach((cookieString) => {\n\t\tconst parts = cookieString.split(\";\").map((part) => part.trim());\n\t\tconst [nameValue, ...attributes] = parts;\n\t\tconst [name, ...valueParts] = (nameValue || \"\").split(\"=\");\n\n\t\tconst value = valueParts.join(\"=\");\n\n\t\tif (!name || value === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst attrObj: CookieAttributes = { value };\n\n\t\tattributes.forEach((attribute) => {\n\t\t\tconst [attrName, ...attrValueParts] = attribute!.split(\"=\");\n\t\t\tconst attrValue = attrValueParts.join(\"=\");\n\n\t\t\tconst normalizedAttrName = attrName!.trim().toLowerCase();\n\n\t\t\tswitch (normalizedAttrName) {\n\t\t\t\tcase \"max-age\":\n\t\t\t\t\tattrObj[\"max-age\"] = attrValue\n\t\t\t\t\t\t? parseInt(attrValue.trim(), 10)\n\t\t\t\t\t\t: undefined;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"expires\":\n\t\t\t\t\tattrObj.expires = attrValue ? new Date(attrValue.trim()) : undefined;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"domain\":\n\t\t\t\t\tattrObj.domain = attrValue ? attrValue.trim() : undefined;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"path\":\n\t\t\t\t\tattrObj.path = attrValue ? attrValue.trim() : undefined;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"secure\":\n\t\t\t\t\tattrObj.secure = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"httponly\":\n\t\t\t\t\tattrObj.httponly = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"samesite\":\n\t\t\t\t\tattrObj.samesite = attrValue\n\t\t\t\t\t\t? (attrValue.trim().toLowerCase() as \"strict\" | \"lax\" | \"none\")\n\t\t\t\t\t\t: undefined;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t// Handle any other attributes\n\t\t\t\t\tattrObj[normalizedAttrName] = attrValue ? attrValue.trim() : true;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t});\n\n\t\tcookies.set(name, attrObj);\n\t});\n\n\treturn cookies;\n}\n\nexport function setCookieToHeader(headers: Headers) {\n\treturn (context: { response: Response }) => {\n\t\tconst setCookieHeader = context.response.headers.get(\"set-cookie\");\n\t\tif (!setCookieHeader) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst cookieMap = new Map<string, string>();\n\n\t\tconst existingCookiesHeader = headers.get(\"cookie\") || \"\";\n\t\texistingCookiesHeader.split(\";\").forEach((cookie) => {\n\t\t\tconst [name, ...rest] = cookie!.trim().split(\"=\");\n\t\t\tif (name && rest.length > 0) {\n\t\t\t\tcookieMap.set(name, rest.join(\"=\"));\n\t\t\t}\n\t\t});\n\n\t\tconst cookies = parseSetCookieHeader(setCookieHeader);\n\t\tcookies.forEach((value, name) => {\n\t\t\tcookieMap.set(name, value.value);\n\t\t});\n\n\t\tconst updatedCookies = Array.from(cookieMap.entries())\n\t\t\t.map(([name, value]) => `${name}=${value}`)\n\t\t\t.join(\"; \");\n\t\theaders.set(\"cookie\", updatedCookies);\n\t};\n}\n"],"mappings":"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"}