feat(auth): auto-login after onboarding, consolidate session cookies
- Extract session cookie issuance into sessionCookies.ts helper; remove duplicated COOKIE_BASE blocks from login, register, oauth callback/authorize, refresh handler, hooks.server.ts, and onboarding. - Derive cookie secure flag from ORIGIN (https://...) instead of NODE_ENV so plain-HTTP production deploys don't silently drop cookies. - Auto-login admin after onboarding completes; UI does a full reload so hooks.server.ts picks up the new session. - Harden onboarding: reject duplicate admin creation, flip onboardingComplete atomically to prevent concurrent completions, error out if no admin found. - Fix Dockerfile CMD operator precedence: node build now always runs after migrate deploy || db push. - Wire ORIGIN env through docker-compose.
This commit is contained in:
+6
-19
@@ -7,6 +7,10 @@ import * as apiTokenService from '$lib/server/services/apiTokenService.js';
|
||||
import { extractBearerToken } from '$lib/server/middleware/authenticate.js';
|
||||
import { isBoardGuestAccessible } from '$lib/server/middleware/guestAccess.js';
|
||||
import { initBackupScheduler } from '$lib/server/jobs/backupScheduler.js';
|
||||
import {
|
||||
clearSessionCookies,
|
||||
setRotatedCookies
|
||||
} from '$lib/server/utils/sessionCookies.js';
|
||||
|
||||
// Initialize backup scheduler on server startup
|
||||
initBackupScheduler();
|
||||
@@ -20,13 +24,6 @@ function isPublicPath(pathname: string): boolean {
|
||||
const ACCESS_TOKEN_COOKIE = 'access_token';
|
||||
const REFRESH_TOKEN_COOKIE = 'refresh_token';
|
||||
|
||||
const COOKIE_BASE = {
|
||||
httpOnly: true,
|
||||
secure: process.env.NODE_ENV === 'production',
|
||||
sameSite: 'lax' as const,
|
||||
path: '/'
|
||||
};
|
||||
|
||||
export const handle: Handle = async ({ event, resolve }) => {
|
||||
// Initialize locals
|
||||
event.locals.user = null;
|
||||
@@ -68,15 +65,7 @@ export const handle: Handle = async ({ event, resolve }) => {
|
||||
const user = await userService.findById(userIdFromCookie);
|
||||
const tokens = await authService.rotateTokens(user.id, user.email, user.role);
|
||||
|
||||
// Set new cookies
|
||||
event.cookies.set(ACCESS_TOKEN_COOKIE, tokens.accessToken, {
|
||||
...COOKIE_BASE,
|
||||
maxAge: 900 // 15 minutes
|
||||
});
|
||||
event.cookies.set(REFRESH_TOKEN_COOKIE, tokens.refreshToken, {
|
||||
...COOKIE_BASE,
|
||||
maxAge: 604800 // 7 days
|
||||
});
|
||||
setRotatedCookies(event.cookies, tokens);
|
||||
|
||||
event.locals.user = {
|
||||
id: user.id,
|
||||
@@ -92,9 +81,7 @@ export const handle: Handle = async ({ event, resolve }) => {
|
||||
}
|
||||
} catch {
|
||||
// Refresh failed — clear stale cookies
|
||||
event.cookies.delete(ACCESS_TOKEN_COOKIE, { path: '/' });
|
||||
event.cookies.delete(REFRESH_TOKEN_COOKIE, { path: '/' });
|
||||
event.cookies.delete('refresh_user_id', { path: '/' });
|
||||
clearSessionCookies(event.cookies);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user