@scalemule/nextjs 0.1.38 → 0.1.39
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/auth.js +81 -60
- package/dist/server/auth.mjs +82 -61
- package/dist/server/index.js +123 -98
- package/dist/server/index.mjs +123 -98
- package/package.json +2 -2
package/dist/server/index.mjs
CHANGED
|
@@ -32,40 +32,40 @@ function validateIP(ip) {
|
|
|
32
32
|
return void 0;
|
|
33
33
|
}
|
|
34
34
|
function extractClientContext(request) {
|
|
35
|
-
const
|
|
35
|
+
const headers3 = request.headers;
|
|
36
36
|
let ip;
|
|
37
|
-
const cfConnectingIp =
|
|
37
|
+
const cfConnectingIp = headers3.get("cf-connecting-ip");
|
|
38
38
|
if (cfConnectingIp) {
|
|
39
39
|
ip = validateIP(cfConnectingIp);
|
|
40
40
|
}
|
|
41
41
|
if (!ip) {
|
|
42
|
-
const doConnectingIp =
|
|
42
|
+
const doConnectingIp = headers3.get("do-connecting-ip");
|
|
43
43
|
if (doConnectingIp) {
|
|
44
44
|
ip = validateIP(doConnectingIp);
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
if (!ip) {
|
|
48
|
-
const realIp =
|
|
48
|
+
const realIp = headers3.get("x-real-ip");
|
|
49
49
|
if (realIp) {
|
|
50
50
|
ip = validateIP(realIp);
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
if (!ip) {
|
|
54
|
-
const forwardedFor =
|
|
54
|
+
const forwardedFor = headers3.get("x-forwarded-for");
|
|
55
55
|
if (forwardedFor) {
|
|
56
56
|
const firstIp = forwardedFor.split(",")[0]?.trim();
|
|
57
57
|
ip = validateIP(firstIp);
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
if (!ip) {
|
|
61
|
-
const vercelForwarded =
|
|
61
|
+
const vercelForwarded = headers3.get("x-vercel-forwarded-for");
|
|
62
62
|
if (vercelForwarded) {
|
|
63
63
|
const firstIp = vercelForwarded.split(",")[0]?.trim();
|
|
64
64
|
ip = validateIP(firstIp);
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
if (!ip) {
|
|
68
|
-
const trueClientIp =
|
|
68
|
+
const trueClientIp = headers3.get("true-client-ip");
|
|
69
69
|
if (trueClientIp) {
|
|
70
70
|
ip = validateIP(trueClientIp);
|
|
71
71
|
}
|
|
@@ -73,10 +73,10 @@ function extractClientContext(request) {
|
|
|
73
73
|
if (!ip && request.ip) {
|
|
74
74
|
ip = validateIP(request.ip);
|
|
75
75
|
}
|
|
76
|
-
const userAgent =
|
|
77
|
-
const deviceFingerprint =
|
|
78
|
-
const referrer =
|
|
79
|
-
const anonymousId =
|
|
76
|
+
const userAgent = headers3.get("user-agent") || void 0;
|
|
77
|
+
const deviceFingerprint = headers3.get("x-device-fingerprint") || void 0;
|
|
78
|
+
const referrer = headers3.get("referer") || void 0;
|
|
79
|
+
const anonymousId = headers3.get("x-anonymous-id") || void 0;
|
|
80
80
|
return {
|
|
81
81
|
ip,
|
|
82
82
|
userAgent,
|
|
@@ -86,9 +86,9 @@ function extractClientContext(request) {
|
|
|
86
86
|
};
|
|
87
87
|
}
|
|
88
88
|
function extractClientContextFromReq(req) {
|
|
89
|
-
const
|
|
89
|
+
const headers3 = req.headers;
|
|
90
90
|
const getHeader = (name) => {
|
|
91
|
-
const value =
|
|
91
|
+
const value = headers3[name.toLowerCase()];
|
|
92
92
|
if (Array.isArray(value)) {
|
|
93
93
|
return value[0];
|
|
94
94
|
}
|
|
@@ -147,27 +147,27 @@ function extractClientContextFromReq(req) {
|
|
|
147
147
|
};
|
|
148
148
|
}
|
|
149
149
|
function buildClientContextHeaders(context) {
|
|
150
|
-
const
|
|
150
|
+
const headers3 = {};
|
|
151
151
|
if (!context) {
|
|
152
|
-
return
|
|
152
|
+
return headers3;
|
|
153
153
|
}
|
|
154
154
|
if (context.ip) {
|
|
155
|
-
|
|
156
|
-
|
|
155
|
+
headers3["x-sm-forwarded-client-ip"] = context.ip;
|
|
156
|
+
headers3["X-Client-IP"] = context.ip;
|
|
157
157
|
}
|
|
158
158
|
if (context.userAgent) {
|
|
159
|
-
|
|
159
|
+
headers3["X-Client-User-Agent"] = context.userAgent;
|
|
160
160
|
}
|
|
161
161
|
if (context.deviceFingerprint) {
|
|
162
|
-
|
|
162
|
+
headers3["X-Client-Device-Fingerprint"] = context.deviceFingerprint;
|
|
163
163
|
}
|
|
164
164
|
if (context.referrer) {
|
|
165
|
-
|
|
165
|
+
headers3["X-Client-Referrer"] = context.referrer;
|
|
166
166
|
}
|
|
167
167
|
if (context.anonymousId) {
|
|
168
|
-
|
|
168
|
+
headers3["x-anonymous-id"] = context.anonymousId;
|
|
169
169
|
}
|
|
170
|
-
return
|
|
170
|
+
return headers3;
|
|
171
171
|
}
|
|
172
172
|
function buildFlagContext(clientContext, extraContext = {}) {
|
|
173
173
|
const context = { ...extraContext };
|
|
@@ -185,6 +185,7 @@ var GATEWAY_URLS = {
|
|
|
185
185
|
function resolveGatewayUrl(config) {
|
|
186
186
|
if (config.gatewayUrl) return config.gatewayUrl;
|
|
187
187
|
if (process.env.SCALEMULE_API_URL) return process.env.SCALEMULE_API_URL;
|
|
188
|
+
if (process.env.SCALEMULE_GATEWAY_URL) return process.env.SCALEMULE_GATEWAY_URL;
|
|
188
189
|
return GATEWAY_URLS[config.environment || "prod"];
|
|
189
190
|
}
|
|
190
191
|
var ScaleMuleServer = class {
|
|
@@ -573,7 +574,7 @@ var ScaleMuleServer = class {
|
|
|
573
574
|
formData.append("file", blob, file.filename);
|
|
574
575
|
formData.append("sm_user_id", userId);
|
|
575
576
|
const url = `${this.gatewayUrl}/v1/storage/upload`;
|
|
576
|
-
const
|
|
577
|
+
const headers3 = {
|
|
577
578
|
"x-api-key": this.apiKey,
|
|
578
579
|
"x-user-id": userId,
|
|
579
580
|
...buildClientContextHeaders(options?.clientContext)
|
|
@@ -584,7 +585,7 @@ var ScaleMuleServer = class {
|
|
|
584
585
|
try {
|
|
585
586
|
const response = await fetch(url, {
|
|
586
587
|
method: "POST",
|
|
587
|
-
headers:
|
|
588
|
+
headers: headers3,
|
|
588
589
|
body: formData
|
|
589
590
|
});
|
|
590
591
|
const text = await response.text();
|
|
@@ -806,14 +807,14 @@ var ScaleMuleServer = class {
|
|
|
806
807
|
*/
|
|
807
808
|
async request(method, path, options = {}) {
|
|
808
809
|
const url = `${this.gatewayUrl}${path}`;
|
|
809
|
-
const
|
|
810
|
+
const headers3 = {
|
|
810
811
|
"x-api-key": this.apiKey,
|
|
811
812
|
"Content-Type": "application/json",
|
|
812
813
|
// Forward client context headers if provided
|
|
813
814
|
...buildClientContextHeaders(options.clientContext)
|
|
814
815
|
};
|
|
815
816
|
if (options.sessionToken) {
|
|
816
|
-
|
|
817
|
+
headers3["Authorization"] = `Bearer ${options.sessionToken}`;
|
|
817
818
|
}
|
|
818
819
|
if (this.debug) {
|
|
819
820
|
console.log(`[ScaleMule Server] ${method} ${path}`);
|
|
@@ -824,7 +825,7 @@ var ScaleMuleServer = class {
|
|
|
824
825
|
try {
|
|
825
826
|
const response = await fetch(url, {
|
|
826
827
|
method,
|
|
827
|
-
headers:
|
|
828
|
+
headers: headers3,
|
|
828
829
|
body: options.body ? JSON.stringify(options.body) : void 0
|
|
829
830
|
});
|
|
830
831
|
const rotated = response.headers.get("x-rotated-session-token");
|
|
@@ -920,87 +921,111 @@ function createCookieHeader(name, value, options = {}) {
|
|
|
920
921
|
}
|
|
921
922
|
function createClearCookieHeader(name, options = {}) {
|
|
922
923
|
const path = options.path ?? "/";
|
|
923
|
-
|
|
924
|
+
const secure = options.secure ?? process.env.NODE_ENV === "production";
|
|
925
|
+
const sameSite = options.sameSite ?? "lax";
|
|
926
|
+
let cookie = `${name}=; Path=${path}; Max-Age=0; HttpOnly; SameSite=${sameSite}`;
|
|
927
|
+
if (secure) {
|
|
928
|
+
cookie += "; Secure";
|
|
929
|
+
}
|
|
924
930
|
if (options.domain) {
|
|
925
931
|
cookie += `; Domain=${options.domain}`;
|
|
926
932
|
}
|
|
927
933
|
return cookie;
|
|
928
934
|
}
|
|
929
935
|
function withSession(loginResponse, responseBody, options = {}) {
|
|
930
|
-
const
|
|
931
|
-
|
|
932
|
-
|
|
936
|
+
const headers3 = new Headers();
|
|
937
|
+
headers3.set("Content-Type", "application/json");
|
|
938
|
+
headers3.append(
|
|
933
939
|
"Set-Cookie",
|
|
934
940
|
createCookieHeader(SESSION_COOKIE_NAME, loginResponse.session_token, options)
|
|
935
941
|
);
|
|
936
|
-
|
|
942
|
+
headers3.append(
|
|
937
943
|
"Set-Cookie",
|
|
938
944
|
createCookieHeader(USER_ID_COOKIE_NAME, loginResponse.user.id, options)
|
|
939
945
|
);
|
|
940
946
|
return new Response(JSON.stringify({ success: true, data: responseBody }), {
|
|
941
947
|
status: 200,
|
|
942
|
-
headers:
|
|
948
|
+
headers: headers3
|
|
943
949
|
});
|
|
944
950
|
}
|
|
945
951
|
function withRefreshedSession(sessionToken, userId, responseBody, options = {}) {
|
|
946
|
-
const
|
|
947
|
-
|
|
948
|
-
|
|
952
|
+
const headers3 = new Headers();
|
|
953
|
+
headers3.set("Content-Type", "application/json");
|
|
954
|
+
headers3.append(
|
|
949
955
|
"Set-Cookie",
|
|
950
956
|
createCookieHeader(SESSION_COOKIE_NAME, sessionToken, options)
|
|
951
957
|
);
|
|
952
|
-
|
|
958
|
+
headers3.append(
|
|
953
959
|
"Set-Cookie",
|
|
954
960
|
createCookieHeader(USER_ID_COOKIE_NAME, userId, options)
|
|
955
961
|
);
|
|
956
962
|
return new Response(JSON.stringify({ success: true, data: responseBody }), {
|
|
957
963
|
status: 200,
|
|
958
|
-
headers:
|
|
964
|
+
headers: headers3
|
|
959
965
|
});
|
|
960
966
|
}
|
|
961
967
|
function clearSession(responseBody, options = {}, status = 200) {
|
|
962
|
-
const
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
968
|
+
const headers3 = new Headers();
|
|
969
|
+
headers3.set("Content-Type", "application/json");
|
|
970
|
+
headers3.append("Set-Cookie", createClearCookieHeader(SESSION_COOKIE_NAME, options));
|
|
971
|
+
headers3.append("Set-Cookie", createClearCookieHeader(USER_ID_COOKIE_NAME, options));
|
|
966
972
|
return new Response(JSON.stringify({ success: status < 300, data: responseBody }), {
|
|
967
973
|
status,
|
|
968
|
-
headers:
|
|
974
|
+
headers: headers3
|
|
969
975
|
});
|
|
970
976
|
}
|
|
971
977
|
async function getSession() {
|
|
972
978
|
const cookieStore = await cookies();
|
|
973
979
|
const sessionCookie = cookieStore.get(SESSION_COOKIE_NAME);
|
|
974
980
|
const userIdCookie = cookieStore.get(USER_ID_COOKIE_NAME);
|
|
975
|
-
if (
|
|
976
|
-
return
|
|
981
|
+
if (sessionCookie?.value && userIdCookie?.value) {
|
|
982
|
+
return {
|
|
983
|
+
sessionToken: sessionCookie.value,
|
|
984
|
+
userId: userIdCookie.value,
|
|
985
|
+
expiresAt: /* @__PURE__ */ new Date()
|
|
986
|
+
// Note: actual expiry is managed by ScaleMule backend
|
|
987
|
+
};
|
|
977
988
|
}
|
|
989
|
+
const headerStore = await headers();
|
|
990
|
+
return sessionFromAuthHeaders(
|
|
991
|
+
headerStore.get("authorization"),
|
|
992
|
+
headerStore.get("x-sm-user-id")
|
|
993
|
+
);
|
|
994
|
+
}
|
|
995
|
+
function sessionFromAuthHeaders(authorization, userId) {
|
|
996
|
+
if (!authorization || !userId) return null;
|
|
997
|
+
const match = /^Bearer\s+(.+)$/i.exec(authorization.trim());
|
|
998
|
+
const token = match?.[1]?.trim();
|
|
999
|
+
if (!token) return null;
|
|
978
1000
|
return {
|
|
979
|
-
sessionToken:
|
|
980
|
-
userId
|
|
1001
|
+
sessionToken: token,
|
|
1002
|
+
userId,
|
|
981
1003
|
expiresAt: /* @__PURE__ */ new Date()
|
|
982
|
-
// Note: actual expiry is managed by ScaleMule backend
|
|
983
1004
|
};
|
|
984
1005
|
}
|
|
985
1006
|
function getSessionFromRequest(request) {
|
|
986
1007
|
const cookieHeader = request.headers.get("cookie");
|
|
987
|
-
if (
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
1008
|
+
if (cookieHeader) {
|
|
1009
|
+
const cookies4 = Object.fromEntries(
|
|
1010
|
+
cookieHeader.split(";").map((c) => {
|
|
1011
|
+
const [key, ...rest] = c.trim().split("=");
|
|
1012
|
+
return [key, decodeURIComponent(rest.join("="))];
|
|
1013
|
+
})
|
|
1014
|
+
);
|
|
1015
|
+
const sessionToken = cookies4[SESSION_COOKIE_NAME];
|
|
1016
|
+
const userId = cookies4[USER_ID_COOKIE_NAME];
|
|
1017
|
+
if (sessionToken && userId) {
|
|
1018
|
+
return {
|
|
1019
|
+
sessionToken,
|
|
1020
|
+
userId,
|
|
1021
|
+
expiresAt: /* @__PURE__ */ new Date()
|
|
1022
|
+
};
|
|
1023
|
+
}
|
|
998
1024
|
}
|
|
999
|
-
return
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
};
|
|
1025
|
+
return sessionFromAuthHeaders(
|
|
1026
|
+
request.headers.get("authorization"),
|
|
1027
|
+
request.headers.get("x-sm-user-id")
|
|
1028
|
+
);
|
|
1004
1029
|
}
|
|
1005
1030
|
var MAX_KNOWN_ACCOUNTS = 10;
|
|
1006
1031
|
function maskEmail(email) {
|
|
@@ -1041,7 +1066,7 @@ function applyPrivacyToEntry(entry, privacy) {
|
|
|
1041
1066
|
};
|
|
1042
1067
|
}
|
|
1043
1068
|
}
|
|
1044
|
-
function appendKnownAccountCookie(
|
|
1069
|
+
function appendKnownAccountCookie(headers3, account, existingCookie, options = {}, privacy) {
|
|
1045
1070
|
let accounts = {};
|
|
1046
1071
|
if (existingCookie) {
|
|
1047
1072
|
try {
|
|
@@ -1070,9 +1095,9 @@ function appendKnownAccountCookie(headers2, account, existingCookie, options = {
|
|
|
1070
1095
|
if (options.domain) {
|
|
1071
1096
|
cookie += `; Domain=${options.domain}`;
|
|
1072
1097
|
}
|
|
1073
|
-
|
|
1098
|
+
headers3.append("Set-Cookie", cookie);
|
|
1074
1099
|
}
|
|
1075
|
-
function removeKnownAccountFromCookie(
|
|
1100
|
+
function removeKnownAccountFromCookie(headers3, userId, existingCookie, options = {}) {
|
|
1076
1101
|
let accounts = {};
|
|
1077
1102
|
if (existingCookie) {
|
|
1078
1103
|
try {
|
|
@@ -1092,15 +1117,15 @@ function removeKnownAccountFromCookie(headers2, userId, existingCookie, options
|
|
|
1092
1117
|
if (options.domain) {
|
|
1093
1118
|
cookie += `; Domain=${options.domain}`;
|
|
1094
1119
|
}
|
|
1095
|
-
|
|
1120
|
+
headers3.append("Set-Cookie", cookie);
|
|
1096
1121
|
}
|
|
1097
|
-
function clearKnownAccountsCookie(
|
|
1122
|
+
function clearKnownAccountsCookie(headers3, options = {}) {
|
|
1098
1123
|
const path = options.path ?? "/";
|
|
1099
1124
|
let cookie = `${KNOWN_ACCOUNTS_COOKIE_NAME}=; Path=${path}; Max-Age=0`;
|
|
1100
1125
|
if (options.domain) {
|
|
1101
1126
|
cookie += `; Domain=${options.domain}`;
|
|
1102
1127
|
}
|
|
1103
|
-
|
|
1128
|
+
headers3.append("Set-Cookie", cookie);
|
|
1104
1129
|
}
|
|
1105
1130
|
function getKnownAccountsFromRequest(request) {
|
|
1106
1131
|
const cookieHeader = request.headers.get("cookie");
|
|
@@ -1598,13 +1623,13 @@ function createAuthRoutes(config = {}) {
|
|
|
1598
1623
|
if (!user_id) {
|
|
1599
1624
|
return errorResponse("VALIDATION_ERROR", "user_id required", 400);
|
|
1600
1625
|
}
|
|
1601
|
-
const
|
|
1602
|
-
|
|
1626
|
+
const headers3 = new Headers();
|
|
1627
|
+
headers3.set("Content-Type", "application/json");
|
|
1603
1628
|
const existingKnown = getKnownAccountsCookieRaw(request);
|
|
1604
|
-
removeKnownAccountFromCookie(
|
|
1629
|
+
removeKnownAccountFromCookie(headers3, user_id, existingKnown, cookieOptions);
|
|
1605
1630
|
return new Response(
|
|
1606
1631
|
JSON.stringify({ success: true, data: { message: "Account forgotten" } }),
|
|
1607
|
-
{ status: 200, headers:
|
|
1632
|
+
{ status: 200, headers: headers3 }
|
|
1608
1633
|
);
|
|
1609
1634
|
}
|
|
1610
1635
|
// ==================== Forget All Accounts ====================
|
|
@@ -1612,12 +1637,12 @@ function createAuthRoutes(config = {}) {
|
|
|
1612
1637
|
if (!config.enableAccountSwitcher) {
|
|
1613
1638
|
return errorResponse("NOT_FOUND", "Account switcher not enabled", 404);
|
|
1614
1639
|
}
|
|
1615
|
-
const
|
|
1616
|
-
|
|
1617
|
-
clearKnownAccountsCookie(
|
|
1640
|
+
const headers3 = new Headers();
|
|
1641
|
+
headers3.set("Content-Type", "application/json");
|
|
1642
|
+
clearKnownAccountsCookie(headers3, cookieOptions);
|
|
1618
1643
|
return new Response(
|
|
1619
1644
|
JSON.stringify({ success: true, data: { message: "All accounts forgotten" } }),
|
|
1620
|
-
{ status: 200, headers:
|
|
1645
|
+
{ status: 200, headers: headers3 }
|
|
1621
1646
|
);
|
|
1622
1647
|
}
|
|
1623
1648
|
default:
|
|
@@ -2327,31 +2352,31 @@ function createPushRoutes(config) {
|
|
|
2327
2352
|
const { apiKey, gatewayUrl, csrf = true } = config;
|
|
2328
2353
|
async function proxyToGateway(request, method, subPath) {
|
|
2329
2354
|
const targetUrl = `${gatewayUrl}/v1/communication/push/${subPath}`;
|
|
2330
|
-
const
|
|
2355
|
+
const headers3 = {
|
|
2331
2356
|
"x-api-key": apiKey
|
|
2332
2357
|
};
|
|
2333
2358
|
const session = getSessionFromRequest(request);
|
|
2334
2359
|
if (session?.sessionToken) {
|
|
2335
|
-
|
|
2360
|
+
headers3["Authorization"] = `Bearer ${session.sessionToken}`;
|
|
2336
2361
|
}
|
|
2337
2362
|
const clientContext = extractClientContext(
|
|
2338
2363
|
request
|
|
2339
2364
|
);
|
|
2340
2365
|
const contextHeaders = buildClientContextHeaders(clientContext);
|
|
2341
|
-
Object.assign(
|
|
2366
|
+
Object.assign(headers3, contextHeaders);
|
|
2342
2367
|
const workspaceId = request.headers.get("x-sm-workspace-id");
|
|
2343
2368
|
if (workspaceId) {
|
|
2344
|
-
|
|
2369
|
+
headers3["x-sm-workspace-id"] = workspaceId;
|
|
2345
2370
|
}
|
|
2346
2371
|
const fetchOptions = {
|
|
2347
2372
|
method,
|
|
2348
|
-
headers:
|
|
2373
|
+
headers: headers3
|
|
2349
2374
|
};
|
|
2350
2375
|
if (method !== "GET" && method !== "DELETE") {
|
|
2351
2376
|
try {
|
|
2352
2377
|
const body = await request.text();
|
|
2353
2378
|
if (body) {
|
|
2354
|
-
|
|
2379
|
+
headers3["Content-Type"] = "application/json";
|
|
2355
2380
|
fetchOptions.body = body;
|
|
2356
2381
|
}
|
|
2357
2382
|
} catch {
|
|
@@ -2446,26 +2471,26 @@ function createNotificationRoutes(config) {
|
|
|
2446
2471
|
const { apiKey, gatewayUrl } = config;
|
|
2447
2472
|
async function proxyToGateway(request, method, subPath) {
|
|
2448
2473
|
const targetUrl = `${gatewayUrl}/v1/notifications/${subPath}`;
|
|
2449
|
-
const
|
|
2474
|
+
const headers3 = {
|
|
2450
2475
|
"x-api-key": apiKey,
|
|
2451
2476
|
"Content-Type": "application/json"
|
|
2452
2477
|
};
|
|
2453
2478
|
const session = getSessionFromRequest(request);
|
|
2454
2479
|
if (session?.sessionToken) {
|
|
2455
|
-
|
|
2480
|
+
headers3["Authorization"] = `Bearer ${session.sessionToken}`;
|
|
2456
2481
|
}
|
|
2457
2482
|
const clientContext = extractClientContext(
|
|
2458
2483
|
request
|
|
2459
2484
|
);
|
|
2460
2485
|
const contextHeaders = buildClientContextHeaders(clientContext);
|
|
2461
|
-
Object.assign(
|
|
2486
|
+
Object.assign(headers3, contextHeaders);
|
|
2462
2487
|
const workspaceId = request.headers.get("x-sm-workspace-id");
|
|
2463
2488
|
if (workspaceId) {
|
|
2464
|
-
|
|
2489
|
+
headers3["x-sm-workspace-id"] = workspaceId;
|
|
2465
2490
|
}
|
|
2466
2491
|
const fetchOptions = {
|
|
2467
2492
|
method,
|
|
2468
|
-
headers:
|
|
2493
|
+
headers: headers3
|
|
2469
2494
|
};
|
|
2470
2495
|
if (method === "PATCH") {
|
|
2471
2496
|
try {
|
|
@@ -3139,47 +3164,47 @@ function formatPermissionsDirective(feature, value) {
|
|
|
3139
3164
|
return `${feature}=(${parts.join(" ")})`;
|
|
3140
3165
|
}
|
|
3141
3166
|
function buildSecurityHeaders(opts = {}) {
|
|
3142
|
-
const
|
|
3167
|
+
const headers3 = [];
|
|
3143
3168
|
const includeHsts = opts.includeHsts ?? true;
|
|
3144
3169
|
const hstsMaxAge = opts.hstsMaxAgeSeconds ?? 31536e3;
|
|
3145
3170
|
if (includeHsts && hstsMaxAge > 0) {
|
|
3146
3171
|
const parts = [`max-age=${hstsMaxAge}`];
|
|
3147
3172
|
if (opts.hstsIncludeSubDomains ?? true) parts.push("includeSubDomains");
|
|
3148
3173
|
if (opts.hstsPreload ?? false) parts.push("preload");
|
|
3149
|
-
|
|
3174
|
+
headers3.push({
|
|
3150
3175
|
key: "Strict-Transport-Security",
|
|
3151
3176
|
value: parts.join("; ")
|
|
3152
3177
|
});
|
|
3153
3178
|
}
|
|
3154
3179
|
const frameOptions = opts.frameOptions === void 0 ? "DENY" : opts.frameOptions;
|
|
3155
3180
|
if (frameOptions !== null) {
|
|
3156
|
-
|
|
3181
|
+
headers3.push({ key: "X-Frame-Options", value: frameOptions });
|
|
3157
3182
|
}
|
|
3158
3183
|
const contentTypeOptions = opts.contentTypeOptions === void 0 ? "nosniff" : opts.contentTypeOptions;
|
|
3159
3184
|
if (contentTypeOptions !== null) {
|
|
3160
|
-
|
|
3185
|
+
headers3.push({ key: "X-Content-Type-Options", value: contentTypeOptions });
|
|
3161
3186
|
}
|
|
3162
|
-
|
|
3187
|
+
headers3.push({
|
|
3163
3188
|
key: "Referrer-Policy",
|
|
3164
3189
|
value: opts.referrerPolicy ?? "strict-origin-when-cross-origin"
|
|
3165
3190
|
});
|
|
3166
3191
|
const xss = opts.xssProtection === void 0 ? "0" : opts.xssProtection;
|
|
3167
3192
|
if (xss !== null) {
|
|
3168
|
-
|
|
3193
|
+
headers3.push({ key: "X-XSS-Protection", value: xss });
|
|
3169
3194
|
}
|
|
3170
3195
|
const permissions = opts.permissionsPolicy === void 0 ? DEFAULT_PERMISSIONS_POLICY : opts.permissionsPolicy;
|
|
3171
3196
|
if (permissions !== null) {
|
|
3172
3197
|
const directives = Object.entries(permissions).map(([feature, value]) => formatPermissionsDirective(feature, value)).join(", ");
|
|
3173
|
-
|
|
3198
|
+
headers3.push({ key: "Permissions-Policy", value: directives });
|
|
3174
3199
|
}
|
|
3175
3200
|
if (opts.extraHeaders?.length) {
|
|
3176
|
-
const byKey = new Map(
|
|
3201
|
+
const byKey = new Map(headers3.map((h) => [h.key.toLowerCase(), h]));
|
|
3177
3202
|
for (const extra of opts.extraHeaders) {
|
|
3178
3203
|
byKey.set(extra.key.toLowerCase(), extra);
|
|
3179
3204
|
}
|
|
3180
3205
|
return Array.from(byKey.values());
|
|
3181
3206
|
}
|
|
3182
|
-
return
|
|
3207
|
+
return headers3;
|
|
3183
3208
|
}
|
|
3184
3209
|
|
|
3185
3210
|
export { CSRF_COOKIE_NAME, CSRF_HEADER_NAME, DEFAULT_PERMISSIONS_POLICY, KNOWN_ACCOUNTS_COOKIE_NAME, OAUTH_STATE_COOKIE_NAME, SESSION_COOKIE_NAME, SM_LEDVERY_ACCESS_TOKEN_COOKIE, SM_LEDVERY_ID_TOKEN_COOKIE, SM_LEDVERY_NONCE_COOKIE, SM_LEDVERY_PKCE_VERIFIER_COOKIE, SM_LEDVERY_STATE_COOKIE, ScaleMuleError, ScaleMuleServer, USER_ID_COOKIE_NAME, apiHandler, appendKnownAccountCookie, buildClientContextHeaders, buildFlagContext, buildSecurityHeaders, clearKnownAccountsCookie, clearOAuthState, clearSession, configureBundles, configureSecrets, createAnalyticsRoutes, createAuthMiddleware, createAuthRoutes, createLedveryRoutes, createNotificationRoutes, createPushRoutes, createServerClient, createWebhookHandler, createWebhookRoutes, errorCodeToStatus, extractClientContext, extractClientContextFromReq, generateCSRFToken, getAppSecret, getAppSecretOrDefault, getBootstrapFlags, getBundle, getCSRFToken, getKnownAccountsCookieRaw, getKnownAccountsFromRequest, getLedverySession, getMySqlBundle, getOAuthBundle, getPostgresBundle, getRedisBundle, getS3Bundle, getSession, getSessionFromRequest, getSmtpBundle, invalidateBundleCache, invalidateSecretCache, isSafeRedirect, normalizeKnownAccountsCookie, parseWebhookEvent, prefetchBundles, prefetchSecrets, registerVideoWebhook, removeKnownAccountFromCookie, requireAppSecret, requireBundle, requireSession, resolveGatewayUrl, setOAuthState, unwrap, validateCSRFToken, validateCSRFTokenAsync, validateOAuthState, validateOAuthStateAsync, validateSafeRedirect, verifyWebhookSignature, withAuth, withCSRFProtection, withCSRFToken, withSession };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scalemule/nextjs",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.39",
|
|
4
4
|
"description": "ScaleMule SDK for Next.js applications - authentication, storage, and user management",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"@scalemule/ledvery": "^0.0.1",
|
|
62
62
|
"@scalemule/money": "^0.0.1",
|
|
63
|
-
"@scalemule/sdk": "^0.0.
|
|
63
|
+
"@scalemule/sdk": "^0.0.63"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
66
|
"next": ">=14.0.0",
|