Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | 1x 1x 1x 1x 1x 1x 1x 19x 19x 19x 19x 2x 2x 2x 1x 1x 1x 1x 1x 1x 2x 19x 1x 1x 18x 19x 3x 1x 1x 2x 3x 1x 1x 1x 1x 1x 1x 3x 19x 2x 2x 2x 2x 2x 2x 19x 19x 2x 2x 2x 2x 2x 2x 2x 12x 19x 1x 1x 12x 12x | import type { MiddlewareHandler } from 'astro';
// Constants
import { API_ROUTES, PRIVATE_ROUTES, ROUTES } from './constants/routes';
import { COOKIE_KEYS } from './constants/auth';
import { HTTP_HEADERS } from './constants/http';
// Utils
import { proxyRequest } from './utils/proxy';
import {
checkPermission,
findMatchedRoute,
isTokenExpired,
} from './utils/auth';
// Services
import { getRefreshToken } from '@/services/auth';
export const onRequest: MiddlewareHandler = async (context, next) => {
const user = await context.session?.get('user');
const { pathname, search } = context.url;
const tokenShared = context.cookies.get(COOKIE_KEYS.TOKEN_SHARED)?.value;
if (!!tokenShared && !!user?.token && isTokenExpired(user?.token)) {
const { data } = await getRefreshToken({ token: tokenShared });
const token = data?.id_token || '';
if (token) {
const newUser = {
...user,
token,
};
await context.session?.set('user', newUser);
}
}
if (user && pathname === ROUTES.SIGN_IN) {
return Response.redirect(new URL(ROUTES.HOME, context.url), 302);
}
const matchedPrivateRoute = findMatchedRoute(pathname, PRIVATE_ROUTES);
if (!!matchedPrivateRoute) {
// If user is not logged in → redirect to sign-in
if (!user) {
return Response.redirect(new URL(ROUTES.SIGN_IN, context.url), 302);
}
const isNoPermission = !checkPermission(user, matchedPrivateRoute);
// If user is logged in but does not have the required role → return 404
if (isNoPermission) {
const res = await next(new URL(ROUTES.NOT_FOUND, context.url));
return new Response(await res.text(), {
status: 404,
headers: res.headers,
});
}
}
// Proxy /rpc requests
if (pathname.startsWith(API_ROUTES.RPC)) {
const res = await proxyRequest(context, pathname + search);
return new Response(await res.text(), {
status: res.status,
headers: res.headers,
});
}
// Proxy /docs requests (e.g. export) stream body to keep binary (XLSX) intact.
if (pathname.startsWith(API_ROUTES.DOCS)) {
const res = await proxyRequest(context, pathname + search);
return new Response(res.body, {
status: res.status,
headers: res.headers,
});
}
// Proxy /ws requests (WebSocket)
if (pathname.startsWith(API_ROUTES.WS)) {
const res = await proxyRequest(context, pathname + search);
return new Response(null, {
status: res.status,
headers: res.headers,
...((res as any).webSocket && { webSocket: (res as any).webSocket }),
});
}
const response = await next();
// Force back/forward navigation to refetch instead of showing a stale cached page.
if (response.headers.get(HTTP_HEADERS.CONTENT_TYPE)?.includes('text/html')) {
response.headers.set(HTTP_HEADERS.CACHE_CONTROL, 'no-store');
}
return response;
};
|