@arcote.tech/arc-adapter-db-postgres 0.8.3 → 0.8.5
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/index.js +104 -48
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1350,9 +1350,74 @@ function apply(state, patches, applyOptions) {
|
|
|
1350
1350
|
var constructorString = Object.prototype.constructor.toString();
|
|
1351
1351
|
|
|
1352
1352
|
// ../../../core/dist/index.js
|
|
1353
|
-
var
|
|
1354
|
-
|
|
1355
|
-
|
|
1353
|
+
var COOKIE_PREFIX = "arc_token";
|
|
1354
|
+
var TOKEN_BUMP_KEY = "arc:token-bump";
|
|
1355
|
+
function hasDocument() {
|
|
1356
|
+
return typeof document !== "undefined";
|
|
1357
|
+
}
|
|
1358
|
+
function signalCrossTabChange() {
|
|
1359
|
+
if (typeof localStorage === "undefined")
|
|
1360
|
+
return;
|
|
1361
|
+
try {
|
|
1362
|
+
localStorage.setItem(TOKEN_BUMP_KEY, String(Date.now()));
|
|
1363
|
+
} catch {}
|
|
1364
|
+
}
|
|
1365
|
+
function isSecureContext() {
|
|
1366
|
+
return typeof location !== "undefined" && location.protocol === "https:";
|
|
1367
|
+
}
|
|
1368
|
+
function tokenCookieName(scopeKey) {
|
|
1369
|
+
return scopeKey === "default" ? COOKIE_PREFIX : `${COOKIE_PREFIX}_${scopeKey.replace(/:/g, ".")}`;
|
|
1370
|
+
}
|
|
1371
|
+
function scopeKeyFromCookieName(name) {
|
|
1372
|
+
if (name === COOKIE_PREFIX)
|
|
1373
|
+
return "default";
|
|
1374
|
+
if (!name.startsWith(`${COOKIE_PREFIX}_`))
|
|
1375
|
+
return null;
|
|
1376
|
+
return name.slice(COOKIE_PREFIX.length + 1).replace(/\./g, ":");
|
|
1377
|
+
}
|
|
1378
|
+
function maxAgeFromExp(exp) {
|
|
1379
|
+
const THIRTY_DAYS = 30 * 24 * 60 * 60;
|
|
1380
|
+
if (typeof exp !== "number" || !Number.isFinite(exp))
|
|
1381
|
+
return THIRTY_DAYS;
|
|
1382
|
+
const expMs = exp > 1000000000000 ? exp : exp * 1000;
|
|
1383
|
+
const secs = Math.floor((expMs - Date.now()) / 1000);
|
|
1384
|
+
return secs > 0 ? secs : THIRTY_DAYS;
|
|
1385
|
+
}
|
|
1386
|
+
function writeTokenCookie(scopeKey, jwt, exp) {
|
|
1387
|
+
if (!hasDocument())
|
|
1388
|
+
return;
|
|
1389
|
+
const attrs = [
|
|
1390
|
+
"Path=/",
|
|
1391
|
+
"SameSite=Lax",
|
|
1392
|
+
`Max-Age=${maxAgeFromExp(exp)}`
|
|
1393
|
+
];
|
|
1394
|
+
if (isSecureContext())
|
|
1395
|
+
attrs.push("Secure");
|
|
1396
|
+
document.cookie = `${tokenCookieName(scopeKey)}=${encodeURIComponent(jwt)}; ${attrs.join("; ")}`;
|
|
1397
|
+
signalCrossTabChange();
|
|
1398
|
+
}
|
|
1399
|
+
function removeTokenCookie(scopeKey) {
|
|
1400
|
+
if (!hasDocument())
|
|
1401
|
+
return;
|
|
1402
|
+
document.cookie = `${tokenCookieName(scopeKey)}=; Path=/; SameSite=Lax; Max-Age=0`;
|
|
1403
|
+
signalCrossTabChange();
|
|
1404
|
+
}
|
|
1405
|
+
function readAllTokenCookies() {
|
|
1406
|
+
if (!hasDocument() || !document.cookie)
|
|
1407
|
+
return [];
|
|
1408
|
+
const out = [];
|
|
1409
|
+
for (const part of document.cookie.split(";")) {
|
|
1410
|
+
const eq = part.indexOf("=");
|
|
1411
|
+
if (eq < 0)
|
|
1412
|
+
continue;
|
|
1413
|
+
const scopeKey = scopeKeyFromCookieName(part.slice(0, eq).trim());
|
|
1414
|
+
if (scopeKey === null)
|
|
1415
|
+
continue;
|
|
1416
|
+
const jwt = decodeURIComponent(part.slice(eq + 1).trim());
|
|
1417
|
+
if (jwt)
|
|
1418
|
+
out.push({ scopeKey, jwt });
|
|
1419
|
+
}
|
|
1420
|
+
return out;
|
|
1356
1421
|
}
|
|
1357
1422
|
function notifyTokenChange(scope) {
|
|
1358
1423
|
if (typeof window !== "undefined") {
|
|
@@ -1368,24 +1433,21 @@ class AuthAdapter {
|
|
|
1368
1433
|
constructor(options) {
|
|
1369
1434
|
this.namespace = options?.storageNamespace || undefined;
|
|
1370
1435
|
}
|
|
1371
|
-
|
|
1372
|
-
return this.namespace ? `${
|
|
1436
|
+
scopeKey(scope) {
|
|
1437
|
+
return this.namespace ? `${this.namespace}:${scope}` : scope;
|
|
1373
1438
|
}
|
|
1374
1439
|
setToken(token, scope = "default") {
|
|
1375
1440
|
if (!token) {
|
|
1376
1441
|
this.scopes.delete(scope);
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
notifyTokenChange(scope);
|
|
1380
|
-
}
|
|
1442
|
+
removeTokenCookie(this.scopeKey(scope));
|
|
1443
|
+
notifyTokenChange(scope);
|
|
1381
1444
|
return;
|
|
1382
1445
|
}
|
|
1383
1446
|
try {
|
|
1384
1447
|
const parts = token.split(".");
|
|
1385
1448
|
if (parts.length !== 3) {
|
|
1386
1449
|
this.scopes.delete(scope);
|
|
1387
|
-
|
|
1388
|
-
localStorage.removeItem(this.storageKey(scope));
|
|
1450
|
+
removeTokenCookie(this.scopeKey(scope));
|
|
1389
1451
|
return;
|
|
1390
1452
|
}
|
|
1391
1453
|
const payload = JSON.parse(atob(parts[1]));
|
|
@@ -1398,49 +1460,45 @@ class AuthAdapter {
|
|
|
1398
1460
|
exp: payload.exp
|
|
1399
1461
|
}
|
|
1400
1462
|
});
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
notifyTokenChange(scope);
|
|
1404
|
-
}
|
|
1463
|
+
writeTokenCookie(this.scopeKey(scope), token, payload.exp);
|
|
1464
|
+
notifyTokenChange(scope);
|
|
1405
1465
|
} catch {
|
|
1406
1466
|
this.scopes.delete(scope);
|
|
1407
|
-
|
|
1408
|
-
localStorage.removeItem(this.storageKey(scope));
|
|
1467
|
+
removeTokenCookie(this.scopeKey(scope));
|
|
1409
1468
|
}
|
|
1410
1469
|
}
|
|
1411
1470
|
setDecoded(decoded, scope = "default") {
|
|
1412
1471
|
this.scopes.set(scope, { raw: "", decoded });
|
|
1413
1472
|
}
|
|
1414
1473
|
loadPersisted() {
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
if (key?.startsWith(prefix)) {
|
|
1421
|
-
const scope = key.slice(prefix.length);
|
|
1422
|
-
if (!this.namespace && scope.includes(":"))
|
|
1474
|
+
const nsPrefix = this.namespace ? `${this.namespace}:` : "";
|
|
1475
|
+
for (const { scopeKey, jwt } of readAllTokenCookies()) {
|
|
1476
|
+
let scope;
|
|
1477
|
+
if (this.namespace) {
|
|
1478
|
+
if (!scopeKey.startsWith(nsPrefix))
|
|
1423
1479
|
continue;
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
}
|
|
1440
|
-
|
|
1441
|
-
|
|
1480
|
+
scope = scopeKey.slice(nsPrefix.length);
|
|
1481
|
+
} else {
|
|
1482
|
+
if (scopeKey.includes(":"))
|
|
1483
|
+
continue;
|
|
1484
|
+
scope = scopeKey;
|
|
1485
|
+
}
|
|
1486
|
+
try {
|
|
1487
|
+
const parts = jwt.split(".");
|
|
1488
|
+
if (parts.length !== 3)
|
|
1489
|
+
continue;
|
|
1490
|
+
const payload = JSON.parse(atob(parts[1]));
|
|
1491
|
+
this.scopes.set(scope, {
|
|
1492
|
+
raw: jwt,
|
|
1493
|
+
decoded: {
|
|
1494
|
+
tokenName: payload.tokenName,
|
|
1495
|
+
params: payload.params || {},
|
|
1496
|
+
iat: payload.iat,
|
|
1497
|
+
exp: payload.exp
|
|
1442
1498
|
}
|
|
1443
|
-
}
|
|
1499
|
+
});
|
|
1500
|
+
} catch {
|
|
1501
|
+
removeTokenCookie(scopeKey);
|
|
1444
1502
|
}
|
|
1445
1503
|
}
|
|
1446
1504
|
}
|
|
@@ -1472,10 +1530,8 @@ class AuthAdapter {
|
|
|
1472
1530
|
return Array.from(this.scopes.keys());
|
|
1473
1531
|
}
|
|
1474
1532
|
clear() {
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
localStorage.removeItem(this.storageKey(scope));
|
|
1478
|
-
}
|
|
1533
|
+
for (const scope of this.scopes.keys()) {
|
|
1534
|
+
removeTokenCookie(this.scopeKey(scope));
|
|
1479
1535
|
}
|
|
1480
1536
|
this.scopes.clear();
|
|
1481
1537
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcote.tech/arc-adapter-db-postgres",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"postgres": "^3.4.4"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
|
-
"@arcote.tech/arc": "^0.8.
|
|
26
|
+
"@arcote.tech/arc": "^0.8.5"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/pg": "^8.11.0",
|