mirror of
https://github.com/okieselbach/AutopilotMonitor.git
synced 2026-10-24 12:42:38 +00:00
feat(web): local dev against deployed API without prod config changes
- msalConfig: NEXT_PUBLIC_ENTRA_API_CLIENT_ID splits the API scope from the SPA client id, so local dev signs in with the dev app registration while requesting the prod API audience. Unset in prod (fallback keeps the single-app behavior). - next.config: dev-only rewrites() proxy forwards /api/* server-side to DEV_API_PROXY_TARGET, keeping the browser same-origin — no localhost CORS entry on the prod Function App. - CSP: script-src gains unsafe-eval only when NODE_ENV=development (next dev HMR/react-refresh needs eval); production CSP unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -79,13 +79,17 @@ export const loginRequest: RedirectRequest = {
|
||||
* Scopes for accessing the backend API
|
||||
* IMPORTANT: Backend API must be exposed in Azure AD App Registration with this scope
|
||||
* Format: api://<backend-client-id>/access_as_user
|
||||
* For testing, you can also use User.Read but disable signature validation in backend
|
||||
*
|
||||
* NEXT_PUBLIC_ENTRA_API_CLIENT_ID lets local dev sign in with the dev app
|
||||
* registration while requesting a token whose audience is the prod API app
|
||||
* (the deployed backend only accepts its own audience). Unset in production,
|
||||
* where one app registration serves as both SPA client and API.
|
||||
*/
|
||||
const apiAppId =
|
||||
process.env.NEXT_PUBLIC_ENTRA_API_CLIENT_ID || process.env.NEXT_PUBLIC_ENTRA_CLIENT_ID;
|
||||
|
||||
export const apiRequest = {
|
||||
scopes: [
|
||||
// Option 1 (recommended): Use backend API scope after exposing API in Azure AD
|
||||
`api://${process.env.NEXT_PUBLIC_ENTRA_CLIENT_ID}/access_as_user`
|
||||
],
|
||||
scopes: [`api://${apiAppId}/access_as_user`],
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -51,6 +51,17 @@ const nextConfig: NextConfig = {
|
||||
{ source: "/roadmap", destination: "/", permanent: false },
|
||||
];
|
||||
},
|
||||
async rewrites() {
|
||||
// Dev-only reverse proxy: with DEV_API_PROXY_TARGET set in .env.local,
|
||||
// /api/* is forwarded server-side through the Next dev server to the
|
||||
// deployed backend. The browser stays same-origin, so the prod Function
|
||||
// App needs no localhost CORS entry. Inactive in production builds.
|
||||
const target = process.env.DEV_API_PROXY_TARGET;
|
||||
if (process.env.NODE_ENV !== "development" || !target) {
|
||||
return [];
|
||||
}
|
||||
return [{ source: "/api/:path*", destination: `${target}/api/:path*` }];
|
||||
},
|
||||
async headers() {
|
||||
return [
|
||||
{
|
||||
@@ -64,7 +75,9 @@ const nextConfig: NextConfig = {
|
||||
key: "Content-Security-Policy",
|
||||
value: [
|
||||
"default-src 'self'",
|
||||
"script-src 'self' 'unsafe-inline'",
|
||||
// Dev-only: next dev serves HMR/react-refresh chunks through eval();
|
||||
// production stays strict without 'unsafe-eval'.
|
||||
`script-src 'self' 'unsafe-inline'${process.env.NODE_ENV === "development" ? " 'unsafe-eval'" : ""}`,
|
||||
"style-src 'self' 'unsafe-inline'",
|
||||
"img-src 'self' data: blob: https://*.tile.openstreetmap.org",
|
||||
"font-src 'self'",
|
||||
|
||||
Reference in New Issue
Block a user