propro-utils 1.6.3 → 1.6.4
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "propro-utils",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.4",
|
|
4
4
|
"description": "Auth middleware for propro-auth",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
"jest-mock-axios": "^4.7.3",
|
|
47
47
|
"jsonwebtoken": "^9.0.2",
|
|
48
48
|
"multer": "^1.4.5-lts.1",
|
|
49
|
+
"neverthrow": "^8.2.0",
|
|
49
50
|
"nodemailer": "^6.9.7",
|
|
50
51
|
"nodemailer-mailgun-transport": "^2.1.5",
|
|
51
52
|
"querystring": "^0.2.1",
|
|
@@ -3,19 +3,19 @@
|
|
|
3
3
|
* This module provides functions for setting and clearing authentication cookies.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
const { URL } = require(
|
|
6
|
+
const { URL } = require("url");
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Safely stringify an object, handling circular references
|
|
10
10
|
* @param {Object} obj - The object to stringify
|
|
11
11
|
* @return {string} A JSON string representation of the object
|
|
12
12
|
*/
|
|
13
|
-
const safeStringify = obj => {
|
|
13
|
+
const safeStringify = (obj) => {
|
|
14
14
|
const seen = new WeakSet();
|
|
15
15
|
return JSON.stringify(obj, (key, value) => {
|
|
16
|
-
if (typeof value ===
|
|
16
|
+
if (typeof value === "object" && value !== null) {
|
|
17
17
|
if (seen.has(value)) {
|
|
18
|
-
return
|
|
18
|
+
return "[Circular]";
|
|
19
19
|
}
|
|
20
20
|
seen.add(value);
|
|
21
21
|
}
|
|
@@ -28,7 +28,7 @@ const safeStringify = obj => {
|
|
|
28
28
|
* @param {Object} user - The user object to sanitize
|
|
29
29
|
* @return {Object} A sanitized version of the user object
|
|
30
30
|
*/
|
|
31
|
-
const sanitizeUser = user => {
|
|
31
|
+
const sanitizeUser = (user) => {
|
|
32
32
|
const sanitized = { ...user };
|
|
33
33
|
|
|
34
34
|
delete sanitized.password;
|
|
@@ -61,10 +61,10 @@ const sanitizeUser = user => {
|
|
|
61
61
|
* @param {Object} details - Cookie details
|
|
62
62
|
* @returns {Promise} Promise that resolves when cookie is set
|
|
63
63
|
*/
|
|
64
|
-
const setChromeExtensionCookie = details => {
|
|
64
|
+
const setChromeExtensionCookie = (details) => {
|
|
65
65
|
return new Promise((resolve, reject) => {
|
|
66
66
|
try {
|
|
67
|
-
chrome.cookies.set(details, cookie => {
|
|
67
|
+
chrome.cookies.set(details, (cookie) => {
|
|
68
68
|
if (chrome.runtime.lastError) {
|
|
69
69
|
reject(chrome.runtime.lastError);
|
|
70
70
|
} else {
|
|
@@ -83,13 +83,13 @@ const setChromeExtensionCookie = details => {
|
|
|
83
83
|
*/
|
|
84
84
|
const setAuthCookies = async (res, tokens, account, user, appUrl) => {
|
|
85
85
|
if (!tokens?.refresh?.token || !tokens?.access?.token) {
|
|
86
|
-
throw new Error(
|
|
86
|
+
throw new Error("Invalid tokens object");
|
|
87
87
|
}
|
|
88
88
|
if (!account) {
|
|
89
|
-
throw new Error(
|
|
89
|
+
throw new Error("Invalid account object");
|
|
90
90
|
}
|
|
91
91
|
if (!user) {
|
|
92
|
-
throw new Error(
|
|
92
|
+
throw new Error("Invalid user object");
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
const currentDateTime = new Date();
|
|
@@ -102,34 +102,38 @@ const setAuthCookies = async (res, tokens, account, user, appUrl) => {
|
|
|
102
102
|
let domain;
|
|
103
103
|
try {
|
|
104
104
|
domain = appUrl ? new URL(appUrl).hostname : undefined;
|
|
105
|
-
if (domain?.includes(
|
|
106
|
-
domain =
|
|
105
|
+
if (domain?.includes("mapmap.app")) {
|
|
106
|
+
domain = ".mapmap.app";
|
|
107
107
|
}
|
|
108
|
-
if (domain?.includes(
|
|
108
|
+
if (domain?.includes("localhost")) {
|
|
109
109
|
domain = undefined;
|
|
110
110
|
}
|
|
111
|
-
if (domain?.includes(
|
|
112
|
-
domain =
|
|
111
|
+
if (domain?.includes("propro.so")) {
|
|
112
|
+
domain = "propro.so";
|
|
113
113
|
}
|
|
114
114
|
} catch (error) {
|
|
115
|
-
console.error(
|
|
115
|
+
console.error("Invalid appUrl:", { error, appUrl });
|
|
116
116
|
domain = undefined;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
// Determine if we're in a local development environment
|
|
120
|
+
const isLocalhost =
|
|
121
|
+
!domain || domain === "localhost" || domain.includes("localhost");
|
|
122
|
+
|
|
119
123
|
const commonAttributes = {
|
|
120
|
-
secure:
|
|
121
|
-
sameSite:
|
|
124
|
+
secure: !isLocalhost, // Only require secure for non-localhost environments
|
|
125
|
+
sameSite: isLocalhost ? "Lax" : "None", // Use Lax for localhost, None for production
|
|
122
126
|
domain,
|
|
123
|
-
path:
|
|
127
|
+
path: "/",
|
|
124
128
|
};
|
|
125
129
|
|
|
126
130
|
const httpOnlyCookies = {
|
|
127
|
-
|
|
131
|
+
"x-refresh-token": {
|
|
128
132
|
value: tokens.refresh.token,
|
|
129
133
|
maxAge: refreshMaxAge,
|
|
130
134
|
httpOnly: true,
|
|
131
135
|
},
|
|
132
|
-
|
|
136
|
+
"x-access-token": {
|
|
133
137
|
value: tokens.access.token,
|
|
134
138
|
maxAge: accessMaxAge,
|
|
135
139
|
httpOnly: true,
|
|
@@ -150,7 +154,7 @@ const setAuthCookies = async (res, tokens, account, user, appUrl) => {
|
|
|
150
154
|
maxAge: refreshMaxAge,
|
|
151
155
|
},
|
|
152
156
|
has_account_token: {
|
|
153
|
-
value: JSON.stringify({ value:
|
|
157
|
+
value: JSON.stringify({ value: "true", expires: accessMaxAge }),
|
|
154
158
|
maxAge: accessMaxAge,
|
|
155
159
|
},
|
|
156
160
|
};
|
|
@@ -170,21 +174,21 @@ const setAuthCookies = async (res, tokens, account, user, appUrl) => {
|
|
|
170
174
|
...regularCookies,
|
|
171
175
|
}).map(([name, config]) => {
|
|
172
176
|
return setChromeExtensionCookie({
|
|
173
|
-
url: `https://${domain ||
|
|
177
|
+
url: `https://${domain || "propro.so"}`,
|
|
174
178
|
name,
|
|
175
179
|
value: config.value,
|
|
176
180
|
secure: true,
|
|
177
181
|
httpOnly: !!config.httpOnly,
|
|
178
|
-
sameSite:
|
|
179
|
-
path:
|
|
182
|
+
sameSite: "no_restriction",
|
|
183
|
+
path: "/",
|
|
180
184
|
expirationDate: Math.floor((Date.now() + config.maxAge) / 1000),
|
|
181
|
-
domain: domain?.startsWith(
|
|
185
|
+
domain: domain?.startsWith(".") ? domain : `.${domain || "propro.so"}`,
|
|
182
186
|
});
|
|
183
187
|
});
|
|
184
188
|
|
|
185
189
|
await Promise.allSettled(extensionCookiePromises);
|
|
186
190
|
|
|
187
|
-
console.log(
|
|
191
|
+
console.log("Auth cookies set successfully", {
|
|
188
192
|
domain,
|
|
189
193
|
sameSite: commonAttributes.sameSite,
|
|
190
194
|
cookieNames: [
|
|
@@ -193,11 +197,11 @@ const setAuthCookies = async (res, tokens, account, user, appUrl) => {
|
|
|
193
197
|
],
|
|
194
198
|
});
|
|
195
199
|
} catch (error) {
|
|
196
|
-
console.error(
|
|
200
|
+
console.error("Error setting cookies:", {
|
|
197
201
|
error: error.message,
|
|
198
202
|
stack: error.stack,
|
|
199
203
|
});
|
|
200
|
-
throw new Error(
|
|
204
|
+
throw new Error("Failed to set authentication cookies");
|
|
201
205
|
}
|
|
202
206
|
};
|
|
203
207
|
|
|
@@ -208,44 +212,48 @@ const clearAuthCookies = async (res, appUrl) => {
|
|
|
208
212
|
let domain;
|
|
209
213
|
try {
|
|
210
214
|
domain = appUrl ? new URL(appUrl).hostname : undefined;
|
|
211
|
-
if (domain?.includes(
|
|
212
|
-
domain =
|
|
215
|
+
if (domain?.includes("mapmap.app")) {
|
|
216
|
+
domain = ".mapmap.app";
|
|
213
217
|
}
|
|
214
|
-
if (domain?.includes(
|
|
218
|
+
if (domain?.includes("localhost")) {
|
|
215
219
|
domain = undefined;
|
|
216
220
|
}
|
|
217
221
|
} catch (error) {
|
|
218
|
-
console.error(
|
|
222
|
+
console.error("Invalid appUrl:", error);
|
|
219
223
|
domain = undefined;
|
|
220
224
|
}
|
|
221
225
|
|
|
226
|
+
// Determine if we're in a local development environment
|
|
227
|
+
const isLocalhost =
|
|
228
|
+
!domain || domain === "localhost" || domain.includes("localhost");
|
|
229
|
+
|
|
222
230
|
const commonAttributes = {
|
|
223
|
-
secure:
|
|
224
|
-
sameSite:
|
|
231
|
+
secure: !isLocalhost, // Only require secure for non-localhost environments
|
|
232
|
+
sameSite: isLocalhost ? "Lax" : "None", // Use Lax for localhost, None for production
|
|
225
233
|
domain,
|
|
226
|
-
path:
|
|
234
|
+
path: "/",
|
|
227
235
|
};
|
|
228
236
|
|
|
229
237
|
const cookieNames = [
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
238
|
+
"x-refresh-token",
|
|
239
|
+
"x-access-token",
|
|
240
|
+
"user",
|
|
241
|
+
"account",
|
|
242
|
+
"has_account_token",
|
|
235
243
|
];
|
|
236
244
|
|
|
237
245
|
// Clear web cookies
|
|
238
|
-
cookieNames.forEach(cookieName => {
|
|
246
|
+
cookieNames.forEach((cookieName) => {
|
|
239
247
|
res.clearCookie(cookieName, commonAttributes);
|
|
240
248
|
});
|
|
241
249
|
|
|
242
250
|
try {
|
|
243
251
|
const extensionClearPromises = cookieNames.map(
|
|
244
|
-
name =>
|
|
245
|
-
new Promise(resolve => {
|
|
252
|
+
(name) =>
|
|
253
|
+
new Promise((resolve) => {
|
|
246
254
|
chrome.cookies.remove(
|
|
247
255
|
{
|
|
248
|
-
url: `https://${domain ||
|
|
256
|
+
url: `https://${domain || "mapmap.app"}`,
|
|
249
257
|
name,
|
|
250
258
|
},
|
|
251
259
|
resolve
|
|
@@ -258,7 +266,7 @@ const clearAuthCookies = async (res, appUrl) => {
|
|
|
258
266
|
// Not in extension context, ignore
|
|
259
267
|
}
|
|
260
268
|
|
|
261
|
-
console.log(
|
|
269
|
+
console.log("Auth cookies cleared successfully", {
|
|
262
270
|
domain,
|
|
263
271
|
cookieNames,
|
|
264
272
|
sameSite: commonAttributes.sameSite,
|