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