Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ab473b1

Browse files
committedMar 27, 2025·
move to internal api
1 parent 35694cd commit ab473b1

File tree

4 files changed

+90
-54
lines changed

4 files changed

+90
-54
lines changed
 

‎src/app/_common/fastApiTracking.ts

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"use client";
2+
3+
import { useEffect } from "react";
4+
import { CookieBannerUtils } from "@navikt/arbeidsplassen-react";
5+
import { usePathname, useSearchParams } from "next/navigation";
6+
7+
export function FastApiTracker(): null {
8+
const pathname = usePathname();
9+
const searchParams = useSearchParams();
10+
11+
useEffect(() => {
12+
const trackPageView = async () => {
13+
try {
14+
const userActionTaken: boolean = CookieBannerUtils.getUserActionTakenValue(document.cookie);
15+
const hasCookieConsent: { analyticsConsent: boolean } = CookieBannerUtils.getConsentValues(
16+
document.cookie,
17+
);
18+
const eventName: string = userActionTaken
19+
? hasCookieConsent.analyticsConsent
20+
? "accepted"
21+
: "not-accepted"
22+
: "no-action";
23+
24+
await fetch("/stillinger/api/internal/fastapi", {
25+
method: "POST",
26+
headers: { "Content-Type": "application/json" },
27+
body: JSON.stringify({
28+
url_host: window.location.host,
29+
url_path: pathname,
30+
url_query: searchParams.toString(),
31+
event_name: eventName,
32+
}),
33+
});
34+
} catch (err) {
35+
console.error("An error occurred sending event to API route:", err);
36+
}
37+
};
38+
39+
trackPageView();
40+
}, [pathname, searchParams]);
41+
42+
return null;
43+
}

‎src/app/layout.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { defaultMetadataDescription, defaultOpenGraphImage, getMetadataTitle } f
1717
import App from "./App";
1818
import Providers from "./Providers";
1919
import { CookieBannerUtils } from "@navikt/arbeidsplassen-react";
20+
import { FastApiTracker } from "@/app/_common/fastApiTracking";
2021

