@njinlabs/njin 0.10.2 → 0.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/modules/analytics.ts +15 -0
- package/src/modules/view.ts +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@njinlabs/njin",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.3",
|
|
4
4
|
"description": "A modern framework for building company profiles, landing pages, and content-driven websites.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": ["bun", "elysia", "surrealdb", "edgejs", "cms", "framework"],
|
package/src/modules/analytics.ts
CHANGED
|
@@ -46,6 +46,21 @@ export const resolveClientIp = (
|
|
|
46
46
|
return server?.requestIP(request)?.address ?? null;
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
+
// `request.url` reflects what the backend itself sees — behind a reverse proxy that
|
|
50
|
+
// terminates TLS (the common case), that's `http://` even though visitors hit the site
|
|
51
|
+
// over `https://`. That scheme mismatch alone breaks isSameOrigin's exact comparison,
|
|
52
|
+
// so every internal navigation gets misclassified as an external referrer. Prefer the
|
|
53
|
+
// headers a trusted proxy sets; fall back to request.url for direct connections.
|
|
54
|
+
export const resolveRequestOrigin = (request: Request) => {
|
|
55
|
+
const forwardedHost = request.headers.get("x-forwarded-host");
|
|
56
|
+
if (forwardedHost) {
|
|
57
|
+
const proto = request.headers.get("x-forwarded-proto")?.split(",")[0]!.trim() || "http";
|
|
58
|
+
return `${proto}://${forwardedHost.split(",")[0]!.trim()}`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return new URL(request.url).origin;
|
|
62
|
+
};
|
|
63
|
+
|
|
49
64
|
const hashVisitor = (ip: string, userAgent: string) => {
|
|
50
65
|
const today = moment().format("YYYY-MM-DD");
|
|
51
66
|
return new Bun.CryptoHasher("sha256").update(`${ip}:${userAgent}:${today}`).digest("hex");
|
package/src/modules/view.ts
CHANGED
|
@@ -155,13 +155,13 @@ const view = makeModule(() => {
|
|
|
155
155
|
});
|
|
156
156
|
|
|
157
157
|
// Fire-and-forget — never awaited, so it can't add latency to the response.
|
|
158
|
-
import("./analytics").then(({ default: analytics, resolveClientIp }) =>
|
|
158
|
+
import("./analytics").then(({ default: analytics, resolveClientIp, resolveRequestOrigin }) =>
|
|
159
159
|
analytics().track({
|
|
160
160
|
path,
|
|
161
161
|
referrer: request.headers.get("referer"),
|
|
162
162
|
userAgent: request.headers.get("user-agent"),
|
|
163
163
|
ip: resolveClientIp(request, server),
|
|
164
|
-
requestUrl: request
|
|
164
|
+
requestUrl: resolveRequestOrigin(request),
|
|
165
165
|
}),
|
|
166
166
|
);
|
|
167
167
|
|