Files
web-app-launcher/src/routes/auth/refresh/+server.ts
T
alexei.dolgolyov 2c001df322 feat(mvp): phase 3 - authentication system
Implement local auth flow: login, registration, logout, JWT access/refresh
tokens in HTTP-only cookies, hooks.server.ts middleware, guest mode support,
Superforms + Zod validation, and reusable auth/authorize middleware.
2026-03-24 20:45:14 +03:00

56 lines
1.7 KiB
TypeScript

import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types.js';
import * as authService from '$lib/server/services/authService.js';
import * as userService from '$lib/server/services/userService.js';
import { error as apiError } from '$lib/server/utils/response.js';
const COOKIE_BASE = {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax' as const,
path: '/'
};
export const POST: RequestHandler = async ({ cookies }) => {
const refreshToken = cookies.get('refresh_token');
const userId = cookies.get('refresh_user_id');
if (!refreshToken || !userId) {
return json(apiError('No refresh token provided'), { status: 401 });
}
try {
const isValid = await authService.validateRefreshToken(userId, refreshToken);
if (!isValid) {
// Clear stale cookies
cookies.delete('access_token', { path: '/' });
cookies.delete('refresh_token', { path: '/' });
cookies.delete('refresh_user_id', { path: '/' });
return json(apiError('Invalid or expired refresh token'), { status: 401 });
}
const user = await userService.findById(userId);
const tokens = await authService.rotateTokens(user.id, user.email, user.role);
cookies.set('access_token', tokens.accessToken, {
...COOKIE_BASE,
maxAge: 900
});
cookies.set('refresh_token', tokens.refreshToken, {
...COOKIE_BASE,
maxAge: 604800
});
return json({
success: true,
data: { expiresIn: 900 },
error: null
});
} catch {
cookies.delete('access_token', { path: '/' });
cookies.delete('refresh_token', { path: '/' });
cookies.delete('refresh_user_id', { path: '/' });
return json(apiError('Token refresh failed'), { status: 401 });
}
};