2122
export async function generateMetadata(): Promise<Metadata> {
2223
return {
@@ -55,6 +56,7 @@ export default async function RootLayout({ children }: RootLayoutProps): Promise
5556
<body data-theme="arbeidsplassen" className={localFont.className}>
5657
<Providers userPreferences={await actions.getUserPreferences()}>
5758
<App userActionTaken={userActionTaken}>{children}</App>
59+
<FastApiTracker />
5860
</Providers>
5961
</body>
6062
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { NextRequest, NextResponse } from "next/server";
2+
3+
const FAST_API_APP_ID_PROD = "41fb84fd-4ff3-43f4-b7e0-d84444fb2f91";
4+
const FAST_API_APP_ID_DEV = "501ec40e-4010-4cb4-ad13-61ab529dd765";
5+
6+
export async function POST(req: NextRequest) {
7+
const allowedOrigins = ["https://arbeidsplassen.intern.dev.nav.no", "https://arbeidsplassen.nav.no"];
8+
9+
const origin = req.headers.get("origin");
10+
if (!origin || !allowedOrigins.includes(origin)) {
11+
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
12+
}
13+
14+
try {
15+
const { url_host, url_path, url_query, event_name } = await req.json();
16+
17+
const appId = process.env.NODE_ENV === "production" ? FAST_API_APP_ID_PROD : FAST_API_APP_ID_DEV;
18+
19+
if (!appId) {
20+
return NextResponse.json({ error: "Missing API ID" }, { status: 500 });
21+
}
22+
23+
const response = await fetch("https://fastapi.nav.no/api/send", {
24+
method: "POST",
25+
headers: { "Content-Type": "application/json" },
26+
body: JSON.stringify({
27+
app_id: appId,
28+
url_host,
29+
url_path,
30+
url_query,
31+
event_name,
32+
}),
33+
});
34+
35+
if (!response.ok) {
36+
throw new Error("Failed to send event to Fast API");
37+
}
38+
39+
return NextResponse.json({ success: true });
40+
} catch (err) {
41+
console.error("Fast API Server Error:", err);
42+
return NextResponse.json({ error: "Internal Server Error" }, { status: 500 });
43+
}
44+
}

‎src/middleware.ts

+1-54
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { getCallId, NAV_CALL_ID_TAG } from "@/app/stillinger/_common/monitoring/
33
import { getSessionId, SESSION_ID_TAG } from "@/app/stillinger/_common/monitoring/session";
44
import { CURRENT_VERSION, migrateSearchParams } from "@/app/stillinger/(sok)/_utils/versioning/searchParamsVersioning";
55
import { QueryNames } from "@/app/stillinger/(sok)/_utils/QueryNames";
6-
import { CookieBannerUtils } from "@navikt/arbeidsplassen-react";
76

87
/*
98
* Match all request paths except for the ones starting with:
@@ -13,18 +12,11 @@ import { CookieBannerUtils } from "@navikt/arbeidsplassen-react";
1312
* Source: https://nextjs.org/docs/pages/building-your-application/configuring/content-security-policy
1413
*/
1514
const CSP_HEADER_MATCH = /^\/((?!api|_next\/static|favicon.ico).*)$/;
16-
const FAST_API_HEADER_MATCH = /^\/((?!.*api.*|_next\/static|favicon.ico).*)$/;
17-
const FAST_API_APP_ID_PROD = "41fb84fd-4ff3-43f4-b7e0-d84444fb2f91";
18-
const FAST_API_APP_ID_DEV = "501ec40e-4010-4cb4-ad13-61ab529dd765";
1915

2016
function shouldAddCspHeaders(request: NextRequest) {
2117
return new RegExp(CSP_HEADER_MATCH).exec(request.nextUrl.pathname);
2218
}
2319

24-
function shouldLogToFastApi(request: NextRequest) {
25-
return new RegExp(FAST_API_HEADER_MATCH).exec(request.nextUrl.pathname);
26-
}
27-
2820
function addCspHeaders(requestHeaders: Headers, responseHeaders: Headers) {
2921
const nonce = Buffer.from(crypto.randomUUID()).toString("base64");
3022
const cspHeader = `
@@ -43,7 +35,7 @@ function addCspHeaders(requestHeaders: Headers, responseHeaders: Headers) {
4335
frame-src 'self';
4436
block-all-mixed-content;
4537
${process.env.NODE_ENV === "production" ? "upgrade-insecure-requests;" : ""};
46-
connect-src 'self' https://sentry.gc.nav.no umami.nav.no;
38+
connect-src 'self' https://sentry.gc.nav.no umami.nav.no https://fastapi.nav.no;
4739
`;
4840

4941
// Replace newline characters and spaces
@@ -63,47 +55,6 @@ function addSessionIdHeader(requestHeaders: Headers) {
6355
requestHeaders.set(SESSION_ID_TAG, getSessionId());
6456
}
6557

66-
function logCookieValueToFastApi(request: NextRequest) {
67-
const pathname = request.nextUrl.pathname;
68-
const appId = process.env.NODE_ENV === "production" ? FAST_API_APP_ID_PROD : FAST_API_APP_ID_DEV;
69-
70-
if (!/\.[a-zA-Z0-9]+$/.test(pathname)) {
71-
try {
72-
const userActionTaken = CookieBannerUtils.getUserActionTakenValue(request.cookies?.toString());
73-
const hasCookieConsent = CookieBannerUtils.getConsentValues(request.cookies?.toString());
74-
let eventName = "";
75-
76-
if (!userActionTaken) {
77-
eventName = "no-action";
78-
} else {
79-
if (hasCookieConsent.analyticsConsent) {
80-
eventName = "accepted";
81-
} else {
82-
eventName = "not-accepted";
83-
}
84-
}
85-
86-
// Fire & Forget API Call (Non-blocking) + Log Response
87-
fetch("https://fastapi.nav.no/api/send", {
88-
method: "POST",
89-
headers: { "Content-Type": "application/json" },
90-
body: JSON.stringify({
91-
app_id: appId,
92-
url_host: request.nextUrl.host,
93-
url_path: pathname,
94-
url_query: request.nextUrl.search,
95-
event_name: eventName,
96-
}),
97-
})
98-
.then((response) => response.text())
99-
.then((data) => console.log("Event sent successfully to Fast API:", data))
100-
.catch((err) => console.error("Failed to send event to Fast API:", err));
101-
} catch (err) {
102-
console.error("An error occured sending event to Fast API:", err);
103-
}
104-
}
105-
}
106-
10758
const PUBLIC_FILE = /\.(.*)$/;
10859

10960
// Due to limitations in the edge runtime, we can't use the prom-client library to track metrics directly here.
@@ -134,10 +85,6 @@ export function middleware(request: NextRequest) {
13485
addCspHeaders(requestHeaders, responseHeaders);
13586
}
13687

137-
if (shouldLogToFastApi(request)) {
138-
logCookieValueToFastApi(request);
139-
}
140-
14188
addCallIdHeader(requestHeaders);
14289
addSessionIdHeader(requestHeaders);
14390

0 commit comments

Comments
 (0)
Please sign in to comment.