@nekm/sveltekit-armor 0.2.0 → 0.2.2
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.
- package/dist/contracts.d.ts +19 -2
- package/dist/index.esm.js +25 -8
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +23 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/contracts.ts +24 -2
- package/src/index.ts +2 -5
- package/src/routes/logout.ts +3 -1
- package/src/routes/redirect-login.ts +22 -1
package/dist/contracts.d.ts
CHANGED
|
@@ -30,7 +30,7 @@ interface OauthEndpoints {
|
|
|
30
30
|
readonly baseUrl?: never;
|
|
31
31
|
readonly jwksEndpoint: string;
|
|
32
32
|
readonly authorizeEndpoint: string;
|
|
33
|
-
readonly logoutEndpoint
|
|
33
|
+
readonly logoutEndpoint?: string;
|
|
34
34
|
readonly tokenEndpoint: string;
|
|
35
35
|
}
|
|
36
36
|
type OauthEndpointsOrBaseUrl = OauthBaseUrl | OauthEndpoints;
|
|
@@ -46,10 +46,27 @@ export interface ArmorConfig {
|
|
|
46
46
|
readonly issuer: string;
|
|
47
47
|
readonly scope?: string;
|
|
48
48
|
readonly audience?: string;
|
|
49
|
+
/**
|
|
50
|
+
* When redirecting a user to the oauth logout flow,
|
|
51
|
+
* what should we name the return to parameter? I.e.
|
|
52
|
+
* the parameter that decides where to redirect the
|
|
53
|
+
* user back.
|
|
54
|
+
* @default {string} logout_uri
|
|
55
|
+
*/
|
|
56
|
+
readonly logoutReturnToParam?: string;
|
|
57
|
+
/**
|
|
58
|
+
* If an error occurs, where should we redirect the
|
|
59
|
+
* user? Should be an internal path. There'll be more
|
|
60
|
+
* information as query parameters:
|
|
61
|
+
* 1. error
|
|
62
|
+
* 2. error_description
|
|
63
|
+
* @default {undefined} Armor will throw an error
|
|
64
|
+
*/
|
|
65
|
+
readonly errorLoginRedirectPath?: string;
|
|
49
66
|
};
|
|
50
67
|
}
|
|
51
68
|
export interface ArmorOpenIdConfig extends Pick<ArmorConfig, "session"> {
|
|
52
|
-
readonly oauth: Pick<ArmorConfig["oauth"], "clientId" | "clientSecret" | "scope" | "audience"> & {
|
|
69
|
+
readonly oauth: Pick<ArmorConfig["oauth"], "clientId" | "clientSecret" | "scope" | "audience" | "logoutReturnToParam" | "errorLoginRedirectPath"> & {
|
|
53
70
|
readonly openIdConfigEndpoint: string;
|
|
54
71
|
};
|
|
55
72
|
}
|
package/dist/index.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { redirect
|
|
2
|
-
import { strTrimEnd, strTrimStart,
|
|
1
|
+
import { redirect } from '@sveltejs/kit';
|
|
2
|
+
import { strTrimEnd, strTrimStart, queryParamsCreate, throwIfUndefined } from '@nekm/core';
|
|
3
3
|
import { jwtVerify, createRemoteJWKSet } from 'jose';
|
|
4
4
|
import { randomUUID } from 'node:crypto';
|
|
5
5
|
|
|
@@ -121,9 +121,26 @@ const routeRedirectLoginFactory = config => {
|
|
|
121
121
|
async handle({
|
|
122
122
|
event
|
|
123
123
|
}) {
|
|
124
|
-
var _event$url$searchPara;
|
|
124
|
+
var _event$url$searchPara, _event$url$searchPara3;
|
|
125
125
|
eventStateValidOrThrow(event);
|
|
126
|
-
const
|
|
126
|
+
const error = (_event$url$searchPara = event.url.searchParams.get("error")) != null ? _event$url$searchPara : undefined;
|
|
127
|
+
if (error) {
|
|
128
|
+
var _event$url$searchPara2;
|
|
129
|
+
const error_description = (_event$url$searchPara2 = event.url.searchParams.get("error_description")) != null ? _event$url$searchPara2 : undefined;
|
|
130
|
+
if (!config.oauth.errorLoginRedirectPath) {
|
|
131
|
+
return new Response(`${error}\n${error_description}`.trimEnd(), {
|
|
132
|
+
headers: {
|
|
133
|
+
"Content-Type": "text/plain"
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
const errorParams = queryParamsCreate({
|
|
138
|
+
error,
|
|
139
|
+
error_description
|
|
140
|
+
});
|
|
141
|
+
throw redirect(302, `${config.oauth.errorLoginRedirectPath}?${errorParams}`);
|
|
142
|
+
}
|
|
143
|
+
const code = (_event$url$searchPara3 = event.url.searchParams.get("code")) != null ? _event$url$searchPara3 : undefined;
|
|
127
144
|
throwIfUndefined(code);
|
|
128
145
|
const exchange = await exchangeCodeForToken(event.fetch, event.url.origin, code);
|
|
129
146
|
const jwks = createRemoteJWKSet(jwksUrl);
|
|
@@ -183,10 +200,12 @@ const routeRedirectLogoutFactory = config => {
|
|
|
183
200
|
|
|
184
201
|
const ROUTE_PATH_LOGOUT = "/_armor/logout";
|
|
185
202
|
const routeLogoutFactory = config => {
|
|
203
|
+
var _config$oauth$logoutR;
|
|
186
204
|
// Check if the oauth provider supports a logout path.
|
|
187
205
|
if (!config.oauth.logoutEndpoint) {
|
|
188
206
|
return undefined;
|
|
189
207
|
}
|
|
208
|
+
const returnTo = (_config$oauth$logoutR = config.oauth.logoutReturnToParam) != null ? _config$oauth$logoutR : "logout_uri";
|
|
190
209
|
return {
|
|
191
210
|
path: ROUTE_PATH_LOGOUT,
|
|
192
211
|
async handle({
|
|
@@ -195,7 +214,7 @@ const routeLogoutFactory = config => {
|
|
|
195
214
|
const state = randomUUID();
|
|
196
215
|
cookieSet(event.cookies, COOKIE_STATE, state);
|
|
197
216
|
const params = queryParamsCreate({
|
|
198
|
-
|
|
217
|
+
[returnTo]: urlConcat(event.url.origin, ROUTE_PATH_REDIRECT_LOGOUT),
|
|
199
218
|
client_id: config.oauth.clientId,
|
|
200
219
|
state
|
|
201
220
|
});
|
|
@@ -251,12 +270,10 @@ function armor(config) {
|
|
|
251
270
|
}) => {
|
|
252
271
|
const routeHandle = routes.get(event.url.pathname);
|
|
253
272
|
if (routeHandle) {
|
|
254
|
-
|
|
273
|
+
return routeHandle({
|
|
255
274
|
event,
|
|
256
275
|
resolve
|
|
257
276
|
});
|
|
258
|
-
// Handle should redirect. If it doesn't, something is wrong.
|
|
259
|
-
throw error(500, "Illegal state");
|
|
260
277
|
}
|
|
261
278
|
const exists = await config.session.exists(event);
|
|
262
279
|
if (!exists) {
|
package/dist/index.esm.js.map
CHANGED
|
@@ -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 { 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 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\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\tlogout_uri: 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 { error, 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\tawait routeHandle({ event, resolve });\n\n\t\t\t// Handle should redirect. If it doesn't, something is wrong.\n\t\t\tthrow error(500, \"Illegal state\");\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","throwIfUndefined","exchange","createRemoteJWKSet","Promise","all","session","login","redirect","ROUTE_PATH_LOGIN","routeLoginFactory","_config$oauth$authori","authorizeEndpoint","randomUUID","queryParamsCreate","response_type","ROUTE_PATH_REDIRECT_LOGOUT","routeRedirectLogoutFactory","logoutEndpoint","logout","ROUTE_PATH_LOGOUT","routeLogoutFactory","logout_uri","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\";\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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"}
|
package/dist/index.js
CHANGED
|
@@ -121,9 +121,26 @@ const routeRedirectLoginFactory = config => {
|
|
|
121
121
|
async handle({
|
|
122
122
|
event
|
|
123
123
|
}) {
|
|
124
|
-
var _event$url$searchPara;
|
|
124
|
+
var _event$url$searchPara, _event$url$searchPara3;
|
|
125
125
|
eventStateValidOrThrow(event);
|
|
126
|
-
const
|
|
126
|
+
const error = (_event$url$searchPara = event.url.searchParams.get("error")) != null ? _event$url$searchPara : undefined;
|
|
127
|
+
if (error) {
|
|
128
|
+
var _event$url$searchPara2;
|
|
129
|
+
const error_description = (_event$url$searchPara2 = event.url.searchParams.get("error_description")) != null ? _event$url$searchPara2 : undefined;
|
|
130
|
+
if (!config.oauth.errorLoginRedirectPath) {
|
|
131
|
+
return new Response(`${error}\n${error_description}`.trimEnd(), {
|
|
132
|
+
headers: {
|
|
133
|
+
"Content-Type": "text/plain"
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
const errorParams = core.queryParamsCreate({
|
|
138
|
+
error,
|
|
139
|
+
error_description
|
|
140
|
+
});
|
|
141
|
+
throw kit.redirect(302, `${config.oauth.errorLoginRedirectPath}?${errorParams}`);
|
|
142
|
+
}
|
|
143
|
+
const code = (_event$url$searchPara3 = event.url.searchParams.get("code")) != null ? _event$url$searchPara3 : undefined;
|
|
127
144
|
core.throwIfUndefined(code);
|
|
128
145
|
const exchange = await exchangeCodeForToken(event.fetch, event.url.origin, code);
|
|
129
146
|
const jwks = jose.createRemoteJWKSet(jwksUrl);
|
|
@@ -183,10 +200,12 @@ const routeRedirectLogoutFactory = config => {
|
|
|
183
200
|
|
|
184
201
|
const ROUTE_PATH_LOGOUT = "/_armor/logout";
|
|
185
202
|
const routeLogoutFactory = config => {
|
|
203
|
+
var _config$oauth$logoutR;
|
|
186
204
|
// Check if the oauth provider supports a logout path.
|
|
187
205
|
if (!config.oauth.logoutEndpoint) {
|
|
188
206
|
return undefined;
|
|
189
207
|
}
|
|
208
|
+
const returnTo = (_config$oauth$logoutR = config.oauth.logoutReturnToParam) != null ? _config$oauth$logoutR : "logout_uri";
|
|
190
209
|
return {
|
|
191
210
|
path: ROUTE_PATH_LOGOUT,
|
|
192
211
|
async handle({
|
|
@@ -195,7 +214,7 @@ const routeLogoutFactory = config => {
|
|
|
195
214
|
const state = node_crypto.randomUUID();
|
|
196
215
|
cookieSet(event.cookies, COOKIE_STATE, state);
|
|
197
216
|
const params = core.queryParamsCreate({
|
|
198
|
-
|
|
217
|
+
[returnTo]: urlConcat(event.url.origin, ROUTE_PATH_REDIRECT_LOGOUT),
|
|
199
218
|
client_id: config.oauth.clientId,
|
|
200
219
|
state
|
|
201
220
|
});
|
|
@@ -251,12 +270,10 @@ function armor(config) {
|
|
|
251
270
|
}) => {
|
|
252
271
|
const routeHandle = routes.get(event.url.pathname);
|
|
253
272
|
if (routeHandle) {
|
|
254
|
-
|
|
273
|
+
return routeHandle({
|
|
255
274
|
event,
|
|
256
275
|
resolve
|
|
257
276
|
});
|
|
258
|
-
// Handle should redirect. If it doesn't, something is wrong.
|
|
259
|
-
throw kit.error(500, "Illegal state");
|
|
260
277
|
}
|
|
261
278
|
const exists = await config.session.exists(event);
|
|
262
279
|
if (!exists) {
|
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 { 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 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\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\tlogout_uri: 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 { error, 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\tawait routeHandle({ event, resolve });\n\n\t\t\t// Handle should redirect. If it doesn't, something is wrong.\n\t\t\tthrow error(500, \"Illegal state\");\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","throwIfUndefined","exchange","createRemoteJWKSet","Promise","all","session","login","redirect","ROUTE_PATH_LOGIN","routeLoginFactory","_config$oauth$authori","authorizeEndpoint","randomUUID","queryParamsCreate","response_type","ROUTE_PATH_REDIRECT_LOGOUT","routeRedirectLogoutFactory","logoutEndpoint","logout","ROUTE_PATH_LOGOUT","routeLogoutFactory","logout_uri","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\";\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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"}
|
package/package.json
CHANGED
package/src/contracts.ts
CHANGED
|
@@ -43,7 +43,7 @@ interface OauthEndpoints {
|
|
|
43
43
|
|
|
44
44
|
readonly jwksEndpoint: string;
|
|
45
45
|
readonly authorizeEndpoint: string;
|
|
46
|
-
readonly logoutEndpoint
|
|
46
|
+
readonly logoutEndpoint?: string;
|
|
47
47
|
readonly tokenEndpoint: string;
|
|
48
48
|
}
|
|
49
49
|
|
|
@@ -64,13 +64,35 @@ export interface ArmorConfig {
|
|
|
64
64
|
readonly issuer: string;
|
|
65
65
|
readonly scope?: string;
|
|
66
66
|
readonly audience?: string;
|
|
67
|
+
/**
|
|
68
|
+
* When redirecting a user to the oauth logout flow,
|
|
69
|
+
* what should we name the return to parameter? I.e.
|
|
70
|
+
* the parameter that decides where to redirect the
|
|
71
|
+
* user back.
|
|
72
|
+
* @default {string} logout_uri
|
|
73
|
+
*/
|
|
74
|
+
readonly logoutReturnToParam?: string;
|
|
75
|
+
/**
|
|
76
|
+
* If an error occurs, where should we redirect the
|
|
77
|
+
* user? Should be an internal path. There'll be more
|
|
78
|
+
* information as query parameters:
|
|
79
|
+
* 1. error
|
|
80
|
+
* 2. error_description
|
|
81
|
+
* @default {undefined} Armor will throw an error
|
|
82
|
+
*/
|
|
83
|
+
readonly errorLoginRedirectPath?: string;
|
|
67
84
|
};
|
|
68
85
|
}
|
|
69
86
|
|
|
70
87
|
export interface ArmorOpenIdConfig extends Pick<ArmorConfig, "session"> {
|
|
71
88
|
readonly oauth: Pick<
|
|
72
89
|
ArmorConfig["oauth"],
|
|
73
|
-
|
|
90
|
+
| "clientId"
|
|
91
|
+
| "clientSecret"
|
|
92
|
+
| "scope"
|
|
93
|
+
| "audience"
|
|
94
|
+
| "logoutReturnToParam"
|
|
95
|
+
| "errorLoginRedirectPath"
|
|
74
96
|
> & {
|
|
75
97
|
readonly openIdConfigEndpoint: string;
|
|
76
98
|
};
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { redirect, type Handle } from "@sveltejs/kit";
|
|
2
2
|
import { ROUTE_PATH_LOGIN } from "./routes/login";
|
|
3
3
|
import type { ArmorConfig, ArmorOpenIdConfig, ArmorTokens } from "./contracts";
|
|
4
4
|
import { ROUTE_PATH_LOGOUT } from "./routes/logout";
|
|
@@ -18,10 +18,7 @@ export function armor(config: ArmorConfig): Handle {
|
|
|
18
18
|
const routeHandle = routes.get(event.url.pathname);
|
|
19
19
|
|
|
20
20
|
if (routeHandle) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
// Handle should redirect. If it doesn't, something is wrong.
|
|
24
|
-
throw error(500, "Illegal state");
|
|
21
|
+
return routeHandle({ event, resolve });
|
|
25
22
|
}
|
|
26
23
|
|
|
27
24
|
const exists = await config.session.exists(event);
|
package/src/routes/logout.ts
CHANGED
|
@@ -15,6 +15,8 @@ export const routeLogoutFactory: RouteFactory = (config: ArmorConfig) => {
|
|
|
15
15
|
return undefined;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
const returnTo = config.oauth.logoutReturnToParam ?? "logout_uri";
|
|
19
|
+
|
|
18
20
|
return {
|
|
19
21
|
path: ROUTE_PATH_LOGOUT,
|
|
20
22
|
async handle({ event }) {
|
|
@@ -22,7 +24,7 @@ export const routeLogoutFactory: RouteFactory = (config: ArmorConfig) => {
|
|
|
22
24
|
cookieSet(event.cookies, COOKIE_STATE, state);
|
|
23
25
|
|
|
24
26
|
const params = queryParamsCreate({
|
|
25
|
-
|
|
27
|
+
[returnTo]: urlConcat(event.url.origin, ROUTE_PATH_REDIRECT_LOGOUT),
|
|
26
28
|
client_id: config.oauth.clientId,
|
|
27
29
|
state,
|
|
28
30
|
});
|
|
@@ -4,7 +4,7 @@ import type {
|
|
|
4
4
|
ArmorIdToken,
|
|
5
5
|
ArmorTokenExchange,
|
|
6
6
|
} from "../contracts";
|
|
7
|
-
import { throwIfUndefined } from "@nekm/core";
|
|
7
|
+
import { queryParamsCreate, throwIfUndefined } from "@nekm/core";
|
|
8
8
|
import { createRemoteJWKSet } from "jose";
|
|
9
9
|
import type { RouteFactory } from "./routes";
|
|
10
10
|
import { urlConcat, isTokenExchange } from "../utils/utils";
|
|
@@ -73,6 +73,27 @@ export const routeRedirectLoginFactory: RouteFactory = (
|
|
|
73
73
|
async handle({ event }) {
|
|
74
74
|
eventStateValidOrThrow(event);
|
|
75
75
|
|
|
76
|
+
const error = event.url.searchParams.get("error") ?? undefined;
|
|
77
|
+
|
|
78
|
+
if (error) {
|
|
79
|
+
const error_description =
|
|
80
|
+
event.url.searchParams.get("error_description") ?? undefined;
|
|
81
|
+
|
|
82
|
+
if (!config.oauth.errorLoginRedirectPath) {
|
|
83
|
+
return new Response(`${error}\n${error_description}`.trimEnd(), {
|
|
84
|
+
headers: {
|
|
85
|
+
"Content-Type": "text/plain",
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const errorParams = queryParamsCreate({ error, error_description });
|
|
91
|
+
throw redirect(
|
|
92
|
+
302,
|
|
93
|
+
`${config.oauth.errorLoginRedirectPath}?${errorParams}`,
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
76
97
|
const code = event.url.searchParams.get("code") ?? undefined;
|
|
77
98
|
throwIfUndefined(code);
|
|
78
99
|
|