@nekm/sveltekit-armor 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,7 +17,7 @@ export interface ArmorAccessToken extends JWTPayload {
17
17
  export interface ArmorTokens {
18
18
  readonly exchange: ArmorTokenExchange;
19
19
  readonly idToken: ArmorIdToken;
20
- readonly accessToken: ArmorAccessToken;
20
+ readonly accessToken: ArmorAccessToken | string;
21
21
  }
22
22
  interface OauthBaseUrl {
23
23
  readonly baseUrl: string;
package/dist/index.esm.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { redirect } from '@sveltejs/kit';
2
- import { strTrimEnd, strTrimStart, queryParamsCreate, throwIfUndefined } from '@nekm/core';
2
+ import { strTrimEnd, strTrimStart, throwIfUndefined, queryParamsCreate } from '@nekm/core';
3
3
  import { jwtVerify, createRemoteJWKSet } from 'jose';
4
4
  import { randomUUID } from 'node:crypto';
5
5
 
@@ -14,11 +14,19 @@ function isTokenExchange(value) {
14
14
  typeof obj.id_token === "string" || obj.id_token === undefined) && (typeof obj.refresh_token === "string" || obj.refresh_token === undefined) && (typeof obj.scope === "string" || obj.scope === undefined);
15
15
  }
16
16
 
17
+ function jwtIsCompactJwt(token) {
18
+ // Must be three base64url segments
19
+ const parts = token.trim().split(".");
20
+ return parts.length === 3 && parts.every(p => p.length > 0);
21
+ }
17
22
  function jwtVerifyIdToken(config, jwks, idToken) {
18
- return jwtVerifyToken(jwks, {
23
+ const payload = jwtVerifyToken(jwks, {
19
24
  issuer: config.oauth.issuer,
20
25
  audience: config.oauth.clientId
21
26
  }, idToken);
27
+ throwIfUndefined(payload);
28
+ // @ts-expect-error We're already verifying non-null above.
29
+ return payload;
22
30
  }
23
31
  function jwtVerifyAccessToken(config, jwks, accessToken) {
24
32
  const opts = {
@@ -29,11 +37,24 @@ function jwtVerifyAccessToken(config, jwks, accessToken) {
29
37
  }
30
38
  return jwtVerifyToken(jwks, opts, accessToken);
31
39
  }
40
+ function isInvalidCompactJwt(error) {
41
+ return Boolean(typeof error === "object" && error && "message" in error && typeof error.message === "string" && /invalid compact jws/gi.test(error.message));
42
+ }
32
43
  async function jwtVerifyToken(jwks, opts, token) {
33
- const {
34
- payload
35
- } = await jwtVerify(token, jwks, opts);
36
- return payload;
44
+ try {
45
+ if (!jwtIsCompactJwt(token)) {
46
+ return undefined;
47
+ }
48
+ const {
49
+ payload
50
+ } = await jwtVerify(token, jwks, opts);
51
+ return payload;
52
+ } catch (error) {
53
+ if (isInvalidCompactJwt(error)) {
54
+ return undefined;
55
+ }
56
+ throw error;
57
+ }
37
58
  }
38
59
 
39
60
  const COOKIE_TOKENS = "tokens";
@@ -148,7 +169,9 @@ const routeRedirectLoginFactory = config => {
148
169
  await config.session.login(event, {
149
170
  exchange,
150
171
  idToken: idToken,
151
- accessToken
172
+ // Generally, IdP's require an audience to get a JWT
173
+ // access token. Most cases, this doesn't matter.
174
+ accessToken: accessToken != null ? accessToken : exchange.access_token
152
175
  });
153
176
  throw redirect(302, "/");
154
177
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/utils/utils.ts","../src/utils/jwt.ts","../src/utils/cookie.ts","../src/errors.ts","../src/utils/event.ts","../src/routes/redirect-login.ts","../src/routes/login.ts","../src/routes/redirect-logout.ts","../src/routes/logout.ts","../src/routes/routes.ts","../src/session/cookie.ts","../src/index.ts"],"sourcesContent":["import { strTrimEnd, strTrimStart } from \"@nekm/core\";\nimport type { ArmorTokenExchange } from \"../contracts\";\n\nexport function urlConcat(origin: string, path: string): string {\n\treturn [strTrimEnd(origin, \"/\"), strTrimStart(path, \"/\")].join(\"/\");\n}\n\nexport function isTokenExchange(value: unknown): value is ArmorTokenExchange {\n\tif (typeof value !== \"object\" || value === null) return false;\n\n\tconst obj = value as Record<string, unknown>;\n\n\treturn (\n\t\ttypeof obj.access_token === \"string\" &&\n\t\tobj.token_type === \"Bearer\" &&\n\t\ttypeof obj.expires_in === \"number\" &&\n\t\t// Optional fields\n\t\t(typeof obj.id_token === \"string\" || obj.id_token === undefined) &&\n\t\t(typeof obj.refresh_token === \"string\" ||\n\t\t\tobj.refresh_token === undefined) &&\n\t\t(typeof obj.scope === \"string\" || obj.scope === undefined)\n\t);\n}\n","import { ArmorConfig } from \"../contracts\";\nimport { JWTPayload, jwtVerify, JWTVerifyGetKey, JWTVerifyOptions } from \"jose\";\n\nexport function jwtVerifyIdToken(\n\tconfig: ArmorConfig,\n\tjwks: JWTVerifyGetKey,\n\tidToken: string,\n): Promise<JWTPayload> {\n\treturn jwtVerifyToken(\n\t\tjwks,\n\t\t{\n\t\t\tissuer: config.oauth.issuer,\n\t\t\taudience: config.oauth.clientId,\n\t\t},\n\t\tidToken,\n\t);\n}\n\nexport function jwtVerifyAccessToken(\n\tconfig: ArmorConfig,\n\tjwks: JWTVerifyGetKey,\n\taccessToken: string,\n): Promise<JWTPayload> {\n\tconst opts: JWTVerifyOptions = { issuer: config.oauth.issuer };\n\n\tif (config.oauth.audience) {\n\t\topts.audience = config.oauth.audience;\n\t}\n\n\treturn jwtVerifyToken(jwks, opts, accessToken);\n}\n\nasync function jwtVerifyToken(\n\tjwks: JWTVerifyGetKey,\n\topts: JWTVerifyOptions,\n\ttoken: string,\n): Promise<JWTPayload> {\n\tconst { payload } = await jwtVerify(token, jwks, opts);\n\treturn payload;\n}\n","import { Cookies } from \"@sveltejs/kit\";\n\nexport const COOKIE_TOKENS = \"tokens\";\nexport const COOKIE_STATE = \"state\";\n\nconst cookieDeleteOptions = Object.freeze({ path: \"/\" });\n\nconst cookieSetOptions = Object.freeze({\n\t...cookieDeleteOptions,\n\thttpOnly: true,\n\tsecure: true,\n\tsameSite: \"lax\",\n\tmaxAge: 1800, // 30 minutes\n});\n\nexport function cookieSet(\n\tcookies: Cookies,\n\tkey: string,\n\tvalue: string | object,\n) {\n\tcookies.set(key, JSON.stringify(value), cookieSetOptions);\n}\n\nexport function cookieGetAndDelete<T>(\n\tcookies: Cookies,\n\tkey: string,\n): T | undefined {\n\tconst value = cookieGet<T>(cookies, key);\n\n\tif (value) {\n\t\tcookies.delete(key, cookieDeleteOptions);\n\t}\n\n\treturn value;\n}\n\nexport function cookieGet<T>(cookies: Cookies, key: string): T | undefined {\n\tconst value = cookies.get(key);\n\n\treturn !value ? undefined : JSON.parse(value);\n}\n\nexport function cookieDelete(cookies: Cookies, key: string): void {\n\tcookies.delete(key, cookieDeleteOptions);\n}\n","export class ArmorError extends Error {}\nexport class ArmorOpenIdConfigError extends ArmorError {}\nexport class ArmorInvalidStateError extends ArmorError {}\nexport class ArmorAuthMissingError extends ArmorError {}\n","import { RequestEvent } from \"@sveltejs/kit\";\nimport { COOKIE_STATE, cookieGetAndDelete } from \"./cookie\";\nimport { ArmorInvalidStateError } from \"../errors\";\n\nexport function eventStateValidOrThrow(event: RequestEvent): void {\n\tconst state = event.url.searchParams.get(\"state\") ?? undefined;\n\tconst stateCookie = cookieGetAndDelete(event.cookies, COOKIE_STATE);\n\n\tif (state !== stateCookie) {\n\t\tthrow new ArmorInvalidStateError();\n\t}\n}\n","import { redirect } from \"@sveltejs/kit\";\nimport type {\n\tArmorConfig,\n\tArmorIdToken,\n\tArmorTokenExchange,\n} from \"../contracts\";\nimport { queryParamsCreate, throwIfUndefined } from \"@nekm/core\";\nimport { createRemoteJWKSet } from \"jose\";\nimport type { RouteFactory } from \"./routes\";\nimport { urlConcat, isTokenExchange } from \"../utils/utils\";\nimport { jwtVerifyAccessToken, jwtVerifyIdToken } from \"../utils/jwt\";\nimport { eventStateValidOrThrow } from \"../utils/event\";\n\nexport const ROUTE_PATH_REDIRECT_LOGIN = \"/_armor/redirect/login\";\n\nexport const routeRedirectLoginFactory: RouteFactory = (\n\tconfig: ArmorConfig,\n) => {\n\tconst jwksUrl = new URL(\n\t\tconfig.oauth.jwksEndpoint ??\n\t\t\turlConcat(config.oauth.baseUrl, \".well-known/jwks.json\"),\n\t);\n\n\tconst tokenUrl =\n\t\tconfig.oauth.tokenEndpoint ??\n\t\turlConcat(config.oauth.baseUrl, \"oauth2/token\");\n\n\tconst scope = config.oauth.scope ?? \"openid profile email\";\n\n\tasync function exchangeCodeForToken(\n\t\tfetch: typeof global.fetch,\n\t\torigin: string,\n\t\tcode: string,\n\t): Promise<ArmorTokenExchange> {\n\t\tconst params: Record<string, string> = {\n\t\t\tgrant_type: \"authorization_code\",\n\t\t\tclient_id: config.oauth.clientId,\n\t\t\tclient_secret: config.oauth.clientSecret,\n\t\t\tcode,\n\t\t\tredirect_uri: urlConcat(origin, ROUTE_PATH_REDIRECT_LOGIN),\n\t\t\tscope,\n\t\t};\n\n\t\tif (config.oauth.audience) {\n\t\t\tparams.audience = config.oauth.audience;\n\t\t}\n\n\t\tconst response = await fetch(tokenUrl, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\tAccept: \"application/json\",\n\t\t\t},\n\t\t\tbody: new URLSearchParams(params).toString(),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst error = await response.text();\n\t\t\tthrow new Error(`Token exchange failed: ${error}`);\n\t\t}\n\n\t\tconst token = await response.json();\n\n\t\tif (!isTokenExchange(token)) {\n\t\t\tthrow new Error(\"Response is not a valid token exchange.\");\n\t\t}\n\n\t\treturn token;\n\t}\n\n\treturn {\n\t\tpath: ROUTE_PATH_REDIRECT_LOGIN,\n\t\tasync handle({ event }) {\n\t\t\teventStateValidOrThrow(event);\n\n\t\t\tconst error = event.url.searchParams.get(\"error\") ?? undefined;\n\n\t\t\tif (error) {\n\t\t\t\tconst error_description =\n\t\t\t\t\tevent.url.searchParams.get(\"error_description\") ?? undefined;\n\n\t\t\t\tif (!config.oauth.errorLoginRedirectPath) {\n\t\t\t\t\treturn new Response(`${error}\\n${error_description}`.trimEnd(), {\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\"Content-Type\": \"text/plain\",\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst errorParams = queryParamsCreate({ error, error_description });\n\t\t\t\tthrow redirect(\n\t\t\t\t\t302,\n\t\t\t\t\t`${config.oauth.errorLoginRedirectPath}?${errorParams}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst code = event.url.searchParams.get(\"code\") ?? undefined;\n\t\t\tthrowIfUndefined(code);\n\n\t\t\tconst exchange = await exchangeCodeForToken(\n\t\t\t\tevent.fetch,\n\t\t\t\tevent.url.origin,\n\t\t\t\tcode,\n\t\t\t);\n\n\t\t\tconst jwks = createRemoteJWKSet(jwksUrl);\n\n\t\t\tconst [idToken, accessToken] = await Promise.all([\n\t\t\t\tjwtVerifyIdToken(config, jwks, exchange.id_token),\n\t\t\t\tjwtVerifyAccessToken(config, jwks, exchange.access_token),\n\t\t\t]);\n\n\t\t\tawait config.session.login(event, {\n\t\t\t\texchange,\n\t\t\t\tidToken: idToken as ArmorIdToken,\n\t\t\t\taccessToken,\n\t\t\t});\n\n\t\t\tthrow redirect(302, \"/\");\n\t\t},\n\t};\n};\n","import { redirect } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport { queryParamsCreate } from \"@nekm/core\";\nimport { ROUTE_PATH_REDIRECT_LOGIN } from \"./redirect-login\";\nimport { randomUUID } from \"node:crypto\";\nimport type { RouteFactory } from \"./routes\";\nimport { COOKIE_STATE, cookieSet } from \"../utils/cookie\";\nimport { urlConcat } from \"../utils/utils\";\n\nexport const ROUTE_PATH_LOGIN = \"/_armor/login\";\n\nexport const routeLoginFactory: RouteFactory = (config: ArmorConfig) => {\n\tconst authorizeEndpoint =\n\t\tconfig.oauth.authorizeEndpoint ??\n\t\turlConcat(config.oauth.baseUrl, \"oauth2/authorize\");\n\n\tconst scope = config.oauth.scope ?? \"openid profile email\";\n\n\treturn {\n\t\tpath: ROUTE_PATH_LOGIN,\n\t\tasync handle({ event }) {\n\t\t\tconst state = randomUUID();\n\t\t\tcookieSet(event.cookies, COOKIE_STATE, state);\n\n\t\t\tconst params = queryParamsCreate({\n\t\t\t\tclient_id: config.oauth.clientId,\n\t\t\t\tresponse_type: \"code\",\n\t\t\t\tredirect_uri: urlConcat(event.url.origin, ROUTE_PATH_REDIRECT_LOGIN),\n\t\t\t\tstate,\n\t\t\t\tscope,\n\t\t\t\taudience: config.oauth.audience,\n\t\t\t});\n\n\t\t\tthrow redirect(302, `${authorizeEndpoint}?${params}`);\n\t\t},\n\t};\n};\n","import { redirect } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport type { RouteFactory } from \"./routes\";\nimport { eventStateValidOrThrow } from \"../utils/event\";\n\nexport const ROUTE_PATH_REDIRECT_LOGOUT = \"/_armor/redirect/logout\";\n\nexport const routeRedirectLogoutFactory: RouteFactory = (\n\tconfig: ArmorConfig,\n) => {\n\t// Check if the oauth provider supports a logout path.\n\tif (!config.oauth.logoutEndpoint) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\tpath: ROUTE_PATH_REDIRECT_LOGOUT,\n\t\tasync handle({ event }) {\n\t\t\teventStateValidOrThrow(event);\n\n\t\t\tawait config.session.logout(event);\n\n\t\t\tthrow redirect(302, \"/\");\n\t\t},\n\t};\n};\n","import { redirect } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport { queryParamsCreate } from \"@nekm/core\";\nimport { ROUTE_PATH_REDIRECT_LOGOUT } from \"./redirect-logout\";\nimport type { RouteFactory } from \"./routes\";\nimport { urlConcat } from \"../utils/utils\";\nimport { randomUUID } from \"node:crypto\";\nimport { COOKIE_STATE, cookieSet } from \"../utils/cookie\";\n\nexport const ROUTE_PATH_LOGOUT = \"/_armor/logout\";\n\nexport const routeLogoutFactory: RouteFactory = (config: ArmorConfig) => {\n\t// Check if the oauth provider supports a logout path.\n\tif (!config.oauth.logoutEndpoint) {\n\t\treturn undefined;\n\t}\n\n\tconst returnTo = config.oauth.logoutReturnToParam ?? \"logout_uri\";\n\n\treturn {\n\t\tpath: ROUTE_PATH_LOGOUT,\n\t\tasync handle({ event }) {\n\t\t\tconst state = randomUUID();\n\t\t\tcookieSet(event.cookies, COOKIE_STATE, state);\n\n\t\t\tconst params = queryParamsCreate({\n\t\t\t\t[returnTo]: urlConcat(event.url.origin, ROUTE_PATH_REDIRECT_LOGOUT),\n\t\t\t\tclient_id: config.oauth.clientId,\n\t\t\t\tstate,\n\t\t\t});\n\n\t\t\tthrow redirect(302, `${config.oauth.logoutEndpoint}?${params}`);\n\t\t},\n\t};\n};\n","import type { Handle } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport { routeLoginFactory } from \"./login\";\nimport { routeLogoutFactory } from \"./logout\";\nimport { routeRedirectLogoutFactory } from \"./redirect-logout\";\nimport { routeRedirectLoginFactory } from \"./redirect-login\";\n\nexport interface Route {\n\treadonly path: string;\n\treadonly handle: Handle;\n}\n\nexport type RouteFactory = (config: ArmorConfig) => Route | undefined;\n\nconst routeFactories = Object.freeze([\n\trouteLoginFactory,\n\trouteLogoutFactory,\n\trouteRedirectLoginFactory,\n\trouteRedirectLogoutFactory,\n]);\n\nexport function routeCreate(config: ArmorConfig): Map<string, Handle> {\n\treturn new Map(\n\t\trouteFactories\n\t\t\t.map((routeFactory) => routeFactory(config))\n\t\t\t.filter((route) => Boolean(route))\n\t\t\t// @ts-expect-error Incorrect typing error.\n\t\t\t.map((route) => [route.path, route.handle]),\n\t);\n}\n","import { RequestEvent } from \"@sveltejs/kit\";\nimport {\n\tCOOKIE_TOKENS,\n\tcookieDelete,\n\tcookieGet,\n\tcookieSet,\n} from \"../utils/cookie\";\nimport { ArmorConfig, ArmorTokens } from \"../contracts\";\nimport { ArmorAuthMissingError } from \"../errors\";\n\nfunction cookieSessionExists({ cookies }: RequestEvent): boolean {\n\treturn Boolean(cookies.get(COOKIE_TOKENS));\n}\n\nexport function cookieSessionLogin(\n\t{ cookies }: RequestEvent,\n\ttokens: ArmorTokens,\n): void {\n\tcookieSet(cookies, COOKIE_TOKENS, tokens);\n}\n\nfunction cookieSessionLogout({ cookies }: RequestEvent): void {\n\tcookieDelete(cookies, COOKIE_TOKENS);\n}\n\nexport function armorCookieSessionGet({ cookies }: RequestEvent): ArmorTokens {\n\tconst tokens = cookieGet<ArmorTokens>(cookies, COOKIE_TOKENS);\n\n\tif (!tokens) {\n\t\tthrow new ArmorAuthMissingError();\n\t}\n\n\treturn tokens;\n}\n\nexport const armorCookieSession: ArmorConfig[\"session\"] = {\n\texists: cookieSessionExists,\n\tlogin: cookieSessionLogin,\n\tlogout: cookieSessionLogout,\n};\n","import { redirect, type Handle } from \"@sveltejs/kit\";\nimport { ROUTE_PATH_LOGIN } from \"./routes/login\";\nimport type { ArmorConfig, ArmorOpenIdConfig, ArmorTokens } from \"./contracts\";\nimport { ROUTE_PATH_LOGOUT } from \"./routes/logout\";\nimport { routeCreate } from \"./routes/routes\";\nimport { ArmorOpenIdConfigError } from \"./errors\";\n\nexport type { ArmorConfig, ArmorTokens };\nexport { armorCookieSession, armorCookieSessionGet } from \"./session/cookie\";\n\nexport const ARMOR_LOGIN = ROUTE_PATH_LOGIN;\nexport const ARMOR_LOGOUT = ROUTE_PATH_LOGOUT;\n\nexport function armor(config: ArmorConfig): Handle {\n\tconst routes = routeCreate(config);\n\n\treturn async ({ event, resolve }) => {\n\t\tconst routeHandle = routes.get(event.url.pathname);\n\n\t\tif (routeHandle) {\n\t\t\treturn routeHandle({ event, resolve });\n\t\t}\n\n\t\tconst exists = await config.session.exists(event);\n\n\t\tif (!exists) {\n\t\t\tthrow redirect(302, ROUTE_PATH_LOGIN);\n\t\t}\n\n\t\treturn resolve(event);\n\t};\n}\n\n/**\n * Some IdP's expose a /.well-known/openid-configuration that specifies how to configure.\n * Use that to create your config.\n * @param config\n * @param fetch\n */\nexport async function armorConfigFromOpenId(\n\tconfig: ArmorOpenIdConfig,\n\tfetch?: typeof global.fetch,\n): Promise<ArmorConfig> {\n\tconst fetchToUse = fetch ?? global.fetch;\n\n\tconst response = await fetchToUse(config.oauth.openIdConfigEndpoint, {\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t},\n\t});\n\n\tif (!response.ok) {\n\t\tconst text = await response.text();\n\t\tthrow new ArmorOpenIdConfigError(text);\n\t}\n\n\tconst body = await response.json();\n\n\treturn {\n\t\t...config,\n\t\toauth: {\n\t\t\t...config.oauth,\n\t\t\ttokenEndpoint: body.token_endpoint,\n\t\t\tauthorizeEndpoint: body.authorization_endpoint,\n\t\t\tissuer: body.issuer,\n\t\t\tjwksEndpoint: body.jwks_uri,\n\t\t\tlogoutEndpoint: body.end_session_endpoint ?? undefined,\n\t\t},\n\t};\n}\n"],"names":["urlConcat","origin","path","strTrimEnd","strTrimStart","join","isTokenExchange","value","obj","access_token","token_type","expires_in","id_token","undefined","refresh_token","scope","jwtVerifyIdToken","config","jwks","idToken","jwtVerifyToken","issuer","oauth","audience","clientId","jwtVerifyAccessToken","accessToken","opts","token","payload","jwtVerify","COOKIE_TOKENS","COOKIE_STATE","cookieDeleteOptions","Object","freeze","cookieSetOptions","httpOnly","secure","sameSite","maxAge","cookieSet","cookies","key","set","JSON","stringify","cookieGetAndDelete","cookieGet","delete","get","parse","cookieDelete","ArmorError","Error","ArmorOpenIdConfigError","ArmorInvalidStateError","ArmorAuthMissingError","eventStateValidOrThrow","event","_event$url$searchPara","state","url","searchParams","stateCookie","ROUTE_PATH_REDIRECT_LOGIN","routeRedirectLoginFactory","_config$oauth$jwksEnd","_config$oauth$tokenEn","_config$oauth$scope","jwksUrl","URL","jwksEndpoint","baseUrl","tokenUrl","tokenEndpoint","exchangeCodeForToken","fetch","code","params","grant_type","client_id","client_secret","clientSecret","redirect_uri","response","method","headers","Accept","body","URLSearchParams","toString","ok","error","text","json","handle","_event$url$searchPara3","_event$url$searchPara2","error_description","errorLoginRedirectPath","Response","trimEnd","errorParams","queryParamsCreate","redirect","throwIfUndefined","exchange","createRemoteJWKSet","Promise","all","session","login","ROUTE_PATH_LOGIN","routeLoginFactory","_config$oauth$authori","authorizeEndpoint","randomUUID","response_type","ROUTE_PATH_REDIRECT_LOGOUT","routeRedirectLogoutFactory","logoutEndpoint","logout","ROUTE_PATH_LOGOUT","routeLogoutFactory","_config$oauth$logoutR","returnTo","logoutReturnToParam","routeFactories","routeCreate","Map","map","routeFactory","filter","route","Boolean","cookieSessionExists","cookieSessionLogin","tokens","cookieSessionLogout","armorCookieSessionGet","armorCookieSession","exists","ARMOR_LOGIN","ARMOR_LOGOUT","armor","routes","resolve","routeHandle","pathname","armorConfigFromOpenId","_body$end_session_end","fetchToUse","global","openIdConfigEndpoint","token_endpoint","authorization_endpoint","jwks_uri","end_session_endpoint"],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/utils/utils.ts","../src/utils/jwt.ts","../src/utils/cookie.ts","../src/errors.ts","../src/utils/event.ts","../src/routes/redirect-login.ts","../src/routes/login.ts","../src/routes/redirect-logout.ts","../src/routes/logout.ts","../src/routes/routes.ts","../src/session/cookie.ts","../src/index.ts"],"sourcesContent":["import { strTrimEnd, strTrimStart } from \"@nekm/core\";\nimport type { ArmorTokenExchange } from \"../contracts\";\n\nexport function urlConcat(origin: string, path: string): string {\n\treturn [strTrimEnd(origin, \"/\"), strTrimStart(path, \"/\")].join(\"/\");\n}\n\nexport function isTokenExchange(value: unknown): value is ArmorTokenExchange {\n\tif (typeof value !== \"object\" || value === null) return false;\n\n\tconst obj = value as Record<string, unknown>;\n\n\treturn (\n\t\ttypeof obj.access_token === \"string\" &&\n\t\tobj.token_type === \"Bearer\" &&\n\t\ttypeof obj.expires_in === \"number\" &&\n\t\t// Optional fields\n\t\t(typeof obj.id_token === \"string\" || obj.id_token === undefined) &&\n\t\t(typeof obj.refresh_token === \"string\" ||\n\t\t\tobj.refresh_token === undefined) &&\n\t\t(typeof obj.scope === \"string\" || obj.scope === undefined)\n\t);\n}\n","import { ArmorConfig } from \"../contracts\";\nimport { JWTPayload, jwtVerify, JWTVerifyGetKey, JWTVerifyOptions } from \"jose\";\nimport { throwIfUndefined } from \"@nekm/core\";\n\nfunction jwtIsCompactJwt(token: string): boolean {\n\t// Must be three base64url segments\n\tconst parts = token.trim().split(\".\");\n\treturn parts.length === 3 && parts.every((p) => p.length > 0);\n}\n\nexport function jwtVerifyIdToken(\n\tconfig: ArmorConfig,\n\tjwks: JWTVerifyGetKey,\n\tidToken: string,\n): Promise<JWTPayload> {\n\tconst payload = jwtVerifyToken(\n\t\tjwks,\n\t\t{\n\t\t\tissuer: config.oauth.issuer,\n\t\t\taudience: config.oauth.clientId,\n\t\t},\n\t\tidToken,\n\t);\n\tthrowIfUndefined(payload);\n\t// @ts-expect-error We're already verifying non-null above.\n\treturn payload;\n}\n\nexport function jwtVerifyAccessToken(\n\tconfig: ArmorConfig,\n\tjwks: JWTVerifyGetKey,\n\taccessToken: string,\n): Promise<JWTPayload | undefined> {\n\tconst opts: JWTVerifyOptions = { issuer: config.oauth.issuer };\n\n\tif (config.oauth.audience) {\n\t\topts.audience = config.oauth.audience;\n\t}\n\n\treturn jwtVerifyToken(jwks, opts, accessToken);\n}\n\nfunction isInvalidCompactJwt(error: unknown): boolean {\n\treturn Boolean(\n\t\ttypeof error === \"object\" &&\n\t\terror &&\n\t\t\"message\" in error &&\n\t\ttypeof error.message === \"string\" &&\n\t\t/invalid compact jws/gi.test(error.message),\n\t);\n}\n\nasync function jwtVerifyToken(\n\tjwks: JWTVerifyGetKey,\n\topts: JWTVerifyOptions,\n\ttoken: string,\n): Promise<JWTPayload | undefined> {\n\ttry {\n\t\tif (!jwtIsCompactJwt(token)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst { payload } = await jwtVerify(token, jwks, opts);\n\t\treturn payload;\n\t} catch (error) {\n\t\tif (isInvalidCompactJwt(error)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tthrow error;\n\t}\n}\n","import { Cookies } from \"@sveltejs/kit\";\n\nexport const COOKIE_TOKENS = \"tokens\";\nexport const COOKIE_STATE = \"state\";\n\nconst cookieDeleteOptions = Object.freeze({ path: \"/\" });\n\nconst cookieSetOptions = Object.freeze({\n\t...cookieDeleteOptions,\n\thttpOnly: true,\n\tsecure: true,\n\tsameSite: \"lax\",\n\tmaxAge: 1800, // 30 minutes\n});\n\nexport function cookieSet(\n\tcookies: Cookies,\n\tkey: string,\n\tvalue: string | object,\n) {\n\tcookies.set(key, JSON.stringify(value), cookieSetOptions);\n}\n\nexport function cookieGetAndDelete<T>(\n\tcookies: Cookies,\n\tkey: string,\n): T | undefined {\n\tconst value = cookieGet<T>(cookies, key);\n\n\tif (value) {\n\t\tcookies.delete(key, cookieDeleteOptions);\n\t}\n\n\treturn value;\n}\n\nexport function cookieGet<T>(cookies: Cookies, key: string): T | undefined {\n\tconst value = cookies.get(key);\n\n\treturn !value ? undefined : JSON.parse(value);\n}\n\nexport function cookieDelete(cookies: Cookies, key: string): void {\n\tcookies.delete(key, cookieDeleteOptions);\n}\n","export class ArmorError extends Error {}\nexport class ArmorOpenIdConfigError extends ArmorError {}\nexport class ArmorInvalidStateError extends ArmorError {}\nexport class ArmorAuthMissingError extends ArmorError {}\n","import { RequestEvent } from \"@sveltejs/kit\";\nimport { COOKIE_STATE, cookieGetAndDelete } from \"./cookie\";\nimport { ArmorInvalidStateError } from \"../errors\";\n\nexport function eventStateValidOrThrow(event: RequestEvent): void {\n\tconst state = event.url.searchParams.get(\"state\") ?? undefined;\n\tconst stateCookie = cookieGetAndDelete(event.cookies, COOKIE_STATE);\n\n\tif (state !== stateCookie) {\n\t\tthrow new ArmorInvalidStateError();\n\t}\n}\n","import { redirect } from \"@sveltejs/kit\";\nimport type {\n\tArmorConfig,\n\tArmorIdToken,\n\tArmorTokenExchange,\n} from \"../contracts\";\nimport { queryParamsCreate, throwIfUndefined } from \"@nekm/core\";\nimport { createRemoteJWKSet } from \"jose\";\nimport type { RouteFactory } from \"./routes\";\nimport { urlConcat, isTokenExchange } from \"../utils/utils\";\nimport { jwtVerifyAccessToken, jwtVerifyIdToken } from \"../utils/jwt\";\nimport { eventStateValidOrThrow } from \"../utils/event\";\n\nexport const ROUTE_PATH_REDIRECT_LOGIN = \"/_armor/redirect/login\";\n\nexport const routeRedirectLoginFactory: RouteFactory = (\n\tconfig: ArmorConfig,\n) => {\n\tconst jwksUrl = new URL(\n\t\tconfig.oauth.jwksEndpoint ??\n\t\t\turlConcat(config.oauth.baseUrl, \".well-known/jwks.json\"),\n\t);\n\n\tconst tokenUrl =\n\t\tconfig.oauth.tokenEndpoint ??\n\t\turlConcat(config.oauth.baseUrl, \"oauth2/token\");\n\n\tconst scope = config.oauth.scope ?? \"openid profile email\";\n\n\tasync function exchangeCodeForToken(\n\t\tfetch: typeof global.fetch,\n\t\torigin: string,\n\t\tcode: string,\n\t): Promise<ArmorTokenExchange> {\n\t\tconst params: Record<string, string> = {\n\t\t\tgrant_type: \"authorization_code\",\n\t\t\tclient_id: config.oauth.clientId,\n\t\t\tclient_secret: config.oauth.clientSecret,\n\t\t\tcode,\n\t\t\tredirect_uri: urlConcat(origin, ROUTE_PATH_REDIRECT_LOGIN),\n\t\t\tscope,\n\t\t};\n\n\t\tif (config.oauth.audience) {\n\t\t\tparams.audience = config.oauth.audience;\n\t\t}\n\n\t\tconst response = await fetch(tokenUrl, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\tAccept: \"application/json\",\n\t\t\t},\n\t\t\tbody: new URLSearchParams(params).toString(),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst error = await response.text();\n\t\t\tthrow new Error(`Token exchange failed: ${error}`);\n\t\t}\n\n\t\tconst token = await response.json();\n\n\t\tif (!isTokenExchange(token)) {\n\t\t\tthrow new Error(\"Response is not a valid token exchange.\");\n\t\t}\n\n\t\treturn token;\n\t}\n\n\treturn {\n\t\tpath: ROUTE_PATH_REDIRECT_LOGIN,\n\t\tasync handle({ event }) {\n\t\t\teventStateValidOrThrow(event);\n\n\t\t\tconst error = event.url.searchParams.get(\"error\") ?? undefined;\n\n\t\t\tif (error) {\n\t\t\t\tconst error_description =\n\t\t\t\t\tevent.url.searchParams.get(\"error_description\") ?? undefined;\n\n\t\t\t\tif (!config.oauth.errorLoginRedirectPath) {\n\t\t\t\t\treturn new Response(`${error}\\n${error_description}`.trimEnd(), {\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\"Content-Type\": \"text/plain\",\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst errorParams = queryParamsCreate({ error, error_description });\n\t\t\t\tthrow redirect(\n\t\t\t\t\t302,\n\t\t\t\t\t`${config.oauth.errorLoginRedirectPath}?${errorParams}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst code = event.url.searchParams.get(\"code\") ?? undefined;\n\t\t\tthrowIfUndefined(code);\n\n\t\t\tconst exchange = await exchangeCodeForToken(\n\t\t\t\tevent.fetch,\n\t\t\t\tevent.url.origin,\n\t\t\t\tcode,\n\t\t\t);\n\n\t\t\tconst jwks = createRemoteJWKSet(jwksUrl);\n\n\t\t\tconst [idToken, accessToken] = await Promise.all([\n\t\t\t\tjwtVerifyIdToken(config, jwks, exchange.id_token),\n\t\t\t\tjwtVerifyAccessToken(config, jwks, exchange.access_token),\n\t\t\t]);\n\n\t\t\tawait config.session.login(event, {\n\t\t\t\texchange,\n\t\t\t\tidToken: idToken as ArmorIdToken,\n\t\t\t\t// Generally, IdP's require an audience to get a JWT\n\t\t\t\t// access token. Most cases, this doesn't matter.\n\t\t\t\taccessToken: accessToken ?? exchange.access_token,\n\t\t\t});\n\n\t\t\tthrow redirect(302, \"/\");\n\t\t},\n\t};\n};\n","import { redirect } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport { queryParamsCreate } from \"@nekm/core\";\nimport { ROUTE_PATH_REDIRECT_LOGIN } from \"./redirect-login\";\nimport { randomUUID } from \"node:crypto\";\nimport type { RouteFactory } from \"./routes\";\nimport { COOKIE_STATE, cookieSet } from \"../utils/cookie\";\nimport { urlConcat } from \"../utils/utils\";\n\nexport const ROUTE_PATH_LOGIN = \"/_armor/login\";\n\nexport const routeLoginFactory: RouteFactory = (config: ArmorConfig) => {\n\tconst authorizeEndpoint =\n\t\tconfig.oauth.authorizeEndpoint ??\n\t\turlConcat(config.oauth.baseUrl, \"oauth2/authorize\");\n\n\tconst scope = config.oauth.scope ?? \"openid profile email\";\n\n\treturn {\n\t\tpath: ROUTE_PATH_LOGIN,\n\t\tasync handle({ event }) {\n\t\t\tconst state = randomUUID();\n\t\t\tcookieSet(event.cookies, COOKIE_STATE, state);\n\n\t\t\tconst params = queryParamsCreate({\n\t\t\t\tclient_id: config.oauth.clientId,\n\t\t\t\tresponse_type: \"code\",\n\t\t\t\tredirect_uri: urlConcat(event.url.origin, ROUTE_PATH_REDIRECT_LOGIN),\n\t\t\t\tstate,\n\t\t\t\tscope,\n\t\t\t\taudience: config.oauth.audience,\n\t\t\t});\n\n\t\t\tthrow redirect(302, `${authorizeEndpoint}?${params}`);\n\t\t},\n\t};\n};\n","import { redirect } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport type { RouteFactory } from \"./routes\";\nimport { eventStateValidOrThrow } from \"../utils/event\";\n\nexport const ROUTE_PATH_REDIRECT_LOGOUT = \"/_armor/redirect/logout\";\n\nexport const routeRedirectLogoutFactory: RouteFactory = (\n\tconfig: ArmorConfig,\n) => {\n\t// Check if the oauth provider supports a logout path.\n\tif (!config.oauth.logoutEndpoint) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\tpath: ROUTE_PATH_REDIRECT_LOGOUT,\n\t\tasync handle({ event }) {\n\t\t\teventStateValidOrThrow(event);\n\n\t\t\tawait config.session.logout(event);\n\n\t\t\tthrow redirect(302, \"/\");\n\t\t},\n\t};\n};\n","import { redirect } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport { queryParamsCreate } from \"@nekm/core\";\nimport { ROUTE_PATH_REDIRECT_LOGOUT } from \"./redirect-logout\";\nimport type { RouteFactory } from \"./routes\";\nimport { urlConcat } from \"../utils/utils\";\nimport { randomUUID } from \"node:crypto\";\nimport { COOKIE_STATE, cookieSet } from \"../utils/cookie\";\n\nexport const ROUTE_PATH_LOGOUT = \"/_armor/logout\";\n\nexport const routeLogoutFactory: RouteFactory = (config: ArmorConfig) => {\n\t// Check if the oauth provider supports a logout path.\n\tif (!config.oauth.logoutEndpoint) {\n\t\treturn undefined;\n\t}\n\n\tconst returnTo = config.oauth.logoutReturnToParam ?? \"logout_uri\";\n\n\treturn {\n\t\tpath: ROUTE_PATH_LOGOUT,\n\t\tasync handle({ event }) {\n\t\t\tconst state = randomUUID();\n\t\t\tcookieSet(event.cookies, COOKIE_STATE, state);\n\n\t\t\tconst params = queryParamsCreate({\n\t\t\t\t[returnTo]: urlConcat(event.url.origin, ROUTE_PATH_REDIRECT_LOGOUT),\n\t\t\t\tclient_id: config.oauth.clientId,\n\t\t\t\tstate,\n\t\t\t});\n\n\t\t\tthrow redirect(302, `${config.oauth.logoutEndpoint}?${params}`);\n\t\t},\n\t};\n};\n","import type { Handle } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport { routeLoginFactory } from \"./login\";\nimport { routeLogoutFactory } from \"./logout\";\nimport { routeRedirectLogoutFactory } from \"./redirect-logout\";\nimport { routeRedirectLoginFactory } from \"./redirect-login\";\n\nexport interface Route {\n\treadonly path: string;\n\treadonly handle: Handle;\n}\n\nexport type RouteFactory = (config: ArmorConfig) => Route | undefined;\n\nconst routeFactories = Object.freeze([\n\trouteLoginFactory,\n\trouteLogoutFactory,\n\trouteRedirectLoginFactory,\n\trouteRedirectLogoutFactory,\n]);\n\nexport function routeCreate(config: ArmorConfig): Map<string, Handle> {\n\treturn new Map(\n\t\trouteFactories\n\t\t\t.map((routeFactory) => routeFactory(config))\n\t\t\t.filter((route) => Boolean(route))\n\t\t\t// @ts-expect-error Incorrect typing error.\n\t\t\t.map((route) => [route.path, route.handle]),\n\t);\n}\n","import { RequestEvent } from \"@sveltejs/kit\";\nimport {\n\tCOOKIE_TOKENS,\n\tcookieDelete,\n\tcookieGet,\n\tcookieSet,\n} from \"../utils/cookie\";\nimport { ArmorConfig, ArmorTokens } from \"../contracts\";\nimport { ArmorAuthMissingError } from \"../errors\";\n\nfunction cookieSessionExists({ cookies }: RequestEvent): boolean {\n\treturn Boolean(cookies.get(COOKIE_TOKENS));\n}\n\nexport function cookieSessionLogin(\n\t{ cookies }: RequestEvent,\n\ttokens: ArmorTokens,\n): void {\n\tcookieSet(cookies, COOKIE_TOKENS, tokens);\n}\n\nfunction cookieSessionLogout({ cookies }: RequestEvent): void {\n\tcookieDelete(cookies, COOKIE_TOKENS);\n}\n\nexport function armorCookieSessionGet({ cookies }: RequestEvent): ArmorTokens {\n\tconst tokens = cookieGet<ArmorTokens>(cookies, COOKIE_TOKENS);\n\n\tif (!tokens) {\n\t\tthrow new ArmorAuthMissingError();\n\t}\n\n\treturn tokens;\n}\n\nexport const armorCookieSession: ArmorConfig[\"session\"] = {\n\texists: cookieSessionExists,\n\tlogin: cookieSessionLogin,\n\tlogout: cookieSessionLogout,\n};\n","import { redirect, type Handle } from \"@sveltejs/kit\";\nimport { ROUTE_PATH_LOGIN } from \"./routes/login\";\nimport type { ArmorConfig, ArmorOpenIdConfig, ArmorTokens } from \"./contracts\";\nimport { ROUTE_PATH_LOGOUT } from \"./routes/logout\";\nimport { routeCreate } from \"./routes/routes\";\nimport { ArmorOpenIdConfigError } from \"./errors\";\n\nexport type { ArmorConfig, ArmorTokens };\nexport { armorCookieSession, armorCookieSessionGet } from \"./session/cookie\";\n\nexport const ARMOR_LOGIN = ROUTE_PATH_LOGIN;\nexport const ARMOR_LOGOUT = ROUTE_PATH_LOGOUT;\n\nexport function armor(config: ArmorConfig): Handle {\n\tconst routes = routeCreate(config);\n\n\treturn async ({ event, resolve }) => {\n\t\tconst routeHandle = routes.get(event.url.pathname);\n\n\t\tif (routeHandle) {\n\t\t\treturn routeHandle({ event, resolve });\n\t\t}\n\n\t\tconst exists = await config.session.exists(event);\n\n\t\tif (!exists) {\n\t\t\tthrow redirect(302, ROUTE_PATH_LOGIN);\n\t\t}\n\n\t\treturn resolve(event);\n\t};\n}\n\n/**\n * Some IdP's expose a /.well-known/openid-configuration that specifies how to configure.\n * Use that to create your config.\n * @param config\n * @param fetch\n */\nexport async function armorConfigFromOpenId(\n\tconfig: ArmorOpenIdConfig,\n\tfetch?: typeof global.fetch,\n): Promise<ArmorConfig> {\n\tconst fetchToUse = fetch ?? global.fetch;\n\n\tconst response = await fetchToUse(config.oauth.openIdConfigEndpoint, {\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t},\n\t});\n\n\tif (!response.ok) {\n\t\tconst text = await response.text();\n\t\tthrow new ArmorOpenIdConfigError(text);\n\t}\n\n\tconst body = await response.json();\n\n\treturn {\n\t\t...config,\n\t\toauth: {\n\t\t\t...config.oauth,\n\t\t\ttokenEndpoint: body.token_endpoint,\n\t\t\tauthorizeEndpoint: body.authorization_endpoint,\n\t\t\tissuer: body.issuer,\n\t\t\tjwksEndpoint: body.jwks_uri,\n\t\t\tlogoutEndpoint: body.end_session_endpoint ?? undefined,\n\t\t},\n\t};\n}\n"],"names":["urlConcat","origin","path","strTrimEnd","strTrimStart","join","isTokenExchange","value","obj","access_token","token_type","expires_in","id_token","undefined","refresh_token","scope","jwtIsCompactJwt","token","parts","trim","split","length","every","p","jwtVerifyIdToken","config","jwks","idToken","payload","jwtVerifyToken","issuer","oauth","audience","clientId","throwIfUndefined","jwtVerifyAccessToken","accessToken","opts","isInvalidCompactJwt","error","Boolean","message","test","jwtVerify","COOKIE_TOKENS","COOKIE_STATE","cookieDeleteOptions","Object","freeze","cookieSetOptions","httpOnly","secure","sameSite","maxAge","cookieSet","cookies","key","set","JSON","stringify","cookieGetAndDelete","cookieGet","delete","get","parse","cookieDelete","ArmorError","Error","ArmorOpenIdConfigError","ArmorInvalidStateError","ArmorAuthMissingError","eventStateValidOrThrow","event","_event$url$searchPara","state","url","searchParams","stateCookie","ROUTE_PATH_REDIRECT_LOGIN","routeRedirectLoginFactory","_config$oauth$jwksEnd","_config$oauth$tokenEn","_config$oauth$scope","jwksUrl","URL","jwksEndpoint","baseUrl","tokenUrl","tokenEndpoint","exchangeCodeForToken","fetch","code","params","grant_type","client_id","client_secret","clientSecret","redirect_uri","response","method","headers","Accept","body","URLSearchParams","toString","ok","text","json","handle","_event$url$searchPara3","_event$url$searchPara2","error_description","errorLoginRedirectPath","Response","trimEnd","errorParams","queryParamsCreate","redirect","exchange","createRemoteJWKSet","Promise","all","session","login","ROUTE_PATH_LOGIN","routeLoginFactory","_config$oauth$authori","authorizeEndpoint","randomUUID","response_type","ROUTE_PATH_REDIRECT_LOGOUT","routeRedirectLogoutFactory","logoutEndpoint","logout","ROUTE_PATH_LOGOUT","routeLogoutFactory","_config$oauth$logoutR","returnTo","logoutReturnToParam","routeFactories","routeCreate","Map","map","routeFactory","filter","route","cookieSessionExists","cookieSessionLogin","tokens","cookieSessionLogout","armorCookieSessionGet","armorCookieSession","exists","ARMOR_LOGIN","ARMOR_LOGOUT","armor","routes","resolve","routeHandle","pathname","armorConfigFromOpenId","_body$end_session_end","fetchToUse","global","openIdConfigEndpoint","token_endpoint","authorization_endpoint","jwks_uri","end_session_endpoint"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -14,11 +14,19 @@ function isTokenExchange(value) {
14
14
  typeof obj.id_token === "string" || obj.id_token === undefined) && (typeof obj.refresh_token === "string" || obj.refresh_token === undefined) && (typeof obj.scope === "string" || obj.scope === undefined);
15
15
  }
16
16
 
17
+ function jwtIsCompactJwt(token) {
18
+ // Must be three base64url segments
19
+ const parts = token.trim().split(".");
20
+ return parts.length === 3 && parts.every(p => p.length > 0);
21
+ }
17
22
  function jwtVerifyIdToken(config, jwks, idToken) {
18
- return jwtVerifyToken(jwks, {
23
+ const payload = jwtVerifyToken(jwks, {
19
24
  issuer: config.oauth.issuer,
20
25
  audience: config.oauth.clientId
21
26
  }, idToken);
27
+ core.throwIfUndefined(payload);
28
+ // @ts-expect-error We're already verifying non-null above.
29
+ return payload;
22
30
  }
23
31
  function jwtVerifyAccessToken(config, jwks, accessToken) {
24
32
  const opts = {
@@ -29,11 +37,24 @@ function jwtVerifyAccessToken(config, jwks, accessToken) {
29
37
  }
30
38
  return jwtVerifyToken(jwks, opts, accessToken);
31
39
  }
40
+ function isInvalidCompactJwt(error) {
41
+ return Boolean(typeof error === "object" && error && "message" in error && typeof error.message === "string" && /invalid compact jws/gi.test(error.message));
42
+ }
32
43
  async function jwtVerifyToken(jwks, opts, token) {
33
- const {
34
- payload
35
- } = await jose.jwtVerify(token, jwks, opts);
36
- return payload;
44
+ try {
45
+ if (!jwtIsCompactJwt(token)) {
46
+ return undefined;
47
+ }
48
+ const {
49
+ payload
50
+ } = await jose.jwtVerify(token, jwks, opts);
51
+ return payload;
52
+ } catch (error) {
53
+ if (isInvalidCompactJwt(error)) {
54
+ return undefined;
55
+ }
56
+ throw error;
57
+ }
37
58
  }
38
59
 
39
60
  const COOKIE_TOKENS = "tokens";
@@ -148,7 +169,9 @@ const routeRedirectLoginFactory = config => {
148
169
  await config.session.login(event, {
149
170
  exchange,
150
171
  idToken: idToken,
151
- accessToken
172
+ // Generally, IdP's require an audience to get a JWT
173
+ // access token. Most cases, this doesn't matter.
174
+ accessToken: accessToken != null ? accessToken : exchange.access_token
152
175
  });
153
176
  throw kit.redirect(302, "/");
154
177
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/utils/utils.ts","../src/utils/jwt.ts","../src/utils/cookie.ts","../src/errors.ts","../src/utils/event.ts","../src/routes/redirect-login.ts","../src/routes/login.ts","../src/routes/redirect-logout.ts","../src/routes/logout.ts","../src/routes/routes.ts","../src/session/cookie.ts","../src/index.ts"],"sourcesContent":["import { strTrimEnd, strTrimStart } from \"@nekm/core\";\nimport type { ArmorTokenExchange } from \"../contracts\";\n\nexport function urlConcat(origin: string, path: string): string {\n\treturn [strTrimEnd(origin, \"/\"), strTrimStart(path, \"/\")].join(\"/\");\n}\n\nexport function isTokenExchange(value: unknown): value is ArmorTokenExchange {\n\tif (typeof value !== \"object\" || value === null) return false;\n\n\tconst obj = value as Record<string, unknown>;\n\n\treturn (\n\t\ttypeof obj.access_token === \"string\" &&\n\t\tobj.token_type === \"Bearer\" &&\n\t\ttypeof obj.expires_in === \"number\" &&\n\t\t// Optional fields\n\t\t(typeof obj.id_token === \"string\" || obj.id_token === undefined) &&\n\t\t(typeof obj.refresh_token === \"string\" ||\n\t\t\tobj.refresh_token === undefined) &&\n\t\t(typeof obj.scope === \"string\" || obj.scope === undefined)\n\t);\n}\n","import { ArmorConfig } from \"../contracts\";\nimport { JWTPayload, jwtVerify, JWTVerifyGetKey, JWTVerifyOptions } from \"jose\";\n\nexport function jwtVerifyIdToken(\n\tconfig: ArmorConfig,\n\tjwks: JWTVerifyGetKey,\n\tidToken: string,\n): Promise<JWTPayload> {\n\treturn jwtVerifyToken(\n\t\tjwks,\n\t\t{\n\t\t\tissuer: config.oauth.issuer,\n\t\t\taudience: config.oauth.clientId,\n\t\t},\n\t\tidToken,\n\t);\n}\n\nexport function jwtVerifyAccessToken(\n\tconfig: ArmorConfig,\n\tjwks: JWTVerifyGetKey,\n\taccessToken: string,\n): Promise<JWTPayload> {\n\tconst opts: JWTVerifyOptions = { issuer: config.oauth.issuer };\n\n\tif (config.oauth.audience) {\n\t\topts.audience = config.oauth.audience;\n\t}\n\n\treturn jwtVerifyToken(jwks, opts, accessToken);\n}\n\nasync function jwtVerifyToken(\n\tjwks: JWTVerifyGetKey,\n\topts: JWTVerifyOptions,\n\ttoken: string,\n): Promise<JWTPayload> {\n\tconst { payload } = await jwtVerify(token, jwks, opts);\n\treturn payload;\n}\n","import { Cookies } from \"@sveltejs/kit\";\n\nexport const COOKIE_TOKENS = \"tokens\";\nexport const COOKIE_STATE = \"state\";\n\nconst cookieDeleteOptions = Object.freeze({ path: \"/\" });\n\nconst cookieSetOptions = Object.freeze({\n\t...cookieDeleteOptions,\n\thttpOnly: true,\n\tsecure: true,\n\tsameSite: \"lax\",\n\tmaxAge: 1800, // 30 minutes\n});\n\nexport function cookieSet(\n\tcookies: Cookies,\n\tkey: string,\n\tvalue: string | object,\n) {\n\tcookies.set(key, JSON.stringify(value), cookieSetOptions);\n}\n\nexport function cookieGetAndDelete<T>(\n\tcookies: Cookies,\n\tkey: string,\n): T | undefined {\n\tconst value = cookieGet<T>(cookies, key);\n\n\tif (value) {\n\t\tcookies.delete(key, cookieDeleteOptions);\n\t}\n\n\treturn value;\n}\n\nexport function cookieGet<T>(cookies: Cookies, key: string): T | undefined {\n\tconst value = cookies.get(key);\n\n\treturn !value ? undefined : JSON.parse(value);\n}\n\nexport function cookieDelete(cookies: Cookies, key: string): void {\n\tcookies.delete(key, cookieDeleteOptions);\n}\n","export class ArmorError extends Error {}\nexport class ArmorOpenIdConfigError extends ArmorError {}\nexport class ArmorInvalidStateError extends ArmorError {}\nexport class ArmorAuthMissingError extends ArmorError {}\n","import { RequestEvent } from \"@sveltejs/kit\";\nimport { COOKIE_STATE, cookieGetAndDelete } from \"./cookie\";\nimport { ArmorInvalidStateError } from \"../errors\";\n\nexport function eventStateValidOrThrow(event: RequestEvent): void {\n\tconst state = event.url.searchParams.get(\"state\") ?? undefined;\n\tconst stateCookie = cookieGetAndDelete(event.cookies, COOKIE_STATE);\n\n\tif (state !== stateCookie) {\n\t\tthrow new ArmorInvalidStateError();\n\t}\n}\n","import { redirect } from \"@sveltejs/kit\";\nimport type {\n\tArmorConfig,\n\tArmorIdToken,\n\tArmorTokenExchange,\n} from \"../contracts\";\nimport { queryParamsCreate, throwIfUndefined } from \"@nekm/core\";\nimport { createRemoteJWKSet } from \"jose\";\nimport type { RouteFactory } from \"./routes\";\nimport { urlConcat, isTokenExchange } from \"../utils/utils\";\nimport { jwtVerifyAccessToken, jwtVerifyIdToken } from \"../utils/jwt\";\nimport { eventStateValidOrThrow } from \"../utils/event\";\n\nexport const ROUTE_PATH_REDIRECT_LOGIN = \"/_armor/redirect/login\";\n\nexport const routeRedirectLoginFactory: RouteFactory = (\n\tconfig: ArmorConfig,\n) => {\n\tconst jwksUrl = new URL(\n\t\tconfig.oauth.jwksEndpoint ??\n\t\t\turlConcat(config.oauth.baseUrl, \".well-known/jwks.json\"),\n\t);\n\n\tconst tokenUrl =\n\t\tconfig.oauth.tokenEndpoint ??\n\t\turlConcat(config.oauth.baseUrl, \"oauth2/token\");\n\n\tconst scope = config.oauth.scope ?? \"openid profile email\";\n\n\tasync function exchangeCodeForToken(\n\t\tfetch: typeof global.fetch,\n\t\torigin: string,\n\t\tcode: string,\n\t): Promise<ArmorTokenExchange> {\n\t\tconst params: Record<string, string> = {\n\t\t\tgrant_type: \"authorization_code\",\n\t\t\tclient_id: config.oauth.clientId,\n\t\t\tclient_secret: config.oauth.clientSecret,\n\t\t\tcode,\n\t\t\tredirect_uri: urlConcat(origin, ROUTE_PATH_REDIRECT_LOGIN),\n\t\t\tscope,\n\t\t};\n\n\t\tif (config.oauth.audience) {\n\t\t\tparams.audience = config.oauth.audience;\n\t\t}\n\n\t\tconst response = await fetch(tokenUrl, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\tAccept: \"application/json\",\n\t\t\t},\n\t\t\tbody: new URLSearchParams(params).toString(),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst error = await response.text();\n\t\t\tthrow new Error(`Token exchange failed: ${error}`);\n\t\t}\n\n\t\tconst token = await response.json();\n\n\t\tif (!isTokenExchange(token)) {\n\t\t\tthrow new Error(\"Response is not a valid token exchange.\");\n\t\t}\n\n\t\treturn token;\n\t}\n\n\treturn {\n\t\tpath: ROUTE_PATH_REDIRECT_LOGIN,\n\t\tasync handle({ event }) {\n\t\t\teventStateValidOrThrow(event);\n\n\t\t\tconst error = event.url.searchParams.get(\"error\") ?? undefined;\n\n\t\t\tif (error) {\n\t\t\t\tconst error_description =\n\t\t\t\t\tevent.url.searchParams.get(\"error_description\") ?? undefined;\n\n\t\t\t\tif (!config.oauth.errorLoginRedirectPath) {\n\t\t\t\t\treturn new Response(`${error}\\n${error_description}`.trimEnd(), {\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\"Content-Type\": \"text/plain\",\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst errorParams = queryParamsCreate({ error, error_description });\n\t\t\t\tthrow redirect(\n\t\t\t\t\t302,\n\t\t\t\t\t`${config.oauth.errorLoginRedirectPath}?${errorParams}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst code = event.url.searchParams.get(\"code\") ?? undefined;\n\t\t\tthrowIfUndefined(code);\n\n\t\t\tconst exchange = await exchangeCodeForToken(\n\t\t\t\tevent.fetch,\n\t\t\t\tevent.url.origin,\n\t\t\t\tcode,\n\t\t\t);\n\n\t\t\tconst jwks = createRemoteJWKSet(jwksUrl);\n\n\t\t\tconst [idToken, accessToken] = await Promise.all([\n\t\t\t\tjwtVerifyIdToken(config, jwks, exchange.id_token),\n\t\t\t\tjwtVerifyAccessToken(config, jwks, exchange.access_token),\n\t\t\t]);\n\n\t\t\tawait config.session.login(event, {\n\t\t\t\texchange,\n\t\t\t\tidToken: idToken as ArmorIdToken,\n\t\t\t\taccessToken,\n\t\t\t});\n\n\t\t\tthrow redirect(302, \"/\");\n\t\t},\n\t};\n};\n","import { redirect } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport { queryParamsCreate } from \"@nekm/core\";\nimport { ROUTE_PATH_REDIRECT_LOGIN } from \"./redirect-login\";\nimport { randomUUID } from \"node:crypto\";\nimport type { RouteFactory } from \"./routes\";\nimport { COOKIE_STATE, cookieSet } from \"../utils/cookie\";\nimport { urlConcat } from \"../utils/utils\";\n\nexport const ROUTE_PATH_LOGIN = \"/_armor/login\";\n\nexport const routeLoginFactory: RouteFactory = (config: ArmorConfig) => {\n\tconst authorizeEndpoint =\n\t\tconfig.oauth.authorizeEndpoint ??\n\t\turlConcat(config.oauth.baseUrl, \"oauth2/authorize\");\n\n\tconst scope = config.oauth.scope ?? \"openid profile email\";\n\n\treturn {\n\t\tpath: ROUTE_PATH_LOGIN,\n\t\tasync handle({ event }) {\n\t\t\tconst state = randomUUID();\n\t\t\tcookieSet(event.cookies, COOKIE_STATE, state);\n\n\t\t\tconst params = queryParamsCreate({\n\t\t\t\tclient_id: config.oauth.clientId,\n\t\t\t\tresponse_type: \"code\",\n\t\t\t\tredirect_uri: urlConcat(event.url.origin, ROUTE_PATH_REDIRECT_LOGIN),\n\t\t\t\tstate,\n\t\t\t\tscope,\n\t\t\t\taudience: config.oauth.audience,\n\t\t\t});\n\n\t\t\tthrow redirect(302, `${authorizeEndpoint}?${params}`);\n\t\t},\n\t};\n};\n","import { redirect } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport type { RouteFactory } from \"./routes\";\nimport { eventStateValidOrThrow } from \"../utils/event\";\n\nexport const ROUTE_PATH_REDIRECT_LOGOUT = \"/_armor/redirect/logout\";\n\nexport const routeRedirectLogoutFactory: RouteFactory = (\n\tconfig: ArmorConfig,\n) => {\n\t// Check if the oauth provider supports a logout path.\n\tif (!config.oauth.logoutEndpoint) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\tpath: ROUTE_PATH_REDIRECT_LOGOUT,\n\t\tasync handle({ event }) {\n\t\t\teventStateValidOrThrow(event);\n\n\t\t\tawait config.session.logout(event);\n\n\t\t\tthrow redirect(302, \"/\");\n\t\t},\n\t};\n};\n","import { redirect } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport { queryParamsCreate } from \"@nekm/core\";\nimport { ROUTE_PATH_REDIRECT_LOGOUT } from \"./redirect-logout\";\nimport type { RouteFactory } from \"./routes\";\nimport { urlConcat } from \"../utils/utils\";\nimport { randomUUID } from \"node:crypto\";\nimport { COOKIE_STATE, cookieSet } from \"../utils/cookie\";\n\nexport const ROUTE_PATH_LOGOUT = \"/_armor/logout\";\n\nexport const routeLogoutFactory: RouteFactory = (config: ArmorConfig) => {\n\t// Check if the oauth provider supports a logout path.\n\tif (!config.oauth.logoutEndpoint) {\n\t\treturn undefined;\n\t}\n\n\tconst returnTo = config.oauth.logoutReturnToParam ?? \"logout_uri\";\n\n\treturn {\n\t\tpath: ROUTE_PATH_LOGOUT,\n\t\tasync handle({ event }) {\n\t\t\tconst state = randomUUID();\n\t\t\tcookieSet(event.cookies, COOKIE_STATE, state);\n\n\t\t\tconst params = queryParamsCreate({\n\t\t\t\t[returnTo]: urlConcat(event.url.origin, ROUTE_PATH_REDIRECT_LOGOUT),\n\t\t\t\tclient_id: config.oauth.clientId,\n\t\t\t\tstate,\n\t\t\t});\n\n\t\t\tthrow redirect(302, `${config.oauth.logoutEndpoint}?${params}`);\n\t\t},\n\t};\n};\n","import type { Handle } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport { routeLoginFactory } from \"./login\";\nimport { routeLogoutFactory } from \"./logout\";\nimport { routeRedirectLogoutFactory } from \"./redirect-logout\";\nimport { routeRedirectLoginFactory } from \"./redirect-login\";\n\nexport interface Route {\n\treadonly path: string;\n\treadonly handle: Handle;\n}\n\nexport type RouteFactory = (config: ArmorConfig) => Route | undefined;\n\nconst routeFactories = Object.freeze([\n\trouteLoginFactory,\n\trouteLogoutFactory,\n\trouteRedirectLoginFactory,\n\trouteRedirectLogoutFactory,\n]);\n\nexport function routeCreate(config: ArmorConfig): Map<string, Handle> {\n\treturn new Map(\n\t\trouteFactories\n\t\t\t.map((routeFactory) => routeFactory(config))\n\t\t\t.filter((route) => Boolean(route))\n\t\t\t// @ts-expect-error Incorrect typing error.\n\t\t\t.map((route) => [route.path, route.handle]),\n\t);\n}\n","import { RequestEvent } from \"@sveltejs/kit\";\nimport {\n\tCOOKIE_TOKENS,\n\tcookieDelete,\n\tcookieGet,\n\tcookieSet,\n} from \"../utils/cookie\";\nimport { ArmorConfig, ArmorTokens } from \"../contracts\";\nimport { ArmorAuthMissingError } from \"../errors\";\n\nfunction cookieSessionExists({ cookies }: RequestEvent): boolean {\n\treturn Boolean(cookies.get(COOKIE_TOKENS));\n}\n\nexport function cookieSessionLogin(\n\t{ cookies }: RequestEvent,\n\ttokens: ArmorTokens,\n): void {\n\tcookieSet(cookies, COOKIE_TOKENS, tokens);\n}\n\nfunction cookieSessionLogout({ cookies }: RequestEvent): void {\n\tcookieDelete(cookies, COOKIE_TOKENS);\n}\n\nexport function armorCookieSessionGet({ cookies }: RequestEvent): ArmorTokens {\n\tconst tokens = cookieGet<ArmorTokens>(cookies, COOKIE_TOKENS);\n\n\tif (!tokens) {\n\t\tthrow new ArmorAuthMissingError();\n\t}\n\n\treturn tokens;\n}\n\nexport const armorCookieSession: ArmorConfig[\"session\"] = {\n\texists: cookieSessionExists,\n\tlogin: cookieSessionLogin,\n\tlogout: cookieSessionLogout,\n};\n","import { redirect, type Handle } from \"@sveltejs/kit\";\nimport { ROUTE_PATH_LOGIN } from \"./routes/login\";\nimport type { ArmorConfig, ArmorOpenIdConfig, ArmorTokens } from \"./contracts\";\nimport { ROUTE_PATH_LOGOUT } from \"./routes/logout\";\nimport { routeCreate } from \"./routes/routes\";\nimport { ArmorOpenIdConfigError } from \"./errors\";\n\nexport type { ArmorConfig, ArmorTokens };\nexport { armorCookieSession, armorCookieSessionGet } from \"./session/cookie\";\n\nexport const ARMOR_LOGIN = ROUTE_PATH_LOGIN;\nexport const ARMOR_LOGOUT = ROUTE_PATH_LOGOUT;\n\nexport function armor(config: ArmorConfig): Handle {\n\tconst routes = routeCreate(config);\n\n\treturn async ({ event, resolve }) => {\n\t\tconst routeHandle = routes.get(event.url.pathname);\n\n\t\tif (routeHandle) {\n\t\t\treturn routeHandle({ event, resolve });\n\t\t}\n\n\t\tconst exists = await config.session.exists(event);\n\n\t\tif (!exists) {\n\t\t\tthrow redirect(302, ROUTE_PATH_LOGIN);\n\t\t}\n\n\t\treturn resolve(event);\n\t};\n}\n\n/**\n * Some IdP's expose a /.well-known/openid-configuration that specifies how to configure.\n * Use that to create your config.\n * @param config\n * @param fetch\n */\nexport async function armorConfigFromOpenId(\n\tconfig: ArmorOpenIdConfig,\n\tfetch?: typeof global.fetch,\n): Promise<ArmorConfig> {\n\tconst fetchToUse = fetch ?? global.fetch;\n\n\tconst response = await fetchToUse(config.oauth.openIdConfigEndpoint, {\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t},\n\t});\n\n\tif (!response.ok) {\n\t\tconst text = await response.text();\n\t\tthrow new ArmorOpenIdConfigError(text);\n\t}\n\n\tconst body = await response.json();\n\n\treturn {\n\t\t...config,\n\t\toauth: {\n\t\t\t...config.oauth,\n\t\t\ttokenEndpoint: body.token_endpoint,\n\t\t\tauthorizeEndpoint: body.authorization_endpoint,\n\t\t\tissuer: body.issuer,\n\t\t\tjwksEndpoint: body.jwks_uri,\n\t\t\tlogoutEndpoint: body.end_session_endpoint ?? undefined,\n\t\t},\n\t};\n}\n"],"names":["urlConcat","origin","path","strTrimEnd","strTrimStart","join","isTokenExchange","value","obj","access_token","token_type","expires_in","id_token","undefined","refresh_token","scope","jwtVerifyIdToken","config","jwks","idToken","jwtVerifyToken","issuer","oauth","audience","clientId","jwtVerifyAccessToken","accessToken","opts","token","payload","jwtVerify","COOKIE_TOKENS","COOKIE_STATE","cookieDeleteOptions","Object","freeze","cookieSetOptions","httpOnly","secure","sameSite","maxAge","cookieSet","cookies","key","set","JSON","stringify","cookieGetAndDelete","cookieGet","delete","get","parse","cookieDelete","ArmorError","Error","ArmorOpenIdConfigError","ArmorInvalidStateError","ArmorAuthMissingError","eventStateValidOrThrow","event","_event$url$searchPara","state","url","searchParams","stateCookie","ROUTE_PATH_REDIRECT_LOGIN","routeRedirectLoginFactory","_config$oauth$jwksEnd","_config$oauth$tokenEn","_config$oauth$scope","jwksUrl","URL","jwksEndpoint","baseUrl","tokenUrl","tokenEndpoint","exchangeCodeForToken","fetch","code","params","grant_type","client_id","client_secret","clientSecret","redirect_uri","response","method","headers","Accept","body","URLSearchParams","toString","ok","error","text","json","handle","_event$url$searchPara3","_event$url$searchPara2","error_description","errorLoginRedirectPath","Response","trimEnd","errorParams","queryParamsCreate","redirect","throwIfUndefined","exchange","createRemoteJWKSet","Promise","all","session","login","ROUTE_PATH_LOGIN","routeLoginFactory","_config$oauth$authori","authorizeEndpoint","randomUUID","response_type","ROUTE_PATH_REDIRECT_LOGOUT","routeRedirectLogoutFactory","logoutEndpoint","logout","ROUTE_PATH_LOGOUT","routeLogoutFactory","_config$oauth$logoutR","returnTo","logoutReturnToParam","routeFactories","routeCreate","Map","map","routeFactory","filter","route","Boolean","cookieSessionExists","cookieSessionLogin","tokens","cookieSessionLogout","armorCookieSessionGet","armorCookieSession","exists","ARMOR_LOGIN","ARMOR_LOGOUT","armor","routes","resolve","routeHandle","pathname","armorConfigFromOpenId","_body$end_session_end","fetchToUse","global","openIdConfigEndpoint","token_endpoint","authorization_endpoint","jwks_uri","end_session_endpoint"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/utils/utils.ts","../src/utils/jwt.ts","../src/utils/cookie.ts","../src/errors.ts","../src/utils/event.ts","../src/routes/redirect-login.ts","../src/routes/login.ts","../src/routes/redirect-logout.ts","../src/routes/logout.ts","../src/routes/routes.ts","../src/session/cookie.ts","../src/index.ts"],"sourcesContent":["import { strTrimEnd, strTrimStart } from \"@nekm/core\";\nimport type { ArmorTokenExchange } from \"../contracts\";\n\nexport function urlConcat(origin: string, path: string): string {\n\treturn [strTrimEnd(origin, \"/\"), strTrimStart(path, \"/\")].join(\"/\");\n}\n\nexport function isTokenExchange(value: unknown): value is ArmorTokenExchange {\n\tif (typeof value !== \"object\" || value === null) return false;\n\n\tconst obj = value as Record<string, unknown>;\n\n\treturn (\n\t\ttypeof obj.access_token === \"string\" &&\n\t\tobj.token_type === \"Bearer\" &&\n\t\ttypeof obj.expires_in === \"number\" &&\n\t\t// Optional fields\n\t\t(typeof obj.id_token === \"string\" || obj.id_token === undefined) &&\n\t\t(typeof obj.refresh_token === \"string\" ||\n\t\t\tobj.refresh_token === undefined) &&\n\t\t(typeof obj.scope === \"string\" || obj.scope === undefined)\n\t);\n}\n","import { ArmorConfig } from \"../contracts\";\nimport { JWTPayload, jwtVerify, JWTVerifyGetKey, JWTVerifyOptions } from \"jose\";\nimport { throwIfUndefined } from \"@nekm/core\";\n\nfunction jwtIsCompactJwt(token: string): boolean {\n\t// Must be three base64url segments\n\tconst parts = token.trim().split(\".\");\n\treturn parts.length === 3 && parts.every((p) => p.length > 0);\n}\n\nexport function jwtVerifyIdToken(\n\tconfig: ArmorConfig,\n\tjwks: JWTVerifyGetKey,\n\tidToken: string,\n): Promise<JWTPayload> {\n\tconst payload = jwtVerifyToken(\n\t\tjwks,\n\t\t{\n\t\t\tissuer: config.oauth.issuer,\n\t\t\taudience: config.oauth.clientId,\n\t\t},\n\t\tidToken,\n\t);\n\tthrowIfUndefined(payload);\n\t// @ts-expect-error We're already verifying non-null above.\n\treturn payload;\n}\n\nexport function jwtVerifyAccessToken(\n\tconfig: ArmorConfig,\n\tjwks: JWTVerifyGetKey,\n\taccessToken: string,\n): Promise<JWTPayload | undefined> {\n\tconst opts: JWTVerifyOptions = { issuer: config.oauth.issuer };\n\n\tif (config.oauth.audience) {\n\t\topts.audience = config.oauth.audience;\n\t}\n\n\treturn jwtVerifyToken(jwks, opts, accessToken);\n}\n\nfunction isInvalidCompactJwt(error: unknown): boolean {\n\treturn Boolean(\n\t\ttypeof error === \"object\" &&\n\t\terror &&\n\t\t\"message\" in error &&\n\t\ttypeof error.message === \"string\" &&\n\t\t/invalid compact jws/gi.test(error.message),\n\t);\n}\n\nasync function jwtVerifyToken(\n\tjwks: JWTVerifyGetKey,\n\topts: JWTVerifyOptions,\n\ttoken: string,\n): Promise<JWTPayload | undefined> {\n\ttry {\n\t\tif (!jwtIsCompactJwt(token)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst { payload } = await jwtVerify(token, jwks, opts);\n\t\treturn payload;\n\t} catch (error) {\n\t\tif (isInvalidCompactJwt(error)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tthrow error;\n\t}\n}\n","import { Cookies } from \"@sveltejs/kit\";\n\nexport const COOKIE_TOKENS = \"tokens\";\nexport const COOKIE_STATE = \"state\";\n\nconst cookieDeleteOptions = Object.freeze({ path: \"/\" });\n\nconst cookieSetOptions = Object.freeze({\n\t...cookieDeleteOptions,\n\thttpOnly: true,\n\tsecure: true,\n\tsameSite: \"lax\",\n\tmaxAge: 1800, // 30 minutes\n});\n\nexport function cookieSet(\n\tcookies: Cookies,\n\tkey: string,\n\tvalue: string | object,\n) {\n\tcookies.set(key, JSON.stringify(value), cookieSetOptions);\n}\n\nexport function cookieGetAndDelete<T>(\n\tcookies: Cookies,\n\tkey: string,\n): T | undefined {\n\tconst value = cookieGet<T>(cookies, key);\n\n\tif (value) {\n\t\tcookies.delete(key, cookieDeleteOptions);\n\t}\n\n\treturn value;\n}\n\nexport function cookieGet<T>(cookies: Cookies, key: string): T | undefined {\n\tconst value = cookies.get(key);\n\n\treturn !value ? undefined : JSON.parse(value);\n}\n\nexport function cookieDelete(cookies: Cookies, key: string): void {\n\tcookies.delete(key, cookieDeleteOptions);\n}\n","export class ArmorError extends Error {}\nexport class ArmorOpenIdConfigError extends ArmorError {}\nexport class ArmorInvalidStateError extends ArmorError {}\nexport class ArmorAuthMissingError extends ArmorError {}\n","import { RequestEvent } from \"@sveltejs/kit\";\nimport { COOKIE_STATE, cookieGetAndDelete } from \"./cookie\";\nimport { ArmorInvalidStateError } from \"../errors\";\n\nexport function eventStateValidOrThrow(event: RequestEvent): void {\n\tconst state = event.url.searchParams.get(\"state\") ?? undefined;\n\tconst stateCookie = cookieGetAndDelete(event.cookies, COOKIE_STATE);\n\n\tif (state !== stateCookie) {\n\t\tthrow new ArmorInvalidStateError();\n\t}\n}\n","import { redirect } from \"@sveltejs/kit\";\nimport type {\n\tArmorConfig,\n\tArmorIdToken,\n\tArmorTokenExchange,\n} from \"../contracts\";\nimport { queryParamsCreate, throwIfUndefined } from \"@nekm/core\";\nimport { createRemoteJWKSet } from \"jose\";\nimport type { RouteFactory } from \"./routes\";\nimport { urlConcat, isTokenExchange } from \"../utils/utils\";\nimport { jwtVerifyAccessToken, jwtVerifyIdToken } from \"../utils/jwt\";\nimport { eventStateValidOrThrow } from \"../utils/event\";\n\nexport const ROUTE_PATH_REDIRECT_LOGIN = \"/_armor/redirect/login\";\n\nexport const routeRedirectLoginFactory: RouteFactory = (\n\tconfig: ArmorConfig,\n) => {\n\tconst jwksUrl = new URL(\n\t\tconfig.oauth.jwksEndpoint ??\n\t\t\turlConcat(config.oauth.baseUrl, \".well-known/jwks.json\"),\n\t);\n\n\tconst tokenUrl =\n\t\tconfig.oauth.tokenEndpoint ??\n\t\turlConcat(config.oauth.baseUrl, \"oauth2/token\");\n\n\tconst scope = config.oauth.scope ?? \"openid profile email\";\n\n\tasync function exchangeCodeForToken(\n\t\tfetch: typeof global.fetch,\n\t\torigin: string,\n\t\tcode: string,\n\t): Promise<ArmorTokenExchange> {\n\t\tconst params: Record<string, string> = {\n\t\t\tgrant_type: \"authorization_code\",\n\t\t\tclient_id: config.oauth.clientId,\n\t\t\tclient_secret: config.oauth.clientSecret,\n\t\t\tcode,\n\t\t\tredirect_uri: urlConcat(origin, ROUTE_PATH_REDIRECT_LOGIN),\n\t\t\tscope,\n\t\t};\n\n\t\tif (config.oauth.audience) {\n\t\t\tparams.audience = config.oauth.audience;\n\t\t}\n\n\t\tconst response = await fetch(tokenUrl, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\tAccept: \"application/json\",\n\t\t\t},\n\t\t\tbody: new URLSearchParams(params).toString(),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst error = await response.text();\n\t\t\tthrow new Error(`Token exchange failed: ${error}`);\n\t\t}\n\n\t\tconst token = await response.json();\n\n\t\tif (!isTokenExchange(token)) {\n\t\t\tthrow new Error(\"Response is not a valid token exchange.\");\n\t\t}\n\n\t\treturn token;\n\t}\n\n\treturn {\n\t\tpath: ROUTE_PATH_REDIRECT_LOGIN,\n\t\tasync handle({ event }) {\n\t\t\teventStateValidOrThrow(event);\n\n\t\t\tconst error = event.url.searchParams.get(\"error\") ?? undefined;\n\n\t\t\tif (error) {\n\t\t\t\tconst error_description =\n\t\t\t\t\tevent.url.searchParams.get(\"error_description\") ?? undefined;\n\n\t\t\t\tif (!config.oauth.errorLoginRedirectPath) {\n\t\t\t\t\treturn new Response(`${error}\\n${error_description}`.trimEnd(), {\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\"Content-Type\": \"text/plain\",\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst errorParams = queryParamsCreate({ error, error_description });\n\t\t\t\tthrow redirect(\n\t\t\t\t\t302,\n\t\t\t\t\t`${config.oauth.errorLoginRedirectPath}?${errorParams}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst code = event.url.searchParams.get(\"code\") ?? undefined;\n\t\t\tthrowIfUndefined(code);\n\n\t\t\tconst exchange = await exchangeCodeForToken(\n\t\t\t\tevent.fetch,\n\t\t\t\tevent.url.origin,\n\t\t\t\tcode,\n\t\t\t);\n\n\t\t\tconst jwks = createRemoteJWKSet(jwksUrl);\n\n\t\t\tconst [idToken, accessToken] = await Promise.all([\n\t\t\t\tjwtVerifyIdToken(config, jwks, exchange.id_token),\n\t\t\t\tjwtVerifyAccessToken(config, jwks, exchange.access_token),\n\t\t\t]);\n\n\t\t\tawait config.session.login(event, {\n\t\t\t\texchange,\n\t\t\t\tidToken: idToken as ArmorIdToken,\n\t\t\t\t// Generally, IdP's require an audience to get a JWT\n\t\t\t\t// access token. Most cases, this doesn't matter.\n\t\t\t\taccessToken: accessToken ?? exchange.access_token,\n\t\t\t});\n\n\t\t\tthrow redirect(302, \"/\");\n\t\t},\n\t};\n};\n","import { redirect } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport { queryParamsCreate } from \"@nekm/core\";\nimport { ROUTE_PATH_REDIRECT_LOGIN } from \"./redirect-login\";\nimport { randomUUID } from \"node:crypto\";\nimport type { RouteFactory } from \"./routes\";\nimport { COOKIE_STATE, cookieSet } from \"../utils/cookie\";\nimport { urlConcat } from \"../utils/utils\";\n\nexport const ROUTE_PATH_LOGIN = \"/_armor/login\";\n\nexport const routeLoginFactory: RouteFactory = (config: ArmorConfig) => {\n\tconst authorizeEndpoint =\n\t\tconfig.oauth.authorizeEndpoint ??\n\t\turlConcat(config.oauth.baseUrl, \"oauth2/authorize\");\n\n\tconst scope = config.oauth.scope ?? \"openid profile email\";\n\n\treturn {\n\t\tpath: ROUTE_PATH_LOGIN,\n\t\tasync handle({ event }) {\n\t\t\tconst state = randomUUID();\n\t\t\tcookieSet(event.cookies, COOKIE_STATE, state);\n\n\t\t\tconst params = queryParamsCreate({\n\t\t\t\tclient_id: config.oauth.clientId,\n\t\t\t\tresponse_type: \"code\",\n\t\t\t\tredirect_uri: urlConcat(event.url.origin, ROUTE_PATH_REDIRECT_LOGIN),\n\t\t\t\tstate,\n\t\t\t\tscope,\n\t\t\t\taudience: config.oauth.audience,\n\t\t\t});\n\n\t\t\tthrow redirect(302, `${authorizeEndpoint}?${params}`);\n\t\t},\n\t};\n};\n","import { redirect } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport type { RouteFactory } from \"./routes\";\nimport { eventStateValidOrThrow } from \"../utils/event\";\n\nexport const ROUTE_PATH_REDIRECT_LOGOUT = \"/_armor/redirect/logout\";\n\nexport const routeRedirectLogoutFactory: RouteFactory = (\n\tconfig: ArmorConfig,\n) => {\n\t// Check if the oauth provider supports a logout path.\n\tif (!config.oauth.logoutEndpoint) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\tpath: ROUTE_PATH_REDIRECT_LOGOUT,\n\t\tasync handle({ event }) {\n\t\t\teventStateValidOrThrow(event);\n\n\t\t\tawait config.session.logout(event);\n\n\t\t\tthrow redirect(302, \"/\");\n\t\t},\n\t};\n};\n","import { redirect } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport { queryParamsCreate } from \"@nekm/core\";\nimport { ROUTE_PATH_REDIRECT_LOGOUT } from \"./redirect-logout\";\nimport type { RouteFactory } from \"./routes\";\nimport { urlConcat } from \"../utils/utils\";\nimport { randomUUID } from \"node:crypto\";\nimport { COOKIE_STATE, cookieSet } from \"../utils/cookie\";\n\nexport const ROUTE_PATH_LOGOUT = \"/_armor/logout\";\n\nexport const routeLogoutFactory: RouteFactory = (config: ArmorConfig) => {\n\t// Check if the oauth provider supports a logout path.\n\tif (!config.oauth.logoutEndpoint) {\n\t\treturn undefined;\n\t}\n\n\tconst returnTo = config.oauth.logoutReturnToParam ?? \"logout_uri\";\n\n\treturn {\n\t\tpath: ROUTE_PATH_LOGOUT,\n\t\tasync handle({ event }) {\n\t\t\tconst state = randomUUID();\n\t\t\tcookieSet(event.cookies, COOKIE_STATE, state);\n\n\t\t\tconst params = queryParamsCreate({\n\t\t\t\t[returnTo]: urlConcat(event.url.origin, ROUTE_PATH_REDIRECT_LOGOUT),\n\t\t\t\tclient_id: config.oauth.clientId,\n\t\t\t\tstate,\n\t\t\t});\n\n\t\t\tthrow redirect(302, `${config.oauth.logoutEndpoint}?${params}`);\n\t\t},\n\t};\n};\n","import type { Handle } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport { routeLoginFactory } from \"./login\";\nimport { routeLogoutFactory } from \"./logout\";\nimport { routeRedirectLogoutFactory } from \"./redirect-logout\";\nimport { routeRedirectLoginFactory } from \"./redirect-login\";\n\nexport interface Route {\n\treadonly path: string;\n\treadonly handle: Handle;\n}\n\nexport type RouteFactory = (config: ArmorConfig) => Route | undefined;\n\nconst routeFactories = Object.freeze([\n\trouteLoginFactory,\n\trouteLogoutFactory,\n\trouteRedirectLoginFactory,\n\trouteRedirectLogoutFactory,\n]);\n\nexport function routeCreate(config: ArmorConfig): Map<string, Handle> {\n\treturn new Map(\n\t\trouteFactories\n\t\t\t.map((routeFactory) => routeFactory(config))\n\t\t\t.filter((route) => Boolean(route))\n\t\t\t// @ts-expect-error Incorrect typing error.\n\t\t\t.map((route) => [route.path, route.handle]),\n\t);\n}\n","import { RequestEvent } from \"@sveltejs/kit\";\nimport {\n\tCOOKIE_TOKENS,\n\tcookieDelete,\n\tcookieGet,\n\tcookieSet,\n} from \"../utils/cookie\";\nimport { ArmorConfig, ArmorTokens } from \"../contracts\";\nimport { ArmorAuthMissingError } from \"../errors\";\n\nfunction cookieSessionExists({ cookies }: RequestEvent): boolean {\n\treturn Boolean(cookies.get(COOKIE_TOKENS));\n}\n\nexport function cookieSessionLogin(\n\t{ cookies }: RequestEvent,\n\ttokens: ArmorTokens,\n): void {\n\tcookieSet(cookies, COOKIE_TOKENS, tokens);\n}\n\nfunction cookieSessionLogout({ cookies }: RequestEvent): void {\n\tcookieDelete(cookies, COOKIE_TOKENS);\n}\n\nexport function armorCookieSessionGet({ cookies }: RequestEvent): ArmorTokens {\n\tconst tokens = cookieGet<ArmorTokens>(cookies, COOKIE_TOKENS);\n\n\tif (!tokens) {\n\t\tthrow new ArmorAuthMissingError();\n\t}\n\n\treturn tokens;\n}\n\nexport const armorCookieSession: ArmorConfig[\"session\"] = {\n\texists: cookieSessionExists,\n\tlogin: cookieSessionLogin,\n\tlogout: cookieSessionLogout,\n};\n","import { redirect, type Handle } from \"@sveltejs/kit\";\nimport { ROUTE_PATH_LOGIN } from \"./routes/login\";\nimport type { ArmorConfig, ArmorOpenIdConfig, ArmorTokens } from \"./contracts\";\nimport { ROUTE_PATH_LOGOUT } from \"./routes/logout\";\nimport { routeCreate } from \"./routes/routes\";\nimport { ArmorOpenIdConfigError } from \"./errors\";\n\nexport type { ArmorConfig, ArmorTokens };\nexport { armorCookieSession, armorCookieSessionGet } from \"./session/cookie\";\n\nexport const ARMOR_LOGIN = ROUTE_PATH_LOGIN;\nexport const ARMOR_LOGOUT = ROUTE_PATH_LOGOUT;\n\nexport function armor(config: ArmorConfig): Handle {\n\tconst routes = routeCreate(config);\n\n\treturn async ({ event, resolve }) => {\n\t\tconst routeHandle = routes.get(event.url.pathname);\n\n\t\tif (routeHandle) {\n\t\t\treturn routeHandle({ event, resolve });\n\t\t}\n\n\t\tconst exists = await config.session.exists(event);\n\n\t\tif (!exists) {\n\t\t\tthrow redirect(302, ROUTE_PATH_LOGIN);\n\t\t}\n\n\t\treturn resolve(event);\n\t};\n}\n\n/**\n * Some IdP's expose a /.well-known/openid-configuration that specifies how to configure.\n * Use that to create your config.\n * @param config\n * @param fetch\n */\nexport async function armorConfigFromOpenId(\n\tconfig: ArmorOpenIdConfig,\n\tfetch?: typeof global.fetch,\n): Promise<ArmorConfig> {\n\tconst fetchToUse = fetch ?? global.fetch;\n\n\tconst response = await fetchToUse(config.oauth.openIdConfigEndpoint, {\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t},\n\t});\n\n\tif (!response.ok) {\n\t\tconst text = await response.text();\n\t\tthrow new ArmorOpenIdConfigError(text);\n\t}\n\n\tconst body = await response.json();\n\n\treturn {\n\t\t...config,\n\t\toauth: {\n\t\t\t...config.oauth,\n\t\t\ttokenEndpoint: body.token_endpoint,\n\t\t\tauthorizeEndpoint: body.authorization_endpoint,\n\t\t\tissuer: body.issuer,\n\t\t\tjwksEndpoint: body.jwks_uri,\n\t\t\tlogoutEndpoint: body.end_session_endpoint ?? undefined,\n\t\t},\n\t};\n}\n"],"names":["urlConcat","origin","path","strTrimEnd","strTrimStart","join","isTokenExchange","value","obj","access_token","token_type","expires_in","id_token","undefined","refresh_token","scope","jwtIsCompactJwt","token","parts","trim","split","length","every","p","jwtVerifyIdToken","config","jwks","idToken","payload","jwtVerifyToken","issuer","oauth","audience","clientId","throwIfUndefined","jwtVerifyAccessToken","accessToken","opts","isInvalidCompactJwt","error","Boolean","message","test","jwtVerify","COOKIE_TOKENS","COOKIE_STATE","cookieDeleteOptions","Object","freeze","cookieSetOptions","httpOnly","secure","sameSite","maxAge","cookieSet","cookies","key","set","JSON","stringify","cookieGetAndDelete","cookieGet","delete","get","parse","cookieDelete","ArmorError","Error","ArmorOpenIdConfigError","ArmorInvalidStateError","ArmorAuthMissingError","eventStateValidOrThrow","event","_event$url$searchPara","state","url","searchParams","stateCookie","ROUTE_PATH_REDIRECT_LOGIN","routeRedirectLoginFactory","_config$oauth$jwksEnd","_config$oauth$tokenEn","_config$oauth$scope","jwksUrl","URL","jwksEndpoint","baseUrl","tokenUrl","tokenEndpoint","exchangeCodeForToken","fetch","code","params","grant_type","client_id","client_secret","clientSecret","redirect_uri","response","method","headers","Accept","body","URLSearchParams","toString","ok","text","json","handle","_event$url$searchPara3","_event$url$searchPara2","error_description","errorLoginRedirectPath","Response","trimEnd","errorParams","queryParamsCreate","redirect","exchange","createRemoteJWKSet","Promise","all","session","login","ROUTE_PATH_LOGIN","routeLoginFactory","_config$oauth$authori","authorizeEndpoint","randomUUID","response_type","ROUTE_PATH_REDIRECT_LOGOUT","routeRedirectLogoutFactory","logoutEndpoint","logout","ROUTE_PATH_LOGOUT","routeLogoutFactory","_config$oauth$logoutR","returnTo","logoutReturnToParam","routeFactories","routeCreate","Map","map","routeFactory","filter","route","cookieSessionExists","cookieSessionLogin","tokens","cookieSessionLogout","armorCookieSessionGet","armorCookieSession","exists","ARMOR_LOGIN","ARMOR_LOGOUT","armor","routes","resolve","routeHandle","pathname","armorConfigFromOpenId","_body$end_session_end","fetchToUse","global","openIdConfigEndpoint","token_endpoint","authorization_endpoint","jwks_uri","end_session_endpoint"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
1
  import { ArmorConfig } from "../contracts";
2
2
  import { JWTPayload, JWTVerifyGetKey } from "jose";
3
3
  export declare function jwtVerifyIdToken(config: ArmorConfig, jwks: JWTVerifyGetKey, idToken: string): Promise<JWTPayload>;
4
- export declare function jwtVerifyAccessToken(config: ArmorConfig, jwks: JWTVerifyGetKey, accessToken: string): Promise<JWTPayload>;
4
+ export declare function jwtVerifyAccessToken(config: ArmorConfig, jwks: JWTVerifyGetKey, accessToken: string): Promise<JWTPayload | undefined>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nekm/sveltekit-armor",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Zero-config OAuth protection for SvelteKit",
5
5
  "license": "MIT",
6
6
  "source": "./src/index.ts",
@@ -57,14 +57,14 @@
57
57
  ],
58
58
  "sideEffects": false,
59
59
  "devDependencies": {
60
- "@sveltejs/kit": "^2.50.1",
60
+ "@sveltejs/kit": "^2.50.2",
61
61
  "@tsconfig/recommended": "^1.0.13",
62
62
  "@types/jest": "^30.0.0",
63
- "@types/node": "^25.0.10",
64
- "@typescript-eslint/eslint-plugin": "^8.53.1",
65
- "@typescript-eslint/parser": "^8.53.1",
66
- "eslint": "^9.39.2",
67
- "globals": "^17.1.0",
63
+ "@types/node": "^24",
64
+ "@typescript-eslint/eslint-plugin": "^8.55.0",
65
+ "@typescript-eslint/parser": "^8.55.0",
66
+ "eslint": "^9",
67
+ "globals": "^17.3.0",
68
68
  "jest": "^30.2.0",
69
69
  "jest-junit": "^16.0.0",
70
70
  "microbundle": "^0.15.1",
@@ -74,7 +74,7 @@
74
74
  "typescript": "^5.9.3"
75
75
  },
76
76
  "dependencies": {
77
- "@nekm/core": "^1.7.0",
77
+ "@nekm/core": "^1.8.0",
78
78
  "jose": "^6.1.3"
79
79
  },
80
80
  "peerDependencies": {
package/src/contracts.ts CHANGED
@@ -26,7 +26,7 @@ export interface ArmorAccessToken extends JWTPayload {
26
26
  export interface ArmorTokens {
27
27
  readonly exchange: ArmorTokenExchange;
28
28
  readonly idToken: ArmorIdToken;
29
- readonly accessToken: ArmorAccessToken;
29
+ readonly accessToken: ArmorAccessToken | string;
30
30
  }
31
31
 
32
32
  interface OauthBaseUrl {
@@ -113,7 +113,9 @@ export const routeRedirectLoginFactory: RouteFactory = (
113
113
  await config.session.login(event, {
114
114
  exchange,
115
115
  idToken: idToken as ArmorIdToken,
116
- accessToken,
116
+ // Generally, IdP's require an audience to get a JWT
117
+ // access token. Most cases, this doesn't matter.
118
+ accessToken: accessToken ?? exchange.access_token,
117
119
  });
118
120
 
119
121
  throw redirect(302, "/");
package/src/utils/jwt.ts CHANGED
@@ -1,12 +1,19 @@
1
1
  import { ArmorConfig } from "../contracts";
2
2
  import { JWTPayload, jwtVerify, JWTVerifyGetKey, JWTVerifyOptions } from "jose";
3
+ import { throwIfUndefined } from "@nekm/core";
4
+
5
+ function jwtIsCompactJwt(token: string): boolean {
6
+ // Must be three base64url segments
7
+ const parts = token.trim().split(".");
8
+ return parts.length === 3 && parts.every((p) => p.length > 0);
9
+ }
3
10
 
4
11
  export function jwtVerifyIdToken(
5
12
  config: ArmorConfig,
6
13
  jwks: JWTVerifyGetKey,
7
14
  idToken: string,
8
15
  ): Promise<JWTPayload> {
9
- return jwtVerifyToken(
16
+ const payload = jwtVerifyToken(
10
17
  jwks,
11
18
  {
12
19
  issuer: config.oauth.issuer,
@@ -14,13 +21,16 @@ export function jwtVerifyIdToken(
14
21
  },
15
22
  idToken,
16
23
  );
24
+ throwIfUndefined(payload);
25
+ // @ts-expect-error We're already verifying non-null above.
26
+ return payload;
17
27
  }
18
28
 
19
29
  export function jwtVerifyAccessToken(
20
30
  config: ArmorConfig,
21
31
  jwks: JWTVerifyGetKey,
22
32
  accessToken: string,
23
- ): Promise<JWTPayload> {
33
+ ): Promise<JWTPayload | undefined> {
24
34
  const opts: JWTVerifyOptions = { issuer: config.oauth.issuer };
25
35
 
26
36
  if (config.oauth.audience) {
@@ -30,11 +40,33 @@ export function jwtVerifyAccessToken(
30
40
  return jwtVerifyToken(jwks, opts, accessToken);
31
41
  }
32
42
 
43
+ function isInvalidCompactJwt(error: unknown): boolean {
44
+ return Boolean(
45
+ typeof error === "object" &&
46
+ error &&
47
+ "message" in error &&
48
+ typeof error.message === "string" &&
49
+ /invalid compact jws/gi.test(error.message),
50
+ );
51
+ }
52
+
33
53
  async function jwtVerifyToken(
34
54
  jwks: JWTVerifyGetKey,
35
55
  opts: JWTVerifyOptions,
36
56
  token: string,
37
- ): Promise<JWTPayload> {
38
- const { payload } = await jwtVerify(token, jwks, opts);
39
- return payload;
57
+ ): Promise<JWTPayload | undefined> {
58
+ try {
59
+ if (!jwtIsCompactJwt(token)) {
60
+ return undefined;
61
+ }
62
+
63
+ const { payload } = await jwtVerify(token, jwks, opts);
64
+ return payload;
65
+ } catch (error) {
66
+ if (isInvalidCompactJwt(error)) {
67
+ return undefined;
68
+ }
69
+
70
+ throw error;
71
+ }
40
72
  }