{
  "version": 3,
  "sources": ["../src/util.ts"],
  "sourcesContent": ["'use strict'\nimport { webcrypto } from '@substrate-system/one-webcrypto'\nimport { fromString } from 'uint8arrays'\n\n/**\n * Default for the \"Max-Age\" attribute of the session cookie.\n */\nconst COOKIE_MAX_AGE_SPAN_DEFAULT = (60 * 60 * 24 * 7)  // 1 week\n\n// Implements Brad Hill's Double HMAC pattern from\n// https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/february/double-hmac-verification/.\n// The approach is similar to the node's native implementation of timing safe buffer comparison that will be available on v6+.\n// https://github.com/nodejs/node/issues/3043\n// https://github.com/nodejs/node/pull/3073\n\n/**\n * RegExp to match field-content in RFC 7230 sec 3.2\n *\n * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]\n * field-vchar   = VCHAR / obs-text\n * obs-text      = %x80-FF\n */\nconst fieldContentRegExp = /^[\\u0009\\u0020-\\u007e\\u0080-\\u00ff]+$/\n\nexport async function timeSafeCompare (\n    a:string|Uint8Array<ArrayBuffer>,\n    b:string|Uint8Array<ArrayBuffer>\n) {\n    const bufA = typeof a === 'string' ?\n        fromString(a) as Uint8Array<ArrayBuffer> :\n        a\n    const bufB = typeof b === 'string' ?\n        fromString(b) as Uint8Array<ArrayBuffer> :\n        b\n    const algorithm = { name: 'HMAC', hash: 'SHA-256' }\n    const key = await webcrypto.subtle.generateKey(\n        algorithm,\n        false,\n        ['sign', 'verify']\n    ) as CryptoKey\n\n    const hmac = await webcrypto.subtle.sign(algorithm, key, bufA)\n    const equal = await webcrypto.subtle.verify(algorithm, key, hmac, bufB)\n    return equal\n}\n\nexport default timeSafeCompare\n\n/**\n * Serialize data into a cookie header.\n *\n * Serialize the a name value pair into a cookie string suitable for\n * http headers. An optional options object specified cookie parameters.\n *\n * serialize('foo', 'bar', { httpOnly: true })\n *   => \"foo=bar; httpOnly\"\n *\n * @param {string} name\n * @param {string} val\n * @param {object} [opts]\n * @return {string}\n */\nexport function serializeCookie (name:string, val:string, opts?:Partial<{\n    encode:(string)=>string;\n    maxAge;\n    domain;\n    path;\n    expires;\n    httpOnly:boolean;\n    secure;\n    partitioned;\n    priority;\n    sameSite;\n}>):string {\n    const enc = opts?.encode || encode\n\n    if (typeof enc !== 'function') {\n        throw new TypeError('option encode is invalid')\n    }\n\n    if (!fieldContentRegExp.test(name)) {\n        throw new TypeError('argument name is invalid')\n    }\n\n    const value = enc(val)\n\n    if (value && !fieldContentRegExp.test(value)) {\n        throw new TypeError('argument val is invalid')\n    }\n\n    let cookie = name + '=' + value\n\n    if (opts?.maxAge != null) {\n        const maxAge = opts?.maxAge - 0\n\n        if (isNaN(maxAge) || !isFinite(maxAge)) {\n            throw new TypeError('option maxAge is invalid')\n        }\n\n        cookie += '; Max-Age=' + Math.floor(maxAge)\n    }\n\n    if (opts?.domain) {\n        if (!fieldContentRegExp.test(opts?.domain)) {\n            throw new TypeError('option domain is invalid')\n        }\n\n        cookie += '; Domain=' + opts?.domain\n    }\n\n    if (opts?.path) {\n        if (!fieldContentRegExp.test(opts?.path)) {\n            throw new TypeError('option path is invalid')\n        }\n\n        cookie += '; Path=' + opts?.path\n    }\n\n    if (opts?.expires) {\n        const expires = opts?.expires\n\n        if (!isDate(expires) || isNaN(expires.valueOf())) {\n            throw new TypeError('option expires is invalid')\n        }\n\n        cookie += '; Expires=' + expires.toUTCString()\n    }\n\n    if (opts?.httpOnly) {\n        cookie += '; HttpOnly'\n    }\n\n    if (opts?.secure) {\n        cookie += '; Secure'\n    }\n\n    if (opts?.partitioned) {\n        cookie += '; Partitioned'\n    }\n\n    if (opts?.priority) {\n        const priority = typeof opts?.priority === 'string'\n            ? opts?.priority.toLowerCase()\n            : opts?.priority\n\n        switch (priority) {\n            case 'low':\n                cookie += '; Priority=Low'\n                break\n            case 'medium':\n                cookie += '; Priority=Medium'\n                break\n            case 'high':\n                cookie += '; Priority=High'\n                break\n            default:\n                throw new TypeError('option priority is invalid')\n        }\n    }\n\n    if (opts?.sameSite) {\n        const sameSite = typeof opts?.sameSite === 'string' ?\n            opts?.sameSite.toLowerCase() :\n            opts?.sameSite\n\n        switch (sameSite) {\n            case true:\n                cookie += '; SameSite=Strict'\n                break\n            case 'lax':\n                cookie += '; SameSite=Lax'\n                break\n            case 'strict':\n                cookie += '; SameSite=Strict'\n                break\n            case 'none':\n                cookie += '; SameSite=None'\n                break\n            default:\n                throw new TypeError('option sameSite is invalid')\n        }\n    }\n\n    return cookie\n}\n\n/**\n * URL-encode value.\n *\n * @param {string} val\n * @returns {string}\n */\n\nfunction encode (val:string):string {\n    return encodeURIComponent(val)\n}\n\nconst __toString = Object.prototype.toString\n\n/**\n * Determine if value is a Date.\n *\n * @param {*} val\n */\nfunction isDate (val:any):boolean {\n    return __toString.call(val) === '[object Date]' ||\n      val instanceof Date\n}\n\nexport type CookieEnv = Partial<{\n    COOKIE_HTTPONLY:string;\n    COOKIE_SECURE:string;\n    COOKIE_SAMESITE:string;\n    COOKIE_MAX_AGE_SPAN:string;\n    COOKIE_DOMAIN:string;\n    COOKIE_PATH:string;\n}>\n\n/**\n * Builds an option object to be used by the cookie serializer.\n * All options have defaults which can be edited using environment variables.\n *\n * Environment variables available:\n * - `env.COOKIE_HTTPONLY`:\n *   Specifies if the cookie should have the `HttpOnly` attribute.\n *   Set to \"0\" to remove this attribute from the cookie definition.\n * - `env.COOKIE_SECURE`:\n *   Specifies if the cookie should have the `Secure` attribute.\n *   Set to \"0\" to remove this attribute from the cookie definition.\n * - `env.COOKIE_SAMESITE`:\n *   Will specify the value for the `SameSite` attribute for the cookie.\n *   Can be \"Strict\", \"None\" or \"Lax\" (default).\n * - `env.COOKIE_MAX_AGE_SPAN`:\n *   Specifies, in second, how long the cookie should be valid for.\n *   Defaults to 7 days.\n * - `env.COOKIE_DOMAIN`:\n *   If set, will specify a value for the `Domain` attribute for the cookie.\n * - `env.COOKIE_PATH`:\n *   If set, will specify a value for the `Path` attribute for the cookie.\n *   Defaults to `/`.\n *\n * @returns {object} - Options object for `cookie.serialize`\n * @private\n */\nexport function getCookieOptions (env:CookieEnv = {}) {\n    // Defaults (options detail: https://github.com/jshttp/cookie#options-1)\n    const options:Partial<{\n        httpOnly,\n        secure,\n        sameSite,\n        maxAge,\n        path,\n        domain\n    }> = {\n        httpOnly: true,\n        secure: true,\n        sameSite: 'lax',\n        maxAge: COOKIE_MAX_AGE_SPAN_DEFAULT,\n        path: '/'\n    }\n\n    //\n    // Use environment variables to edit defaults.\n    //\n    const {\n        COOKIE_HTTPONLY,\n        COOKIE_SECURE,\n        COOKIE_SAMESITE,\n        COOKIE_MAX_AGE_SPAN,\n        COOKIE_DOMAIN,\n        COOKIE_PATH\n    } = env\n\n    // HttpOnly\n    if (COOKIE_HTTPONLY === '0') {\n        delete options.httpOnly\n    }\n\n    // Secure\n    if (COOKIE_SECURE === '0') {\n        delete options.secure\n    }\n\n    // SameSite\n    if (['Strict', 'Lax', 'None'].includes(COOKIE_SAMESITE!)) {\n        options.sameSite = COOKIE_SAMESITE!.toLowerCase()\n    }\n\n    // Max-Age\n    if (!isNaN(parseInt(COOKIE_MAX_AGE_SPAN!))) {\n        options.maxAge = parseInt(COOKIE_MAX_AGE_SPAN!)\n    }\n\n    // Domain\n    if (COOKIE_DOMAIN) {\n        options.domain = COOKIE_DOMAIN\n    }\n\n    // Path\n    if (COOKIE_PATH) {\n        options.path = COOKIE_PATH\n    }\n\n    return options\n}\n"],
  "mappings": "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",
  "names": []
}
