{
  "version": 3,
  "sources": ["../src/index.ts"],
  "sourcesContent": ["import { webcrypto } from '@substrate-system/one-webcrypto'\nimport stringify from 'json-canon'\nimport { fromString, toString } from 'uint8arrays'\nimport {\n    type CookieEnv,\n    getCookieOptions,\n    timeSafeCompare as compare,\n    serializeCookie\n} from './util.js'\nexport { serializeCookie, CookieEnv }\n\n/**\n * Name to be used for the session cookie if none provided.\n */\nexport const SESSION_COOKIE_NAME_DEFAULT = 'session'\n\n/**\n * Length of the signature digest, in characters.\n * Used to separate signature from data in the raw session cookie.\n */\nconst SIGNATURE_DIGEST_LENGTH = 43\n\n/**\n * Patch and return the given headers instance, removing the cookie.\n *\n * @param {Headers} headers The headers to patch\n * @param {string} [name] Optional name of the cookie. Default is `session`.\n * @returns {Headers} The patchec headers\n */\nexport function rmCookie (headers:Headers, name?:string):Headers {\n    const key = name || SESSION_COOKIE_NAME_DEFAULT\n    const del = `${key}=deleted; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT`\n    headers.set('Set-Cookie', del)\n\n    return headers\n}\n\n/**\n * Parse the given cookie string into an object of key - values.\n *\n * @param {string} cookie The cookie string\n * @param {(s:string)=>string} [_decode] Optional decode function\n * @returns {Record<string, string>}\n */\nexport function parseCookie (\n    cookie:string,\n    _decode?:(s:string)=>string\n):(Record<string, string|boolean> & { session:string }) {\n    const dec = _decode || decode\n    const parsed = cookie.split(';').map(str => {\n        const split = str.trim().split('=')\n        return split\n    }).reduce<Record<string, string|true> & { session:string }>((acc, val) => {\n        acc[val[0]] = tryDecode(val[1], dec) ?? true\n        return acc\n    }, { session: '' })\n\n    return parsed\n}\n\n/**\n * Try decoding a string using a decoding function. Doesn't throw; returns\n * the input on error.\n *\n * @param {string} str\n * @param {function} decode\n * @returns {string}\n * @private\n */\nfunction tryDecode (str:string, decode:(s:string)=>string):string {\n    try {\n        return decode(str)\n    } catch (_err) {\n        return str\n    }\n}\n\n/**\n * Patch or create a Headers object.\n */\nexport function setCookie (\n    cookie:string,\n    _headers?:Headers,\n):Headers {\n    const headers = _headers || new Headers()\n    headers.set('Set-Cookie', cookie)\n\n    return headers\n}\n\n/**\n * Create a cookie and return it as a string.\n *\n * @param sessionData Data to encode with the cookie\n * @param secretKey The secret key\n * @param name The name for the cookie; defaults to `session`\n * @returns {string} The cookie as string\n */\nexport async function createCookie (\n    sessionData:Record<string, string>,\n    secretKey:string,\n    name?:string,\n    env?:CookieEnv,\n):Promise<string> {\n    const session = await createSession(sessionData, secretKey)\n    const newCookie = serializeCookie(\n        name || SESSION_COOKIE_NAME_DEFAULT,\n        session,\n        getCookieOptions(env)\n    )\n\n    return newCookie\n}\n\n/**\n * Create a new session token.\n *\n * @param newSessionData Any object of data to include in this session token.\n * @param {string} [secretKey] Optional secret key to use. Will get it from\n * environment variables if it is not passed in.\n * @returns {string} Signature + JSON session data encoded as base64\n */\nexport async function createSession (\n    newSessionData:Record<string, string>,\n    secretKey:string\n):Promise<string> {\n    const key = secretKey\n    const sessionAsJSON:string = stringify(newSessionData)\n\n    const arrFromString = fromString(sessionAsJSON, 'utf-8')\n    const base64Json = toString(arrFromString, 'base64')\n    const sig = await sign(sessionAsJSON, key)\n    // sig + base64SessionValue\n    const session = sig + base64Json\n\n    return session\n}\n\n/**\n * Given an encoded signature + data string, return if the signature is\n * valid for the data.\n * @param {string} session The encoded session cookie\n * @returns {boolean}\n */\nexport async function verifySessionString (\n    session:string,\n    key:string\n):Promise<boolean> {\n    const signature = session.substring(\n        0,\n        SIGNATURE_DIGEST_LENGTH\n    )\n\n    try {\n        let data:string = session.substring(SIGNATURE_DIGEST_LENGTH)\n        const arr = fromString(data, 'base64')\n        data = toString(arr, 'utf-8')\n\n        return await verify(key, data, signature)\n    } catch (_err) {\n        return false\n    }\n}\n\n/**\n * Compare a given signature to a new signature created with the given data.\n *\n * @param {string} key The key\n * @param {Buffer|string} data The data to sign\n * @param {string} signature The signature to check\n * @returns {boolean} True or false, if the signature is valid or not\n */\nasync function verify (\n    key:string,\n    data:Uint8Array|string,\n    signature:string\n):Promise<boolean> {\n    return await compare(signature, await sign(\n        (typeof data === 'string' ?\n            fromString(data) :\n            data) as Uint8Array<ArrayBuffer>,\n        key\n    ))\n}\n\n/**\n * Sign the given data and return the signature as a string.\n *\n * @returns {string}\n */\nexport async function sign (\n    data:string|Uint8Array<ArrayBuffer>,\n    key:string,\n    opts?:Partial<{\n        algorithm:'sha-256'|'sha-512';\n    }>\n):Promise<string> {\n    const algorithm = opts?.algorithm || 'sha-256'\n\n    // this gets called with `sessionDataAsJSON` for data param,\n    // so if string, it is not base64 encoded\n\n    const signingKey = await webcrypto.subtle.importKey(\n        'raw',\n        (fromString(key, 'base64')) as Uint8Array<ArrayBuffer>,\n        { name: 'HMAC', hash: algorithm },\n        false,\n        ['sign', 'verify']\n    )\n\n    const _data = typeof data === 'string' ?\n        fromString(data) as Uint8Array<ArrayBuffer> :\n        data\n\n    const sig = await webcrypto.subtle.sign(\n        'HMAC',\n        signingKey,\n        _data\n    )\n    const sigString = toString(new Uint8Array(sig), 'base64')\n\n    const str = sigString.replace(/\\/|\\+|=/g, (x) => {\n        return ({ '/': '_', '+': '-', '=': '' })[x] as string\n    })\n\n    return str\n}\n\n/**\n * This depends on the signature being a specific length.\n *\n * The cookie is serialized like `signature + base64(JSON.stringify(data))`\n */\nexport function parseSession<T=Record<string, string|boolean>> (\n    encodedSession:string\n):T|null {\n    const data:string = encodedSession.substring(SIGNATURE_DIGEST_LENGTH)\n    const asBuf = fromString(data, 'base64')\n    const asString = toString(asBuf, 'utf-8')\n    return JSON.parse(asString)\n}\n\n/**\n * URL-decode string value. Optimized to skip native call when no %.\n *\n * @param {string} str\n * @returns {string}\n */\nfunction decode (str:string):string {\n    return str.indexOf('%') !== -1 ?\n        decodeURIComponent(str) :\n        str\n}\n"],
  "mappings": "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",
  "names": ["decode", "stringify", "compare"]
}
