This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

reafactor: dal for session verification

+108 -19
+1 -19
src/webapp/app/api/auth/me/route.ts
··· 1 1 import { NextRequest, NextResponse } from 'next/server'; 2 2 import { cookies } from 'next/headers'; 3 - 4 - // Helper to check if token is expired or will expire soon 5 - function isTokenExpiringSoon( 6 - token: string | null | undefined, 7 - bufferMinutes: number = 5, 8 - ): boolean { 9 - if (!token) return true; 10 - 11 - try { 12 - const payload = JSON.parse( 13 - Buffer.from(token.split('.')[1], 'base64').toString(), 14 - ); 15 - const expiry = payload.exp * 1000; 16 - const bufferTime = bufferMinutes * 60 * 1000; 17 - return Date.now() >= expiry - bufferTime; 18 - } catch { 19 - return true; 20 - } 21 - } 3 + import { isTokenExpiringSoon } from '@/lib/auth/token'; 22 4 23 5 export async function GET(request: NextRequest) { 24 6 try {
+90
src/webapp/lib/auth/dal.ts
··· 1 + import 'server-only'; 2 + 3 + import { cache } from 'react'; 4 + import { cookies } from 'next/headers'; 5 + import { redirect } from 'next/navigation'; 6 + import { isTokenExpiringSoon } from './token'; 7 + 8 + export const verifySession = cache(async () => { 9 + const cookieStore = await cookies(); 10 + const accessToken = cookieStore.get('accessToken')?.value; 11 + const refreshToken = cookieStore.get('refreshToken')?.value; 12 + 13 + // no session tokens — redirect to login 14 + if (!accessToken && !refreshToken) { 15 + redirect('/login'); 16 + } 17 + 18 + const backendUrl = 19 + process.env.NEXT_PUBLIC_API_BASE_URL || 'http://127.0.0.1:3000'; 20 + 21 + // token expired or about to expire 22 + if ((!accessToken || isTokenExpiringSoon(accessToken)) && refreshToken) { 23 + const refreshResponse = await fetch( 24 + `${backendUrl}/api/users/oauth/refresh`, 25 + { 26 + method: 'POST', 27 + headers: { 'Content-Type': 'application/json' }, 28 + body: JSON.stringify({ refreshToken }), 29 + cache: 'no-store', 30 + }, 31 + ); 32 + 33 + if (!refreshResponse.ok) { 34 + // clear invalid tokens and redirect to login 35 + cookieStore.delete('accessToken'); 36 + cookieStore.delete('refreshToken'); 37 + redirect('/login'); 38 + } 39 + 40 + const newTokens = await refreshResponse.json(); 41 + const newAccessToken = newTokens.accessToken; 42 + 43 + // update cookie 44 + cookieStore.set('accessToken', newAccessToken, { 45 + httpOnly: true, 46 + secure: true, 47 + sameSite: 'lax', 48 + path: '/', 49 + }); 50 + 51 + return { isAuthenticated: true }; 52 + } 53 + 54 + // if access token is valid 55 + return { isAuthenticated: true }; 56 + }); 57 + 58 + export const getUser = cache(async () => { 59 + const cookieStore = await cookies(); 60 + const accessToken = cookieStore.get('accessToken')?.value; 61 + const refreshToken = cookieStore.get('refreshToken')?.value; 62 + 63 + if (!accessToken && !refreshToken) redirect('/login'); 64 + 65 + const backendUrl = 66 + process.env.NEXT_PUBLIC_API_BASE_URL || 'http://127.0.0.1:3000'; 67 + 68 + // Forward cookies manually 69 + const cookieHeader = [ 70 + accessToken ? `accessToken=${accessToken}` : null, 71 + refreshToken ? `refreshToken=${refreshToken}` : null, 72 + ] 73 + .filter(Boolean) 74 + .join('; '); 75 + 76 + const res = await fetch(`${backendUrl}/api/users/me`, { 77 + headers: { 78 + 'Content-Type': 'application/json', 79 + Cookie: cookieHeader, // forward the cookies 80 + }, 81 + cache: 'no-store', 82 + }); 83 + 84 + if (!res.ok) { 85 + redirect('/login'); 86 + } 87 + 88 + const user = await res.json(); 89 + return user; 90 + });
+17
src/webapp/lib/auth/token.ts
··· 1 + export const isTokenExpiringSoon = ( 2 + token: string | null | undefined, 3 + bufferMinutes: number = 5, 4 + ): boolean => { 5 + if (!token) return true; 6 + 7 + try { 8 + const payload = JSON.parse( 9 + Buffer.from(token.split('.')[1], 'base64').toString(), 10 + ); 11 + const expiry = payload.exp * 1000; 12 + const bufferTime = bufferMinutes * 60 * 1000; 13 + return Date.now() >= expiry - bufferTime; 14 + } catch { 15 + return true; 16 + } 17 + };