wcz-layout
Version:
78 lines (77 loc) • 3.42 kB
JavaScript
import { t as serverEnv } from "./env-CGwonXSv.mjs";
import { i as buildUser, l as getAccessToken, o as hasPermission, u as getSessionUser } from "./utils-CnwPC4sC.mjs";
import { n as getTokenOnBehalfOf, t as getAppToken } from "./msalServer-VQVVDgat.mjs";
import { createMiddleware } from "@tanstack/react-start";
import axios, { AxiosError } from "axios";
import https from "node:https";
import * as jose from "jose";
//#region src/middleware/apiMiddleware.ts
const httpsAgent = new https.Agent({ rejectUnauthorized: false });
const apiMiddleware = ({ baseURL, scopeKey }) => createMiddleware().server(async ({ next, request }) => {
const resolvedBaseURL = process.env[baseURL];
if (!resolvedBaseURL) throw new Error(`"${baseURL}" env variable is not set.`);
const authHeader = request.headers.get("Authorization");
let accessToken;
if (authHeader?.startsWith("Bearer ")) accessToken = await getTokenOnBehalfOf(authHeader.substring(7), scopeKey);
else try {
accessToken = await getAccessToken(scopeKey);
} catch {
accessToken = await getAppToken(scopeKey);
}
const api = axios.create({
baseURL: resolvedBaseURL,
httpsAgent,
headers: { Authorization: `Bearer ${accessToken}` }
});
try {
return await next({ context: { api } });
} catch (error) {
if (error instanceof AxiosError) throw new Error(error.response?.data?.message ?? error.message);
throw error;
}
});
//#endregion
//#region src/middleware/authMiddleware.ts
async function resolveUser(request) {
const authHeader = request.headers.get("Authorization");
if (authHeader?.startsWith("Bearer ")) {
let payload;
try {
payload = await verifyToken(authHeader.substring(7));
} catch (error) {
throw Response.json({ message: error instanceof Error ? error.message : "Unauthorized: Invalid access token" }, { status: 401 });
}
return buildUser(payload);
}
return getSessionUser();
}
const requiredAuthenticationMiddleware = createMiddleware().server(async ({ next, request }) => {
const user = await resolveUser(request);
if (!user) throw Response.json({ message: "Unauthorized: User not signed in" }, { status: 401 });
return next({ context: { user } });
});
const publicAuthenticationMiddleware = createMiddleware().server(async ({ next, request }) => {
return next({ context: { user: await resolveUser(request) } });
});
function authenticationMiddleware(options) {
return options?.optional ? publicAuthenticationMiddleware : requiredAuthenticationMiddleware;
}
const authorizationMiddleware = (permissionKey) => createMiddleware().middleware([authenticationMiddleware()]).server(async ({ next, context }) => {
if (hasPermission(context.user, permissionKey)) return next();
throw Response.json({ message: `Forbidden: User ${context.user.name} is not authorized to access this resource` }, { status: 403 });
});
async function verifyToken(token) {
const { payload } = await jose.jwtVerify(token, getJWKS(), {
issuer: `https://login.microsoftonline.com/${serverEnv.ENTRA_TENANT_ID}/v2.0`,
audience: serverEnv.ENTRA_CLIENT_ID
});
return payload;
}
let jwksCache = null;
function getJWKS() {
jwksCache ??= jose.createRemoteJWKSet(new URL(`https://login.microsoftonline.com/${serverEnv.ENTRA_TENANT_ID}/discovery/v2.0/keys`));
return jwksCache;
}
//#endregion
export { authorizationMiddleware as n, apiMiddleware as r, authenticationMiddleware as t };
//# sourceMappingURL=authMiddleware-DkRImzMr.mjs.map