@luckystack/login 0.7.2 → 0.7.4

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/register.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  microsoftProvider,
10
10
  registerOAuthProviderFactory,
11
11
  registerUserAdapter
12
- } from "./chunk-L5MHCPNN.js";
12
+ } from "./chunk-CLYMWF3A.js";
13
13
 
14
14
  // src/register.ts
15
15
  import { getProjectConfig, resolveEnvKey } from "@luckystack/core";
@@ -90,7 +90,7 @@ The rules:
90
90
  '/org/123/projects' // ✓ relative path with multi-segment
91
91
  ```
92
92
 
93
- The trick is parsing against a `'http://placeholder'` base — if the resulting origin matches the base, the input was a relative URL (no scheme/host of its own). Relative URLs land on the same origin as the app, so they're safe by definition.
93
+ The trick is parsing against a `'http://placeholder'` base — if the resulting origin matches the base, the input was a relative URL (no scheme/host of its own). Relative URLs are safe by definition, but the OAuth callback may run on a separate backend origin. After validation, the framework resolves a relative result against the trusted absolute `defaultUrl` supplied by the callback route, so `/dashboard` inherits the frontend origin instead of the backend callback origin.
94
94
 
95
95
  ### 2. Absolute URL — origin must match `http.cors.allowedOrigins`
96
96
 
@@ -160,7 +160,9 @@ const resolvePostLoginRedirect = async ({ fallbackUrl, userId, providerName, isN
160
160
  getLogger().warn(`[oauth] postLoginRedirect resolver threw`, { message: (resolverError as Error).message });
161
161
  return fallbackUrl;
162
162
  }
163
- if (resolved && isAllowedRedirectUrl(resolved)) return resolved;
163
+ if (resolved && isAllowedRedirectUrl(resolved)) {
164
+ return resolvePostLoginRedirectAgainstDefault(resolved, fallbackUrl);
165
+ }
164
166
  if (resolved) {
165
167
  getLogger().warn(
166
168
  `[oauth] postLoginRedirect returned a URL not in allowed origins — falling back`,
@@ -244,7 +246,7 @@ registerPostLoginRedirect(async ({ userId, defaultUrl }) => {
244
246
  });
245
247
  ```
246
248
 
247
- Look up the user's tenant and route to a tenant-scoped URL. The relative path is always same-origin so it passes `isAllowedRedirectUrl` without needing `allowedOrigins` entries.
249
+ Look up the user's tenant and route to a tenant-scoped URL. The relative path passes `isAllowedRedirectUrl` without needing `allowedOrigins` entries and then inherits the callback route's trusted frontend `defaultUrl` origin.
248
250
 
249
251
  ### Per-provider deep link
250
252
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luckystack/login",
3
- "version": "0.7.2",
3
+ "version": "0.7.4",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -59,7 +59,7 @@
59
59
  "test": "vitest run"
60
60
  },
61
61
  "dependencies": {
62
- "@luckystack/core": "^0.7.2",
62
+ "@luckystack/core": "^0.7.4",
63
63
  "bcryptjs": "^3.0.0",
64
64
  "dotenv": "^17.0.0",
65
65
  "validator": "^13.15.35"
@@ -67,7 +67,7 @@
67
67
  "peerDependencies": {
68
68
  "@prisma/client": "^6.19.0",
69
69
  "socket.io": "^4.8.0",
70
- "@luckystack/email": "^0.7.2"
70
+ "@luckystack/email": "^0.7.4"
71
71
  },
72
72
  "peerDependenciesMeta": {
73
73
  "@prisma/client": {