From b628952e65d98df0be7a7451cce61142f9436799 Mon Sep 17 00:00:00 2001 From: shkuls Date: Sat, 11 Jul 2026 16:33:02 +0530 Subject: [PATCH 1/2] fix(functions): use error key for JWT verification failures in serve.main.ts The edge-runtime bootstrap template returned JWT verification failures as { msg: "..." }, inconsistent with the platform gateway's { error: "..." } shape. Consumers (e.g. Studio's edge function test panel) that check the error key never see the real failure reason on `supabase start`. Aligns both JWT-failure paths to { error: "..." }, matching the shape already used elsewhere in this same file for worker boot/crash errors. Regenerated the Go CLI's bundled copy of the template (drift-guard test in serve-main-go-template.unit.test.ts) and added an e2e test that boots the real bundled template under edge-runtime and asserts on the response shape for both JWT-failure paths (missing header, wrongly-signed token). Related: supabase/supabase#47835, supabase/supabase#47836 --- .../functions/serve/templates/main.bundled.js | 2 +- .../serve-main-jwt-error-shape.e2e.test.ts | 163 ++++++++++++++++++ apps/cli/src/shared/functions/serve.main.ts | 4 +- 3 files changed, 166 insertions(+), 3 deletions(-) create mode 100644 apps/cli/src/shared/functions/serve-main-jwt-error-shape.e2e.test.ts diff --git a/apps/cli-go/internal/functions/serve/templates/main.bundled.js b/apps/cli-go/internal/functions/serve/templates/main.bundled.js index 101a7920cd..dd4246b587 100644 --- a/apps/cli-go/internal/functions/serve/templates/main.bundled.js +++ b/apps/cli-go/internal/functions/serve/templates/main.bundled.js @@ -1,4 +1,4 @@ -var h={OK:200,Unauthorized:401,NotFound:404,InternalServerError:500,ServiceUnavailable:503},Z={[h.OK]:"OK",[h.Unauthorized]:"Unauthorized",[h.NotFound]:"Not Found",[h.InternalServerError]:"Internal Server Error",[h.ServiceUnavailable]:"Service Unavailable"};function Ye(e){let t=e.startsWith("/"),r=[];for(let n of e.split("/"))if(!(n===""||n===".")){if(n===".."){r.length>0&&r[r.length-1]!==".."?r.pop():t||r.push("..");continue}r.push(n)}let o=r.join("/");return t?"/"+o:o===""?".":o}function Q(...e){let t=e.filter(r=>r.length>0).join("/");return t===""?".":Ye(t)}function ee(e){if(e.length===0)return".";let t=e.length;for(;t>1&&e[t-1]==="/";)t-=1;let r=e.slice(0,t),o=r.lastIndexOf("/");return o===-1?".":o===0?"/":r.slice(0,o)}function qe(e){return e.replace(/\s/g,t=>`%${t.charCodeAt(0).toString(16).padStart(2,"0").toUpperCase()}`)}function me(e){if(!e.startsWith("/"))throw new TypeError(`Path must be absolute: received "${e}"`);let t=new URL("file:///");return t.pathname=qe(e.replace(/%/g,"%25").replace(/\\/g,"%5C")),t}var L=new TextEncoder,g=new TextDecoder,Ut=2**32;function ye(...e){let t=e.reduce((n,{length:i})=>n+i,0),r=new Uint8Array(t),o=0;for(let n of e)r.set(n,o),o+=n.length;return r}function k(e){let t=new Uint8Array(e.length);for(let r=0;r127)throw new TypeError("non-ASCII string encountered in encode()");t[r]=o}return t}function Se(e){if(Uint8Array.fromBase64)return Uint8Array.fromBase64(e);let t=atob(e),r=new Uint8Array(t.length);for(let o=0;onew TypeError(`CryptoKey does not support this operation, its ${t} must be ${e}`),W=(e,t)=>e.name===t;function je(e){return parseInt(e.name.slice(4),10)}function te(e,t){if(je(e.hash)!==t)throw T(`SHA-${t}`,"algorithm.hash")}function Ze(e){switch(e){case"ES256":return"P-256";case"ES384":return"P-384";case"ES512":return"P-521";default:throw new Error("unreachable")}}function Qe(e,t){if(t&&!e.usages.includes(t))throw new TypeError(`CryptoKey does not support this operation, its usages must include ${t}.`)}function Ee(e,t,r){switch(t){case"HS256":case"HS384":case"HS512":{if(!W(e.algorithm,"HMAC"))throw T("HMAC");te(e.algorithm,parseInt(t.slice(2),10));break}case"RS256":case"RS384":case"RS512":{if(!W(e.algorithm,"RSASSA-PKCS1-v1_5"))throw T("RSASSA-PKCS1-v1_5");te(e.algorithm,parseInt(t.slice(2),10));break}case"PS256":case"PS384":case"PS512":{if(!W(e.algorithm,"RSA-PSS"))throw T("RSA-PSS");te(e.algorithm,parseInt(t.slice(2),10));break}case"Ed25519":case"EdDSA":{if(!W(e.algorithm,"Ed25519"))throw T("Ed25519");break}case"ML-DSA-44":case"ML-DSA-65":case"ML-DSA-87":{if(!W(e.algorithm,t))throw T(t);break}case"ES256":case"ES384":case"ES512":{if(!W(e.algorithm,"ECDSA"))throw T("ECDSA");let o=Ze(t);if(e.algorithm.namedCurve!==o)throw T(o,"algorithm.namedCurve");break}default:throw new TypeError("CryptoKey does not support this operation")}Qe(e,r)}function we(e,t,...r){if(r=r.filter(Boolean),r.length>2){let o=r.pop();e+=`one of type ${r.join(", ")}, or ${o}.`}else r.length===2?e+=`one of type ${r[0]} or ${r[1]}.`:e+=`of type ${r[0]}.`;return t==null?e+=` Received ${t}`:typeof t=="function"&&t.name?e+=` Received function ${t.name}`:typeof t=="object"&&t!=null&&t.constructor?.name&&(e+=` Received an instance of ${t.constructor.name}`),e}var ge=(e,...t)=>we("Key must be ",e,...t),re=(e,t,...r)=>we(`Key for the ${e} algorithm must be `,t,...r);var m=class extends Error{static code="ERR_JOSE_GENERIC";code="ERR_JOSE_GENERIC";constructor(t,r){super(t,r),this.name=this.constructor.name,Error.captureStackTrace?.(this,this.constructor)}},w=class extends m{static code="ERR_JWT_CLAIM_VALIDATION_FAILED";code="ERR_JWT_CLAIM_VALIDATION_FAILED";claim;reason;payload;constructor(t,r,o="unspecified",n="unspecified"){super(t,{cause:{claim:o,reason:n,payload:r}}),this.claim=o,this.reason=n,this.payload=r}},M=class extends m{static code="ERR_JWT_EXPIRED";code="ERR_JWT_EXPIRED";claim;reason;payload;constructor(t,r,o="unspecified",n="unspecified"){super(t,{cause:{claim:o,reason:n,payload:r}}),this.claim=o,this.reason=n,this.payload=r}},F=class extends m{static code="ERR_JOSE_ALG_NOT_ALLOWED";code="ERR_JOSE_ALG_NOT_ALLOWED"},l=class extends m{static code="ERR_JOSE_NOT_SUPPORTED";code="ERR_JOSE_NOT_SUPPORTED"};var u=class extends m{static code="ERR_JWS_INVALID";code="ERR_JWS_INVALID"},v=class extends m{static code="ERR_JWT_INVALID";code="ERR_JWT_INVALID"};var H=class extends m{static code="ERR_JWKS_INVALID";code="ERR_JWKS_INVALID"},I=class extends m{static code="ERR_JWKS_NO_MATCHING_KEY";code="ERR_JWKS_NO_MATCHING_KEY";constructor(t="no applicable key found in the JSON Web Key Set",r){super(t,r)}},$=class extends m{[Symbol.asyncIterator];static code="ERR_JWKS_MULTIPLE_MATCHING_KEYS";code="ERR_JWKS_MULTIPLE_MATCHING_KEYS";constructor(t="multiple matching keys found in the JSON Web Key Set",r){super(t,r)}},V=class extends m{static code="ERR_JWKS_TIMEOUT";code="ERR_JWKS_TIMEOUT";constructor(t="request timed out",r){super(t,r)}},G=class extends m{static code="ERR_JWS_SIGNATURE_VERIFICATION_FAILED";code="ERR_JWS_SIGNATURE_VERIFICATION_FAILED";constructor(t="signature verification failed",r){super(t,r)}};var oe=e=>{if(e?.[Symbol.toStringTag]==="CryptoKey")return!0;try{return e instanceof CryptoKey}catch{return!1}},ne=e=>e?.[Symbol.toStringTag]==="KeyObject",ie=e=>oe(e)||ne(e);function se(e,t,r){try{return A(e)}catch{throw new r(`Failed to base64url decode the ${t}`)}}var et=e=>typeof e=="object"&&e!==null;function y(e){if(!et(e)||Object.prototype.toString.call(e)!=="[object Object]")return!1;if(Object.getPrototypeOf(e)===null)return!0;let t=e;for(;Object.getPrototypeOf(t)!==null;)t=Object.getPrototypeOf(t);return Object.getPrototypeOf(e)===t}function Ae(...e){let t=e.filter(Boolean);if(t.length===0||t.length===1)return!0;let r;for(let o of t){let n=Object.keys(o);if(!r||r.size===0){r=new Set(n);continue}for(let i of n){if(r.has(i))return!1;r.add(i)}}return!0}var B=e=>y(e)&&typeof e.kty=="string",be=e=>e.kty!=="oct"&&(e.kty==="AKP"&&typeof e.priv=="string"||typeof e.d=="string"),Re=e=>e.kty!=="oct"&&e.d===void 0&&e.priv===void 0,Te=e=>e.kty==="oct"&&typeof e.k=="string";function rt(e,t){if(e.startsWith("RS")||e.startsWith("PS")){let{modulusLength:r}=t.algorithm;if(typeof r!="number"||r<2048)throw new TypeError(`${e} requires key modulusLength to be 2048 bits or larger`)}}function ot(e,t){let r=`SHA-${e.slice(-3)}`;switch(e){case"HS256":case"HS384":case"HS512":return{hash:r,name:"HMAC"};case"PS256":case"PS384":case"PS512":return{hash:r,name:"RSA-PSS",saltLength:parseInt(e.slice(-3),10)>>3};case"RS256":case"RS384":case"RS512":return{hash:r,name:"RSASSA-PKCS1-v1_5"};case"ES256":case"ES384":case"ES512":return{hash:r,name:"ECDSA",namedCurve:t.namedCurve};case"Ed25519":case"EdDSA":return{name:"Ed25519"};case"ML-DSA-44":case"ML-DSA-65":case"ML-DSA-87":return{name:e};default:throw new l(`alg ${e} is not supported either by JOSE or your javascript runtime`)}}async function nt(e,t,r){if(t instanceof Uint8Array){if(!e.startsWith("HS"))throw new TypeError(ge(t,"CryptoKey","KeyObject","JSON Web Key"));return crypto.subtle.importKey("raw",t,{hash:`SHA-${e.slice(-3)}`,name:"HMAC"},!1,[r])}return Ee(t,e,r),t}async function Ke(e,t,r,o){let n=await nt(e,t,"verify");rt(e,n);let i=ot(e,n.algorithm);try{return await crypto.subtle.verify(i,n,r,o)}catch{return!1}}var X='Invalid or unsupported JWK "alg" (Algorithm) Parameter value';function it(e){let t,r;switch(e.kty){case"AKP":{switch(e.alg){case"ML-DSA-44":case"ML-DSA-65":case"ML-DSA-87":t={name:e.alg},r=e.priv?["sign"]:["verify"];break;default:throw new l(X)}break}case"RSA":{switch(e.alg){case"PS256":case"PS384":case"PS512":t={name:"RSA-PSS",hash:`SHA-${e.alg.slice(-3)}`},r=e.d?["sign"]:["verify"];break;case"RS256":case"RS384":case"RS512":t={name:"RSASSA-PKCS1-v1_5",hash:`SHA-${e.alg.slice(-3)}`},r=e.d?["sign"]:["verify"];break;case"RSA-OAEP":case"RSA-OAEP-256":case"RSA-OAEP-384":case"RSA-OAEP-512":t={name:"RSA-OAEP",hash:`SHA-${parseInt(e.alg.slice(-3),10)||1}`},r=e.d?["decrypt","unwrapKey"]:["encrypt","wrapKey"];break;default:throw new l(X)}break}case"EC":{switch(e.alg){case"ES256":case"ES384":case"ES512":t={name:"ECDSA",namedCurve:{ES256:"P-256",ES384:"P-384",ES512:"P-521"}[e.alg]},r=e.d?["sign"]:["verify"];break;case"ECDH-ES":case"ECDH-ES+A128KW":case"ECDH-ES+A192KW":case"ECDH-ES+A256KW":t={name:"ECDH",namedCurve:e.crv},r=e.d?["deriveBits"]:[];break;default:throw new l(X)}break}case"OKP":{switch(e.alg){case"Ed25519":case"EdDSA":t={name:"Ed25519"},r=e.d?["sign"]:["verify"];break;case"ECDH-ES":case"ECDH-ES+A128KW":case"ECDH-ES+A192KW":case"ECDH-ES+A256KW":t={name:e.crv},r=e.d?["deriveBits"]:[];break;default:throw new l(X)}break}default:throw new l('Invalid or unsupported JWK "kty" (Key Type) Parameter value')}return{algorithm:t,keyUsages:r}}async function O(e){if(!e.alg)throw new TypeError('"alg" argument is required when "jwk.alg" is not present');let{algorithm:t,keyUsages:r}=it(e),o={...e};return o.kty!=="AKP"&&delete o.alg,delete o.use,crypto.subtle.importKey("jwk",o,t,e.ext??!(e.d||e.priv),e.key_ops??r)}var J="given KeyObject instance cannot be used for this algorithm",N,_e=async(e,t,r,o=!1)=>{N||=new WeakMap;let n=N.get(e);if(n?.[r])return n[r];let i=await O({...t,alg:r});return o&&Object.freeze(e),n?n[r]=i:N.set(e,{[r]:i}),i},st=(e,t)=>{N||=new WeakMap;let r=N.get(e);if(r?.[t])return r[t];let o=e.type==="public",n=!!o,i;if(e.asymmetricKeyType==="x25519"){switch(t){case"ECDH-ES":case"ECDH-ES+A128KW":case"ECDH-ES+A192KW":case"ECDH-ES+A256KW":break;default:throw new TypeError(J)}i=e.toCryptoKey(e.asymmetricKeyType,n,o?[]:["deriveBits"])}if(e.asymmetricKeyType==="ed25519"){if(t!=="EdDSA"&&t!=="Ed25519")throw new TypeError(J);i=e.toCryptoKey(e.asymmetricKeyType,n,[o?"verify":"sign"])}switch(e.asymmetricKeyType){case"ml-dsa-44":case"ml-dsa-65":case"ml-dsa-87":{if(t!==e.asymmetricKeyType.toUpperCase())throw new TypeError(J);i=e.toCryptoKey(e.asymmetricKeyType,n,[o?"verify":"sign"])}}if(e.asymmetricKeyType==="rsa"){let s;switch(t){case"RSA-OAEP":s="SHA-1";break;case"RS256":case"PS256":case"RSA-OAEP-256":s="SHA-256";break;case"RS384":case"PS384":case"RSA-OAEP-384":s="SHA-384";break;case"RS512":case"PS512":case"RSA-OAEP-512":s="SHA-512";break;default:throw new TypeError(J)}if(t.startsWith("RSA-OAEP"))return e.toCryptoKey({name:"RSA-OAEP",hash:s},n,o?["encrypt"]:["decrypt"]);i=e.toCryptoKey({name:t.startsWith("PS")?"RSA-PSS":"RSASSA-PKCS1-v1_5",hash:s},n,[o?"verify":"sign"])}if(e.asymmetricKeyType==="ec"){let f=new Map([["prime256v1","P-256"],["secp384r1","P-384"],["secp521r1","P-521"]]).get(e.asymmetricKeyDetails?.namedCurve);if(!f)throw new TypeError(J);let p={ES256:"P-256",ES384:"P-384",ES512:"P-521"};p[t]&&f===p[t]&&(i=e.toCryptoKey({name:"ECDSA",namedCurve:f},n,[o?"verify":"sign"])),t.startsWith("ECDH-ES")&&(i=e.toCryptoKey({name:"ECDH",namedCurve:f},n,o?[]:["deriveBits"]))}if(!i)throw new TypeError(J);return r?r[t]=i:N.set(e,{[t]:i}),i};async function Pe(e,t){if(e instanceof Uint8Array||oe(e))return e;if(ne(e)){if(e.type==="secret")return e.export();if("toCryptoKey"in e&&typeof e.toCryptoKey=="function")try{return st(e,t)}catch(o){if(o instanceof TypeError)throw o}let r=e.export({format:"jwk"});return _e(e,r,t)}if(B(e))return e.k?A(e.k):_e(e,e,t,!0);throw new Error("unreachable")}async function Ce(e,t,r){if(!y(e))throw new TypeError("JWK must be an object");let o;switch(t??=e.alg,o??=r?.extractable??e.ext,e.kty){case"oct":if(typeof e.k!="string"||!e.k)throw new TypeError('missing "k" (Key Value) Parameter value');return A(e.k);case"RSA":if("oth"in e&&e.oth!==void 0)throw new l('RSA JWK "oth" (Other Primes Info) Parameter value is not supported');return O({...e,alg:t,ext:o});case"AKP":{if(typeof e.alg!="string"||!e.alg)throw new TypeError('missing "alg" (Algorithm) Parameter value');if(t!==void 0&&t!==e.alg)throw new TypeError("JWK alg and alg option value mismatch");return O({...e,ext:o})}case"EC":case"OKP":return O({...e,alg:t,ext:o});default:throw new l('Unsupported "kty" (Key Type) Parameter value')}}function xe(e,t,r,o,n){if(n.crit!==void 0&&o?.crit===void 0)throw new e('"crit" (Critical) Header Parameter MUST be integrity protected');if(!o||o.crit===void 0)return new Set;if(!Array.isArray(o.crit)||o.crit.length===0||o.crit.some(s=>typeof s!="string"||s.length===0))throw new e('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');let i;r!==void 0?i=new Map([...Object.entries(r),...t.entries()]):i=t;for(let s of o.crit){if(!i.has(s))throw new l(`Extension Header Parameter "${s}" is not recognized`);if(n[s]===void 0)throw new e(`Extension Header Parameter "${s}" is missing`);if(i.get(s)&&o[s]===void 0)throw new e(`Extension Header Parameter "${s}" MUST be integrity protected`)}return new Set(o.crit)}function We(e,t){if(t!==void 0&&(!Array.isArray(t)||t.some(r=>typeof r!="string")))throw new TypeError(`"${e}" option must be an array of strings`);if(t)return new Set(t)}var D=e=>e?.[Symbol.toStringTag],ae=(e,t,r)=>{if(t.use!==void 0){let o;switch(r){case"sign":case"verify":o="sig";break;case"encrypt":case"decrypt":o="enc";break}if(t.use!==o)throw new TypeError(`Invalid key for this operation, its "use" must be "${o}" when present`)}if(t.alg!==void 0&&t.alg!==e)throw new TypeError(`Invalid key for this operation, its "alg" must be "${e}" when present`);if(Array.isArray(t.key_ops)){let o;switch(!0){case(r==="sign"||r==="verify"):case e==="dir":case e.includes("CBC-HS"):o=r;break;case e.startsWith("PBES2"):o="deriveBits";break;case/^A\d{3}(?:GCM)?(?:KW)?$/.test(e):!e.includes("GCM")&&e.endsWith("KW")?o=r==="encrypt"?"wrapKey":"unwrapKey":o=r;break;case(r==="encrypt"&&e.startsWith("RSA")):o="wrapKey";break;case r==="decrypt":o=e.startsWith("RSA")?"unwrapKey":"deriveBits";break}if(o&&t.key_ops?.includes?.(o)===!1)throw new TypeError(`Invalid key for this operation, its "key_ops" must include "${o}" when present`)}return!0},at=(e,t,r)=>{if(!(t instanceof Uint8Array)){if(B(t)){if(Te(t)&&ae(e,t,r))return;throw new TypeError('JSON Web Key for symmetric algorithms must have JWK "kty" (Key Type) equal to "oct" and the JWK "k" (Key Value) present')}if(!ie(t))throw new TypeError(re(e,t,"CryptoKey","KeyObject","JSON Web Key","Uint8Array"));if(t.type!=="secret")throw new TypeError(`${D(t)} instances for symmetric algorithms must be of type "secret"`)}},ct=(e,t,r)=>{if(B(t))switch(r){case"decrypt":case"sign":if(be(t)&&ae(e,t,r))return;throw new TypeError("JSON Web Key for this operation must be a private JWK");case"encrypt":case"verify":if(Re(t)&&ae(e,t,r))return;throw new TypeError("JSON Web Key for this operation must be a public JWK")}if(!ie(t))throw new TypeError(re(e,t,"CryptoKey","KeyObject","JSON Web Key"));if(t.type==="secret")throw new TypeError(`${D(t)} instances for asymmetric algorithms must not be of type "secret"`);if(t.type==="public")switch(r){case"sign":throw new TypeError(`${D(t)} instances for asymmetric algorithm signing must be of type "private"`);case"decrypt":throw new TypeError(`${D(t)} instances for asymmetric algorithm decryption must be of type "private"`)}if(t.type==="private")switch(r){case"verify":throw new TypeError(`${D(t)} instances for asymmetric algorithm verifying must be of type "public"`);case"encrypt":throw new TypeError(`${D(t)} instances for asymmetric algorithm encryption must be of type "public"`)}};function ve(e,t,r){switch(e.substring(0,2)){case"A1":case"A2":case"di":case"HS":case"PB":at(e,t,r);break;default:ct(e,t,r)}}async function Ie(e,t,r){if(!y(e))throw new u("Flattened JWS must be an object");if(e.protected===void 0&&e.header===void 0)throw new u('Flattened JWS must have either of the "protected" or "header" members');if(e.protected!==void 0&&typeof e.protected!="string")throw new u("JWS Protected Header incorrect type");if(e.payload===void 0)throw new u("JWS Payload missing");if(typeof e.signature!="string")throw new u("JWS Signature missing or incorrect type");if(e.header!==void 0&&!y(e.header))throw new u("JWS Unprotected Header incorrect type");let o={};if(e.protected)try{let q=A(e.protected);o=JSON.parse(g.decode(q))}catch{throw new u("JWS Protected Header is invalid")}if(!Ae(o,e.header))throw new u("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");let n={...o,...e.header},i=xe(u,new Map([["b64",!0]]),r?.crit,o,n),s=!0;if(i.has("b64")&&(s=o.b64,typeof s!="boolean"))throw new u('The "b64" (base64url-encode payload) Header Parameter must be a boolean');let{alg:f}=n;if(typeof f!="string"||!f)throw new u('JWS "alg" (Algorithm) Header Parameter missing or invalid');let p=r&&We("algorithms",r.algorithms);if(p&&!p.has(f))throw new F('"alg" (Algorithm) Header Parameter value not allowed');if(s){if(typeof e.payload!="string")throw new u("JWS Payload must be a string")}else if(typeof e.payload!="string"&&!(e.payload instanceof Uint8Array))throw new u("JWS Payload must be a string or an Uint8Array instance");let a=!1;typeof t=="function"&&(t=await t(o,e),a=!0),ve(f,t,"verify");let c=ye(e.protected!==void 0?k(e.protected):new Uint8Array,k("."),typeof e.payload=="string"?s?k(e.payload):L.encode(e.payload):e.payload),S=se(e.signature,"signature",u),C=await Pe(t,f);if(!await Ke(f,C,S,c))throw new G;let E;s?E=se(e.payload,"payload",u):typeof e.payload=="string"?E=L.encode(e.payload):E=e.payload;let R={payload:E};return e.protected!==void 0&&(R.protectedHeader=o),e.header!==void 0&&(R.unprotectedHeader=e.header),a?{...R,key:C}:R}async function Oe(e,t,r){if(e instanceof Uint8Array&&(e=g.decode(e)),typeof e!="string")throw new u("Compact JWS must be a string or Uint8Array");let{0:o,1:n,2:i,length:s}=e.split(".");if(s!==3)throw new u("Invalid Compact JWS");let f=await Ie({payload:n,protected:o,signature:i},t,r),p={payload:f.payload,protectedHeader:f.protectedHeader};return typeof t=="function"?{...p,key:f.key}:p}var ft=e=>Math.floor(e.getTime()/1e3),De=60,Ue=De*60,ce=Ue*24,ut=ce*7,pt=ce*365.25,dt=/^(\+|\-)? ?(\d+|\d+\.\d+) ?(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)(?: (ago|from now))?$/i;function Je(e){let t=dt.exec(e);if(!t||t[4]&&t[1])throw new TypeError("Invalid time period format");let r=parseFloat(t[2]),o=t[3].toLowerCase(),n;switch(o){case"sec":case"secs":case"second":case"seconds":case"s":n=Math.round(r);break;case"minute":case"minutes":case"min":case"mins":case"m":n=Math.round(r*De);break;case"hour":case"hours":case"hr":case"hrs":case"h":n=Math.round(r*Ue);break;case"day":case"days":case"d":n=Math.round(r*ce);break;case"week":case"weeks":case"w":n=Math.round(r*ut);break;default:n=Math.round(r*pt);break}return t[1]==="-"||t[4]==="ago"?-n:n}var Ne=e=>e.includes("/")?e.toLowerCase():`application/${e.toLowerCase()}`,lt=(e,t)=>typeof e=="string"?t.includes(e):Array.isArray(e)?t.some(Set.prototype.has.bind(new Set(e))):!1;function Le(e,t,r={}){let o;try{o=JSON.parse(g.decode(t))}catch{}if(!y(o))throw new v("JWT Claims Set must be a top-level JSON object");let{typ:n}=r;if(n&&(typeof e.typ!="string"||Ne(e.typ)!==Ne(n)))throw new w('unexpected "typ" JWT header value',o,"typ","check_failed");let{requiredClaims:i=[],issuer:s,subject:f,audience:p,maxTokenAge:a}=r,c=[...i];a!==void 0&&c.push("iat"),p!==void 0&&c.push("aud"),f!==void 0&&c.push("sub"),s!==void 0&&c.push("iss");for(let E of new Set(c.reverse()))if(!(E in o))throw new w(`missing required "${E}" claim`,o,E,"missing");if(s&&!(Array.isArray(s)?s:[s]).includes(o.iss))throw new w('unexpected "iss" claim value',o,"iss","check_failed");if(f&&o.sub!==f)throw new w('unexpected "sub" claim value',o,"sub","check_failed");if(p&&!lt(o.aud,typeof p=="string"?[p]:p))throw new w('unexpected "aud" claim value',o,"aud","check_failed");let S;switch(typeof r.clockTolerance){case"string":S=Je(r.clockTolerance);break;case"number":S=r.clockTolerance;break;case"undefined":S=0;break;default:throw new TypeError("Invalid clockTolerance option type")}let{currentDate:C}=r,x=ft(C||new Date);if((o.iat!==void 0||a)&&typeof o.iat!="number")throw new w('"iat" claim must be a number',o,"iat","invalid");if(o.nbf!==void 0){if(typeof o.nbf!="number")throw new w('"nbf" claim must be a number',o,"nbf","invalid");if(o.nbf>x+S)throw new w('"nbf" claim timestamp check failed',o,"nbf","check_failed")}if(o.exp!==void 0){if(typeof o.exp!="number")throw new w('"exp" claim must be a number',o,"exp","invalid");if(o.exp<=x-S)throw new M('"exp" claim timestamp check failed',o,"exp","check_failed")}if(a){let E=x-o.iat,R=typeof a=="number"?a:Je(a);if(E-S>R)throw new M('"iat" claim timestamp check failed (too far in the past)',o,"iat","check_failed");if(E<0-S)throw new w('"iat" claim timestamp check failed (it should be in the past)',o,"iat","check_failed")}return o}async function z(e,t,r){let o=await Oe(e,t,r);if(o.protectedHeader.crit?.includes("b64")&&o.protectedHeader.b64===!1)throw new v("JWTs MUST NOT use unencoded payload");let i={payload:Le(o.protectedHeader,o.payload,r),protectedHeader:o.protectedHeader};return typeof t=="function"?{...i,key:o.key}:i}function ht(e){switch(typeof e=="string"&&e.slice(0,2)){case"RS":case"PS":return"RSA";case"ES":return"EC";case"Ed":return"OKP";case"ML":return"AKP";default:throw new l('Unsupported "alg" value for a JSON Web Key Set')}}function mt(e){return e&&typeof e=="object"&&Array.isArray(e.keys)&&e.keys.every(yt)}function yt(e){return y(e)}var fe=class{#r;#s=new WeakMap;constructor(t){if(!mt(t))throw new H("JSON Web Key Set malformed");this.#r=structuredClone(t)}jwks(){return this.#r}async getKey(t,r){let{alg:o,kid:n}={...t,...r?.header},i=ht(o),s=this.#r.keys.filter(a=>{let c=i===a.kty;if(c&&typeof n=="string"&&(c=n===a.kid),c&&(typeof a.alg=="string"||i==="AKP")&&(c=o===a.alg),c&&typeof a.use=="string"&&(c=a.use==="sig"),c&&Array.isArray(a.key_ops)&&(c=a.key_ops.includes("verify")),c)switch(o){case"ES256":c=a.crv==="P-256";break;case"ES384":c=a.crv==="P-384";break;case"ES512":c=a.crv==="P-521";break;case"Ed25519":case"EdDSA":c=a.crv==="Ed25519";break}return c}),{0:f,length:p}=s;if(p===0)throw new I;if(p!==1){let a=new $,c=this.#s;throw a[Symbol.asyncIterator]=async function*(){for(let S of s)try{yield await Me(c,S,o)}catch{}},a}return Me(this.#s,f,o)}};async function Me(e,t,r){let o=e.get(t)||e.set(t,{}).get(t);if(o[r]===void 0){let n=await Ce({...t,ext:!0},r);if(n instanceof Uint8Array||n.type!=="public")throw new H("JSON Web Key Set members must be public keys");o[r]=n}return o[r]}function U(e){let t=new fe(e),r=async(o,n)=>t.getKey(o,n);return Object.defineProperties(r,{jwks:{value:()=>structuredClone(t.jwks()),enumerable:!1,configurable:!1,writable:!1}}),r}function St(){return typeof WebSocketPair<"u"||typeof navigator<"u"&&navigator.userAgent==="Cloudflare-Workers"||typeof EdgeRuntime<"u"&&EdgeRuntime==="vercel"}var ue;(typeof navigator>"u"||!navigator.userAgent?.startsWith?.("Mozilla/5.0 "))&&(ue="jose/v6.2.3");var He=Symbol();async function Et(e,t,r,o=fetch){let n=await o(e,{method:"GET",signal:r,redirect:"manual",headers:t}).catch(i=>{throw i.name==="TimeoutError"?new V:i});if(n.status!==200)throw new m("Expected 200 OK from the JSON Web Key Set HTTP response");try{return await n.json()}catch{throw new m("Failed to parse the JSON Web Key Set HTTP response as JSON")}}var Y=Symbol();function wt(e,t){return!(typeof e!="object"||e===null||!("uat"in e)||typeof e.uat!="number"||Date.now()-e.uat>=t||!("jwks"in e)||!y(e.jwks)||!Array.isArray(e.jwks.keys)||!Array.prototype.every.call(e.jwks.keys,y))}var pe=class{#r;#s;#c;#a;#o;#e;#t;#f;#n;#i;constructor(t,r){if(!(t instanceof URL))throw new TypeError("url must be an instance of URL");this.#r=new URL(t.href),this.#s=typeof r?.timeoutDuration=="number"?r?.timeoutDuration:5e3,this.#c=typeof r?.cooldownDuration=="number"?r?.cooldownDuration:3e4,this.#a=typeof r?.cacheMaxAge=="number"?r?.cacheMaxAge:6e5,this.#t=new Headers(r?.headers),ue&&!this.#t.has("User-Agent")&&this.#t.set("User-Agent",ue),this.#t.has("accept")||(this.#t.set("accept","application/json"),this.#t.append("accept","application/jwk-set+json")),this.#f=r?.[He],r?.[Y]!==void 0&&(this.#i=r?.[Y],wt(r?.[Y],this.#a)&&(this.#o=this.#i.uat,this.#n=U(this.#i.jwks)))}pendingFetch(){return!!this.#e}coolingDown(){return typeof this.#o=="number"?Date.now(){this.#n=U(t),this.#i&&(this.#i.uat=Date.now(),this.#i.jwks=t),this.#o=Date.now(),this.#e=void 0}).catch(t=>{throw this.#e=void 0,t}),await this.#e}};function de(e,t){let r=new pe(e,t),o=async(n,i)=>r.getKey(n,i);return Object.defineProperties(o,{coolingDown:{get:()=>r.coolingDown(),enumerable:!0,configurable:!1},fresh:{get:()=>r.fresh(),enumerable:!0,configurable:!1},reload:{value:()=>r.reload(),enumerable:!0,configurable:!1,writable:!1},reloading:{get:()=>r.pendingFetch(),enumerable:!0,configurable:!1},jwks:{value:()=>r.jwks(),enumerable:!0,configurable:!1,writable:!1}}),o}function le(e){let t;if(typeof e=="string"){let r=e.split(".");(r.length===3||r.length===5)&&([t]=r)}else if(typeof e=="object"&&e)if("protected"in e)t=e.protected;else throw new TypeError("Token does not contain a Protected Header");try{if(typeof t!="string"||!t)throw new Error;let r=JSON.parse(g.decode(A(t)));if(!y(r))throw new Error;return r}catch{throw new TypeError("Invalid Token or Protected Header formatting")}}var b={BootError:h.ServiceUnavailable,InvalidWorkerResponse:h.InternalServerError,WorkerLimit:546},At={[b.BootError]:"BOOT_ERROR",[b.InvalidWorkerResponse]:"WORKER_ERROR",[b.WorkerLimit]:"WORKER_LIMIT"},bt={[b.BootError]:"Worker failed to boot (please check logs)",[b.InvalidWorkerResponse]:"Function exited due to an error (please check logs)",[b.WorkerLimit]:"Worker failed to respond due to a resource limit (please check logs)"},Rt=["HOME","HOSTNAME","PATH","PWD"],Ve=Deno.env.get("SUPABASE_INTERNAL_HOST_PORT"),Tt=Deno.env.get("SUPABASE_INTERNAL_JWT_SECRET"),Kt=new URL("/auth/v1/.well-known/jwks.json",Deno.env.get("SUPABASE_URL")),_t=Deno.env.get("SUPABASE_INTERNAL_DEBUG")==="true",Pt=Deno.env.get("SUPABASE_INTERNAL_FUNCTIONS_CONFIG"),Be=Deno.env.get("SUPABASE_INTERNAL_PUBLISHABLE_KEY"),ke=Deno.env.get("SUPABASE_INTERNAL_SECRET_KEY"),Fe=parseInt(Deno.env.get("SUPABASE_INTERNAL_WALLCLOCK_LIMIT_SEC")),Ct=new Map([[Deno.errors.InvalidWorkerCreation,b.BootError],[Deno.errors.InvalidWorkerResponse,b.InvalidWorkerResponse],[Deno.errors.WorkerRequestCancelled,b.WorkerLimit]]),$e=`Serving functions on http://127.0.0.1:${Ve}/functions/v1/`;function P(e,t,r={}){let o={...r},n=null;return e&&(typeof e=="object"?(o["Content-Type"]="application/json",n=JSON.stringify(e)):typeof e=="string"?(o["Content-Type"]="text/plain",n=e):n=null),new Response(n,{status:t,headers:o})}var K=(()=>{try{let e=JSON.parse(Pt);return _t&&console.log("Functions config:",JSON.stringify(e,null,2)),e}catch(e){throw new Error("Failed to parse functions config",{cause:e})}})();function xt(e){let t=e.split(" "),[r,o]=t;return r!=="Bearer"||t.length!==2?null:o}function Wt(e){let t=e.headers.get("authorization"),o=e.headers.get("sb-api-key")?.replace("Bearer","")?.trim();if(!t&&!o)throw new Error("Missing authorization header");let n=xt(t??""),i=!n||n.startsWith("sb_")?o:n;if(!i)throw new Error("Auth header is not 'Bearer {token}'");return i}async function vt(e,t){let o=new TextEncoder().encode(e);try{await z(t,o)}catch(n){return console.error("Symmetric Legacy JWT verification error",n),!1}return!0}var he=(()=>{try{return U(JSON.parse(Deno.env.get("SUPABASE_JWKS")))}catch{return null}})();async function It(e,t){try{he||(he=de(new URL(e))),await z(t,he)}catch(r){return console.error("Asymmetric JWT verification error",r),!1}return!0}async function Ot(e,t,r){let{alg:o}=le(r);return o==="HS256"?(console.log(`Legacy token type detected, attempting ${o} verification.`),await vt(e,r)):o==="ES256"||o==="RS256"?await It(t,r):!1}async function Jt({entrypointPath:e,importMapPath:t}){if(t)return!1;let r=Q(ee(e),"package.json");try{await Deno.lstat(r)}catch(o){if(o instanceof Deno.errors.NotFound)return!1}return!0}function Nt(e){let t=new URL(e.url),r=e.headers.get("x-forwarded-host");t.hostname=r??t.hostname;let o=new Request(t,e.clone());return o.headers.delete("sb-api-key"),EdgeRuntime.applySupabaseTag(e,o),o}Deno.serve({handler:async e=>{let t=new URL(e.url),{pathname:r}=t;if(r==="/_internal/health")return P({message:"ok"},h.OK);if(r==="/_internal/metric"){let d=await EdgeRuntime.getRuntimeMetrics();return Response.json(d)}let n=r.split("/")[1];if(!n||!(n in K))return P("Function not found",h.NotFound);if(e.method!=="OPTIONS"&&K[n].verifyJWT)try{let d=Wt(e);if(!await Ot(Tt,Kt,d))return P({msg:"Invalid JWT"},h.Unauthorized)}catch(d){return console.error(d),P({msg:d.toString()},h.Unauthorized)}let i=ee(K[n].entrypointPath);console.error(`serving the request with ${i}`);let s=256,f=isFinite(Fe)?Fe*1e3:400*1e3,p=!1,a={...Deno.env.toObject(),...Object.fromEntries(Object.entries(K[n].env??{}).filter(([d,_])=>!d.startsWith("SUPABASE_")))};Be&&(a.SUPABASE_PUBLISHABLE_KEYS=JSON.stringify({default:Be})),ke&&(a.SUPABASE_SECRET_KEYS=JSON.stringify({default:ke}));let c=Object.entries(a).filter(([d,_])=>!Rt.includes(d)&&!d.startsWith("SUPABASE_INTERNAL_")),S=!1,C="",x=1e3,E=2e3,R="tc39",q=Q(Deno.cwd(),K[n].entrypointPath),Ge=me(q).href,Xe=await Jt(K[n]),ze=K[n].staticFiles;try{let d=await EdgeRuntime.userWorkers.create({servicePath:i,memoryLimitMb:s,workerTimeoutMs:f,noModuleCache:p,noNpm:!Xe,importMapPath:K[n].importMapPath,envVars:c,forceCreate:S,customModuleRoot:C,cpuTimeSoftLimitMs:x,cpuTimeHardLimitMs:E,decoratorType:R,maybeEntrypoint:Ge,context:{useReadSyncFileAPI:!0},staticPatterns:ze}),_=Nt(e);return await d.fetch(_)}catch(d){console.error(d);for(let[_,j]of Ct.entries())if(_!==void 0&&d instanceof _)return P({code:At[j],message:bt[j]},j);return P({code:Z[h.InternalServerError],message:"Request failed due to an internal server error",trace:JSON.stringify(d.stack)},h.InternalServerError)}},onListen:()=>{try{let e=Deno.env.get("SUPABASE_INTERNAL_FUNCTIONS_CONFIG");if(e){let r=JSON.parse(e),o=Object.keys(r),i=o.slice(0,5).map(f=>` - http://127.0.0.1:${Ve}/functions/v1/${f}`),s=o.length>0?` +var h={OK:200,Unauthorized:401,NotFound:404,InternalServerError:500,ServiceUnavailable:503},Z={[h.OK]:"OK",[h.Unauthorized]:"Unauthorized",[h.NotFound]:"Not Found",[h.InternalServerError]:"Internal Server Error",[h.ServiceUnavailable]:"Service Unavailable"};function Ye(e){let t=e.startsWith("/"),r=[];for(let n of e.split("/"))if(!(n===""||n===".")){if(n===".."){r.length>0&&r[r.length-1]!==".."?r.pop():t||r.push("..");continue}r.push(n)}let o=r.join("/");return t?"/"+o:o===""?".":o}function Q(...e){let t=e.filter(r=>r.length>0).join("/");return t===""?".":Ye(t)}function ee(e){if(e.length===0)return".";let t=e.length;for(;t>1&&e[t-1]==="/";)t-=1;let r=e.slice(0,t),o=r.lastIndexOf("/");return o===-1?".":o===0?"/":r.slice(0,o)}function qe(e){return e.replace(/\s/g,t=>`%${t.charCodeAt(0).toString(16).padStart(2,"0").toUpperCase()}`)}function me(e){if(!e.startsWith("/"))throw new TypeError(`Path must be absolute: received "${e}"`);let t=new URL("file:///");return t.pathname=qe(e.replace(/%/g,"%25").replace(/\\/g,"%5C")),t}var L=new TextEncoder,g=new TextDecoder,Ut=2**32;function ye(...e){let t=e.reduce((n,{length:i})=>n+i,0),r=new Uint8Array(t),o=0;for(let n of e)r.set(n,o),o+=n.length;return r}function k(e){let t=new Uint8Array(e.length);for(let r=0;r127)throw new TypeError("non-ASCII string encountered in encode()");t[r]=o}return t}function Se(e){if(Uint8Array.fromBase64)return Uint8Array.fromBase64(e);let t=atob(e),r=new Uint8Array(t.length);for(let o=0;onew TypeError(`CryptoKey does not support this operation, its ${t} must be ${e}`),W=(e,t)=>e.name===t;function je(e){return parseInt(e.name.slice(4),10)}function te(e,t){if(je(e.hash)!==t)throw T(`SHA-${t}`,"algorithm.hash")}function Ze(e){switch(e){case"ES256":return"P-256";case"ES384":return"P-384";case"ES512":return"P-521";default:throw new Error("unreachable")}}function Qe(e,t){if(t&&!e.usages.includes(t))throw new TypeError(`CryptoKey does not support this operation, its usages must include ${t}.`)}function Ee(e,t,r){switch(t){case"HS256":case"HS384":case"HS512":{if(!W(e.algorithm,"HMAC"))throw T("HMAC");te(e.algorithm,parseInt(t.slice(2),10));break}case"RS256":case"RS384":case"RS512":{if(!W(e.algorithm,"RSASSA-PKCS1-v1_5"))throw T("RSASSA-PKCS1-v1_5");te(e.algorithm,parseInt(t.slice(2),10));break}case"PS256":case"PS384":case"PS512":{if(!W(e.algorithm,"RSA-PSS"))throw T("RSA-PSS");te(e.algorithm,parseInt(t.slice(2),10));break}case"Ed25519":case"EdDSA":{if(!W(e.algorithm,"Ed25519"))throw T("Ed25519");break}case"ML-DSA-44":case"ML-DSA-65":case"ML-DSA-87":{if(!W(e.algorithm,t))throw T(t);break}case"ES256":case"ES384":case"ES512":{if(!W(e.algorithm,"ECDSA"))throw T("ECDSA");let o=Ze(t);if(e.algorithm.namedCurve!==o)throw T(o,"algorithm.namedCurve");break}default:throw new TypeError("CryptoKey does not support this operation")}Qe(e,r)}function we(e,t,...r){if(r=r.filter(Boolean),r.length>2){let o=r.pop();e+=`one of type ${r.join(", ")}, or ${o}.`}else r.length===2?e+=`one of type ${r[0]} or ${r[1]}.`:e+=`of type ${r[0]}.`;return t==null?e+=` Received ${t}`:typeof t=="function"&&t.name?e+=` Received function ${t.name}`:typeof t=="object"&&t!=null&&t.constructor?.name&&(e+=` Received an instance of ${t.constructor.name}`),e}var ge=(e,...t)=>we("Key must be ",e,...t),re=(e,t,...r)=>we(`Key for the ${e} algorithm must be `,t,...r);var m=class extends Error{static code="ERR_JOSE_GENERIC";code="ERR_JOSE_GENERIC";constructor(t,r){super(t,r),this.name=this.constructor.name,Error.captureStackTrace?.(this,this.constructor)}},w=class extends m{static code="ERR_JWT_CLAIM_VALIDATION_FAILED";code="ERR_JWT_CLAIM_VALIDATION_FAILED";claim;reason;payload;constructor(t,r,o="unspecified",n="unspecified"){super(t,{cause:{claim:o,reason:n,payload:r}}),this.claim=o,this.reason=n,this.payload=r}},M=class extends m{static code="ERR_JWT_EXPIRED";code="ERR_JWT_EXPIRED";claim;reason;payload;constructor(t,r,o="unspecified",n="unspecified"){super(t,{cause:{claim:o,reason:n,payload:r}}),this.claim=o,this.reason=n,this.payload=r}},F=class extends m{static code="ERR_JOSE_ALG_NOT_ALLOWED";code="ERR_JOSE_ALG_NOT_ALLOWED"},l=class extends m{static code="ERR_JOSE_NOT_SUPPORTED";code="ERR_JOSE_NOT_SUPPORTED"};var u=class extends m{static code="ERR_JWS_INVALID";code="ERR_JWS_INVALID"},v=class extends m{static code="ERR_JWT_INVALID";code="ERR_JWT_INVALID"};var H=class extends m{static code="ERR_JWKS_INVALID";code="ERR_JWKS_INVALID"},I=class extends m{static code="ERR_JWKS_NO_MATCHING_KEY";code="ERR_JWKS_NO_MATCHING_KEY";constructor(t="no applicable key found in the JSON Web Key Set",r){super(t,r)}},$=class extends m{[Symbol.asyncIterator];static code="ERR_JWKS_MULTIPLE_MATCHING_KEYS";code="ERR_JWKS_MULTIPLE_MATCHING_KEYS";constructor(t="multiple matching keys found in the JSON Web Key Set",r){super(t,r)}},V=class extends m{static code="ERR_JWKS_TIMEOUT";code="ERR_JWKS_TIMEOUT";constructor(t="request timed out",r){super(t,r)}},G=class extends m{static code="ERR_JWS_SIGNATURE_VERIFICATION_FAILED";code="ERR_JWS_SIGNATURE_VERIFICATION_FAILED";constructor(t="signature verification failed",r){super(t,r)}};var oe=e=>{if(e?.[Symbol.toStringTag]==="CryptoKey")return!0;try{return e instanceof CryptoKey}catch{return!1}},ne=e=>e?.[Symbol.toStringTag]==="KeyObject",ie=e=>oe(e)||ne(e);function se(e,t,r){try{return A(e)}catch{throw new r(`Failed to base64url decode the ${t}`)}}var et=e=>typeof e=="object"&&e!==null;function y(e){if(!et(e)||Object.prototype.toString.call(e)!=="[object Object]")return!1;if(Object.getPrototypeOf(e)===null)return!0;let t=e;for(;Object.getPrototypeOf(t)!==null;)t=Object.getPrototypeOf(t);return Object.getPrototypeOf(e)===t}function Ae(...e){let t=e.filter(Boolean);if(t.length===0||t.length===1)return!0;let r;for(let o of t){let n=Object.keys(o);if(!r||r.size===0){r=new Set(n);continue}for(let i of n){if(r.has(i))return!1;r.add(i)}}return!0}var B=e=>y(e)&&typeof e.kty=="string",be=e=>e.kty!=="oct"&&(e.kty==="AKP"&&typeof e.priv=="string"||typeof e.d=="string"),Re=e=>e.kty!=="oct"&&e.d===void 0&&e.priv===void 0,Te=e=>e.kty==="oct"&&typeof e.k=="string";function rt(e,t){if(e.startsWith("RS")||e.startsWith("PS")){let{modulusLength:r}=t.algorithm;if(typeof r!="number"||r<2048)throw new TypeError(`${e} requires key modulusLength to be 2048 bits or larger`)}}function ot(e,t){let r=`SHA-${e.slice(-3)}`;switch(e){case"HS256":case"HS384":case"HS512":return{hash:r,name:"HMAC"};case"PS256":case"PS384":case"PS512":return{hash:r,name:"RSA-PSS",saltLength:parseInt(e.slice(-3),10)>>3};case"RS256":case"RS384":case"RS512":return{hash:r,name:"RSASSA-PKCS1-v1_5"};case"ES256":case"ES384":case"ES512":return{hash:r,name:"ECDSA",namedCurve:t.namedCurve};case"Ed25519":case"EdDSA":return{name:"Ed25519"};case"ML-DSA-44":case"ML-DSA-65":case"ML-DSA-87":return{name:e};default:throw new l(`alg ${e} is not supported either by JOSE or your javascript runtime`)}}async function nt(e,t,r){if(t instanceof Uint8Array){if(!e.startsWith("HS"))throw new TypeError(ge(t,"CryptoKey","KeyObject","JSON Web Key"));return crypto.subtle.importKey("raw",t,{hash:`SHA-${e.slice(-3)}`,name:"HMAC"},!1,[r])}return Ee(t,e,r),t}async function Ke(e,t,r,o){let n=await nt(e,t,"verify");rt(e,n);let i=ot(e,n.algorithm);try{return await crypto.subtle.verify(i,n,r,o)}catch{return!1}}var X='Invalid or unsupported JWK "alg" (Algorithm) Parameter value';function it(e){let t,r;switch(e.kty){case"AKP":{switch(e.alg){case"ML-DSA-44":case"ML-DSA-65":case"ML-DSA-87":t={name:e.alg},r=e.priv?["sign"]:["verify"];break;default:throw new l(X)}break}case"RSA":{switch(e.alg){case"PS256":case"PS384":case"PS512":t={name:"RSA-PSS",hash:`SHA-${e.alg.slice(-3)}`},r=e.d?["sign"]:["verify"];break;case"RS256":case"RS384":case"RS512":t={name:"RSASSA-PKCS1-v1_5",hash:`SHA-${e.alg.slice(-3)}`},r=e.d?["sign"]:["verify"];break;case"RSA-OAEP":case"RSA-OAEP-256":case"RSA-OAEP-384":case"RSA-OAEP-512":t={name:"RSA-OAEP",hash:`SHA-${parseInt(e.alg.slice(-3),10)||1}`},r=e.d?["decrypt","unwrapKey"]:["encrypt","wrapKey"];break;default:throw new l(X)}break}case"EC":{switch(e.alg){case"ES256":case"ES384":case"ES512":t={name:"ECDSA",namedCurve:{ES256:"P-256",ES384:"P-384",ES512:"P-521"}[e.alg]},r=e.d?["sign"]:["verify"];break;case"ECDH-ES":case"ECDH-ES+A128KW":case"ECDH-ES+A192KW":case"ECDH-ES+A256KW":t={name:"ECDH",namedCurve:e.crv},r=e.d?["deriveBits"]:[];break;default:throw new l(X)}break}case"OKP":{switch(e.alg){case"Ed25519":case"EdDSA":t={name:"Ed25519"},r=e.d?["sign"]:["verify"];break;case"ECDH-ES":case"ECDH-ES+A128KW":case"ECDH-ES+A192KW":case"ECDH-ES+A256KW":t={name:e.crv},r=e.d?["deriveBits"]:[];break;default:throw new l(X)}break}default:throw new l('Invalid or unsupported JWK "kty" (Key Type) Parameter value')}return{algorithm:t,keyUsages:r}}async function O(e){if(!e.alg)throw new TypeError('"alg" argument is required when "jwk.alg" is not present');let{algorithm:t,keyUsages:r}=it(e),o={...e};return o.kty!=="AKP"&&delete o.alg,delete o.use,crypto.subtle.importKey("jwk",o,t,e.ext??!(e.d||e.priv),e.key_ops??r)}var J="given KeyObject instance cannot be used for this algorithm",N,_e=async(e,t,r,o=!1)=>{N||=new WeakMap;let n=N.get(e);if(n?.[r])return n[r];let i=await O({...t,alg:r});return o&&Object.freeze(e),n?n[r]=i:N.set(e,{[r]:i}),i},st=(e,t)=>{N||=new WeakMap;let r=N.get(e);if(r?.[t])return r[t];let o=e.type==="public",n=!!o,i;if(e.asymmetricKeyType==="x25519"){switch(t){case"ECDH-ES":case"ECDH-ES+A128KW":case"ECDH-ES+A192KW":case"ECDH-ES+A256KW":break;default:throw new TypeError(J)}i=e.toCryptoKey(e.asymmetricKeyType,n,o?[]:["deriveBits"])}if(e.asymmetricKeyType==="ed25519"){if(t!=="EdDSA"&&t!=="Ed25519")throw new TypeError(J);i=e.toCryptoKey(e.asymmetricKeyType,n,[o?"verify":"sign"])}switch(e.asymmetricKeyType){case"ml-dsa-44":case"ml-dsa-65":case"ml-dsa-87":{if(t!==e.asymmetricKeyType.toUpperCase())throw new TypeError(J);i=e.toCryptoKey(e.asymmetricKeyType,n,[o?"verify":"sign"])}}if(e.asymmetricKeyType==="rsa"){let s;switch(t){case"RSA-OAEP":s="SHA-1";break;case"RS256":case"PS256":case"RSA-OAEP-256":s="SHA-256";break;case"RS384":case"PS384":case"RSA-OAEP-384":s="SHA-384";break;case"RS512":case"PS512":case"RSA-OAEP-512":s="SHA-512";break;default:throw new TypeError(J)}if(t.startsWith("RSA-OAEP"))return e.toCryptoKey({name:"RSA-OAEP",hash:s},n,o?["encrypt"]:["decrypt"]);i=e.toCryptoKey({name:t.startsWith("PS")?"RSA-PSS":"RSASSA-PKCS1-v1_5",hash:s},n,[o?"verify":"sign"])}if(e.asymmetricKeyType==="ec"){let f=new Map([["prime256v1","P-256"],["secp384r1","P-384"],["secp521r1","P-521"]]).get(e.asymmetricKeyDetails?.namedCurve);if(!f)throw new TypeError(J);let p={ES256:"P-256",ES384:"P-384",ES512:"P-521"};p[t]&&f===p[t]&&(i=e.toCryptoKey({name:"ECDSA",namedCurve:f},n,[o?"verify":"sign"])),t.startsWith("ECDH-ES")&&(i=e.toCryptoKey({name:"ECDH",namedCurve:f},n,o?[]:["deriveBits"]))}if(!i)throw new TypeError(J);return r?r[t]=i:N.set(e,{[t]:i}),i};async function Pe(e,t){if(e instanceof Uint8Array||oe(e))return e;if(ne(e)){if(e.type==="secret")return e.export();if("toCryptoKey"in e&&typeof e.toCryptoKey=="function")try{return st(e,t)}catch(o){if(o instanceof TypeError)throw o}let r=e.export({format:"jwk"});return _e(e,r,t)}if(B(e))return e.k?A(e.k):_e(e,e,t,!0);throw new Error("unreachable")}async function Ce(e,t,r){if(!y(e))throw new TypeError("JWK must be an object");let o;switch(t??=e.alg,o??=r?.extractable??e.ext,e.kty){case"oct":if(typeof e.k!="string"||!e.k)throw new TypeError('missing "k" (Key Value) Parameter value');return A(e.k);case"RSA":if("oth"in e&&e.oth!==void 0)throw new l('RSA JWK "oth" (Other Primes Info) Parameter value is not supported');return O({...e,alg:t,ext:o});case"AKP":{if(typeof e.alg!="string"||!e.alg)throw new TypeError('missing "alg" (Algorithm) Parameter value');if(t!==void 0&&t!==e.alg)throw new TypeError("JWK alg and alg option value mismatch");return O({...e,ext:o})}case"EC":case"OKP":return O({...e,alg:t,ext:o});default:throw new l('Unsupported "kty" (Key Type) Parameter value')}}function xe(e,t,r,o,n){if(n.crit!==void 0&&o?.crit===void 0)throw new e('"crit" (Critical) Header Parameter MUST be integrity protected');if(!o||o.crit===void 0)return new Set;if(!Array.isArray(o.crit)||o.crit.length===0||o.crit.some(s=>typeof s!="string"||s.length===0))throw new e('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');let i;r!==void 0?i=new Map([...Object.entries(r),...t.entries()]):i=t;for(let s of o.crit){if(!i.has(s))throw new l(`Extension Header Parameter "${s}" is not recognized`);if(n[s]===void 0)throw new e(`Extension Header Parameter "${s}" is missing`);if(i.get(s)&&o[s]===void 0)throw new e(`Extension Header Parameter "${s}" MUST be integrity protected`)}return new Set(o.crit)}function We(e,t){if(t!==void 0&&(!Array.isArray(t)||t.some(r=>typeof r!="string")))throw new TypeError(`"${e}" option must be an array of strings`);if(t)return new Set(t)}var D=e=>e?.[Symbol.toStringTag],ae=(e,t,r)=>{if(t.use!==void 0){let o;switch(r){case"sign":case"verify":o="sig";break;case"encrypt":case"decrypt":o="enc";break}if(t.use!==o)throw new TypeError(`Invalid key for this operation, its "use" must be "${o}" when present`)}if(t.alg!==void 0&&t.alg!==e)throw new TypeError(`Invalid key for this operation, its "alg" must be "${e}" when present`);if(Array.isArray(t.key_ops)){let o;switch(!0){case(r==="sign"||r==="verify"):case e==="dir":case e.includes("CBC-HS"):o=r;break;case e.startsWith("PBES2"):o="deriveBits";break;case/^A\d{3}(?:GCM)?(?:KW)?$/.test(e):!e.includes("GCM")&&e.endsWith("KW")?o=r==="encrypt"?"wrapKey":"unwrapKey":o=r;break;case(r==="encrypt"&&e.startsWith("RSA")):o="wrapKey";break;case r==="decrypt":o=e.startsWith("RSA")?"unwrapKey":"deriveBits";break}if(o&&t.key_ops?.includes?.(o)===!1)throw new TypeError(`Invalid key for this operation, its "key_ops" must include "${o}" when present`)}return!0},at=(e,t,r)=>{if(!(t instanceof Uint8Array)){if(B(t)){if(Te(t)&&ae(e,t,r))return;throw new TypeError('JSON Web Key for symmetric algorithms must have JWK "kty" (Key Type) equal to "oct" and the JWK "k" (Key Value) present')}if(!ie(t))throw new TypeError(re(e,t,"CryptoKey","KeyObject","JSON Web Key","Uint8Array"));if(t.type!=="secret")throw new TypeError(`${D(t)} instances for symmetric algorithms must be of type "secret"`)}},ct=(e,t,r)=>{if(B(t))switch(r){case"decrypt":case"sign":if(be(t)&&ae(e,t,r))return;throw new TypeError("JSON Web Key for this operation must be a private JWK");case"encrypt":case"verify":if(Re(t)&&ae(e,t,r))return;throw new TypeError("JSON Web Key for this operation must be a public JWK")}if(!ie(t))throw new TypeError(re(e,t,"CryptoKey","KeyObject","JSON Web Key"));if(t.type==="secret")throw new TypeError(`${D(t)} instances for asymmetric algorithms must not be of type "secret"`);if(t.type==="public")switch(r){case"sign":throw new TypeError(`${D(t)} instances for asymmetric algorithm signing must be of type "private"`);case"decrypt":throw new TypeError(`${D(t)} instances for asymmetric algorithm decryption must be of type "private"`)}if(t.type==="private")switch(r){case"verify":throw new TypeError(`${D(t)} instances for asymmetric algorithm verifying must be of type "public"`);case"encrypt":throw new TypeError(`${D(t)} instances for asymmetric algorithm encryption must be of type "public"`)}};function ve(e,t,r){switch(e.substring(0,2)){case"A1":case"A2":case"di":case"HS":case"PB":at(e,t,r);break;default:ct(e,t,r)}}async function Ie(e,t,r){if(!y(e))throw new u("Flattened JWS must be an object");if(e.protected===void 0&&e.header===void 0)throw new u('Flattened JWS must have either of the "protected" or "header" members');if(e.protected!==void 0&&typeof e.protected!="string")throw new u("JWS Protected Header incorrect type");if(e.payload===void 0)throw new u("JWS Payload missing");if(typeof e.signature!="string")throw new u("JWS Signature missing or incorrect type");if(e.header!==void 0&&!y(e.header))throw new u("JWS Unprotected Header incorrect type");let o={};if(e.protected)try{let q=A(e.protected);o=JSON.parse(g.decode(q))}catch{throw new u("JWS Protected Header is invalid")}if(!Ae(o,e.header))throw new u("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");let n={...o,...e.header},i=xe(u,new Map([["b64",!0]]),r?.crit,o,n),s=!0;if(i.has("b64")&&(s=o.b64,typeof s!="boolean"))throw new u('The "b64" (base64url-encode payload) Header Parameter must be a boolean');let{alg:f}=n;if(typeof f!="string"||!f)throw new u('JWS "alg" (Algorithm) Header Parameter missing or invalid');let p=r&&We("algorithms",r.algorithms);if(p&&!p.has(f))throw new F('"alg" (Algorithm) Header Parameter value not allowed');if(s){if(typeof e.payload!="string")throw new u("JWS Payload must be a string")}else if(typeof e.payload!="string"&&!(e.payload instanceof Uint8Array))throw new u("JWS Payload must be a string or an Uint8Array instance");let a=!1;typeof t=="function"&&(t=await t(o,e),a=!0),ve(f,t,"verify");let c=ye(e.protected!==void 0?k(e.protected):new Uint8Array,k("."),typeof e.payload=="string"?s?k(e.payload):L.encode(e.payload):e.payload),S=se(e.signature,"signature",u),C=await Pe(t,f);if(!await Ke(f,C,S,c))throw new G;let E;s?E=se(e.payload,"payload",u):typeof e.payload=="string"?E=L.encode(e.payload):E=e.payload;let R={payload:E};return e.protected!==void 0&&(R.protectedHeader=o),e.header!==void 0&&(R.unprotectedHeader=e.header),a?{...R,key:C}:R}async function Oe(e,t,r){if(e instanceof Uint8Array&&(e=g.decode(e)),typeof e!="string")throw new u("Compact JWS must be a string or Uint8Array");let{0:o,1:n,2:i,length:s}=e.split(".");if(s!==3)throw new u("Invalid Compact JWS");let f=await Ie({payload:n,protected:o,signature:i},t,r),p={payload:f.payload,protectedHeader:f.protectedHeader};return typeof t=="function"?{...p,key:f.key}:p}var ft=e=>Math.floor(e.getTime()/1e3),De=60,Ue=De*60,ce=Ue*24,ut=ce*7,pt=ce*365.25,dt=/^(\+|\-)? ?(\d+|\d+\.\d+) ?(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)(?: (ago|from now))?$/i;function Je(e){let t=dt.exec(e);if(!t||t[4]&&t[1])throw new TypeError("Invalid time period format");let r=parseFloat(t[2]),o=t[3].toLowerCase(),n;switch(o){case"sec":case"secs":case"second":case"seconds":case"s":n=Math.round(r);break;case"minute":case"minutes":case"min":case"mins":case"m":n=Math.round(r*De);break;case"hour":case"hours":case"hr":case"hrs":case"h":n=Math.round(r*Ue);break;case"day":case"days":case"d":n=Math.round(r*ce);break;case"week":case"weeks":case"w":n=Math.round(r*ut);break;default:n=Math.round(r*pt);break}return t[1]==="-"||t[4]==="ago"?-n:n}var Ne=e=>e.includes("/")?e.toLowerCase():`application/${e.toLowerCase()}`,lt=(e,t)=>typeof e=="string"?t.includes(e):Array.isArray(e)?t.some(Set.prototype.has.bind(new Set(e))):!1;function Le(e,t,r={}){let o;try{o=JSON.parse(g.decode(t))}catch{}if(!y(o))throw new v("JWT Claims Set must be a top-level JSON object");let{typ:n}=r;if(n&&(typeof e.typ!="string"||Ne(e.typ)!==Ne(n)))throw new w('unexpected "typ" JWT header value',o,"typ","check_failed");let{requiredClaims:i=[],issuer:s,subject:f,audience:p,maxTokenAge:a}=r,c=[...i];a!==void 0&&c.push("iat"),p!==void 0&&c.push("aud"),f!==void 0&&c.push("sub"),s!==void 0&&c.push("iss");for(let E of new Set(c.reverse()))if(!(E in o))throw new w(`missing required "${E}" claim`,o,E,"missing");if(s&&!(Array.isArray(s)?s:[s]).includes(o.iss))throw new w('unexpected "iss" claim value',o,"iss","check_failed");if(f&&o.sub!==f)throw new w('unexpected "sub" claim value',o,"sub","check_failed");if(p&&!lt(o.aud,typeof p=="string"?[p]:p))throw new w('unexpected "aud" claim value',o,"aud","check_failed");let S;switch(typeof r.clockTolerance){case"string":S=Je(r.clockTolerance);break;case"number":S=r.clockTolerance;break;case"undefined":S=0;break;default:throw new TypeError("Invalid clockTolerance option type")}let{currentDate:C}=r,x=ft(C||new Date);if((o.iat!==void 0||a)&&typeof o.iat!="number")throw new w('"iat" claim must be a number',o,"iat","invalid");if(o.nbf!==void 0){if(typeof o.nbf!="number")throw new w('"nbf" claim must be a number',o,"nbf","invalid");if(o.nbf>x+S)throw new w('"nbf" claim timestamp check failed',o,"nbf","check_failed")}if(o.exp!==void 0){if(typeof o.exp!="number")throw new w('"exp" claim must be a number',o,"exp","invalid");if(o.exp<=x-S)throw new M('"exp" claim timestamp check failed',o,"exp","check_failed")}if(a){let E=x-o.iat,R=typeof a=="number"?a:Je(a);if(E-S>R)throw new M('"iat" claim timestamp check failed (too far in the past)',o,"iat","check_failed");if(E<0-S)throw new w('"iat" claim timestamp check failed (it should be in the past)',o,"iat","check_failed")}return o}async function z(e,t,r){let o=await Oe(e,t,r);if(o.protectedHeader.crit?.includes("b64")&&o.protectedHeader.b64===!1)throw new v("JWTs MUST NOT use unencoded payload");let i={payload:Le(o.protectedHeader,o.payload,r),protectedHeader:o.protectedHeader};return typeof t=="function"?{...i,key:o.key}:i}function ht(e){switch(typeof e=="string"&&e.slice(0,2)){case"RS":case"PS":return"RSA";case"ES":return"EC";case"Ed":return"OKP";case"ML":return"AKP";default:throw new l('Unsupported "alg" value for a JSON Web Key Set')}}function mt(e){return e&&typeof e=="object"&&Array.isArray(e.keys)&&e.keys.every(yt)}function yt(e){return y(e)}var fe=class{#r;#s=new WeakMap;constructor(t){if(!mt(t))throw new H("JSON Web Key Set malformed");this.#r=structuredClone(t)}jwks(){return this.#r}async getKey(t,r){let{alg:o,kid:n}={...t,...r?.header},i=ht(o),s=this.#r.keys.filter(a=>{let c=i===a.kty;if(c&&typeof n=="string"&&(c=n===a.kid),c&&(typeof a.alg=="string"||i==="AKP")&&(c=o===a.alg),c&&typeof a.use=="string"&&(c=a.use==="sig"),c&&Array.isArray(a.key_ops)&&(c=a.key_ops.includes("verify")),c)switch(o){case"ES256":c=a.crv==="P-256";break;case"ES384":c=a.crv==="P-384";break;case"ES512":c=a.crv==="P-521";break;case"Ed25519":case"EdDSA":c=a.crv==="Ed25519";break}return c}),{0:f,length:p}=s;if(p===0)throw new I;if(p!==1){let a=new $,c=this.#s;throw a[Symbol.asyncIterator]=async function*(){for(let S of s)try{yield await Me(c,S,o)}catch{}},a}return Me(this.#s,f,o)}};async function Me(e,t,r){let o=e.get(t)||e.set(t,{}).get(t);if(o[r]===void 0){let n=await Ce({...t,ext:!0},r);if(n instanceof Uint8Array||n.type!=="public")throw new H("JSON Web Key Set members must be public keys");o[r]=n}return o[r]}function U(e){let t=new fe(e),r=async(o,n)=>t.getKey(o,n);return Object.defineProperties(r,{jwks:{value:()=>structuredClone(t.jwks()),enumerable:!1,configurable:!1,writable:!1}}),r}function St(){return typeof WebSocketPair<"u"||typeof navigator<"u"&&navigator.userAgent==="Cloudflare-Workers"||typeof EdgeRuntime<"u"&&EdgeRuntime==="vercel"}var ue;(typeof navigator>"u"||!navigator.userAgent?.startsWith?.("Mozilla/5.0 "))&&(ue="jose/v6.2.3");var He=Symbol();async function Et(e,t,r,o=fetch){let n=await o(e,{method:"GET",signal:r,redirect:"manual",headers:t}).catch(i=>{throw i.name==="TimeoutError"?new V:i});if(n.status!==200)throw new m("Expected 200 OK from the JSON Web Key Set HTTP response");try{return await n.json()}catch{throw new m("Failed to parse the JSON Web Key Set HTTP response as JSON")}}var Y=Symbol();function wt(e,t){return!(typeof e!="object"||e===null||!("uat"in e)||typeof e.uat!="number"||Date.now()-e.uat>=t||!("jwks"in e)||!y(e.jwks)||!Array.isArray(e.jwks.keys)||!Array.prototype.every.call(e.jwks.keys,y))}var pe=class{#r;#s;#c;#a;#o;#e;#t;#f;#n;#i;constructor(t,r){if(!(t instanceof URL))throw new TypeError("url must be an instance of URL");this.#r=new URL(t.href),this.#s=typeof r?.timeoutDuration=="number"?r?.timeoutDuration:5e3,this.#c=typeof r?.cooldownDuration=="number"?r?.cooldownDuration:3e4,this.#a=typeof r?.cacheMaxAge=="number"?r?.cacheMaxAge:6e5,this.#t=new Headers(r?.headers),ue&&!this.#t.has("User-Agent")&&this.#t.set("User-Agent",ue),this.#t.has("accept")||(this.#t.set("accept","application/json"),this.#t.append("accept","application/jwk-set+json")),this.#f=r?.[He],r?.[Y]!==void 0&&(this.#i=r?.[Y],wt(r?.[Y],this.#a)&&(this.#o=this.#i.uat,this.#n=U(this.#i.jwks)))}pendingFetch(){return!!this.#e}coolingDown(){return typeof this.#o=="number"?Date.now(){this.#n=U(t),this.#i&&(this.#i.uat=Date.now(),this.#i.jwks=t),this.#o=Date.now(),this.#e=void 0}).catch(t=>{throw this.#e=void 0,t}),await this.#e}};function de(e,t){let r=new pe(e,t),o=async(n,i)=>r.getKey(n,i);return Object.defineProperties(o,{coolingDown:{get:()=>r.coolingDown(),enumerable:!0,configurable:!1},fresh:{get:()=>r.fresh(),enumerable:!0,configurable:!1},reload:{value:()=>r.reload(),enumerable:!0,configurable:!1,writable:!1},reloading:{get:()=>r.pendingFetch(),enumerable:!0,configurable:!1},jwks:{value:()=>r.jwks(),enumerable:!0,configurable:!1,writable:!1}}),o}function le(e){let t;if(typeof e=="string"){let r=e.split(".");(r.length===3||r.length===5)&&([t]=r)}else if(typeof e=="object"&&e)if("protected"in e)t=e.protected;else throw new TypeError("Token does not contain a Protected Header");try{if(typeof t!="string"||!t)throw new Error;let r=JSON.parse(g.decode(A(t)));if(!y(r))throw new Error;return r}catch{throw new TypeError("Invalid Token or Protected Header formatting")}}var b={BootError:h.ServiceUnavailable,InvalidWorkerResponse:h.InternalServerError,WorkerLimit:546},At={[b.BootError]:"BOOT_ERROR",[b.InvalidWorkerResponse]:"WORKER_ERROR",[b.WorkerLimit]:"WORKER_LIMIT"},bt={[b.BootError]:"Worker failed to boot (please check logs)",[b.InvalidWorkerResponse]:"Function exited due to an error (please check logs)",[b.WorkerLimit]:"Worker failed to respond due to a resource limit (please check logs)"},Rt=["HOME","HOSTNAME","PATH","PWD"],Ve=Deno.env.get("SUPABASE_INTERNAL_HOST_PORT"),Tt=Deno.env.get("SUPABASE_INTERNAL_JWT_SECRET"),Kt=new URL("/auth/v1/.well-known/jwks.json",Deno.env.get("SUPABASE_URL")),_t=Deno.env.get("SUPABASE_INTERNAL_DEBUG")==="true",Pt=Deno.env.get("SUPABASE_INTERNAL_FUNCTIONS_CONFIG"),Be=Deno.env.get("SUPABASE_INTERNAL_PUBLISHABLE_KEY"),ke=Deno.env.get("SUPABASE_INTERNAL_SECRET_KEY"),Fe=parseInt(Deno.env.get("SUPABASE_INTERNAL_WALLCLOCK_LIMIT_SEC")),Ct=new Map([[Deno.errors.InvalidWorkerCreation,b.BootError],[Deno.errors.InvalidWorkerResponse,b.InvalidWorkerResponse],[Deno.errors.WorkerRequestCancelled,b.WorkerLimit]]),$e=`Serving functions on http://127.0.0.1:${Ve}/functions/v1/`;function P(e,t,r={}){let o={...r},n=null;return e&&(typeof e=="object"?(o["Content-Type"]="application/json",n=JSON.stringify(e)):typeof e=="string"?(o["Content-Type"]="text/plain",n=e):n=null),new Response(n,{status:t,headers:o})}var K=(()=>{try{let e=JSON.parse(Pt);return _t&&console.log("Functions config:",JSON.stringify(e,null,2)),e}catch(e){throw new Error("Failed to parse functions config",{cause:e})}})();function xt(e){let t=e.split(" "),[r,o]=t;return r!=="Bearer"||t.length!==2?null:o}function Wt(e){let t=e.headers.get("authorization"),o=e.headers.get("sb-api-key")?.replace("Bearer","")?.trim();if(!t&&!o)throw new Error("Missing authorization header");let n=xt(t??""),i=!n||n.startsWith("sb_")?o:n;if(!i)throw new Error("Auth header is not 'Bearer {token}'");return i}async function vt(e,t){let o=new TextEncoder().encode(e);try{await z(t,o)}catch(n){return console.error("Symmetric Legacy JWT verification error",n),!1}return!0}var he=(()=>{try{return U(JSON.parse(Deno.env.get("SUPABASE_JWKS")))}catch{return null}})();async function It(e,t){try{he||(he=de(new URL(e))),await z(t,he)}catch(r){return console.error("Asymmetric JWT verification error",r),!1}return!0}async function Ot(e,t,r){let{alg:o}=le(r);return o==="HS256"?(console.log(`Legacy token type detected, attempting ${o} verification.`),await vt(e,r)):o==="ES256"||o==="RS256"?await It(t,r):!1}async function Jt({entrypointPath:e,importMapPath:t}){if(t)return!1;let r=Q(ee(e),"package.json");try{await Deno.lstat(r)}catch(o){if(o instanceof Deno.errors.NotFound)return!1}return!0}function Nt(e){let t=new URL(e.url),r=e.headers.get("x-forwarded-host");t.hostname=r??t.hostname;let o=new Request(t,e.clone());return o.headers.delete("sb-api-key"),EdgeRuntime.applySupabaseTag(e,o),o}Deno.serve({handler:async e=>{let t=new URL(e.url),{pathname:r}=t;if(r==="/_internal/health")return P({message:"ok"},h.OK);if(r==="/_internal/metric"){let d=await EdgeRuntime.getRuntimeMetrics();return Response.json(d)}let n=r.split("/")[1];if(!n||!(n in K))return P("Function not found",h.NotFound);if(e.method!=="OPTIONS"&&K[n].verifyJWT)try{let d=Wt(e);if(!await Ot(Tt,Kt,d))return P({error:"Invalid JWT"},h.Unauthorized)}catch(d){return console.error(d),P({error:d.toString()},h.Unauthorized)}let i=ee(K[n].entrypointPath);console.error(`serving the request with ${i}`);let s=256,f=isFinite(Fe)?Fe*1e3:400*1e3,p=!1,a={...Deno.env.toObject(),...Object.fromEntries(Object.entries(K[n].env??{}).filter(([d,_])=>!d.startsWith("SUPABASE_")))};Be&&(a.SUPABASE_PUBLISHABLE_KEYS=JSON.stringify({default:Be})),ke&&(a.SUPABASE_SECRET_KEYS=JSON.stringify({default:ke}));let c=Object.entries(a).filter(([d,_])=>!Rt.includes(d)&&!d.startsWith("SUPABASE_INTERNAL_")),S=!1,C="",x=1e3,E=2e3,R="tc39",q=Q(Deno.cwd(),K[n].entrypointPath),Ge=me(q).href,Xe=await Jt(K[n]),ze=K[n].staticFiles;try{let d=await EdgeRuntime.userWorkers.create({servicePath:i,memoryLimitMb:s,workerTimeoutMs:f,noModuleCache:p,noNpm:!Xe,importMapPath:K[n].importMapPath,envVars:c,forceCreate:S,customModuleRoot:C,cpuTimeSoftLimitMs:x,cpuTimeHardLimitMs:E,decoratorType:R,maybeEntrypoint:Ge,context:{useReadSyncFileAPI:!0},staticPatterns:ze}),_=Nt(e);return await d.fetch(_)}catch(d){console.error(d);for(let[_,j]of Ct.entries())if(_!==void 0&&d instanceof _)return P({code:At[j],message:bt[j]},j);return P({code:Z[h.InternalServerError],message:"Request failed due to an internal server error",trace:JSON.stringify(d.stack)},h.InternalServerError)}},onListen:()=>{try{let e=Deno.env.get("SUPABASE_INTERNAL_FUNCTIONS_CONFIG");if(e){let r=JSON.parse(e),o=Object.keys(r),i=o.slice(0,5).map(f=>` - http://127.0.0.1:${Ve}/functions/v1/${f}`),s=o.length>0?` ${i.join(` `)}${o.length>5?` ... and ${o.length-5} more functions`:""}`:"";console.log(`${$e}${s} diff --git a/apps/cli/src/shared/functions/serve-main-jwt-error-shape.e2e.test.ts b/apps/cli/src/shared/functions/serve-main-jwt-error-shape.e2e.test.ts new file mode 100644 index 0000000000..ce884e291b --- /dev/null +++ b/apps/cli/src/shared/functions/serve-main-jwt-error-shape.e2e.test.ts @@ -0,0 +1,163 @@ +import { execSync, spawnSync } from "node:child_process"; +import { mkdtemp, rm, writeFile } from "node:fs/promises"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; + +import * as jose from "jose"; +import { afterEach, describe, expect, test } from "vitest"; + +import { LEGACY_EDGE_RUNTIME_IMAGE } from "../../legacy/shared/legacy-edge-runtime-image.ts"; +import { bundleServeMainTemplate } from "./serve-main-bundler.ts"; + +/** + * Regression guard for supabase/supabase#47836: JWT verification failures must be + * returned as `{ "error": "..." }`, matching the platform edge runtime's shape, not + * the template's former `{ "msg": "..." }`. Studio (and other consumers) parse the + * `error` key to surface the real failure reason instead of falling back to a + * generic message. + * + * Boots the real bundled template under edge-runtime with networking enabled and + * asserts the JSON body shape for both JWT-failure paths: a missing Authorization + * header (caught exception path) and a syntactically valid but wrongly-signed JWT + * (the `!isValidJWT` path). + */ + +function hasDocker(): boolean { + try { + execSync("docker info", { stdio: "ignore" }); + return true; + } catch { + return false; + } +} + +const dockerAvailable = hasDocker(); +const JWT_SECRET = "serve-main-jwt-error-shape-e2e-secret"; +const STARTUP_TIMEOUT_MS = 60_000; +const TEST_TIMEOUT_MS = 120_000; +const PORT = 8082; + +function containerLogs(container: string): string { + const result = spawnSync("docker", ["logs", container], { encoding: "utf8" }); + return `${result.stdout ?? ""}\n${result.stderr ?? ""}`; +} + +async function waitForServer(url: string, deadline: number): Promise { + while (Date.now() < deadline) { + try { + await fetch(url, { method: "OPTIONS" }); + return; + } catch { + await new Promise((resolve) => setTimeout(resolve, 250)); + } + } + throw new Error(`Server at ${url} did not become reachable in time`); +} + +const containers: string[] = []; +const dirs: string[] = []; + +afterEach(async () => { + for (const container of containers.splice(0)) { + spawnSync("docker", ["rm", "-f", container], { stdio: "ignore" }); + } + for (const dir of dirs.splice(0)) { + await rm(dir, { recursive: true, force: true }); + } +}); + +describe("functions serve runtime template (JWT error shape)", () => { + test.skipIf(!dockerAvailable)( + "returns { error } (not { msg }) for JWT verification failures", + { timeout: TEST_TIMEOUT_MS }, + async () => { + const dir = await mkdtemp(join(tmpdir(), "supabase-serve-jwt-error-shape-e2e-")); + dirs.push(dir); + const container = `supabase-serve-jwt-error-shape-e2e-${process.pid.toString()}`; + containers.push(container); + + await writeFile(join(dir, "index.ts"), await bundleServeMainTemplate()); + + const functionsConfig = { + "test-func": { + entrypointPath: "unused.ts", + importMapPath: null, + staticFiles: [], + verifyJWT: true, + }, + }; + + const run = spawnSync( + "docker", + [ + "run", + "-d", + "--name", + container, + "-p", + `${PORT.toString()}:${PORT.toString()}`, + "-e", + `SUPABASE_INTERNAL_HOST_PORT=${PORT.toString()}`, + "-e", + `SUPABASE_INTERNAL_JWT_SECRET=${JWT_SECRET}`, + "-e", + "SUPABASE_URL=http://127.0.0.1:54321", + "-e", + `SUPABASE_INTERNAL_FUNCTIONS_CONFIG=${JSON.stringify(functionsConfig)}`, + "-e", + "SUPABASE_INTERNAL_WALLCLOCK_LIMIT_SEC=400", + "-v", + `${dir}:/app:ro`, + "--entrypoint", + "edge-runtime", + LEGACY_EDGE_RUNTIME_IMAGE, + "start", + "--main-service=/app", + `--port=${PORT.toString()}`, + ], + { encoding: "utf8" }, + ); + expect(run.status, run.stderr).toBe(0); + + const deadline = Date.now() + STARTUP_TIMEOUT_MS; + let logs = ""; + while (Date.now() < deadline) { + logs = containerLogs(container); + if (/Serving functions on/.test(logs) || /worker boot error/i.test(logs)) { + break; + } + await new Promise((resolve) => setTimeout(resolve, 250)); + } + expect(logs).toMatch(/Serving functions on/); + + const url = `http://127.0.0.1:${PORT.toString()}/test-func`; + await waitForServer(url, deadline); + + // Missing Authorization header: caught-exception path (previously { msg: e.toString() }). + const missingAuthRes = await fetch(url, { method: "POST" }); + expect(missingAuthRes.status).toBe(401); + const missingAuthBody = (await missingAuthRes.json()) as Record; + expect(missingAuthBody).toHaveProperty("error"); + expect(missingAuthBody.error).toContain("Missing authorization header"); + expect(missingAuthBody).not.toHaveProperty("msg"); + + // Well-formed but wrongly-signed JWT: `!isValidJWT` path (previously { msg: "Invalid JWT" }). + const wrongSecretKey = new TextEncoder().encode("a-different-secret-than-the-server-has"); + const badJwt = await new jose.SignJWT({ sub: "e2e-test" }) + .setProtectedHeader({ alg: "HS256" }) + .setIssuedAt() + .setExpirationTime("5m") + .sign(wrongSecretKey); + + const invalidJwtRes = await fetch(url, { + method: "POST", + headers: { Authorization: `Bearer ${badJwt}` }, + }); + expect(invalidJwtRes.status).toBe(401); + const invalidJwtBody = (await invalidJwtRes.json()) as Record; + expect(invalidJwtBody).toHaveProperty("error"); + expect(invalidJwtBody.error).toBe("Invalid JWT"); + expect(invalidJwtBody).not.toHaveProperty("msg"); + }, + ); +}); diff --git a/apps/cli/src/shared/functions/serve.main.ts b/apps/cli/src/shared/functions/serve.main.ts index e86b82ebda..9a63a7736d 100644 --- a/apps/cli/src/shared/functions/serve.main.ts +++ b/apps/cli/src/shared/functions/serve.main.ts @@ -245,11 +245,11 @@ Deno.serve({ const isValidJWT = await verifyHybridJWT(JWT_SECRET, JWKS_ENDPOINT, token); if (!isValidJWT) { - return getResponse({ msg: "Invalid JWT" }, STATUS_CODE.Unauthorized); + return getResponse({ error: "Invalid JWT" }, STATUS_CODE.Unauthorized); } } catch (e) { console.error(e); - return getResponse({ msg: e.toString() }, STATUS_CODE.Unauthorized); + return getResponse({ error: e.toString() }, STATUS_CODE.Unauthorized); } } From 503dc7f9289840b5c02954b99c901ff2b48875d8 Mon Sep 17 00:00:00 2001 From: shkuls Date: Sat, 11 Jul 2026 20:16:57 +0530 Subject: [PATCH 2/2] test: trim redundant readiness check and doc comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The container log wait already gates on "Serving functions on" before any request is sent, and Docker's -p port mapping is live from container creation, not app-listen time — the extra waitForServer() HTTP poll was redundant. Matches the existing offline e2e test in this file, which trusts the same log-based readiness signal with no additional HTTP check. --- .../serve-main-jwt-error-shape.e2e.test.ts | 28 ++++--------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/apps/cli/src/shared/functions/serve-main-jwt-error-shape.e2e.test.ts b/apps/cli/src/shared/functions/serve-main-jwt-error-shape.e2e.test.ts index ce884e291b..d7c6b4890b 100644 --- a/apps/cli/src/shared/functions/serve-main-jwt-error-shape.e2e.test.ts +++ b/apps/cli/src/shared/functions/serve-main-jwt-error-shape.e2e.test.ts @@ -10,16 +10,13 @@ import { LEGACY_EDGE_RUNTIME_IMAGE } from "../../legacy/shared/legacy-edge-runti import { bundleServeMainTemplate } from "./serve-main-bundler.ts"; /** - * Regression guard for supabase/supabase#47836: JWT verification failures must be - * returned as `{ "error": "..." }`, matching the platform edge runtime's shape, not - * the template's former `{ "msg": "..." }`. Studio (and other consumers) parse the - * `error` key to surface the real failure reason instead of falling back to a - * generic message. + * Regression guard for supabase/supabase#47836: JWT verification failures must + * return `{ "error": "..." }`, matching the platform edge runtime's shape, not + * the template's former `{ "msg": "..." }`. * - * Boots the real bundled template under edge-runtime with networking enabled and - * asserts the JSON body shape for both JWT-failure paths: a missing Authorization - * header (caught exception path) and a syntactically valid but wrongly-signed JWT - * (the `!isValidJWT` path). + * Boots the real bundled template under edge-runtime and asserts the JSON body + * for both JWT-failure paths: a missing Authorization header (caught-exception + * path) and a wrongly-signed JWT (the `!isValidJWT` path). */ function hasDocker(): boolean { @@ -42,18 +39,6 @@ function containerLogs(container: string): string { return `${result.stdout ?? ""}\n${result.stderr ?? ""}`; } -async function waitForServer(url: string, deadline: number): Promise { - while (Date.now() < deadline) { - try { - await fetch(url, { method: "OPTIONS" }); - return; - } catch { - await new Promise((resolve) => setTimeout(resolve, 250)); - } - } - throw new Error(`Server at ${url} did not become reachable in time`); -} - const containers: string[] = []; const dirs: string[] = []; @@ -131,7 +116,6 @@ describe("functions serve runtime template (JWT error shape)", () => { expect(logs).toMatch(/Serving functions on/); const url = `http://127.0.0.1:${PORT.toString()}/test-func`; - await waitForServer(url, deadline); // Missing Authorization header: caught-exception path (previously { msg: e.toString() }). const missingAuthRes = await fetch(url, { method: "POST" });