{"version":3,"sources":["../../src/auth/extractJWT.ts"],"sourcesContent":["import type { BasePayload } from '../index.js'\nimport type { AuthStrategyFunctionArgs } from './index.js'\n\nimport { parseCookies } from '../utilities/parseCookies.js'\n\ntype ExtractionMethod = (args: { headers: Headers; payload: BasePayload }) => null | string\n\nconst extractionMethods: Record<string, ExtractionMethod> = {\n  Bearer: ({ headers }) => {\n    const jwtFromHeader = headers.get('Authorization')\n\n    // RFC6750 OAuth 2.0 Bearer token\n    if (jwtFromHeader?.startsWith('Bearer ')) {\n      return jwtFromHeader.replace('Bearer ', '')\n    }\n\n    return null\n  },\n  cookie: ({ headers, payload }) => {\n    const cookies = parseCookies(headers)\n    const tokenCookieName = `${payload.config.cookiePrefix}-token`\n    const cookieToken = cookies.get(tokenCookieName)\n\n    if (!cookieToken) {\n      return null\n    }\n\n    const origin = headers.get('Origin')\n\n    // Origin present — validate against csrf allowlist\n    if (origin) {\n      if (payload.config.csrf.length === 0 || payload.config.csrf.includes(origin)) {\n        return cookieToken\n      }\n      return null\n    }\n\n    // No Origin and no csrf configured — no allowlist to enforce\n    if (payload.config.csrf.length === 0) {\n      return cookieToken\n    }\n\n    // No Origin with csrf configured — fall back to Sec-Fetch-Site\n    const secFetchSite = headers.get('Sec-Fetch-Site')\n\n    // Allow same-origin, same-site, and direct navigations (none)\n    if (secFetchSite === 'same-origin' || secFetchSite === 'same-site' || secFetchSite === 'none') {\n      return cookieToken\n    }\n\n    // Reject cross-site requests and missing header (non-browser clients)\n    return null\n  },\n  JWT: ({ headers }) => {\n    const jwtFromHeader = headers.get('Authorization')\n\n    if (jwtFromHeader?.startsWith('JWT ')) {\n      return jwtFromHeader.replace('JWT ', '')\n    }\n\n    return null\n  },\n}\n\nexport const extractJWT = (args: Omit<AuthStrategyFunctionArgs, 'strategyName'>): null | string => {\n  const { headers, payload } = args\n\n  const extractionOrder = payload.config.auth.jwtOrder\n\n  for (const extractionStrategy of extractionOrder) {\n    const result = extractionMethods[extractionStrategy]!({ headers, payload })\n\n    if (result) {\n      return result\n    }\n  }\n\n  return null\n}\n"],"names":["parseCookies","extractionMethods","Bearer","headers","jwtFromHeader","get","startsWith","replace","cookie","payload","cookies","tokenCookieName","config","cookiePrefix","cookieToken","origin","csrf","length","includes","secFetchSite","JWT","extractJWT","args","extractionOrder","auth","jwtOrder","extractionStrategy","result"],"mappings":"AAGA,SAASA,YAAY,QAAQ,+BAA8B;AAI3D,MAAMC,oBAAsD;IAC1DC,QAAQ,CAAC,EAAEC,OAAO,EAAE;QAClB,MAAMC,gBAAgBD,QAAQE,GAAG,CAAC;QAElC,iCAAiC;QACjC,IAAID,eAAeE,WAAW,YAAY;YACxC,OAAOF,cAAcG,OAAO,CAAC,WAAW;QAC1C;QAEA,OAAO;IACT;IACAC,QAAQ,CAAC,EAAEL,OAAO,EAAEM,OAAO,EAAE;QAC3B,MAAMC,UAAUV,aAAaG;QAC7B,MAAMQ,kBAAkB,GAAGF,QAAQG,MAAM,CAACC,YAAY,CAAC,MAAM,CAAC;QAC9D,MAAMC,cAAcJ,QAAQL,GAAG,CAACM;QAEhC,IAAI,CAACG,aAAa;YAChB,OAAO;QACT;QAEA,MAAMC,SAASZ,QAAQE,GAAG,CAAC;QAE3B,mDAAmD;QACnD,IAAIU,QAAQ;YACV,IAAIN,QAAQG,MAAM,CAACI,IAAI,CAACC,MAAM,KAAK,KAAKR,QAAQG,MAAM,CAACI,IAAI,CAACE,QAAQ,CAACH,SAAS;gBAC5E,OAAOD;YACT;YACA,OAAO;QACT;QAEA,6DAA6D;QAC7D,IAAIL,QAAQG,MAAM,CAACI,IAAI,CAACC,MAAM,KAAK,GAAG;YACpC,OAAOH;QACT;QAEA,+DAA+D;QAC/D,MAAMK,eAAehB,QAAQE,GAAG,CAAC;QAEjC,8DAA8D;QAC9D,IAAIc,iBAAiB,iBAAiBA,iBAAiB,eAAeA,iBAAiB,QAAQ;YAC7F,OAAOL;QACT;QAEA,sEAAsE;QACtE,OAAO;IACT;IACAM,KAAK,CAAC,EAAEjB,OAAO,EAAE;QACf,MAAMC,gBAAgBD,QAAQE,GAAG,CAAC;QAElC,IAAID,eAAeE,WAAW,SAAS;YACrC,OAAOF,cAAcG,OAAO,CAAC,QAAQ;QACvC;QAEA,OAAO;IACT;AACF;AAEA,OAAO,MAAMc,aAAa,CAACC;IACzB,MAAM,EAAEnB,OAAO,EAAEM,OAAO,EAAE,GAAGa;IAE7B,MAAMC,kBAAkBd,QAAQG,MAAM,CAACY,IAAI,CAACC,QAAQ;IAEpD,KAAK,MAAMC,sBAAsBH,gBAAiB;QAChD,MAAMI,SAAS1B,iBAAiB,CAACyB,mBAAmB,CAAE;YAAEvB;YAASM;QAAQ;QAEzE,IAAIkB,QAAQ;YACV,OAAOA;QACT;IACF;IAEA,OAAO;AACT,EAAC"}