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