@sylphx/sdk 0.10.6 → 0.11.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.
- package/README.md +6 -0
- package/dist/health/index.d.ts +681 -0
- package/dist/health/index.mjs.map +1 -1
- package/dist/index.d.ts +64 -98
- package/dist/index.mjs +16 -15
- package/dist/index.mjs.map +1 -1
- package/dist/nextjs/index.d.ts +23 -0
- package/dist/nextjs/index.mjs +161 -25
- package/dist/nextjs/index.mjs.map +1 -1
- package/dist/react/index.d.ts +6 -10
- package/dist/react/index.mjs +4 -4
- package/dist/react/index.mjs.map +1 -1
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.mjs.map +1 -1
- package/dist/web-analytics.d.ts +90 -0
- package/package.json +4 -4
package/dist/nextjs/index.d.ts
CHANGED
|
@@ -64,14 +64,18 @@ interface SylphxMiddlewareConfig {
|
|
|
64
64
|
afterSignInUrl?: string;
|
|
65
65
|
/**
|
|
66
66
|
* Auth routes prefix. Routes are mounted at:
|
|
67
|
+
* - {prefix}/register — email/password registration handler
|
|
67
68
|
* - {prefix}/login — credentials login handler
|
|
69
|
+
* - {prefix}/verify-email — email verification handler
|
|
68
70
|
* - {prefix}/oauth-providers — enabled social login providers
|
|
69
71
|
* - {prefix}/oauth/authorize — social login start handler
|
|
70
72
|
* - {prefix}/callback — OAuth callback handler
|
|
71
73
|
* - {prefix}/passkey/options — passkey login challenge handler
|
|
72
74
|
* - {prefix}/passkey/authenticate — passkey login verification handler
|
|
75
|
+
* - {prefix}/verify-2fa — TOTP/backup-code verification handler
|
|
73
76
|
* - {prefix}/forgot-password — password reset email handler
|
|
74
77
|
* - {prefix}/reset-password — password reset verification handler
|
|
78
|
+
* - {prefix}/session — safe session metadata handler
|
|
75
79
|
* - {prefix}/signout — Sign out handler
|
|
76
80
|
*
|
|
77
81
|
* @default '/auth'
|
|
@@ -112,6 +116,25 @@ interface SylphxMiddlewareConfig {
|
|
|
112
116
|
* @default process.env.SYLPHX_SECRET_URL
|
|
113
117
|
*/
|
|
114
118
|
secretUrl?: string;
|
|
119
|
+
/**
|
|
120
|
+
* Publishable key for browser-safe auth routes.
|
|
121
|
+
*
|
|
122
|
+
* Public auth handlers (`/auth/login`, `/auth/oauth-providers`,
|
|
123
|
+
* `/auth/oauth/authorize`, password reset, passkeys) call runtime routes
|
|
124
|
+
* guarded by projectAuth, which accepts pk_* only.
|
|
125
|
+
*
|
|
126
|
+
* @default credential parsed from process.env.SYLPHX_URL or
|
|
127
|
+
* process.env.NEXT_PUBLIC_SYLPHX_URL
|
|
128
|
+
*/
|
|
129
|
+
publishableKey?: string;
|
|
130
|
+
/**
|
|
131
|
+
* Public connection URL for browser-safe auth routes.
|
|
132
|
+
*
|
|
133
|
+
* Format: sylphx://pk_<env>_<hex>@<tenant>.api.sylphx.com
|
|
134
|
+
*
|
|
135
|
+
* @default process.env.SYLPHX_URL or process.env.NEXT_PUBLIC_SYLPHX_URL
|
|
136
|
+
*/
|
|
137
|
+
publicUrl?: string;
|
|
115
138
|
/**
|
|
116
139
|
* Platform URL for API calls.
|
|
117
140
|
* Override for self-hosted or same-origin deployments.
|
package/dist/nextjs/index.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import { NextResponse } from "next/server";
|
|
|
3
3
|
|
|
4
4
|
// src/constants.ts
|
|
5
5
|
var ENV_URL = "SYLPHX_URL";
|
|
6
|
+
var ENV_PUBLIC_URL = "NEXT_PUBLIC_SYLPHX_URL";
|
|
6
7
|
var ENV_SECRET_URL = "SYLPHX_SECRET_URL";
|
|
7
8
|
var DEFAULT_SDK_API_HOST = "api.sylphx.com";
|
|
8
9
|
var SDK_PLATFORM = typeof window !== "undefined" ? "browser" : typeof process !== "undefined" && process.versions?.node ? "node" : "unknown";
|
|
@@ -127,6 +128,12 @@ function validateKeyForType(key, keyType, pattern, envVarName) {
|
|
|
127
128
|
function validatePublicKey(key) {
|
|
128
129
|
return validateKeyForType(key, "publicKey", PUBLIC_KEY_PATTERN, "publishable credential");
|
|
129
130
|
}
|
|
131
|
+
function validateAndSanitizePublicKey(key) {
|
|
132
|
+
const result = validatePublicKey(key);
|
|
133
|
+
if (!result.valid) throw new Error(result.error);
|
|
134
|
+
if (result.warning) console.warn(result.warning);
|
|
135
|
+
return result.sanitizedKey;
|
|
136
|
+
}
|
|
130
137
|
function validateAppId(key) {
|
|
131
138
|
return validateKeyForType(key, "appId", APP_ID_PATTERN, "NEXT_PUBLIC_SYLPHX_APP_ID");
|
|
132
139
|
}
|
|
@@ -427,6 +434,11 @@ function secretKeyFromConnectionUrl(value) {
|
|
|
427
434
|
if (!parsed || parsed.credentialType !== "sk") return null;
|
|
428
435
|
return parsed.credential;
|
|
429
436
|
}
|
|
437
|
+
function publishableKeyFromConnectionUrl(value) {
|
|
438
|
+
const parsed = parseConnection(value);
|
|
439
|
+
if (!parsed || parsed.credentialType !== "pk") return null;
|
|
440
|
+
return parsed.credential;
|
|
441
|
+
}
|
|
430
442
|
function resolveNextjsPlatformUrl(options) {
|
|
431
443
|
if (options.explicitPlatformUrl) return normalizePlatformUrl(options.explicitPlatformUrl);
|
|
432
444
|
const fromExplicitSecretUrl = platformUrlFromConnectionUrl(options.secretUrl);
|
|
@@ -451,6 +463,16 @@ function resolveNextjsSecretKey(options) {
|
|
|
451
463
|
if (fromGenericUrl) return fromGenericUrl;
|
|
452
464
|
return null;
|
|
453
465
|
}
|
|
466
|
+
function resolveNextjsPublishableKey(options) {
|
|
467
|
+
if (options.explicitPublishableKey?.trim()) return options.explicitPublishableKey.trim();
|
|
468
|
+
const fromExplicitPublicUrl = publishableKeyFromConnectionUrl(options.explicitPublicUrl);
|
|
469
|
+
if (fromExplicitPublicUrl) return fromExplicitPublicUrl;
|
|
470
|
+
const fromPublicUrl = publishableKeyFromConnectionUrl(process.env[ENV_URL]);
|
|
471
|
+
if (fromPublicUrl) return fromPublicUrl;
|
|
472
|
+
const fromNextPublicUrl = publishableKeyFromConnectionUrl(process.env[ENV_PUBLIC_URL]);
|
|
473
|
+
if (fromNextPublicUrl) return fromNextPublicUrl;
|
|
474
|
+
return null;
|
|
475
|
+
}
|
|
454
476
|
|
|
455
477
|
// src/nextjs/middleware.ts
|
|
456
478
|
var OAUTH_PKCE_TTL_SECONDS = 10 * 60;
|
|
@@ -634,12 +656,30 @@ function isTwoFactorLoginResponse(data) {
|
|
|
634
656
|
function isOAuthAuthorizeResponse(data) {
|
|
635
657
|
return typeof data === "object" && data !== null && typeof data.authorization_url === "string";
|
|
636
658
|
}
|
|
637
|
-
function
|
|
659
|
+
function authCookieJsonResponse(ctx, data) {
|
|
660
|
+
const response = NextResponse.json({ success: true, user: data.user });
|
|
661
|
+
setAuthCookiesMiddleware(response, ctx.namespace, data);
|
|
662
|
+
return response;
|
|
663
|
+
}
|
|
664
|
+
function headersForProjectAuth(ctx) {
|
|
638
665
|
return {
|
|
639
666
|
"Content-Type": "application/json",
|
|
640
|
-
"x-app-secret": ctx.
|
|
667
|
+
"x-app-secret": ctx.publishableKey
|
|
641
668
|
};
|
|
642
669
|
}
|
|
670
|
+
async function handleRegister(request, ctx) {
|
|
671
|
+
if (request.method !== "POST") {
|
|
672
|
+
return NextResponse.json({ error: "Method not allowed" }, { status: 405 });
|
|
673
|
+
}
|
|
674
|
+
const body = await parseJsonObject(request);
|
|
675
|
+
const res = await fetch(`${ctx.platformUrl}/v1/auth/register`, {
|
|
676
|
+
method: "POST",
|
|
677
|
+
headers: headersForProjectAuth(ctx),
|
|
678
|
+
body: JSON.stringify(body ?? {})
|
|
679
|
+
});
|
|
680
|
+
const data = await res.json().catch(() => ({}));
|
|
681
|
+
return NextResponse.json(data, { status: res.status });
|
|
682
|
+
}
|
|
643
683
|
async function handleLogin(request, ctx) {
|
|
644
684
|
if (request.method !== "POST") {
|
|
645
685
|
return NextResponse.json({ error: "Method not allowed" }, { status: 405 });
|
|
@@ -652,7 +692,7 @@ async function handleLogin(request, ctx) {
|
|
|
652
692
|
}
|
|
653
693
|
const res = await fetch(`${ctx.platformUrl}/v1/auth/login`, {
|
|
654
694
|
method: "POST",
|
|
655
|
-
headers:
|
|
695
|
+
headers: headersForProjectAuth(ctx),
|
|
656
696
|
body: JSON.stringify({ email, password })
|
|
657
697
|
});
|
|
658
698
|
const data = await res.json().catch(() => ({}));
|
|
@@ -665,14 +705,83 @@ async function handleLogin(request, ctx) {
|
|
|
665
705
|
if (!isTokenResponse(data)) {
|
|
666
706
|
return NextResponse.json({ error: "invalid_response" }, { status: 502 });
|
|
667
707
|
}
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
708
|
+
return authCookieJsonResponse(ctx, data);
|
|
709
|
+
}
|
|
710
|
+
async function handleVerifyEmail(request, ctx) {
|
|
711
|
+
if (request.method !== "POST") {
|
|
712
|
+
return NextResponse.json({ error: "Method not allowed" }, { status: 405 });
|
|
713
|
+
}
|
|
714
|
+
const body = await parseJsonObject(request);
|
|
715
|
+
const token = typeof body?.token === "string" ? body.token : null;
|
|
716
|
+
if (!token) {
|
|
717
|
+
return NextResponse.json({ error: "token is required" }, { status: 400 });
|
|
718
|
+
}
|
|
719
|
+
const res = await fetch(`${ctx.platformUrl}/v1/auth/verify-email`, {
|
|
720
|
+
method: "POST",
|
|
721
|
+
headers: headersForProjectAuth(ctx),
|
|
722
|
+
body: JSON.stringify({ token })
|
|
723
|
+
});
|
|
724
|
+
const data = await res.json().catch(() => ({}));
|
|
725
|
+
return NextResponse.json(data, { status: res.status });
|
|
726
|
+
}
|
|
727
|
+
async function handleVerifyTwoFactor(request, ctx) {
|
|
728
|
+
if (request.method !== "POST") {
|
|
729
|
+
return NextResponse.json({ error: "Method not allowed" }, { status: 405 });
|
|
730
|
+
}
|
|
731
|
+
const body = await parseJsonObject(request);
|
|
732
|
+
const userId = typeof body?.userId === "string" ? body.userId : null;
|
|
733
|
+
const code = typeof body?.code === "string" ? body.code : null;
|
|
734
|
+
if (!userId || !code) {
|
|
735
|
+
return NextResponse.json({ error: "userId and code are required" }, { status: 400 });
|
|
736
|
+
}
|
|
737
|
+
const res = await fetch(`${ctx.platformUrl}/v1/auth/verify-2fa`, {
|
|
738
|
+
method: "POST",
|
|
739
|
+
headers: headersForProjectAuth(ctx),
|
|
740
|
+
body: JSON.stringify({ userId, code })
|
|
741
|
+
});
|
|
742
|
+
const data = await res.json().catch(() => ({}));
|
|
743
|
+
if (!res.ok) {
|
|
744
|
+
return NextResponse.json(data, { status: res.status });
|
|
745
|
+
}
|
|
746
|
+
if (!isTokenResponse(data)) {
|
|
747
|
+
return NextResponse.json({ error: "invalid_response" }, { status: 502 });
|
|
748
|
+
}
|
|
749
|
+
return authCookieJsonResponse(ctx, data);
|
|
750
|
+
}
|
|
751
|
+
function handleSession(request, ctx) {
|
|
752
|
+
if (request.method !== "GET") {
|
|
753
|
+
return NextResponse.json({ error: "Method not allowed" }, { status: 405 });
|
|
754
|
+
}
|
|
755
|
+
const sessionToken = request.cookies.get(ctx.cookieNames.SESSION)?.value;
|
|
756
|
+
const userCookieValue = request.cookies.get(ctx.cookieNames.USER)?.value;
|
|
757
|
+
let userCookie = userCookieValue ? parseUserCookie2(userCookieValue) : null;
|
|
758
|
+
if (!userCookie && userCookieValue) {
|
|
759
|
+
try {
|
|
760
|
+
userCookie = parseUserCookie2(decodeURIComponent(userCookieValue));
|
|
761
|
+
} catch {
|
|
762
|
+
userCookie = null;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
if (!sessionToken || isTokenExpired(sessionToken) || !userCookie?.user) {
|
|
766
|
+
return NextResponse.json({ success: true, session: null, user: null });
|
|
767
|
+
}
|
|
768
|
+
const payload = decodeJwtPayload(sessionToken);
|
|
769
|
+
const userId = payload?.sub ?? userCookie.user.id;
|
|
770
|
+
const expiresAt = typeof payload?.exp === "number" ? new Date(payload.exp * 1e3).toISOString() : new Date(userCookie.expiresAt).toISOString();
|
|
771
|
+
return NextResponse.json({
|
|
772
|
+
success: true,
|
|
773
|
+
session: {
|
|
774
|
+
id: `platform:${userId}`,
|
|
775
|
+
userId,
|
|
776
|
+
expiresAt
|
|
777
|
+
},
|
|
778
|
+
user: userCookie.user
|
|
779
|
+
});
|
|
671
780
|
}
|
|
672
781
|
async function handleOAuthProviders(ctx) {
|
|
673
782
|
const res = await fetch(`${ctx.platformUrl}/v1/auth/oauth-providers`, {
|
|
674
783
|
method: "GET",
|
|
675
|
-
headers:
|
|
784
|
+
headers: headersForProjectAuth(ctx)
|
|
676
785
|
});
|
|
677
786
|
const data = await res.json().catch(() => ({}));
|
|
678
787
|
return NextResponse.json(data, { status: res.status });
|
|
@@ -695,7 +804,7 @@ async function handleOAuthAuthorize(request, ctx) {
|
|
|
695
804
|
const scopes = Array.isArray(body?.scopes) ? body.scopes.filter((scope) => typeof scope === "string") : void 0;
|
|
696
805
|
const res = await fetch(`${ctx.platformUrl}/v1/oauth/authorize`, {
|
|
697
806
|
method: "POST",
|
|
698
|
-
headers:
|
|
807
|
+
headers: headersForProjectAuth(ctx),
|
|
699
808
|
body: JSON.stringify({
|
|
700
809
|
provider,
|
|
701
810
|
redirect_uri: redirectUri.toString(),
|
|
@@ -724,7 +833,7 @@ async function handlePasskeyOptions(request, ctx) {
|
|
|
724
833
|
const body = await parseJsonObject(request);
|
|
725
834
|
const res = await fetch(`${ctx.platformUrl}/v1/auth/passkey/options`, {
|
|
726
835
|
method: "POST",
|
|
727
|
-
headers:
|
|
836
|
+
headers: headersForProjectAuth(ctx),
|
|
728
837
|
body: JSON.stringify(body ?? {})
|
|
729
838
|
});
|
|
730
839
|
const data = await res.json().catch(() => ({}));
|
|
@@ -737,7 +846,7 @@ async function handlePasskeyAuthenticate(request, ctx) {
|
|
|
737
846
|
const body = await parseJsonObject(request);
|
|
738
847
|
const res = await fetch(`${ctx.platformUrl}/v1/auth/passkey/authenticate`, {
|
|
739
848
|
method: "POST",
|
|
740
|
-
headers:
|
|
849
|
+
headers: headersForProjectAuth(ctx),
|
|
741
850
|
body: JSON.stringify(body ?? {})
|
|
742
851
|
});
|
|
743
852
|
const data = await res.json().catch(() => ({}));
|
|
@@ -747,9 +856,7 @@ async function handlePasskeyAuthenticate(request, ctx) {
|
|
|
747
856
|
if (!isTokenResponse(data)) {
|
|
748
857
|
return NextResponse.json({ error: "invalid_response" }, { status: 502 });
|
|
749
858
|
}
|
|
750
|
-
|
|
751
|
-
setAuthCookiesMiddleware(response, ctx.namespace, data);
|
|
752
|
-
return response;
|
|
859
|
+
return authCookieJsonResponse(ctx, data);
|
|
753
860
|
}
|
|
754
861
|
async function handleForgotPassword(request, ctx) {
|
|
755
862
|
if (request.method !== "POST") {
|
|
@@ -767,7 +874,7 @@ async function handleForgotPassword(request, ctx) {
|
|
|
767
874
|
}
|
|
768
875
|
const res = await fetch(`${ctx.platformUrl}/v1/auth/forgot-password`, {
|
|
769
876
|
method: "POST",
|
|
770
|
-
headers:
|
|
877
|
+
headers: headersForProjectAuth(ctx),
|
|
771
878
|
body: JSON.stringify({ email, redirectUrl })
|
|
772
879
|
});
|
|
773
880
|
const data = await res.json().catch(() => ({}));
|
|
@@ -785,7 +892,7 @@ async function handleResetPassword(request, ctx) {
|
|
|
785
892
|
}
|
|
786
893
|
const res = await fetch(`${ctx.platformUrl}/v1/auth/reset-password`, {
|
|
787
894
|
method: "POST",
|
|
788
|
-
headers:
|
|
895
|
+
headers: headersForProjectAuth(ctx),
|
|
789
896
|
body: JSON.stringify({ token, password })
|
|
790
897
|
});
|
|
791
898
|
const data = await res.json().catch(() => ({}));
|
|
@@ -1091,12 +1198,15 @@ async function handleSwitchOrg(request, ctx) {
|
|
|
1091
1198
|
}
|
|
1092
1199
|
const expiresIn = resolveOrgScopedTokenExpiresIn(data);
|
|
1093
1200
|
const expiresAt = Date.now() + expiresIn * 1e3;
|
|
1201
|
+
const payload = decodeJwtPayload(accessToken);
|
|
1202
|
+
const activeOrganization = {
|
|
1203
|
+
id: payload?.org_id ?? orgId,
|
|
1204
|
+
slug: payload?.org_slug ?? requestedOrgSlug
|
|
1205
|
+
};
|
|
1094
1206
|
const response = NextResponse.json({
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
tokenType: resolveOrgScopedTokenType(data),
|
|
1099
|
-
user: data.user ?? null
|
|
1207
|
+
success: true,
|
|
1208
|
+
user: data.user ?? null,
|
|
1209
|
+
organization: activeOrganization
|
|
1100
1210
|
});
|
|
1101
1211
|
response.cookies.set(ctx.cookieNames.SESSION, accessToken, {
|
|
1102
1212
|
...SECURE_COOKIE_OPTIONS,
|
|
@@ -1117,11 +1227,7 @@ async function handleSwitchOrg(request, ctx) {
|
|
|
1117
1227
|
}
|
|
1118
1228
|
);
|
|
1119
1229
|
}
|
|
1120
|
-
|
|
1121
|
-
setActiveOrganizationCookies(response, ctx, {
|
|
1122
|
-
id: payload?.org_id ?? orgId,
|
|
1123
|
-
slug: payload?.org_slug ?? requestedOrgSlug
|
|
1124
|
-
});
|
|
1230
|
+
setActiveOrganizationCookies(response, ctx, activeOrganization);
|
|
1125
1231
|
ctx.log("Switch org success", { orgId });
|
|
1126
1232
|
return response;
|
|
1127
1233
|
} catch (err) {
|
|
@@ -1197,6 +1303,21 @@ function createSylphxMiddleware(userConfig = {}) {
|
|
|
1197
1303
|
secretKey = validateAndSanitizeSecretKey(rawSecretKey);
|
|
1198
1304
|
return secretKey;
|
|
1199
1305
|
}
|
|
1306
|
+
let publishableKey = null;
|
|
1307
|
+
function resolvePublishableKey() {
|
|
1308
|
+
if (publishableKey) return publishableKey;
|
|
1309
|
+
const rawPublishableKey = resolveNextjsPublishableKey({
|
|
1310
|
+
explicitPublishableKey: userConfig.publishableKey,
|
|
1311
|
+
explicitPublicUrl: userConfig.publicUrl
|
|
1312
|
+
});
|
|
1313
|
+
if (!rawPublishableKey) {
|
|
1314
|
+
throw new Error(
|
|
1315
|
+
"[Sylphx] Publishable connection URL is required for public auth routes.\nEither pass publicUrl/publishableKey in config or set SYLPHX_URL/NEXT_PUBLIC_SYLPHX_URL."
|
|
1316
|
+
);
|
|
1317
|
+
}
|
|
1318
|
+
publishableKey = validateAndSanitizePublicKey(rawPublishableKey);
|
|
1319
|
+
return publishableKey;
|
|
1320
|
+
}
|
|
1200
1321
|
let platformUrl;
|
|
1201
1322
|
let namespace;
|
|
1202
1323
|
let cookieNames;
|
|
@@ -1244,6 +1365,9 @@ function createSylphxMiddleware(userConfig = {}) {
|
|
|
1244
1365
|
get secretKey() {
|
|
1245
1366
|
return secretKey;
|
|
1246
1367
|
},
|
|
1368
|
+
get publishableKey() {
|
|
1369
|
+
return resolvePublishableKey();
|
|
1370
|
+
},
|
|
1247
1371
|
get platformUrl() {
|
|
1248
1372
|
return platformUrl;
|
|
1249
1373
|
},
|
|
@@ -1267,12 +1391,18 @@ function createSylphxMiddleware(userConfig = {}) {
|
|
|
1267
1391
|
if (pathname.includes(".") || pathname.startsWith("/_next")) {
|
|
1268
1392
|
return NextResponse.next();
|
|
1269
1393
|
}
|
|
1394
|
+
if (pathname === `${config.authPrefix}/register`) {
|
|
1395
|
+
return handleRegister(request, ctx);
|
|
1396
|
+
}
|
|
1270
1397
|
if (pathname === `${config.authPrefix}/callback`) {
|
|
1271
1398
|
return handleCallback(request, ctx);
|
|
1272
1399
|
}
|
|
1273
1400
|
if (pathname === `${config.authPrefix}/login`) {
|
|
1274
1401
|
return handleLogin(request, ctx);
|
|
1275
1402
|
}
|
|
1403
|
+
if (pathname === `${config.authPrefix}/verify-email`) {
|
|
1404
|
+
return handleVerifyEmail(request, ctx);
|
|
1405
|
+
}
|
|
1276
1406
|
if (pathname === `${config.authPrefix}/oauth-providers`) {
|
|
1277
1407
|
return handleOAuthProviders(ctx);
|
|
1278
1408
|
}
|
|
@@ -1285,12 +1415,18 @@ function createSylphxMiddleware(userConfig = {}) {
|
|
|
1285
1415
|
if (pathname === `${config.authPrefix}/passkey/authenticate`) {
|
|
1286
1416
|
return handlePasskeyAuthenticate(request, ctx);
|
|
1287
1417
|
}
|
|
1418
|
+
if (pathname === `${config.authPrefix}/verify-2fa`) {
|
|
1419
|
+
return handleVerifyTwoFactor(request, ctx);
|
|
1420
|
+
}
|
|
1288
1421
|
if (pathname === `${config.authPrefix}/forgot-password`) {
|
|
1289
1422
|
return handleForgotPassword(request, ctx);
|
|
1290
1423
|
}
|
|
1291
1424
|
if (pathname === `${config.authPrefix}/reset-password`) {
|
|
1292
1425
|
return handleResetPassword(request, ctx);
|
|
1293
1426
|
}
|
|
1427
|
+
if (pathname === `${config.authPrefix}/session`) {
|
|
1428
|
+
return handleSession(request, ctx);
|
|
1429
|
+
}
|
|
1294
1430
|
if (pathname === `${config.authPrefix}/signout`) {
|
|
1295
1431
|
return handleSignOut(request, ctx);
|
|
1296
1432
|
}
|