From a300932fd8b705506a3f52192c3b9a12ec33006c Mon Sep 17 00:00:00 2001 From: Steel <mael.acier@ensiie.fr> Date: Tue, 12 Dec 2023 00:11:17 +0100 Subject: [PATCH] fix: remove env dependency --- package.json | 2 +- src/lib/cookies.ts | 36 ++++++++++++++++++------------ src/lib/env.ts | 10 --------- src/lib/handlers/cookie.ts | 6 ++--- src/lib/handlers/login.ts | 3 +-- src/lib/handlers/loginCallback.ts | 4 ++-- src/lib/handlers/logoutCallback.ts | 3 +-- src/lib/index.ts | 27 ++++++++++++++-------- src/lib/types.ts | 7 ++++++ src/lib/utils/jwt_cookie.ts | 10 ++++----- 10 files changed, 60 insertions(+), 48 deletions(-) delete mode 100644 src/lib/env.ts diff --git a/package.json b/package.json index 5bc5b0e..acf7c42 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@arise/aidc-sveltekit", - "version": "0.0.6", + "version": "0.0.7", "type": "module", "scripts": { "dev": "vite dev", diff --git a/src/lib/cookies.ts b/src/lib/cookies.ts index feb8630..5a30671 100644 --- a/src/lib/cookies.ts +++ b/src/lib/cookies.ts @@ -2,7 +2,7 @@ import { JWTCookieManager } from "$lib/utils/jwt_cookie.js"; import type { Cookies } from "@sveltejs/kit"; import type { TokenSet } from "openid-client"; import { z } from "zod"; -import type { InternalConfig } from "$lib/types.js"; +import type { InternalConfig, Config } from "$lib/types.js"; const ONE_HOUR = 60 * 60; const ONE_DAY = 24 * ONE_HOUR; @@ -14,10 +14,14 @@ export const authSchema = z.object({ nonce: z.string(), }); -export const authCookie = new JWTCookieManager(authSchema, { - serialize: { path: "/", maxAge: ONE_HOUR }, - name: "tmp_arise_auth_secrets", -}); +export type AuthCookie = JWTCookieManager<typeof authSchema>; + +export function authCookieBuilder({ jwt_secret }: Config): AuthCookie { + return new JWTCookieManager(authSchema, jwt_secret, { + serialize: { path: "/", maxAge: ONE_HOUR }, + name: "tmp_arise_auth_secrets", + }); +} export const tokenSetSchema = z.object({ access_token: z.string().optional(), @@ -29,21 +33,25 @@ export const tokenSetSchema = z.object({ session_state: z.string().optional(), }); -export const tokenSetCookie = new JWTCookieManager(tokenSetSchema, { - name: "arise_token_set", - serialize: { - maxAge: ONE_MONTH, - }, -}); +export type TokenSetCookie = JWTCookieManager<typeof tokenSetSchema>; + +export function tokenSetCookieBuilder({ jwt_secret }: Config): TokenSetCookie { + return new JWTCookieManager(tokenSetSchema, jwt_secret, { + name: "arise_token_set", + serialize: { + maxAge: ONE_MONTH, + }, + }); +} export async function setTokenSetCookie( tokenSet: TokenSet, cookies: Cookies, - { client }: InternalConfig, + config: InternalConfig, ) { - const userinfo = await client.userinfo(tokenSet); + const userinfo = await config.client.userinfo(tokenSet); - tokenSetCookie.send(cookies, { + config.cookies.tokenSet.send(cookies, { payload: tokenSet, jwt: { subject: userinfo.sub, expiresIn: ONE_MONTH }, }); diff --git a/src/lib/env.ts b/src/lib/env.ts deleted file mode 100644 index dfa9da6..0000000 --- a/src/lib/env.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { ensureEnv } from "$lib/utils/env.js"; - -export const env = ensureEnv([ - "API_URL", - "API_TOKEN", - "JWT_SECRET", - "AIDC_CLIENT_ID", - "AIDC_CLIENT_SECRET", - "ORIGIN", -] as const); diff --git a/src/lib/handlers/cookie.ts b/src/lib/handlers/cookie.ts index 6ec9052..c30e239 100644 --- a/src/lib/handlers/cookie.ts +++ b/src/lib/handlers/cookie.ts @@ -1,11 +1,11 @@ import { TokenSet } from "openid-client"; -import { setTokenSetCookie, tokenSetCookie } from "$lib/cookies.js"; +import { setTokenSetCookie } from "$lib/cookies.js"; import type { Handle } from "@sveltejs/kit"; import type { InternalConfig } from "$lib/types.js"; export default function (config: InternalConfig): Handle { return async function ({ event, resolve }) { - const jwtTokenSet = tokenSetCookie.receive(event.cookies); + const jwtTokenSet = config.cookies.tokenSet.receive(event.cookies); if (jwtTokenSet !== null) { let tokenSet = new TokenSet(jwtTokenSet); @@ -23,7 +23,7 @@ export default function (config: InternalConfig): Handle { }; } catch (error) { console.error(error); - tokenSetCookie.delete(event.cookies); + config.cookies.tokenSet.delete(event.cookies); } } diff --git a/src/lib/handlers/login.ts b/src/lib/handlers/login.ts index 6735e0d..7f6c3a5 100644 --- a/src/lib/handlers/login.ts +++ b/src/lib/handlers/login.ts @@ -1,6 +1,5 @@ import { redirect } from "@sveltejs/kit"; import { generators } from "openid-client"; -import { authCookie } from "$lib/cookies.js"; import type { Handle } from "@sveltejs/kit"; import type { InternalConfig } from "$lib/types.js"; import { SEE_OTHER } from "readable-http-codes"; @@ -11,7 +10,7 @@ export default function (config: InternalConfig): Handle { const state = generators.state(); const nonce = generators.nonce(); - authCookie.send(event.cookies, { + config.cookies.auth.send(event.cookies, { payload: { codeVerifier, state, nonce }, }); diff --git a/src/lib/handlers/loginCallback.ts b/src/lib/handlers/loginCallback.ts index f1df019..7b9581d 100644 --- a/src/lib/handlers/loginCallback.ts +++ b/src/lib/handlers/loginCallback.ts @@ -1,5 +1,5 @@ import { type Handle, redirect } from "@sveltejs/kit"; -import { authCookie, setTokenSetCookie } from "$lib/cookies.js"; +import { setTokenSetCookie } from "$lib/cookies.js"; import { errors } from "openid-client"; import type { InternalConfig } from "$lib/types.js"; import { base } from "$app/paths"; @@ -9,7 +9,7 @@ export default function (config: InternalConfig): Handle { return async function ({ event, resolve }) { const params = config.client.callbackParams(event.url.toString()); - const cookie = authCookie.receive(event.cookies); + const cookie = config.cookies.auth.receive(event.cookies); if (cookie === null) { throw redirect(SEE_OTHER, config.paths.login); diff --git a/src/lib/handlers/logoutCallback.ts b/src/lib/handlers/logoutCallback.ts index dd7cae4..a95bdad 100644 --- a/src/lib/handlers/logoutCallback.ts +++ b/src/lib/handlers/logoutCallback.ts @@ -1,11 +1,10 @@ import { type Handle, redirect } from "@sveltejs/kit"; -import { tokenSetCookie } from "$lib/cookies.js"; import type { InternalConfig } from "$lib/types.js"; import { SEE_OTHER } from "readable-http-codes"; export default function (config: InternalConfig): Handle { return async function ({ event }) { - tokenSetCookie.delete(event.cookies); + config.cookies.tokenSet.delete(event.cookies); if (config.on?.loggedOut) { return config.on.loggedOut(event); diff --git a/src/lib/index.ts b/src/lib/index.ts index b70ab83..e261e2e 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -1,8 +1,9 @@ import { Issuer } from "openid-client"; import { base } from "$app/paths"; import handler from "./handlers/index.js"; -import type { Config } from "./types.js"; +import type { Config, InternalConfig } from "./types.js"; import * as paths from "./paths.js"; +import { authCookieBuilder, tokenSetCookieBuilder } from "./cookies.js"; export type { AuthData as AriseData, Config, Locals } from "./types.js"; export { handleBuilder as ariseIdConnectBuilder } from "./index.js"; @@ -23,16 +24,24 @@ export async function handleBuilder(config: Config) { response_types: ["code", "id_token"], }); + const flowPaths: InternalConfig["paths"] = { + callback: addBase(config.paths?.callback ?? paths.CALLBACK), + logoutCallback: addBase( + config.paths?.logoutCallback ?? paths.LOGOUT_CALLBACK, + ), + login: addBase(config.paths?.login ?? paths.LOGIN), + logout: addBase(config.paths?.logout ?? paths.LOGOUT), + }; + + const cookies: InternalConfig["cookies"] = { + auth: authCookieBuilder(config), + tokenSet: tokenSetCookieBuilder(config), + }; + return handler({ ...config, - paths: { - callback: addBase(config.paths?.callback ?? paths.CALLBACK), - logoutCallback: addBase( - config.paths?.logoutCallback ?? paths.LOGOUT_CALLBACK, - ), - login: addBase(config.paths?.login ?? paths.LOGIN), - logout: addBase(config.paths?.logout ?? paths.LOGOUT), - }, + paths: flowPaths, client, + cookies, }); } diff --git a/src/lib/types.ts b/src/lib/types.ts index 5237925..ae7f85f 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -5,6 +5,7 @@ import type { errors, TokenSet, } from "openid-client"; +import type { AuthCookie, TokenSetCookie } from "./cookies.js"; export type AuthData = { loggedIn?: { @@ -30,6 +31,8 @@ type Paths = { export interface Config extends ClientMetadata { client_secret: string; scope: string; + /** JWT Secret */ + jwt_secret: string; paths?: Partial<Paths>; issuer?: string; on?: { @@ -45,4 +48,8 @@ export interface Config extends ClientMetadata { export interface InternalConfig extends Config { client: BaseClient; paths: Paths; + cookies: { + auth: AuthCookie; + tokenSet: TokenSetCookie; + }; } diff --git a/src/lib/utils/jwt_cookie.ts b/src/lib/utils/jwt_cookie.ts index 04b98d8..0561b10 100644 --- a/src/lib/utils/jwt_cookie.ts +++ b/src/lib/utils/jwt_cookie.ts @@ -1,6 +1,5 @@ import type { Cookies } from "@sveltejs/kit"; import jwt from "jsonwebtoken"; -import { env } from "$lib/env.js"; import type { z, ZodObject, ZodSchema } from "zod"; import type { CookieSerializeOptions } from "cookie"; import { dev } from "$app/environment"; @@ -10,7 +9,7 @@ type Empty = Record<string, never>; export type JWT<T extends ZodSchema = ZodObject<Empty>> = jwt.JwtPayload & z.output<T>; -export interface FlashSendOptions<T> { +export interface SendOptions<T> { payload: T; jwt?: jwt.SignOptions; } @@ -23,6 +22,7 @@ export interface CookieOptions { export class JWTCookieManager<T extends ZodSchema = ZodObject<Empty>> { constructor( private schema: T, + private secret: string, private cookieOptions?: CookieOptions, ) {} @@ -39,14 +39,14 @@ export class JWTCookieManager<T extends ZodSchema = ZodObject<Empty>> { }; } - send(cookies: Cookies, options: FlashSendOptions<z.output<T>>) { + send(cookies: Cookies, options: SendOptions<z.output<T>>) { const payload = this.schema.safeParse(options.payload); if (!payload.success) { throw payload.error; } - const cookie = jwt.sign(payload.data, env.JWT_SECRET, options.jwt); + const cookie = jwt.sign(payload.data, this.secret, options.jwt); cookies.set(this.cookieName(), cookie, this.cookieSerializeOptions()); } @@ -56,7 +56,7 @@ export class JWTCookieManager<T extends ZodSchema = ZodObject<Empty>> { if (!token) return null; try { - jwt.verify(token, env.JWT_SECRET); + jwt.verify(token, this.secret); } catch { return null; } -- GitLab