Documentation changes
This commit is contained in:
parent
2724c77b55
commit
fb382e55e9
16
README.md
16
README.md
@ -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`.
|
||||
|
@ -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}"`)
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user