@sylphx/sdk 0.11.2 → 0.12.0

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.
@@ -142,6 +142,16 @@ interface SylphxMiddlewareConfig {
142
142
  * @default resolved from SYLPHX_SECRET_URL, SYLPHX_URL, SYLPHX_BAAS_URL, or SYLPHX_RUNTIME_URL
143
143
  */
144
144
  platformUrl?: string;
145
+ /**
146
+ * Canonical public application URL used for OAuth callback URLs.
147
+ *
148
+ * Set this when the app is served behind a proxy, custom domain, or platform
149
+ * generated hostname where the request URL may not be the user-facing origin.
150
+ * Only the origin is used; callback path remains owned by `authPrefix`.
151
+ *
152
+ * @default request URL origin
153
+ */
154
+ appUrl?: string;
145
155
  /**
146
156
  * Callback to add custom headers/logic to responses.
147
157
  * Called for every non-auth-route request after SDK processing.
@@ -595,6 +595,19 @@ function resolveSameOriginUrl(request, value, fallbackPath) {
595
595
  return null;
596
596
  }
597
597
  }
598
+ function normalizeAppUrl(value) {
599
+ if (!value?.trim()) return null;
600
+ try {
601
+ const url = new URL(value);
602
+ return url.origin;
603
+ } catch {
604
+ return null;
605
+ }
606
+ }
607
+ function resolveOAuthCallbackUrl(request, ctx) {
608
+ const origin = ctx.config.appUrl ?? new URL(request.url).origin;
609
+ return new URL(`${ctx.config.authPrefix}/callback`, origin);
610
+ }
598
611
  function bytesToBase64Url(bytes) {
599
612
  let binary = "";
600
613
  for (const byte of bytes) binary += String.fromCharCode(byte);
@@ -798,7 +811,7 @@ async function handleOAuthAuthorize(request, ctx) {
798
811
  return NextResponse.json({ error: "provider is required" }, { status: 400 });
799
812
  }
800
813
  const redirectTo = resolveSafeRelativeRedirectPath(rawRedirectTo, ctx.config.afterSignInUrl);
801
- const redirectUri = new URL(`${ctx.config.authPrefix}/callback`, request.url);
814
+ const redirectUri = resolveOAuthCallbackUrl(request, ctx);
802
815
  redirectUri.searchParams.set("redirect_to", redirectTo);
803
816
  const verifier = randomBase64Url(32);
804
817
  const challenge = await sha256Base64Url(verifier);
@@ -1340,6 +1353,7 @@ function createSylphxMiddleware(userConfig = {}) {
1340
1353
  afterSignInUrl: userConfig.afterSignInUrl ?? "/dashboard",
1341
1354
  authPrefix: userConfig.authPrefix ?? "/auth",
1342
1355
  baasPrefix: userConfig.baasPrefix === false ? null : normalizeRoutePrefix(userConfig.baasPrefix ?? DEFAULT_BAAS_PREFIX),
1356
+ appUrl: normalizeAppUrl(userConfig.appUrl),
1343
1357
  debug: userConfig.debug ?? false,
1344
1358
  orgRequired: userConfig.orgRequired ?? false,
1345
1359
  orgSelectionUrl: userConfig.orgSelectionUrl ?? "/select-organization",