Buckets:
| // src/utils/cookie.ts | |
| import { decodeURIComponent_, tryDecode } from "./url.js"; | |
| var algorithm = { name: "HMAC", hash: "SHA-256" }; | |
| var getCryptoKey = async (secret) => { | |
| const secretBuf = typeof secret === "string" ? new TextEncoder().encode(secret) : secret; | |
| return await crypto.subtle.importKey("raw", secretBuf, algorithm, false, ["sign", "verify"]); | |
| }; | |
| var makeSignature = async (value, secret) => { | |
| const key = await getCryptoKey(secret); | |
| const signature = await crypto.subtle.sign(algorithm.name, key, new TextEncoder().encode(value)); | |
| return btoa(String.fromCharCode(...new Uint8Array(signature))); | |
| }; | |
| var verifySignature = async (base64Signature, value, secret) => { | |
| try { | |
| const signatureBinStr = atob(base64Signature); | |
| const signature = new Uint8Array(signatureBinStr.length); | |
| for (let i = 0, len = signatureBinStr.length; i < len; i++) { | |
| signature[i] = signatureBinStr.charCodeAt(i); | |
| } | |
| return await crypto.subtle.verify(algorithm, secret, signature, new TextEncoder().encode(value)); | |
| } catch { | |
| return false; | |
| } | |
| }; | |
| var validCookieNameRegEx = /^[\w!#$%&'*.^`|~+-]+$/; | |
| var validCookieValueRegEx = /^[ !#-:<-[\]-~]*$/; | |
| var parse = (cookie, name) => { | |
| if (name && cookie.indexOf(name) === -1) { | |
| return {}; | |
| } | |
| const pairs = cookie.trim().split(";"); | |
| const parsedCookie = {}; | |
| for (let pairStr of pairs) { | |
| pairStr = pairStr.trim(); | |
| const valueStartPos = pairStr.indexOf("="); | |
| if (valueStartPos === -1) { | |
| continue; | |
| } | |
| const cookieName = pairStr.substring(0, valueStartPos).trim(); | |
| if (name && name !== cookieName || !validCookieNameRegEx.test(cookieName)) { | |
| continue; | |
| } | |
| let cookieValue = pairStr.substring(valueStartPos + 1).trim(); | |
| if (cookieValue.startsWith('"') && cookieValue.endsWith('"')) { | |
| cookieValue = cookieValue.slice(1, -1); | |
| } | |
| if (validCookieValueRegEx.test(cookieValue)) { | |
| parsedCookie[cookieName] = cookieValue.indexOf("%") !== -1 ? tryDecode(cookieValue, decodeURIComponent_) : cookieValue; | |
| if (name) { | |
| break; | |
| } | |
| } | |
| } | |
| return parsedCookie; | |
| }; | |
| var parseSigned = async (cookie, secret, name) => { | |
| const parsedCookie = {}; | |
| const secretKey = await getCryptoKey(secret); | |
| for (const [key, value] of Object.entries(parse(cookie, name))) { | |
| const signatureStartPos = value.lastIndexOf("."); | |
| if (signatureStartPos < 1) { | |
| continue; | |
| } | |
| const signedValue = value.substring(0, signatureStartPos); | |
| const signature = value.substring(signatureStartPos + 1); | |
| if (signature.length !== 44 || !signature.endsWith("=")) { | |
| continue; | |
| } | |
| const isVerified = await verifySignature(signature, signedValue, secretKey); | |
| parsedCookie[key] = isVerified ? signedValue : false; | |
| } | |
| return parsedCookie; | |
| }; | |
| var _serialize = (name, value, opt = {}) => { | |
| let cookie = `${name}=${value}`; | |
| if (name.startsWith("__Secure-") && !opt.secure) { | |
| throw new Error("__Secure- Cookie must have Secure attributes"); | |
| } | |
| if (name.startsWith("__Host-")) { | |
| if (!opt.secure) { | |
| throw new Error("__Host- Cookie must have Secure attributes"); | |
| } | |
| if (opt.path !== "/") { | |
| throw new Error('__Host- Cookie must have Path attributes with "/"'); | |
| } | |
| if (opt.domain) { | |
| throw new Error("__Host- Cookie must not have Domain attributes"); | |
| } | |
| } | |
| if (opt && typeof opt.maxAge === "number" && opt.maxAge >= 0) { | |
| if (opt.maxAge > 3456e4) { | |
| throw new Error( | |
| "Cookies Max-Age SHOULD NOT be greater than 400 days (34560000 seconds) in duration." | |
| ); | |
| } | |
| cookie += `; Max-Age=${opt.maxAge | 0}`; | |
| } | |
| if (opt.domain && opt.prefix !== "host") { | |
| cookie += `; Domain=${opt.domain}`; | |
| } | |
| if (opt.path) { | |
| cookie += `; Path=${opt.path}`; | |
| } | |
| if (opt.expires) { | |
| if (opt.expires.getTime() - Date.now() > 3456e7) { | |
| throw new Error( | |
| "Cookies Expires SHOULD NOT be greater than 400 days (34560000 seconds) in the future." | |
| ); | |
| } | |
| cookie += `; Expires=${opt.expires.toUTCString()}`; | |
| } | |
| if (opt.httpOnly) { | |
| cookie += "; HttpOnly"; | |
| } | |
| if (opt.secure) { | |
| cookie += "; Secure"; | |
| } | |
| if (opt.sameSite) { | |
| cookie += `; SameSite=${opt.sameSite.charAt(0).toUpperCase() + opt.sameSite.slice(1)}`; | |
| } | |
| if (opt.priority) { | |
| cookie += `; Priority=${opt.priority.charAt(0).toUpperCase() + opt.priority.slice(1)}`; | |
| } | |
| if (opt.partitioned) { | |
| if (!opt.secure) { | |
| throw new Error("Partitioned Cookie must have Secure attributes"); | |
| } | |
| cookie += "; Partitioned"; | |
| } | |
| return cookie; | |
| }; | |
| var serialize = (name, value, opt) => { | |
| value = encodeURIComponent(value); | |
| return _serialize(name, value, opt); | |
| }; | |
| var serializeSigned = async (name, value, secret, opt = {}) => { | |
| const signature = await makeSignature(value, secret); | |
| value = `${value}.${signature}`; | |
| value = encodeURIComponent(value); | |
| return _serialize(name, value, opt); | |
| }; | |
| export { | |
| parse, | |
| parseSigned, | |
| serialize, | |
| serializeSigned | |
| }; | |
Xet Storage Details
- Size:
- 4.99 kB
- Xet hash:
- 13a00feaa1b8bdc2541f12d7eea50aec7701fe6674ba105a004ff099eb282a16
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.