Documentation changes

This commit is contained in:
Evert Prants 2024-06-11 19:49:57 +03:00
parent 2724c77b55
commit fb382e55e9
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
4 changed files with 43 additions and 17 deletions

View File

@ -2,14 +2,20 @@
This is a SvelteKit-powered authentication service.
## Requirements
1. A MySQL or MariaDB database.
2. Node.js 20+ or Docker.
## Set up
1. Install dependenices - `npm install`.
2. Configure the environment - `cp .env.example .env`.
3. Generate secrets and stuff:
1. Clone the repository.
2. Install dependenices - `npm install`.
3. Configure the environment - `cp .env.example .env`.
4. Generate secrets and stuff:
1. Session secret - `node -e 'console.log(require("crypto").randomBytes(16).toString("hex"))'`.
2. Challenge secret - `node -e 'console.log(require("crypto").randomBytes(32).toString("hex"))'`.
3. Generate JWT keys in the `private` directory - `openssl genpkey -out jwt.private.pem -algorithm RSA -pkeyopt rsa_keygen_bits:2048`.
4. Also make the public key - `openssl rsa -in jwt.private.pem -pubout -outform PEM -out jwt.public.pem`.
4. Build the application - `npm run build`.
5. Run the application - `node -r dotenv/config build`.
5. Build the application - `npm run build`.
6. Run the application - `node -r dotenv/config build`.

View File

@ -11,19 +11,26 @@ import { handleSession } from 'svelte-kit-cookie-session';
const { AUTO_MIGRATE, SESSION_SECRET, SESSION_SECURE } = env;
// Initialize the database
await DB.init();
// Initialize the JWT keys
await JWT.init();
// Migrate the database when automatic migration is enabled
if (AUTO_MIGRATE === 'true') {
await migrate(DB.drizzle, { migrationsFolder: './migrations' });
}
// Run database data seeders
await runSeeds();
/**
* Set the document theme mode from the cookies
*/
const handleThemeHook = (async ({ resolve, event }) => {
// Take the theme from the cookies
const cookieTheme = event.cookies.get('themeMode') as ThemeModeType;
if (cookieTheme) {
return await resolve(event, {
transformPageChunk: ({ html }) => html.replace('theme-base=""', `theme-base="${cookieTheme}"`)

View File

@ -26,14 +26,21 @@ export class JWT {
static jwksKid: string;
static async init() {
const privateKeyFile = await readFile(join('private', 'jwt.private.pem'), {
encoding: 'utf-8'
});
const publicKeyFile = await readFile(join('private', 'jwt.public.pem'), { encoding: 'utf-8' });
JWT.privateKey = await importPKCS8(privateKeyFile, JWT_ALGORITHM);
JWT.publicKey = await importSPKI(publicKeyFile, JWT_ALGORITHM);
JWT.jwks = await exportJWK(JWT.publicKey);
JWT.jwksKid = uuidv4({ random: Buffer.from(JWT.jwks.n as string).subarray(0, 16) });
try {
const privateKeyFile = await readFile(join('private', 'jwt.private.pem'), {
encoding: 'utf-8'
});
const publicKeyFile = await readFile(join('private', 'jwt.public.pem'), {
encoding: 'utf-8'
});
JWT.privateKey = await importPKCS8(privateKeyFile, JWT_ALGORITHM);
JWT.publicKey = await importSPKI(publicKeyFile, JWT_ALGORITHM);
JWT.jwks = await exportJWK(JWT.publicKey);
JWT.jwksKid = uuidv4({ random: Buffer.from(JWT.jwks.n as string).subarray(0, 16) });
} catch (error) {
console.error('Failed to initialize the JWT backend:', error);
console.error('OpenID Connect flows will not work!');
}
}
static async issue(claims: Record<string, unknown>, subject: string, audience?: string) {

View File

@ -18,25 +18,31 @@ export const themeMode = writable<ThemeModeType>('light', (set) => {
export const setThemeCookie = (theme: ThemeModeType) =>
(document.cookie = `themeMode=${theme}; path=/; SameSite=Lax; Max-Age=${THEME_COOKIE_MAX_AGE}`);
/**
* Forward the initial theme to the theme store, and subscribe to changes.
*/
export const forwardInitialTheme = () =>
onMount(() => {
// If a cookie-set theme is not present, set the theme to current user agent theme.
const hasServerTheme = !!document.documentElement.getAttribute('theme-base');
const uaTheme = window?.matchMedia?.('(prefers-color-scheme: dark)');
const uaMode: ThemeModeType = uaTheme?.matches ? 'dark' : 'light';
const uaSetter = () => {
themeMode.set(uaTheme?.matches ? 'dark' : 'light');
};
if (!hasServerTheme) {
themeMode.set(uaMode);
}
// Set the theme to the current theme store value, and set the cookie.
const unsubscribeForward = themeMode.subscribe(async (theme) => {
document.documentElement.setAttribute('theme-base', theme);
setThemeCookie(theme);
});
// Set the theme to the user agent theme when the user agent theme changes.
const uaSetter = () => {
themeMode.set(uaTheme?.matches ? 'dark' : 'light');
};
uaTheme?.addEventListener?.('change', uaSetter);
return () => {
unsubscribeForward();