@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@njinlabs/njin",
3
- "version": "0.10.2",
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"],
@@ -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");
@@ -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.url,
164
+ requestUrl: resolveRequestOrigin(request),
165
165
  }),
166
166
  );
167
167