@sylphx/sdk 0.15.1 → 0.15.2
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/nextjs/index.d.ts +14 -1
- package/dist/nextjs/index.mjs +49 -21
- package/dist/nextjs/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/nextjs/index.d.ts
CHANGED
|
@@ -649,6 +649,19 @@ interface AuthCookiesData {
|
|
|
649
649
|
/** Expiry timestamp from USER cookie */
|
|
650
650
|
expiresAt: number | null;
|
|
651
651
|
}
|
|
652
|
+
/**
|
|
653
|
+
* Decode a cookie value without throwing on malformed percent-encoding.
|
|
654
|
+
*/
|
|
655
|
+
declare function decodeCookieValue(value: string): string;
|
|
656
|
+
/**
|
|
657
|
+
* Read the last value for a cookie name from a raw Cookie header.
|
|
658
|
+
*
|
|
659
|
+
* Browsers can legitimately send duplicate cookie names when an application
|
|
660
|
+
* has migrated between host-only and domain-scoped cookies. RFC 6265 orders
|
|
661
|
+
* same-path duplicates by creation time, so the most recently set cookie is the
|
|
662
|
+
* right value for auth session recovery.
|
|
663
|
+
*/
|
|
664
|
+
declare function readCookieValueFromHeader(cookieHeader: string | null | undefined, name: string): string | null;
|
|
652
665
|
/**
|
|
653
666
|
* Get auth cookies from the request
|
|
654
667
|
*
|
|
@@ -703,4 +716,4 @@ declare function clearAuthCookiesMiddleware(response: NextResponse, namespace: s
|
|
|
703
716
|
*/
|
|
704
717
|
declare function parseUserCookie(value: string): UserCookieData | null;
|
|
705
718
|
|
|
706
|
-
export { ACTIVE_ORG_COOKIE_OPTIONS, ACTIVE_ORG_LIFETIME, type AuthCookiesData, type AuthResult, REFRESH_TOKEN_LIFETIME, SECURE_COOKIE_OPTIONS, SESSION_TOKEN_LIFETIME, SESSION_TOKEN_LIFETIME_MS, type SylphxMiddlewareConfig, type SylphxOrganizationContextConfig, TOKEN_EXPIRY_BUFFER_MS, USER_COOKIE_OPTIONS, type UserCookieData, auth, clearAuthCookies, clearAuthCookiesMiddleware, configureServer, createMatcher, createSylphxMiddleware, currentUser, currentUserId, decodeUserId, encodeUserId, getAuthCookies, getAuthorizationUrl, getCookieNames, getNamespace, getSessionToken, handleCallback, hasRefreshToken, isSessionExpired, parseUserCookie, setAuthCookies, setAuthCookiesMiddleware, signOut, sylphxMiddleware, syncAuthToCookies };
|
|
719
|
+
export { ACTIVE_ORG_COOKIE_OPTIONS, ACTIVE_ORG_LIFETIME, type AuthCookiesData, type AuthResult, REFRESH_TOKEN_LIFETIME, SECURE_COOKIE_OPTIONS, SESSION_TOKEN_LIFETIME, SESSION_TOKEN_LIFETIME_MS, type SylphxMiddlewareConfig, type SylphxOrganizationContextConfig, TOKEN_EXPIRY_BUFFER_MS, USER_COOKIE_OPTIONS, type UserCookieData, auth, clearAuthCookies, clearAuthCookiesMiddleware, configureServer, createMatcher, createSylphxMiddleware, currentUser, currentUserId, decodeCookieValue, decodeUserId, encodeUserId, getAuthCookies, getAuthorizationUrl, getCookieNames, getNamespace, getSessionToken, handleCallback, hasRefreshToken, isSessionExpired, parseUserCookie, readCookieValueFromHeader, setAuthCookies, setAuthCookiesMiddleware, signOut, sylphxMiddleware, syncAuthToCookies };
|
package/dist/nextjs/index.mjs
CHANGED
|
@@ -230,6 +230,26 @@ var ACTIVE_ORG_COOKIE_OPTIONS = {
|
|
|
230
230
|
...SECURE_COOKIE_OPTIONS,
|
|
231
231
|
httpOnly: true
|
|
232
232
|
};
|
|
233
|
+
function decodeCookieValue(value) {
|
|
234
|
+
try {
|
|
235
|
+
return decodeURIComponent(value);
|
|
236
|
+
} catch {
|
|
237
|
+
return value;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
function readCookieValueFromHeader(cookieHeader, name) {
|
|
241
|
+
if (!cookieHeader) return null;
|
|
242
|
+
let value = null;
|
|
243
|
+
for (const cookie of cookieHeader.split(";")) {
|
|
244
|
+
const trimmed = cookie.trim();
|
|
245
|
+
const eq = trimmed.indexOf("=");
|
|
246
|
+
if (eq === -1) continue;
|
|
247
|
+
if (trimmed.slice(0, eq) === name) {
|
|
248
|
+
value = decodeCookieValue(trimmed.slice(eq + 1));
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return value;
|
|
252
|
+
}
|
|
233
253
|
async function getAuthCookies(namespace) {
|
|
234
254
|
const cookieStore = await cookies();
|
|
235
255
|
const names = getCookieNames(namespace);
|
|
@@ -670,6 +690,19 @@ function clearOAuthPkceCookie(response, ctx) {
|
|
|
670
690
|
path: ctx.config.authPrefix
|
|
671
691
|
});
|
|
672
692
|
}
|
|
693
|
+
function readRequestCookieValue(request, name) {
|
|
694
|
+
const values = request.cookies.getAll(name);
|
|
695
|
+
if (values.length > 0) {
|
|
696
|
+
const value = values[values.length - 1]?.value;
|
|
697
|
+
return value === void 0 ? void 0 : decodeCookieValue(value);
|
|
698
|
+
}
|
|
699
|
+
const cookie = request.cookies.get(name);
|
|
700
|
+
if (cookie) return decodeCookieValue(cookie.value);
|
|
701
|
+
return readCookieValueFromHeader(request.headers.get("cookie"), name) ?? void 0;
|
|
702
|
+
}
|
|
703
|
+
function hasRequestCookie(request, name) {
|
|
704
|
+
return readRequestCookieValue(request, name) !== void 0;
|
|
705
|
+
}
|
|
673
706
|
function isTwoFactorLoginResponse(data) {
|
|
674
707
|
return typeof data === "object" && data !== null && data.requiresTwoFactor === true && typeof data.userId === "string";
|
|
675
708
|
}
|
|
@@ -702,7 +735,7 @@ function setRestoredSessionCookies(response, ctx, restored) {
|
|
|
702
735
|
}
|
|
703
736
|
}
|
|
704
737
|
async function refreshSessionFromCookie(request, ctx, previousSessionToken) {
|
|
705
|
-
const refreshToken = request
|
|
738
|
+
const refreshToken = readRequestCookieValue(request, ctx.cookieNames.REFRESH);
|
|
706
739
|
if (!refreshToken) return null;
|
|
707
740
|
const refreshedTokens = await refreshTokens(refreshToken, ctx);
|
|
708
741
|
if (!refreshedTokens) return null;
|
|
@@ -799,8 +832,8 @@ async function handleSession(request, ctx) {
|
|
|
799
832
|
if (request.method !== "GET") {
|
|
800
833
|
return NextResponse.json({ error: "Method not allowed" }, { status: 405 });
|
|
801
834
|
}
|
|
802
|
-
const sessionToken = request
|
|
803
|
-
const userCookie = parseUserCookie2(request
|
|
835
|
+
const sessionToken = readRequestCookieValue(request, ctx.cookieNames.SESSION);
|
|
836
|
+
const userCookie = parseUserCookie2(readRequestCookieValue(request, ctx.cookieNames.USER));
|
|
804
837
|
if (sessionToken && !isTokenExpired(sessionToken) && userCookie?.user) {
|
|
805
838
|
return NextResponse.json(sessionMetadataBody(sessionToken, userCookie.user));
|
|
806
839
|
}
|
|
@@ -813,7 +846,7 @@ async function handleSession(request, ctx) {
|
|
|
813
846
|
return response2;
|
|
814
847
|
}
|
|
815
848
|
const response = NextResponse.json({ success: true, session: null, user: null });
|
|
816
|
-
if (sessionToken || request
|
|
849
|
+
if (sessionToken || hasRequestCookie(request, ctx.cookieNames.REFRESH) || userCookie) {
|
|
817
850
|
clearAuthCookiesMiddleware(response, ctx.namespace);
|
|
818
851
|
}
|
|
819
852
|
return response;
|
|
@@ -999,7 +1032,7 @@ async function handleCallback(request, ctx) {
|
|
|
999
1032
|
}
|
|
1000
1033
|
async function handleSignOut(request, ctx) {
|
|
1001
1034
|
ctx.log("Signout");
|
|
1002
|
-
const refreshToken = request
|
|
1035
|
+
const refreshToken = readRequestCookieValue(request, ctx.cookieNames.REFRESH);
|
|
1003
1036
|
if (refreshToken) {
|
|
1004
1037
|
try {
|
|
1005
1038
|
await fetch(`${ctx.platformUrl}/v1/auth/revoke`, {
|
|
@@ -1021,7 +1054,7 @@ async function handleSignOut(request, ctx) {
|
|
|
1021
1054
|
}
|
|
1022
1055
|
async function handleToken(request, ctx) {
|
|
1023
1056
|
ctx.log("Token request");
|
|
1024
|
-
const sessionToken = request
|
|
1057
|
+
const sessionToken = readRequestCookieValue(request, ctx.cookieNames.SESSION);
|
|
1025
1058
|
if (sessionToken && !isTokenExpired(sessionToken)) {
|
|
1026
1059
|
ctx.log("Token returned");
|
|
1027
1060
|
return NextResponse.json({ accessToken: sessionToken });
|
|
@@ -1038,7 +1071,7 @@ async function handleToken(request, ctx) {
|
|
|
1038
1071
|
{ error: sessionToken ? "Session expired" : "Not authenticated", accessToken: null },
|
|
1039
1072
|
{ status: 401 }
|
|
1040
1073
|
);
|
|
1041
|
-
if (sessionToken || request
|
|
1074
|
+
if (sessionToken || hasRequestCookie(request, ctx.cookieNames.REFRESH)) {
|
|
1042
1075
|
clearAuthCookiesMiddleware(response, ctx.namespace);
|
|
1043
1076
|
}
|
|
1044
1077
|
return response;
|
|
@@ -1071,17 +1104,10 @@ function parseUserCookie2(value) {
|
|
|
1071
1104
|
return null;
|
|
1072
1105
|
}
|
|
1073
1106
|
}
|
|
1074
|
-
function decodeCookieValue(value) {
|
|
1075
|
-
try {
|
|
1076
|
-
return decodeURIComponent(value);
|
|
1077
|
-
} catch {
|
|
1078
|
-
return value;
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
1081
1107
|
function readFirstCookieValue(request, names) {
|
|
1082
1108
|
for (const name of names) {
|
|
1083
|
-
const value = request
|
|
1084
|
-
if (value) return
|
|
1109
|
+
const value = readRequestCookieValue(request, name);
|
|
1110
|
+
if (value) return value;
|
|
1085
1111
|
}
|
|
1086
1112
|
return null;
|
|
1087
1113
|
}
|
|
@@ -1214,7 +1240,7 @@ async function handleSwitchOrg(request, ctx) {
|
|
|
1214
1240
|
if (request.method !== "POST") {
|
|
1215
1241
|
return NextResponse.json({ error: "Method not allowed" }, { status: 405 });
|
|
1216
1242
|
}
|
|
1217
|
-
const currentSessionToken = request
|
|
1243
|
+
const currentSessionToken = readRequestCookieValue(request, ctx.cookieNames.SESSION);
|
|
1218
1244
|
let sessionToken = currentSessionToken && !isTokenExpired(currentSessionToken) ? currentSessionToken : null;
|
|
1219
1245
|
let restoredBaseSession = null;
|
|
1220
1246
|
if (!sessionToken) {
|
|
@@ -1226,7 +1252,7 @@ async function handleSwitchOrg(request, ctx) {
|
|
|
1226
1252
|
{ error: "Not authenticated", accessToken: null },
|
|
1227
1253
|
{ status: 401 }
|
|
1228
1254
|
);
|
|
1229
|
-
if (currentSessionToken || request
|
|
1255
|
+
if (currentSessionToken || hasRequestCookie(request, ctx.cookieNames.REFRESH)) {
|
|
1230
1256
|
clearAuthCookiesMiddleware(response, ctx.namespace);
|
|
1231
1257
|
}
|
|
1232
1258
|
return response;
|
|
@@ -1281,7 +1307,7 @@ async function handleSwitchOrg(request, ctx) {
|
|
|
1281
1307
|
...SECURE_COOKIE_OPTIONS,
|
|
1282
1308
|
maxAge: expiresIn
|
|
1283
1309
|
});
|
|
1284
|
-
const existingUser = parseUserCookie2(request
|
|
1310
|
+
const existingUser = parseUserCookie2(readRequestCookieValue(request, ctx.cookieNames.USER));
|
|
1285
1311
|
const user = data.user ?? existingUser?.user;
|
|
1286
1312
|
if (user) {
|
|
1287
1313
|
response.cookies.set(
|
|
@@ -1506,8 +1532,8 @@ function createSylphxMiddleware(userConfig = {}) {
|
|
|
1506
1532
|
if (pathname === `${config.authPrefix}/switch-org`) {
|
|
1507
1533
|
return handleSwitchOrg(request, ctx);
|
|
1508
1534
|
}
|
|
1509
|
-
const sessionToken = request
|
|
1510
|
-
const refreshToken = request
|
|
1535
|
+
const sessionToken = readRequestCookieValue(request, cookieNames.SESSION);
|
|
1536
|
+
const refreshToken = readRequestCookieValue(request, cookieNames.REFRESH);
|
|
1511
1537
|
const hasValidSession = sessionToken && !isTokenExpired(sessionToken);
|
|
1512
1538
|
const response = NextResponse.next({ request: { headers: request.headers } });
|
|
1513
1539
|
let isAuthenticated = hasValidSession;
|
|
@@ -3028,6 +3054,7 @@ export {
|
|
|
3028
3054
|
createSylphxMiddleware,
|
|
3029
3055
|
currentUser,
|
|
3030
3056
|
currentUserId,
|
|
3057
|
+
decodeCookieValue,
|
|
3031
3058
|
decodeUserId,
|
|
3032
3059
|
encodeUserId,
|
|
3033
3060
|
getAuthCookies,
|
|
@@ -3039,6 +3066,7 @@ export {
|
|
|
3039
3066
|
hasRefreshToken,
|
|
3040
3067
|
isSessionExpired,
|
|
3041
3068
|
parseUserCookie,
|
|
3069
|
+
readCookieValueFromHeader,
|
|
3042
3070
|
setAuthCookies,
|
|
3043
3071
|
setAuthCookiesMiddleware,
|
|
3044
3072
|
signOut,
|