@poly-x/next 0.1.0-alpha.16 → 0.1.0-alpha.18

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/dist/server.cjs CHANGED
@@ -131,6 +131,20 @@ function geoHeadersFromBody(geo) {
131
131
  if (g.consent === "granted" || g.consent === "denied" || g.consent === "revoked") headers["x-polyx-geo-consent"] = g.consent;
132
132
  return headers;
133
133
  }
134
+ /**
135
+ * Build the device-context headers (`x-timezone` / `x-screen-resolution`) from the browser's login
136
+ * body (v6). These are not automatic request headers — the browser captures them client-side and
137
+ * posts them; the platform reads them for session device attribution. Only well-formed values are
138
+ * forwarded (a sane timezone string, a `WxH` resolution) so junk never reaches the platform.
139
+ */
140
+ function deviceContextHeadersFromBody(deviceContext) {
141
+ const headers = {};
142
+ if (!deviceContext || typeof deviceContext !== "object") return headers;
143
+ const d = deviceContext;
144
+ if (typeof d.timezone === "string" && d.timezone.length > 0 && d.timezone.length <= 64) headers["x-timezone"] = d.timezone;
145
+ if (typeof d.screenResolution === "string" && /^\d{1,5}x\d{1,5}$/.test(d.screenResolution)) headers["x-screen-resolution"] = d.screenResolution;
146
+ return headers;
147
+ }
134
148
  /** Read the current session — safe in Server Components (no cookie write). */
135
149
  async function auth(overrides) {
136
150
  const config = resolveNextConfig(overrides);
@@ -188,6 +202,7 @@ function createAuthHandlers(handlersConfig = {}) {
188
202
  return Response.json({ status: "invalid_request" }, { status: 400 });
189
203
  }
190
204
  const geoHeaders = geoHeadersFromBody(payload.geo);
205
+ const deviceContextHeaders = deviceContextHeadersFromBody(payload.deviceContext);
191
206
  const email = typeof payload.email === "string" ? payload.email : "";
192
207
  const password = typeof payload.password === "string" ? payload.password : "";
193
208
  if (!email || !password) return Response.json({ status: "invalid_request" }, { status: 400 });
@@ -211,7 +226,8 @@ function createAuthHandlers(handlersConfig = {}) {
211
226
  case "authorized":
212
227
  await newSession(adapt(await (0, next_headers.cookies)()), config, secure).establishFromCode(outcome.code, verifier, redirectUri, {
213
228
  ...collectForwardedDeviceHeaders(request),
214
- ...geoHeaders
229
+ ...geoHeaders,
230
+ ...deviceContextHeaders
215
231
  });
216
232
  return Response.json({
217
233
  status: "success",
package/dist/server.mjs CHANGED
@@ -130,6 +130,20 @@ function geoHeadersFromBody(geo) {
130
130
  if (g.consent === "granted" || g.consent === "denied" || g.consent === "revoked") headers["x-polyx-geo-consent"] = g.consent;
131
131
  return headers;
132
132
  }
133
+ /**
134
+ * Build the device-context headers (`x-timezone` / `x-screen-resolution`) from the browser's login
135
+ * body (v6). These are not automatic request headers — the browser captures them client-side and
136
+ * posts them; the platform reads them for session device attribution. Only well-formed values are
137
+ * forwarded (a sane timezone string, a `WxH` resolution) so junk never reaches the platform.
138
+ */
139
+ function deviceContextHeadersFromBody(deviceContext) {
140
+ const headers = {};
141
+ if (!deviceContext || typeof deviceContext !== "object") return headers;
142
+ const d = deviceContext;
143
+ if (typeof d.timezone === "string" && d.timezone.length > 0 && d.timezone.length <= 64) headers["x-timezone"] = d.timezone;
144
+ if (typeof d.screenResolution === "string" && /^\d{1,5}x\d{1,5}$/.test(d.screenResolution)) headers["x-screen-resolution"] = d.screenResolution;
145
+ return headers;
146
+ }
133
147
  /** Read the current session — safe in Server Components (no cookie write). */
134
148
  async function auth(overrides) {
135
149
  const config = resolveNextConfig(overrides);
@@ -187,6 +201,7 @@ function createAuthHandlers(handlersConfig = {}) {
187
201
  return Response.json({ status: "invalid_request" }, { status: 400 });
188
202
  }
189
203
  const geoHeaders = geoHeadersFromBody(payload.geo);
204
+ const deviceContextHeaders = deviceContextHeadersFromBody(payload.deviceContext);
190
205
  const email = typeof payload.email === "string" ? payload.email : "";
191
206
  const password = typeof payload.password === "string" ? payload.password : "";
192
207
  if (!email || !password) return Response.json({ status: "invalid_request" }, { status: 400 });
@@ -210,7 +225,8 @@ function createAuthHandlers(handlersConfig = {}) {
210
225
  case "authorized":
211
226
  await newSession(adapt(await cookies()), config, secure).establishFromCode(outcome.code, verifier, redirectUri, {
212
227
  ...collectForwardedDeviceHeaders(request),
213
- ...geoHeaders
228
+ ...geoHeaders,
229
+ ...deviceContextHeaders
214
230
  });
215
231
  return Response.json({
216
232
  status: "success",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poly-x/next",
3
- "version": "0.1.0-alpha.16",
3
+ "version": "0.1.0-alpha.18",
4
4
  "description": "PolyX SDK for Next.js App Router - components plus server helpers",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -47,8 +47,8 @@
47
47
  "module": "./dist/index.mjs",
48
48
  "types": "./dist/index.d.cts",
49
49
  "dependencies": {
50
- "@poly-x/react": "0.1.0-alpha.16",
51
- "@poly-x/core": "0.1.0-alpha.16"
50
+ "@poly-x/core": "0.1.0-alpha.18",
51
+ "@poly-x/react": "0.1.0-alpha.18"
52
52
  },
53
53
  "peerDependencies": {
54
54
  "next": ">=14",