najm-auth 3.4.0 → 4.0.0
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/README.md +93 -47
- package/dist/client/edge.d.ts +15 -2
- package/dist/client/edge.js +25 -7
- package/dist/client/server/index.d.ts +4 -4
- package/dist/client/server/index.js +25 -7
- package/dist/index.d.ts +301 -97
- package/dist/index.js +1208 -762
- package/dist/schema/pg.d.ts +2 -2
- package/dist/schema/sqlite.d.ts +4 -4
- package/package.json +6 -5
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ var __export = (target, all) => {
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
// src/AuthPlugin.ts
|
|
9
|
-
import { Err as
|
|
9
|
+
import { Err as Err16, plugin } from "najm-core";
|
|
10
10
|
import { cache } from "najm-cache";
|
|
11
11
|
|
|
12
12
|
// src/auth.tokens.ts
|
|
@@ -354,6 +354,7 @@ function parseSessionCookiePayload(payload, maxAgeSeconds = DEFAULT_SESSION_MAX_
|
|
|
354
354
|
if (!isRecord(data) || !isValidUser(data.user)) return null;
|
|
355
355
|
if (!isStringArray(data.roles) || !isStringArray(data.permissions)) return null;
|
|
356
356
|
if (!Number.isInteger(data.sessionVersion) || data.sessionVersion < 0) return null;
|
|
357
|
+
if (typeof data.tokenFamily !== "string" || !data.tokenFamily) return null;
|
|
357
358
|
if (!Number.isFinite(data.iat) || !Number.isInteger(data.iat) || data.iat <= 0) return null;
|
|
358
359
|
const issuedAt = data.iat;
|
|
359
360
|
if (issuedAt > now + MAX_CLOCK_SKEW_MS) return null;
|
|
@@ -363,6 +364,7 @@ function parseSessionCookiePayload(payload, maxAgeSeconds = DEFAULT_SESSION_MAX_
|
|
|
363
364
|
roles: [...data.roles],
|
|
364
365
|
permissions: [...data.permissions],
|
|
365
366
|
sessionVersion: data.sessionVersion,
|
|
367
|
+
tokenFamily: data.tokenFamily,
|
|
366
368
|
iat: issuedAt
|
|
367
369
|
};
|
|
368
370
|
} catch {
|
|
@@ -439,8 +441,10 @@ var CookieManager = class CookieManager2 {
|
|
|
439
441
|
// =========================================================================
|
|
440
442
|
/**
|
|
441
443
|
* Write a signed session cookie containing user data, roles, and permissions.
|
|
442
|
-
* The cookie is HMAC-signed with the configured session secret so
|
|
443
|
-
*
|
|
444
|
+
* The cookie is HMAC-signed with the configured session secret, so its claims
|
|
445
|
+
* can be parsed without a database query. Authorization still verifies the
|
|
446
|
+
* session version and positive family liveness; a valid signature alone is
|
|
447
|
+
* never a revocation check. Short TTL (5 min) bounds claim staleness.
|
|
444
448
|
*/
|
|
445
449
|
setSessionCookie(data) {
|
|
446
450
|
const payload = { ...data, iat: Date.now() };
|
|
@@ -486,7 +490,7 @@ import { Get, Post, ResMsg } from "najm-core";
|
|
|
486
490
|
import { Body, User as User2, Headers, Ctx } from "najm-core";
|
|
487
491
|
|
|
488
492
|
// src/auth/AuthService.ts
|
|
489
|
-
import { Injectable as
|
|
493
|
+
import { Injectable as Injectable12, Inject as Inject12 } from "najm-core";
|
|
490
494
|
import { Err as Err12, Log } from "najm-core";
|
|
491
495
|
import { Transaction as Transaction4 } from "najm-database";
|
|
492
496
|
import { I18n as I18n8, I18nService as I18nService2 } from "najm-i18n";
|
|
@@ -494,7 +498,7 @@ import { EmailService, passwordResetTemplate, accountInviteTemplate } from "najm
|
|
|
494
498
|
import { nanoid as nanoid5 } from "nanoid";
|
|
495
499
|
|
|
496
500
|
// src/users/UserService.ts
|
|
497
|
-
import { Injectable as
|
|
501
|
+
import { Injectable as Injectable6, Inject as Inject7 } from "najm-core";
|
|
498
502
|
import { Transaction } from "najm-database";
|
|
499
503
|
import { I18nService } from "najm-i18n";
|
|
500
504
|
import { I18n as I18n4 } from "najm-i18n";
|
|
@@ -674,6 +678,15 @@ var UserRepository = class UserRepository2 {
|
|
|
674
678
|
const [newUser] = await this.db.insert(this.users).values(data).returning();
|
|
675
679
|
return newUser;
|
|
676
680
|
}
|
|
681
|
+
/**
|
|
682
|
+
* Ids of everyone holding a role. Used to end sessions when the role's
|
|
683
|
+
* permission set changes: tokens carry permissions as claims, so the holders
|
|
684
|
+
* keep exercising the old set until their sessions do.
|
|
685
|
+
*/
|
|
686
|
+
async getIdsByRole(roleId) {
|
|
687
|
+
const rows = await this.db.select({ id: this.users.id }).from(this.users).where(eq2(this.users.roleId, roleId));
|
|
688
|
+
return rows.map((row) => row.id);
|
|
689
|
+
}
|
|
677
690
|
async update(id, data) {
|
|
678
691
|
const [updatedUser] = await this.db.update(this.users).set(data).where(eq2(this.users.id, id)).returning();
|
|
679
692
|
return updatedUser;
|
|
@@ -1334,6 +1347,16 @@ __name(isEmailIdentifier, "isEmailIdentifier");
|
|
|
1334
1347
|
|
|
1335
1348
|
// src/users/UserService.ts
|
|
1336
1349
|
import { Err as Err5 } from "najm-core";
|
|
1350
|
+
|
|
1351
|
+
// src/tokens/SessionInvalidationService.ts
|
|
1352
|
+
import { Inject as Inject6, Injectable as Injectable5 } from "najm-core";
|
|
1353
|
+
import { CacheService } from "najm-cache";
|
|
1354
|
+
import timestring2 from "timestring";
|
|
1355
|
+
|
|
1356
|
+
// src/tokens/TokenRepository.ts
|
|
1357
|
+
import { and, eq as eq4, isNull, lt } from "drizzle-orm";
|
|
1358
|
+
import { Repository as Repository3, Inject as Inject5 } from "najm-core";
|
|
1359
|
+
import { DB as DB3 } from "najm-database";
|
|
1337
1360
|
var __decorate8 = function(decorators, target, key, desc) {
|
|
1338
1361
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1339
1362
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -1343,19 +1366,383 @@ var __decorate8 = function(decorators, target, key, desc) {
|
|
|
1343
1366
|
var __metadata8 = function(k, v) {
|
|
1344
1367
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1345
1368
|
};
|
|
1369
|
+
var TokenRepository = class TokenRepository2 {
|
|
1370
|
+
static {
|
|
1371
|
+
__name(this, "TokenRepository");
|
|
1372
|
+
}
|
|
1373
|
+
db;
|
|
1374
|
+
schema;
|
|
1375
|
+
get tokens() {
|
|
1376
|
+
return this.schema.tokens;
|
|
1377
|
+
}
|
|
1378
|
+
get users() {
|
|
1379
|
+
return this.schema.users;
|
|
1380
|
+
}
|
|
1381
|
+
/** Shared query helper, scoped to the current database/transaction identity. */
|
|
1382
|
+
queryHelper;
|
|
1383
|
+
get q() {
|
|
1384
|
+
const db = this.db;
|
|
1385
|
+
if (this.queryHelper?.db !== db) {
|
|
1386
|
+
this.queryHelper = { db, queries: new AuthQueries(db, this.schema) };
|
|
1387
|
+
}
|
|
1388
|
+
return this.queryHelper.queries;
|
|
1389
|
+
}
|
|
1390
|
+
/**
|
|
1391
|
+
* Upsert the refresh-token row for a session, keyed on `tokenFamily` (the
|
|
1392
|
+
* per-login session identifier, unique). A brand-new login inserts a fresh
|
|
1393
|
+
* family row; a refresh rotation updates only that family's row, leaving the
|
|
1394
|
+
* user's other sessions untouched.
|
|
1395
|
+
*/
|
|
1396
|
+
async storeRefreshToken(tokenData) {
|
|
1397
|
+
return await this.db.insert(this.tokens).values(tokenData).onConflictDoUpdate({
|
|
1398
|
+
target: this.tokens.tokenFamily,
|
|
1399
|
+
set: {
|
|
1400
|
+
token: tokenData.token,
|
|
1401
|
+
expiresAt: tokenData.expiresAt,
|
|
1402
|
+
previousHash: tokenData.previousHash ?? null,
|
|
1403
|
+
previousValidUntil: tokenData.previousValidUntil ?? null,
|
|
1404
|
+
previousUsedAt: tokenData.previousUsedAt ?? null
|
|
1405
|
+
},
|
|
1406
|
+
// A revoked family is a durable tombstone. It must never be revived by
|
|
1407
|
+
// an issuance racing with logout, or after the cache markers are lost.
|
|
1408
|
+
setWhere: and(eq4(this.tokens.status, "active"), eq4(this.tokens.userId, tokenData.userId))
|
|
1409
|
+
}).returning();
|
|
1410
|
+
}
|
|
1411
|
+
/**
|
|
1412
|
+
* Rotate an existing refresh-token family with compare-and-swap semantics.
|
|
1413
|
+
* This can never update a family durably revoked by a concurrent logout.
|
|
1414
|
+
*/
|
|
1415
|
+
async rotateRefreshToken(tokenData, expectedCurrentHash) {
|
|
1416
|
+
return await this.db.update(this.tokens).set({
|
|
1417
|
+
token: tokenData.token,
|
|
1418
|
+
expiresAt: tokenData.expiresAt,
|
|
1419
|
+
previousHash: tokenData.previousHash,
|
|
1420
|
+
previousValidUntil: tokenData.previousValidUntil,
|
|
1421
|
+
previousUsedAt: tokenData.previousUsedAt ?? null
|
|
1422
|
+
}).where(and(eq4(this.tokens.tokenFamily, tokenData.tokenFamily), eq4(this.tokens.userId, tokenData.userId), eq4(this.tokens.token, expectedCurrentHash), eq4(this.tokens.status, "active"))).returning();
|
|
1423
|
+
}
|
|
1424
|
+
/**
|
|
1425
|
+
* Claim the previous-token grace slot for a single family. Conditional on
|
|
1426
|
+
* BOTH the stored previousHash still matching the presented token AND
|
|
1427
|
+
* previousUsedAt being NULL. Gating on the hash (not just the flag) closes
|
|
1428
|
+
* the rotation race: the winner's rotation rewrites previousHash via
|
|
1429
|
+
* storeRefreshToken (and resets previousUsedAt to NULL), so a loser whose
|
|
1430
|
+
* UPDATE lands after that rotation no longer matches and gets zero rows —
|
|
1431
|
+
* exactly one caller ever claims the slot.
|
|
1432
|
+
*/
|
|
1433
|
+
async markPreviousUsed(tokenFamily, previousHash) {
|
|
1434
|
+
return await this.db.update(this.tokens).set({ previousUsedAt: (/* @__PURE__ */ new Date()).toISOString() }).where(and(eq4(this.tokens.tokenFamily, tokenFamily), eq4(this.tokens.previousHash, previousHash), isNull(this.tokens.previousUsedAt), eq4(this.tokens.status, "active"))).returning();
|
|
1435
|
+
}
|
|
1436
|
+
/** Look up a single session's token row by its family identifier. */
|
|
1437
|
+
async getByFamily(tokenFamily) {
|
|
1438
|
+
const [token] = await this.db.select().from(this.tokens).where(and(eq4(this.tokens.tokenFamily, tokenFamily), eq4(this.tokens.status, "active")));
|
|
1439
|
+
return token ?? null;
|
|
1440
|
+
}
|
|
1441
|
+
/**
|
|
1442
|
+
* Durably revoke one family without depending on physical deletion.
|
|
1443
|
+
*
|
|
1444
|
+
* The row remains as a tombstone until its original refresh expiry. This is
|
|
1445
|
+
* what prevents a later cache loss from turning a failed/omitted cleanup
|
|
1446
|
+
* delete into a valid database-backed recovery session.
|
|
1447
|
+
*/
|
|
1448
|
+
async revokeFamily(tokenFamily) {
|
|
1449
|
+
return this.db.update(this.tokens).set({
|
|
1450
|
+
status: "revoked",
|
|
1451
|
+
previousHash: null,
|
|
1452
|
+
previousValidUntil: null,
|
|
1453
|
+
previousUsedAt: null
|
|
1454
|
+
}).where(and(eq4(this.tokens.tokenFamily, tokenFamily), eq4(this.tokens.status, "active"))).returning();
|
|
1455
|
+
}
|
|
1456
|
+
/** Durably revoke every active family for a user. */
|
|
1457
|
+
async revokeAllForUser(userId) {
|
|
1458
|
+
return this.db.update(this.tokens).set({
|
|
1459
|
+
status: "revoked",
|
|
1460
|
+
previousHash: null,
|
|
1461
|
+
previousValidUntil: null,
|
|
1462
|
+
previousUsedAt: null
|
|
1463
|
+
}).where(and(eq4(this.tokens.userId, userId), eq4(this.tokens.status, "active"))).returning();
|
|
1464
|
+
}
|
|
1465
|
+
/**
|
|
1466
|
+
* Opportunistic cleanup: with one row per family (no unique userId), expired
|
|
1467
|
+
* and abandoned sessions accumulate. Delete every expired row.
|
|
1468
|
+
*/
|
|
1469
|
+
async deleteExpired() {
|
|
1470
|
+
return this.db.delete(this.tokens).where(lt(this.tokens.expiresAt, (/* @__PURE__ */ new Date()).toISOString())).returning();
|
|
1471
|
+
}
|
|
1472
|
+
async isUserExists(userId) {
|
|
1473
|
+
const [user] = await this.db.select({ id: this.users.id }).from(this.users).where(eq4(this.users.id, userId)).limit(1);
|
|
1474
|
+
return !!user;
|
|
1475
|
+
}
|
|
1476
|
+
async getRoleNameById(userId) {
|
|
1477
|
+
return this.q.getRoleName(userId);
|
|
1478
|
+
}
|
|
1479
|
+
async getUserPermissions(userId) {
|
|
1480
|
+
return this.q.getUserPermissions(userId);
|
|
1481
|
+
}
|
|
1482
|
+
async getRoleAndPermissions(userId) {
|
|
1483
|
+
return this.q.getRoleAndPermissions(userId);
|
|
1484
|
+
}
|
|
1485
|
+
async getUser(userId) {
|
|
1486
|
+
return await this.q.getUserWithPermissions(eq4(this.users.id, userId)) ?? null;
|
|
1487
|
+
}
|
|
1488
|
+
};
|
|
1489
|
+
__decorate8([
|
|
1490
|
+
DB3(),
|
|
1491
|
+
__metadata8("design:type", Object)
|
|
1492
|
+
], TokenRepository.prototype, "db", void 0);
|
|
1493
|
+
__decorate8([
|
|
1494
|
+
Inject5(AUTH_SCHEMA),
|
|
1495
|
+
__metadata8("design:type", Object)
|
|
1496
|
+
], TokenRepository.prototype, "schema", void 0);
|
|
1497
|
+
TokenRepository = __decorate8([
|
|
1498
|
+
Repository3()
|
|
1499
|
+
], TokenRepository);
|
|
1500
|
+
|
|
1501
|
+
// src/tokens/SessionInvalidationService.ts
|
|
1502
|
+
var __decorate9 = function(decorators, target, key, desc) {
|
|
1503
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1504
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1505
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1506
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1507
|
+
};
|
|
1508
|
+
var __metadata9 = function(k, v) {
|
|
1509
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1510
|
+
};
|
|
1511
|
+
var SessionInvalidationService_1;
|
|
1512
|
+
var _a5;
|
|
1513
|
+
var _b3;
|
|
1514
|
+
var SessionInvalidationService = class SessionInvalidationService2 {
|
|
1515
|
+
static {
|
|
1516
|
+
__name(this, "SessionInvalidationService");
|
|
1517
|
+
}
|
|
1518
|
+
static {
|
|
1519
|
+
SessionInvalidationService_1 = this;
|
|
1520
|
+
}
|
|
1521
|
+
cache;
|
|
1522
|
+
tokens;
|
|
1523
|
+
config;
|
|
1524
|
+
constructor(cache2, tokens) {
|
|
1525
|
+
this.cache = cache2;
|
|
1526
|
+
this.tokens = tokens;
|
|
1527
|
+
}
|
|
1528
|
+
/**
|
|
1529
|
+
* Fields whose change ends existing sessions. Everything absent from this set
|
|
1530
|
+
* — display name, avatar, language — is a profile edit and must leave the
|
|
1531
|
+
* user signed in, on every device.
|
|
1532
|
+
*/
|
|
1533
|
+
static SECURITY_FIELDS = Object.freeze([
|
|
1534
|
+
"password",
|
|
1535
|
+
"status",
|
|
1536
|
+
"role",
|
|
1537
|
+
"roleId",
|
|
1538
|
+
"email",
|
|
1539
|
+
"emailVerified",
|
|
1540
|
+
"phone"
|
|
1541
|
+
]);
|
|
1542
|
+
/** Whether an update payload touches anything that must end sessions. */
|
|
1543
|
+
static affectsSecurityState(data) {
|
|
1544
|
+
if (!data)
|
|
1545
|
+
return false;
|
|
1546
|
+
return SessionInvalidationService_1.SECURITY_FIELDS.some((field) => data[field] !== void 0);
|
|
1547
|
+
}
|
|
1548
|
+
get accessTokenTtlMs() {
|
|
1549
|
+
return timestring2(this.config.jwt.accessExpiresIn, "ms");
|
|
1550
|
+
}
|
|
1551
|
+
get refreshTokenTtlMs() {
|
|
1552
|
+
return timestring2(this.config.jwt.refreshExpiresIn, "ms");
|
|
1553
|
+
}
|
|
1554
|
+
sessionVersionKey(userId) {
|
|
1555
|
+
return `auth:session-version:${userId}`;
|
|
1556
|
+
}
|
|
1557
|
+
revokedFamilyKey(tokenFamily) {
|
|
1558
|
+
return `auth:revoked-family:${tokenFamily}`;
|
|
1559
|
+
}
|
|
1560
|
+
/**
|
|
1561
|
+
* Positive liveness marker for one session family.
|
|
1562
|
+
*
|
|
1563
|
+
* The signed session snapshot is authorized against this rather than against
|
|
1564
|
+
* the absence of a revocation marker, so losing the cache cannot make a
|
|
1565
|
+
* logged-out family look valid again: with no marker the fast path simply
|
|
1566
|
+
* declines and the request falls through to the database-backed resolver.
|
|
1567
|
+
*/
|
|
1568
|
+
familyKey(tokenFamily) {
|
|
1569
|
+
return `auth:family:${tokenFamily}`;
|
|
1570
|
+
}
|
|
1571
|
+
userCacheKey(userId) {
|
|
1572
|
+
return `auth:user:${userId}`;
|
|
1573
|
+
}
|
|
1574
|
+
parseSessionVersion(raw) {
|
|
1575
|
+
if (!raw)
|
|
1576
|
+
return 0;
|
|
1577
|
+
const parsed = Number(raw);
|
|
1578
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
|
|
1579
|
+
}
|
|
1580
|
+
async getSessionVersion(userId) {
|
|
1581
|
+
return this.parseSessionVersion(await this.cache.get(this.sessionVersionKey(userId)));
|
|
1582
|
+
}
|
|
1583
|
+
/**
|
|
1584
|
+
* Extend the version key's lifetime without rewriting its value.
|
|
1585
|
+
*
|
|
1586
|
+
* Token issuance used to `set()` the version it had just read, which meant an
|
|
1587
|
+
* invalidation landing between that read and that write was silently undone —
|
|
1588
|
+
* the revoked version came back and the old tokens verified again. Only the
|
|
1589
|
+
* expiry is touched here, so a concurrent bump always survives.
|
|
1590
|
+
*/
|
|
1591
|
+
async touchSessionVersion(userId) {
|
|
1592
|
+
await this.cache.expire(this.sessionVersionKey(userId), this.accessTokenTtlMs);
|
|
1593
|
+
}
|
|
1594
|
+
/**
|
|
1595
|
+
* Invalidate every access token already issued for a user, and drop the
|
|
1596
|
+
* cached user record so the next read sees the new state rather than a stale
|
|
1597
|
+
* snapshot that is merely truthy.
|
|
1598
|
+
*
|
|
1599
|
+
* The bump is an atomic increment, so concurrent invalidations cannot read
|
|
1600
|
+
* the same version and write the same successor back.
|
|
1601
|
+
*/
|
|
1602
|
+
async invalidateAccessTokens(userId) {
|
|
1603
|
+
const key = this.sessionVersionKey(userId);
|
|
1604
|
+
const { count } = await this.cache.incr(key, this.accessTokenTtlMs);
|
|
1605
|
+
await this.cache.expire(key, this.accessTokenTtlMs);
|
|
1606
|
+
await this.dropUserCache(userId);
|
|
1607
|
+
return count;
|
|
1608
|
+
}
|
|
1609
|
+
async dropUserCache(userId) {
|
|
1610
|
+
await this.cache.del(this.userCacheKey(userId));
|
|
1611
|
+
}
|
|
1612
|
+
/**
|
|
1613
|
+
* End every session a user holds: access tokens by version, refresh sessions
|
|
1614
|
+
* by row, and each family's liveness marker.
|
|
1615
|
+
*
|
|
1616
|
+
* Callers run this AFTER their database mutation has committed. Running it
|
|
1617
|
+
* before would leave a window in which a concurrent login re-established a
|
|
1618
|
+
* session against the state the mutation was about to remove; running it
|
|
1619
|
+
* after a rollback merely signs the user out again, which is safe.
|
|
1620
|
+
*/
|
|
1621
|
+
async invalidateUser(userId) {
|
|
1622
|
+
await this.invalidateAccessTokens(userId);
|
|
1623
|
+
const revoked = await this.tokens.revokeAllForUser(userId);
|
|
1624
|
+
await Promise.all(familiesOf(revoked).map((family) => this.markFamilyRevoked(family)));
|
|
1625
|
+
}
|
|
1626
|
+
/**
|
|
1627
|
+
* Record that a family is live, and whose it is. Called wherever the family's
|
|
1628
|
+
* refresh row is written.
|
|
1629
|
+
*
|
|
1630
|
+
* The marker stores the owning user rather than a bare flag so a reader can
|
|
1631
|
+
* confirm, in the same single lookup, that the family it was handed actually
|
|
1632
|
+
* belongs to the identity claiming it.
|
|
1633
|
+
*
|
|
1634
|
+
* Revocation always wins. A refresh that rotated its row, was descheduled,
|
|
1635
|
+
* and resumed after a logout would otherwise re-mark its family live and
|
|
1636
|
+
* hand the browser back the session it had just ended — the database row is
|
|
1637
|
+
* gone by then, but nothing on the fast path reads the database. So this
|
|
1638
|
+
* writes, then re-reads the revocation marker and withdraws the write if one
|
|
1639
|
+
* appeared. Combined with `markFamilyRevoked` setting the revocation marker
|
|
1640
|
+
* *before* clearing liveness, every interleaving of the two converges on
|
|
1641
|
+
* revoked: whichever of the pair observes the other, the liveness key ends
|
|
1642
|
+
* up deleted.
|
|
1643
|
+
*
|
|
1644
|
+
* @returns whether the family is live after this call.
|
|
1645
|
+
*/
|
|
1646
|
+
async markFamilyIssued(tokenFamily, userId) {
|
|
1647
|
+
await this.cache.set(this.familyKey(tokenFamily), userId, this.refreshTokenTtlMs);
|
|
1648
|
+
if (await this.isFamilyRevoked(tokenFamily)) {
|
|
1649
|
+
await this.cache.del(this.familyKey(tokenFamily));
|
|
1650
|
+
return false;
|
|
1651
|
+
}
|
|
1652
|
+
return true;
|
|
1653
|
+
}
|
|
1654
|
+
/**
|
|
1655
|
+
* What one lookup can say about a family, in a single batched cache read.
|
|
1656
|
+
*
|
|
1657
|
+
* The three answers are deliberately distinct. `revoked` is authoritative and
|
|
1658
|
+
* must deny. `unknown` means the cache cannot vouch for the family — it was
|
|
1659
|
+
* evicted, or the cache was lost — and must send the caller to an
|
|
1660
|
+
* authoritative, database-backed check rather than being read either way.
|
|
1661
|
+
* Only `live` is a positive assertion, and only for the named user.
|
|
1662
|
+
*/
|
|
1663
|
+
async familyStatus(tokenFamily, userId) {
|
|
1664
|
+
if (!tokenFamily)
|
|
1665
|
+
return "unknown";
|
|
1666
|
+
const [owner, revoked] = await this.readMany([
|
|
1667
|
+
this.familyKey(tokenFamily),
|
|
1668
|
+
this.revokedFamilyKey(tokenFamily)
|
|
1669
|
+
]);
|
|
1670
|
+
if (revoked != null)
|
|
1671
|
+
return "revoked";
|
|
1672
|
+
if (owner == null)
|
|
1673
|
+
return "unknown";
|
|
1674
|
+
if (userId !== void 0 && owner !== userId)
|
|
1675
|
+
return "revoked";
|
|
1676
|
+
return "live";
|
|
1677
|
+
}
|
|
1678
|
+
/**
|
|
1679
|
+
* Whether a family is positively known to be live, and — when a user is
|
|
1680
|
+
* given — to belong to that user.
|
|
1681
|
+
*
|
|
1682
|
+
* `false` means "not proven live" — revoked, mismatched, or simply not in
|
|
1683
|
+
* cache. Callers must treat it as a reason to fall back to an authoritative
|
|
1684
|
+
* check, never as proof of validity in the other direction.
|
|
1685
|
+
*/
|
|
1686
|
+
async isFamilyLive(tokenFamily, userId) {
|
|
1687
|
+
return await this.familyStatus(tokenFamily, userId) === "live";
|
|
1688
|
+
}
|
|
1689
|
+
async readMany(keys) {
|
|
1690
|
+
const cache2 = this.cache;
|
|
1691
|
+
if (cache2.getMany)
|
|
1692
|
+
return cache2.getMany(keys);
|
|
1693
|
+
return Promise.all(keys.map((key) => cache2.get(key)));
|
|
1694
|
+
}
|
|
1695
|
+
/**
|
|
1696
|
+
* Keep revocation through both credential lifetimes. If deleting the refresh
|
|
1697
|
+
* row fails, its still-valid cookie must remain denied after access expires.
|
|
1698
|
+
*/
|
|
1699
|
+
async markFamilyRevoked(tokenFamily) {
|
|
1700
|
+
await this.cache.set(this.revokedFamilyKey(tokenFamily), "1", Math.max(this.accessTokenTtlMs, this.refreshTokenTtlMs));
|
|
1701
|
+
await this.cache.del(this.familyKey(tokenFamily));
|
|
1702
|
+
}
|
|
1703
|
+
async isFamilyRevoked(tokenFamily) {
|
|
1704
|
+
return await this.cache.get(this.revokedFamilyKey(tokenFamily)) !== null;
|
|
1705
|
+
}
|
|
1706
|
+
};
|
|
1707
|
+
__decorate9([
|
|
1708
|
+
Inject6(AUTH_CONFIG),
|
|
1709
|
+
__metadata9("design:type", Object)
|
|
1710
|
+
], SessionInvalidationService.prototype, "config", void 0);
|
|
1711
|
+
SessionInvalidationService = SessionInvalidationService_1 = __decorate9([
|
|
1712
|
+
Injectable5(),
|
|
1713
|
+
__metadata9("design:paramtypes", [typeof (_a5 = typeof CacheService !== "undefined" && CacheService) === "function" ? _a5 : Object, typeof (_b3 = typeof TokenRepository !== "undefined" && TokenRepository) === "function" ? _b3 : Object])
|
|
1714
|
+
], SessionInvalidationService);
|
|
1715
|
+
function familiesOf(rows) {
|
|
1716
|
+
if (!Array.isArray(rows))
|
|
1717
|
+
return [];
|
|
1718
|
+
return rows.map((row) => row?.tokenFamily).filter((family) => typeof family === "string" && family.length > 0);
|
|
1719
|
+
}
|
|
1720
|
+
__name(familiesOf, "familiesOf");
|
|
1721
|
+
|
|
1722
|
+
// src/users/UserService.ts
|
|
1723
|
+
var __decorate10 = function(decorators, target, key, desc) {
|
|
1724
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1725
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1726
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1727
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1728
|
+
};
|
|
1729
|
+
var __metadata10 = function(k, v) {
|
|
1730
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1731
|
+
};
|
|
1346
1732
|
var __param2 = function(paramIndex, decorator) {
|
|
1347
1733
|
return function(target, key) {
|
|
1348
1734
|
decorator(target, key, paramIndex);
|
|
1349
1735
|
};
|
|
1350
1736
|
};
|
|
1351
|
-
var
|
|
1352
|
-
var
|
|
1737
|
+
var _a6;
|
|
1738
|
+
var _b4;
|
|
1353
1739
|
var _c;
|
|
1354
1740
|
var _d;
|
|
1355
1741
|
var _e;
|
|
1356
1742
|
var _f;
|
|
1357
1743
|
var _g;
|
|
1358
1744
|
var _h;
|
|
1745
|
+
var _j;
|
|
1359
1746
|
var E164_PHONE = /^\+[1-9]\d{7,14}$/;
|
|
1360
1747
|
var UserService = class UserService2 {
|
|
1361
1748
|
static {
|
|
@@ -1368,8 +1755,9 @@ var UserService = class UserService2 {
|
|
|
1368
1755
|
encryptionService;
|
|
1369
1756
|
i18nService;
|
|
1370
1757
|
authConfig;
|
|
1758
|
+
sessionInvalidation;
|
|
1371
1759
|
t;
|
|
1372
|
-
constructor(roleValidator, roleService, userRepository, userValidator, encryptionService, i18nService, authConfig) {
|
|
1760
|
+
constructor(roleValidator, roleService, userRepository, userValidator, encryptionService, i18nService, authConfig, sessionInvalidation) {
|
|
1373
1761
|
this.roleValidator = roleValidator;
|
|
1374
1762
|
this.roleService = roleService;
|
|
1375
1763
|
this.userRepository = userRepository;
|
|
@@ -1377,6 +1765,19 @@ var UserService = class UserService2 {
|
|
|
1377
1765
|
this.encryptionService = encryptionService;
|
|
1378
1766
|
this.i18nService = i18nService;
|
|
1379
1767
|
this.authConfig = authConfig;
|
|
1768
|
+
this.sessionInvalidation = sessionInvalidation;
|
|
1769
|
+
}
|
|
1770
|
+
/**
|
|
1771
|
+
* End the user's sessions after a security-relevant mutation has committed.
|
|
1772
|
+
*
|
|
1773
|
+
* Deactivating, deleting, or re-roling an account through the generic
|
|
1774
|
+
* endpoints used to leave every already-issued token working until it
|
|
1775
|
+
* expired. Invalidation belongs here, next to the write, so no caller can
|
|
1776
|
+
* forget it — the application-level commands that already revoke keep doing
|
|
1777
|
+
* so, and a second call is harmless.
|
|
1778
|
+
*/
|
|
1779
|
+
async invalidateSessions(userId) {
|
|
1780
|
+
await this.sessionInvalidation?.invalidateUser(userId);
|
|
1380
1781
|
}
|
|
1381
1782
|
sanitizeUser(user) {
|
|
1382
1783
|
if (!user)
|
|
@@ -1494,15 +1895,23 @@ var UserService = class UserService2 {
|
|
|
1494
1895
|
};
|
|
1495
1896
|
const cleanedUpdateData = clean(updateData);
|
|
1496
1897
|
const updatedUser = await this.userRepository.update(id, cleanedUpdateData);
|
|
1497
|
-
|
|
1898
|
+
const result = this.sanitizeUser(this.requireUser(updatedUser));
|
|
1899
|
+
if (SessionInvalidationService.affectsSecurityState(cleanedUpdateData)) {
|
|
1900
|
+
await this.invalidateSessions(id);
|
|
1901
|
+
}
|
|
1902
|
+
return result;
|
|
1498
1903
|
}
|
|
1499
1904
|
async delete(id) {
|
|
1500
1905
|
const user = await this.userRepository.delete(id);
|
|
1501
|
-
|
|
1906
|
+
const result = this.sanitizeUser(this.requireUser(user));
|
|
1907
|
+
await this.invalidateSessions(id);
|
|
1908
|
+
return result;
|
|
1502
1909
|
}
|
|
1503
1910
|
async deleteAll() {
|
|
1504
1911
|
const deletedUsers = await this.userRepository.deleteAll();
|
|
1505
|
-
|
|
1912
|
+
const result = this.sanitizeUsers(deletedUsers);
|
|
1913
|
+
await Promise.all(result.map((user) => this.invalidateSessions(user.id)));
|
|
1914
|
+
return result;
|
|
1506
1915
|
}
|
|
1507
1916
|
async getRoleName(id) {
|
|
1508
1917
|
await this.userValidator.checkUserExists(id);
|
|
@@ -1524,11 +1933,15 @@ var UserService = class UserService2 {
|
|
|
1524
1933
|
async assignRole(id, roleId, roleName) {
|
|
1525
1934
|
const resolvedRoleId = await this.resolveUserRole(roleId, roleName);
|
|
1526
1935
|
const updatedUser = await this.userRepository.update(id, { roleId: resolvedRoleId });
|
|
1527
|
-
|
|
1936
|
+
const result = this.sanitizeUser(this.requireUser(updatedUser));
|
|
1937
|
+
await this.invalidateSessions(id);
|
|
1938
|
+
return result;
|
|
1528
1939
|
}
|
|
1529
1940
|
async removeRole(id) {
|
|
1530
1941
|
const updatedUser = await this.userRepository.update(id, { roleId: null });
|
|
1531
|
-
|
|
1942
|
+
const result = this.sanitizeUser(this.requireUser(updatedUser));
|
|
1943
|
+
await this.invalidateSessions(id);
|
|
1944
|
+
return result;
|
|
1532
1945
|
}
|
|
1533
1946
|
async seedAdminUser(config) {
|
|
1534
1947
|
if (!config?.email || !config?.password) {
|
|
@@ -1563,170 +1976,42 @@ var UserService = class UserService2 {
|
|
|
1563
1976
|
return this.i18nService.getCurrentLanguage();
|
|
1564
1977
|
}
|
|
1565
1978
|
};
|
|
1566
|
-
|
|
1979
|
+
__decorate10([
|
|
1567
1980
|
I18n4("users"),
|
|
1568
|
-
|
|
1981
|
+
__metadata10("design:type", Object)
|
|
1569
1982
|
], UserService.prototype, "t", void 0);
|
|
1570
|
-
|
|
1983
|
+
__decorate10([
|
|
1571
1984
|
Transaction(),
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1985
|
+
__metadata10("design:type", Function),
|
|
1986
|
+
__metadata10("design:paramtypes", [typeof (_h = typeof Record !== "undefined" && Record) === "function" ? _h : Object, Object]),
|
|
1987
|
+
__metadata10("design:returntype", typeof (_j = typeof Promise !== "undefined" && Promise) === "function" ? _j : Object)
|
|
1575
1988
|
], UserService.prototype, "create", null);
|
|
1576
|
-
UserService =
|
|
1577
|
-
|
|
1578
|
-
__param2(6,
|
|
1579
|
-
|
|
1989
|
+
UserService = __decorate10([
|
|
1990
|
+
Injectable6(),
|
|
1991
|
+
__param2(6, Inject7(AUTH_CONFIG)),
|
|
1992
|
+
__metadata10("design:paramtypes", [typeof (_a6 = typeof RoleValidator !== "undefined" && RoleValidator) === "function" ? _a6 : Object, typeof (_b4 = typeof RoleService !== "undefined" && RoleService) === "function" ? _b4 : Object, typeof (_c = typeof UserRepository !== "undefined" && UserRepository) === "function" ? _c : Object, typeof (_d = typeof UserValidator !== "undefined" && UserValidator) === "function" ? _d : Object, typeof (_e = typeof EncryptionService !== "undefined" && EncryptionService) === "function" ? _e : Object, typeof (_f = typeof I18nService !== "undefined" && I18nService) === "function" ? _f : Object, Object, typeof (_g = typeof SessionInvalidationService !== "undefined" && SessionInvalidationService) === "function" ? _g : Object])
|
|
1580
1993
|
], UserService);
|
|
1581
1994
|
|
|
1582
1995
|
// src/tokens/TokenService.ts
|
|
1583
|
-
import { Injectable as
|
|
1996
|
+
import { Injectable as Injectable7, Inject as Inject9 } from "najm-core";
|
|
1584
1997
|
import { I18n as I18n5 } from "najm-i18n";
|
|
1585
|
-
import { CacheService } from "najm-cache";
|
|
1998
|
+
import { CacheService as CacheService2 } from "najm-cache";
|
|
1586
1999
|
import { createHash } from "crypto";
|
|
1587
2000
|
import jwt from "jsonwebtoken";
|
|
1588
2001
|
import { nanoid as nanoid4 } from "nanoid";
|
|
1589
|
-
|
|
1590
|
-
// src/tokens/TokenRepository.ts
|
|
1591
|
-
import { and, eq as eq4, isNull, lt } from "drizzle-orm";
|
|
1592
|
-
import { Repository as Repository3, Inject as Inject6 } from "najm-core";
|
|
1593
|
-
import { DB as DB3 } from "najm-database";
|
|
1594
|
-
var __decorate9 = function(decorators, target, key, desc) {
|
|
1595
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1596
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1597
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1598
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1599
|
-
};
|
|
1600
|
-
var __metadata9 = function(k, v) {
|
|
1601
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1602
|
-
};
|
|
1603
|
-
var TokenRepository = class TokenRepository2 {
|
|
1604
|
-
static {
|
|
1605
|
-
__name(this, "TokenRepository");
|
|
1606
|
-
}
|
|
1607
|
-
db;
|
|
1608
|
-
schema;
|
|
1609
|
-
get tokens() {
|
|
1610
|
-
return this.schema.tokens;
|
|
1611
|
-
}
|
|
1612
|
-
get users() {
|
|
1613
|
-
return this.schema.users;
|
|
1614
|
-
}
|
|
1615
|
-
/** Shared query helper, scoped to the current database/transaction identity. */
|
|
1616
|
-
queryHelper;
|
|
1617
|
-
get q() {
|
|
1618
|
-
const db = this.db;
|
|
1619
|
-
if (this.queryHelper?.db !== db) {
|
|
1620
|
-
this.queryHelper = { db, queries: new AuthQueries(db, this.schema) };
|
|
1621
|
-
}
|
|
1622
|
-
return this.queryHelper.queries;
|
|
1623
|
-
}
|
|
1624
|
-
/**
|
|
1625
|
-
* Upsert the refresh-token row for a session, keyed on `tokenFamily` (the
|
|
1626
|
-
* per-login session identifier, unique). A brand-new login inserts a fresh
|
|
1627
|
-
* family row; a refresh rotation updates only that family's row, leaving the
|
|
1628
|
-
* user's other sessions untouched.
|
|
1629
|
-
*/
|
|
1630
|
-
async storeRefreshToken(tokenData) {
|
|
1631
|
-
return await this.db.insert(this.tokens).values(tokenData).onConflictDoUpdate({
|
|
1632
|
-
target: this.tokens.tokenFamily,
|
|
1633
|
-
set: {
|
|
1634
|
-
token: tokenData.token,
|
|
1635
|
-
expiresAt: tokenData.expiresAt,
|
|
1636
|
-
previousHash: tokenData.previousHash ?? null,
|
|
1637
|
-
previousValidUntil: tokenData.previousValidUntil ?? null,
|
|
1638
|
-
previousUsedAt: tokenData.previousUsedAt ?? null
|
|
1639
|
-
}
|
|
1640
|
-
}).returning();
|
|
1641
|
-
}
|
|
1642
|
-
/**
|
|
1643
|
-
* Rotate an existing refresh-token family with compare-and-swap semantics.
|
|
1644
|
-
* This can never insert a family deleted by a concurrent logout.
|
|
1645
|
-
*/
|
|
1646
|
-
async rotateRefreshToken(tokenData, expectedCurrentHash) {
|
|
1647
|
-
return await this.db.update(this.tokens).set({
|
|
1648
|
-
token: tokenData.token,
|
|
1649
|
-
expiresAt: tokenData.expiresAt,
|
|
1650
|
-
previousHash: tokenData.previousHash,
|
|
1651
|
-
previousValidUntil: tokenData.previousValidUntil,
|
|
1652
|
-
previousUsedAt: tokenData.previousUsedAt ?? null
|
|
1653
|
-
}).where(and(eq4(this.tokens.tokenFamily, tokenData.tokenFamily), eq4(this.tokens.userId, tokenData.userId), eq4(this.tokens.token, expectedCurrentHash))).returning();
|
|
1654
|
-
}
|
|
1655
|
-
/**
|
|
1656
|
-
* Claim the previous-token grace slot for a single family. Conditional on
|
|
1657
|
-
* BOTH the stored previousHash still matching the presented token AND
|
|
1658
|
-
* previousUsedAt being NULL. Gating on the hash (not just the flag) closes
|
|
1659
|
-
* the rotation race: the winner's rotation rewrites previousHash via
|
|
1660
|
-
* storeRefreshToken (and resets previousUsedAt to NULL), so a loser whose
|
|
1661
|
-
* UPDATE lands after that rotation no longer matches and gets zero rows —
|
|
1662
|
-
* exactly one caller ever claims the slot.
|
|
1663
|
-
*/
|
|
1664
|
-
async markPreviousUsed(tokenFamily, previousHash) {
|
|
1665
|
-
return await this.db.update(this.tokens).set({ previousUsedAt: (/* @__PURE__ */ new Date()).toISOString() }).where(and(eq4(this.tokens.tokenFamily, tokenFamily), eq4(this.tokens.previousHash, previousHash), isNull(this.tokens.previousUsedAt))).returning();
|
|
1666
|
-
}
|
|
1667
|
-
/** Look up a single session's token row by its family identifier. */
|
|
1668
|
-
async getByFamily(tokenFamily) {
|
|
1669
|
-
const [token] = await this.db.select().from(this.tokens).where(eq4(this.tokens.tokenFamily, tokenFamily));
|
|
1670
|
-
return token ?? null;
|
|
1671
|
-
}
|
|
1672
|
-
/** Revoke a single session (one family). */
|
|
1673
|
-
async revokeFamily(tokenFamily) {
|
|
1674
|
-
return this.db.delete(this.tokens).where(eq4(this.tokens.tokenFamily, tokenFamily)).returning();
|
|
1675
|
-
}
|
|
1676
|
-
/** Revoke every session for a user (password change/reset, logout-all). */
|
|
1677
|
-
async revokeAllForUser(userId) {
|
|
1678
|
-
return this.db.delete(this.tokens).where(eq4(this.tokens.userId, userId)).returning();
|
|
1679
|
-
}
|
|
1680
|
-
/**
|
|
1681
|
-
* Opportunistic cleanup: with one row per family (no unique userId), expired
|
|
1682
|
-
* and abandoned sessions accumulate. Delete every expired row.
|
|
1683
|
-
*/
|
|
1684
|
-
async deleteExpired() {
|
|
1685
|
-
return this.db.delete(this.tokens).where(lt(this.tokens.expiresAt, (/* @__PURE__ */ new Date()).toISOString())).returning();
|
|
1686
|
-
}
|
|
1687
|
-
async isUserExists(userId) {
|
|
1688
|
-
const [user] = await this.db.select({ id: this.users.id }).from(this.users).where(eq4(this.users.id, userId)).limit(1);
|
|
1689
|
-
return !!user;
|
|
1690
|
-
}
|
|
1691
|
-
async getRoleNameById(userId) {
|
|
1692
|
-
return this.q.getRoleName(userId);
|
|
1693
|
-
}
|
|
1694
|
-
async getUserPermissions(userId) {
|
|
1695
|
-
return this.q.getUserPermissions(userId);
|
|
1696
|
-
}
|
|
1697
|
-
async getRoleAndPermissions(userId) {
|
|
1698
|
-
return this.q.getRoleAndPermissions(userId);
|
|
1699
|
-
}
|
|
1700
|
-
async getUser(userId) {
|
|
1701
|
-
return await this.q.getUserWithPermissions(eq4(this.users.id, userId)) ?? null;
|
|
1702
|
-
}
|
|
1703
|
-
};
|
|
1704
|
-
__decorate9([
|
|
1705
|
-
DB3(),
|
|
1706
|
-
__metadata9("design:type", Object)
|
|
1707
|
-
], TokenRepository.prototype, "db", void 0);
|
|
1708
|
-
__decorate9([
|
|
1709
|
-
Inject6(AUTH_SCHEMA),
|
|
1710
|
-
__metadata9("design:type", Object)
|
|
1711
|
-
], TokenRepository.prototype, "schema", void 0);
|
|
1712
|
-
TokenRepository = __decorate9([
|
|
1713
|
-
Repository3()
|
|
1714
|
-
], TokenRepository);
|
|
1715
|
-
|
|
1716
|
-
// src/tokens/TokenService.ts
|
|
1717
|
-
import timestring2 from "timestring";
|
|
2002
|
+
import timestring3 from "timestring";
|
|
1718
2003
|
|
|
1719
2004
|
// src/credentialSetup/CredentialSetupRequirementRepository.ts
|
|
1720
2005
|
import { and as and2, eq as eq5 } from "drizzle-orm";
|
|
1721
|
-
import { Err as Err6, Inject as
|
|
2006
|
+
import { Err as Err6, Inject as Inject8, Repository as Repository4 } from "najm-core";
|
|
1722
2007
|
import { DB as DB4 } from "najm-database";
|
|
1723
|
-
var
|
|
2008
|
+
var __decorate11 = function(decorators, target, key, desc) {
|
|
1724
2009
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1725
2010
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1726
2011
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1727
2012
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1728
2013
|
};
|
|
1729
|
-
var
|
|
2014
|
+
var __metadata11 = function(k, v) {
|
|
1730
2015
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1731
2016
|
};
|
|
1732
2017
|
var CredentialSetupRequirementRepository = class CredentialSetupRequirementRepository2 {
|
|
@@ -1774,15 +2059,15 @@ var CredentialSetupRequirementRepository = class CredentialSetupRequirementRepos
|
|
|
1774
2059
|
return requirement;
|
|
1775
2060
|
}
|
|
1776
2061
|
};
|
|
1777
|
-
|
|
2062
|
+
__decorate11([
|
|
1778
2063
|
DB4(),
|
|
1779
|
-
|
|
2064
|
+
__metadata11("design:type", Object)
|
|
1780
2065
|
], CredentialSetupRequirementRepository.prototype, "db", void 0);
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
2066
|
+
__decorate11([
|
|
2067
|
+
Inject8(AUTH_SCHEMA),
|
|
2068
|
+
__metadata11("design:type", Object)
|
|
1784
2069
|
], CredentialSetupRequirementRepository.prototype, "schema", void 0);
|
|
1785
|
-
CredentialSetupRequirementRepository =
|
|
2070
|
+
CredentialSetupRequirementRepository = __decorate11([
|
|
1786
2071
|
Repository4()
|
|
1787
2072
|
], CredentialSetupRequirementRepository);
|
|
1788
2073
|
|
|
@@ -1791,20 +2076,21 @@ var PASSWORD_SETUP_PURPOSE = "password";
|
|
|
1791
2076
|
|
|
1792
2077
|
// src/tokens/TokenService.ts
|
|
1793
2078
|
import { Err as Err7 } from "najm-core";
|
|
1794
|
-
var
|
|
2079
|
+
var __decorate12 = function(decorators, target, key, desc) {
|
|
1795
2080
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1796
2081
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1797
2082
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1798
2083
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1799
2084
|
};
|
|
1800
|
-
var
|
|
2085
|
+
var __metadata12 = function(k, v) {
|
|
1801
2086
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1802
2087
|
};
|
|
1803
2088
|
var TokenService_1;
|
|
1804
|
-
var
|
|
1805
|
-
var
|
|
2089
|
+
var _a7;
|
|
2090
|
+
var _b5;
|
|
1806
2091
|
var _c2;
|
|
1807
2092
|
var _d2;
|
|
2093
|
+
var _e2;
|
|
1808
2094
|
var TokenService = class TokenService2 {
|
|
1809
2095
|
static {
|
|
1810
2096
|
__name(this, "TokenService");
|
|
@@ -1816,13 +2102,23 @@ var TokenService = class TokenService2 {
|
|
|
1816
2102
|
cookieManager;
|
|
1817
2103
|
cache;
|
|
1818
2104
|
credentialSetupRequirements;
|
|
2105
|
+
sessions;
|
|
1819
2106
|
config;
|
|
1820
2107
|
t;
|
|
1821
|
-
constructor(tokenRepository, cookieManager, cache2, credentialSetupRequirements) {
|
|
2108
|
+
constructor(tokenRepository, cookieManager, cache2, credentialSetupRequirements, sessions) {
|
|
1822
2109
|
this.tokenRepository = tokenRepository;
|
|
1823
2110
|
this.cookieManager = cookieManager;
|
|
1824
2111
|
this.cache = cache2;
|
|
1825
2112
|
this.credentialSetupRequirements = credentialSetupRequirements;
|
|
2113
|
+
this.sessions = sessions;
|
|
2114
|
+
}
|
|
2115
|
+
/** The shared invalidation contract — see SessionInvalidationService. */
|
|
2116
|
+
get invalidation() {
|
|
2117
|
+
if (!this.sessions) {
|
|
2118
|
+
this.sessions = new SessionInvalidationService(this.cache, this.tokenRepository);
|
|
2119
|
+
this.sessions.config = this.config;
|
|
2120
|
+
}
|
|
2121
|
+
return this.sessions;
|
|
1826
2122
|
}
|
|
1827
2123
|
/**
|
|
1828
2124
|
* Get blacklist key prefix
|
|
@@ -1833,17 +2129,11 @@ var TokenService = class TokenService2 {
|
|
|
1833
2129
|
get resetTokenPrefix() {
|
|
1834
2130
|
return "auth:reset:";
|
|
1835
2131
|
}
|
|
1836
|
-
get sessionVersionPrefix() {
|
|
1837
|
-
return "auth:session-version:";
|
|
1838
|
-
}
|
|
1839
2132
|
sessionVersionKey(userId) {
|
|
1840
|
-
return
|
|
1841
|
-
}
|
|
1842
|
-
accessTokenTtlMs() {
|
|
1843
|
-
return timestring2(this.config.jwt.accessExpiresIn, "ms");
|
|
2133
|
+
return this.invalidation.sessionVersionKey(userId);
|
|
1844
2134
|
}
|
|
1845
2135
|
expiresAt(expiresIn) {
|
|
1846
|
-
return Math.floor((Date.now() +
|
|
2136
|
+
return Math.floor((Date.now() + timestring3(expiresIn, "ms")) / 1e3);
|
|
1847
2137
|
}
|
|
1848
2138
|
async getCacheValues(keys) {
|
|
1849
2139
|
const cache2 = this.cache;
|
|
@@ -1852,10 +2142,7 @@ var TokenService = class TokenService2 {
|
|
|
1852
2142
|
return Promise.all(keys.map((key) => cache2.get(key)));
|
|
1853
2143
|
}
|
|
1854
2144
|
parseSessionVersion(raw) {
|
|
1855
|
-
|
|
1856
|
-
return 0;
|
|
1857
|
-
const parsed = Number(raw);
|
|
1858
|
-
return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
|
|
2145
|
+
return this.invalidation.parseSessionVersion(raw);
|
|
1859
2146
|
}
|
|
1860
2147
|
// ============ TOKEN VALIDATION ============
|
|
1861
2148
|
extractAccessToken(authorization) {
|
|
@@ -1877,18 +2164,23 @@ var TokenService = class TokenService2 {
|
|
|
1877
2164
|
}
|
|
1878
2165
|
const sessionKey = this.sessionVersionKey(payload.userId);
|
|
1879
2166
|
const blacklistKey = payload.jti ? `${this.blacklistPrefix}${payload.jti}` : null;
|
|
1880
|
-
const
|
|
2167
|
+
const revokedKey = payload.tokenFamily ? this.revokedFamilyKey(payload.tokenFamily) : null;
|
|
2168
|
+
const liveKey = payload.tokenFamily ? this.invalidation.familyKey(payload.tokenFamily) : null;
|
|
1881
2169
|
const keys = [
|
|
1882
2170
|
...blacklistKey ? [blacklistKey] : [],
|
|
1883
2171
|
sessionKey,
|
|
1884
|
-
...
|
|
2172
|
+
...revokedKey ? [revokedKey] : [],
|
|
2173
|
+
...liveKey ? [liveKey] : []
|
|
1885
2174
|
];
|
|
1886
2175
|
const values = await this.getCacheValues(keys);
|
|
1887
2176
|
const valueByKey = new Map(keys.map((key, i) => [key, values[i]]));
|
|
1888
2177
|
if (blacklistKey && valueByKey.get(blacklistKey) != null) {
|
|
1889
2178
|
Err7(this.t("errors.tokenRevoked"), 401);
|
|
1890
2179
|
}
|
|
1891
|
-
if (
|
|
2180
|
+
if (revokedKey && valueByKey.get(revokedKey) != null) {
|
|
2181
|
+
Err7(this.t("errors.tokenRevoked"), 401);
|
|
2182
|
+
}
|
|
2183
|
+
if (!liveKey || valueByKey.get(liveKey) !== payload.userId) {
|
|
1892
2184
|
Err7(this.t("errors.tokenRevoked"), 401);
|
|
1893
2185
|
}
|
|
1894
2186
|
const activeSessionVersion = this.parseSessionVersion(valueByKey.get(sessionKey) ?? null);
|
|
@@ -1922,6 +2214,11 @@ var TokenService = class TokenService2 {
|
|
|
1922
2214
|
this.clearRefreshSessionCookies();
|
|
1923
2215
|
Err7(this.t(messageKey), 401);
|
|
1924
2216
|
}
|
|
2217
|
+
async assertRefreshFamilyAllowed(tokenFamily, userId) {
|
|
2218
|
+
if (await this.invalidation.familyStatus(tokenFamily, userId) === "revoked") {
|
|
2219
|
+
this.rejectRefreshSession();
|
|
2220
|
+
}
|
|
2221
|
+
}
|
|
1925
2222
|
readRefreshSessionCookie() {
|
|
1926
2223
|
const refreshToken = this.cookieManager.getRefreshToken();
|
|
1927
2224
|
if (!refreshToken) {
|
|
@@ -1948,6 +2245,7 @@ var TokenService = class TokenService2 {
|
|
|
1948
2245
|
async resolveRefreshSessionFromCookie() {
|
|
1949
2246
|
const { refreshToken, userId, tokenFamily } = this.readRefreshSessionCookie();
|
|
1950
2247
|
const stored = await this.tokenRepository.getByFamily(tokenFamily);
|
|
2248
|
+
await this.assertRefreshFamilyAllowed(tokenFamily, userId);
|
|
1951
2249
|
if (!stored || stored.userId !== userId) {
|
|
1952
2250
|
this.rejectRefreshSession();
|
|
1953
2251
|
}
|
|
@@ -1979,7 +2277,8 @@ var TokenService = class TokenService2 {
|
|
|
1979
2277
|
user,
|
|
1980
2278
|
roles: user.role ? [user.role] : [],
|
|
1981
2279
|
permissions: Array.isArray(user.permissions) ? user.permissions : [],
|
|
1982
|
-
sessionVersion
|
|
2280
|
+
sessionVersion,
|
|
2281
|
+
tokenFamily
|
|
1983
2282
|
};
|
|
1984
2283
|
}
|
|
1985
2284
|
// ============ USER RETRIEVAL (MAIN METHOD) ============
|
|
@@ -1988,7 +2287,26 @@ var TokenService = class TokenService2 {
|
|
|
1988
2287
|
return null;
|
|
1989
2288
|
const token = this.extractAccessToken(auth2);
|
|
1990
2289
|
const { userId } = await this.verifyAccessToken(token);
|
|
1991
|
-
return this.getUserById(userId);
|
|
2290
|
+
return this.requireActiveUser(await this.getUserById(userId));
|
|
2291
|
+
}
|
|
2292
|
+
/**
|
|
2293
|
+
* A user record is only an authorization if the account is still usable.
|
|
2294
|
+
*
|
|
2295
|
+
* A valid signature and an unrevoked version say the *token* is intact; they
|
|
2296
|
+
* say nothing about whether the account behind it was since deactivated or
|
|
2297
|
+
* deleted. Session invalidation is what normally ends such a token, but this
|
|
2298
|
+
* check is what makes a truthy cached record insufficient on its own — so a
|
|
2299
|
+
* missed invalidation, or a record filled into cache moments before the
|
|
2300
|
+
* change, still cannot authorize a request.
|
|
2301
|
+
*/
|
|
2302
|
+
requireActiveUser(user) {
|
|
2303
|
+
if (!user) {
|
|
2304
|
+
Err7(this.t("errors.tokenVerificationFailed"), 401);
|
|
2305
|
+
}
|
|
2306
|
+
if (user.status !== void 0 && user.status !== "active") {
|
|
2307
|
+
Err7(this.t("errors.accountInactive"), 403);
|
|
2308
|
+
}
|
|
2309
|
+
return user;
|
|
1992
2310
|
}
|
|
1993
2311
|
async getUserById(userId) {
|
|
1994
2312
|
const cacheKey = `auth:user:${userId}`;
|
|
@@ -2018,7 +2336,7 @@ var TokenService = class TokenService2 {
|
|
|
2018
2336
|
const sessionVersion = await this.getUserSessionVersion(data.userId);
|
|
2019
2337
|
const expiresAt = this.expiresAt(this.config.jwt.accessExpiresIn);
|
|
2020
2338
|
if (sessionVersion > 0) {
|
|
2021
|
-
await this.
|
|
2339
|
+
await this.invalidation.touchSessionVersion(data.userId);
|
|
2022
2340
|
}
|
|
2023
2341
|
const token = jwt.sign({ ...data, jti, sessionVersion, exp: expiresAt }, this.config.jwt.accessSecret);
|
|
2024
2342
|
return { token, expiresAt, sessionVersion };
|
|
@@ -2031,9 +2349,24 @@ var TokenService = class TokenService2 {
|
|
|
2031
2349
|
async getSessionVersion(userId) {
|
|
2032
2350
|
return this.getUserSessionVersion(userId);
|
|
2033
2351
|
}
|
|
2352
|
+
/**
|
|
2353
|
+
* Whether one session family is positively known to be live.
|
|
2354
|
+
*
|
|
2355
|
+
* `false` means "not proven live" — logged out, or simply not in cache — and
|
|
2356
|
+
* is a reason to fall back to an authoritative check, never on its own a
|
|
2357
|
+
* reason to treat a session as valid.
|
|
2358
|
+
*/
|
|
2359
|
+
async isSessionFamilyLive(tokenFamily, userId) {
|
|
2360
|
+
return await this.invalidation.familyStatus(tokenFamily, userId) === "live";
|
|
2361
|
+
}
|
|
2034
2362
|
/**
|
|
2035
2363
|
* Generate access token with unique jti for blacklist support.
|
|
2036
2364
|
* Includes roles/permissions for client-side RBAC/PBAC.
|
|
2365
|
+
*
|
|
2366
|
+
* The token only verifies while its `tokenFamily` is a live session — see
|
|
2367
|
+
* verifyAccessToken. A token minted without one, or for a family that has
|
|
2368
|
+
* been revoked, is refused by design rather than trusted on its signature.
|
|
2369
|
+
* Use generateTokens() to establish a family.
|
|
2037
2370
|
*/
|
|
2038
2371
|
async generateAccessToken(data) {
|
|
2039
2372
|
return (await this.signAccessToken(data)).token;
|
|
@@ -2118,12 +2451,13 @@ var TokenService = class TokenService2 {
|
|
|
2118
2451
|
* This prevents token theft in case of database breach
|
|
2119
2452
|
*/
|
|
2120
2453
|
async storeRefreshToken(userId, refreshToken, tokenFamily) {
|
|
2121
|
-
|
|
2454
|
+
await this.assertRefreshFamilyAllowed(tokenFamily, userId);
|
|
2455
|
+
const expireInSecond = timestring3(this.config.jwt.refreshExpiresIn, "s");
|
|
2122
2456
|
const hashedToken = this.hashToken(refreshToken);
|
|
2123
2457
|
const existing = await this.tokenRepository.getByFamily(tokenFamily);
|
|
2124
2458
|
const previousHash = existing?.token ?? null;
|
|
2125
2459
|
const previousValidUntil = previousHash ? new Date(Date.now() + TokenService_1.PREVIOUS_GRACE_SECONDS * 1e3).toISOString() : null;
|
|
2126
|
-
await this.tokenRepository.storeRefreshToken({
|
|
2460
|
+
const stored = await this.tokenRepository.storeRefreshToken({
|
|
2127
2461
|
userId,
|
|
2128
2462
|
token: hashedToken,
|
|
2129
2463
|
tokenFamily,
|
|
@@ -2132,6 +2466,12 @@ var TokenService = class TokenService2 {
|
|
|
2132
2466
|
previousValidUntil,
|
|
2133
2467
|
previousUsedAt: null
|
|
2134
2468
|
});
|
|
2469
|
+
if (!stored?.length) {
|
|
2470
|
+
this.rejectRefreshSession();
|
|
2471
|
+
}
|
|
2472
|
+
if (!await this.invalidation.markFamilyIssued(tokenFamily, userId)) {
|
|
2473
|
+
this.rejectRefreshSession();
|
|
2474
|
+
}
|
|
2135
2475
|
}
|
|
2136
2476
|
/**
|
|
2137
2477
|
* Rotate only the family row observed by refreshTokens(). This conditional
|
|
@@ -2139,7 +2479,7 @@ var TokenService = class TokenService2 {
|
|
|
2139
2479
|
*/
|
|
2140
2480
|
async rotateTokens(userId, tokenFamily, expectedCurrentHash) {
|
|
2141
2481
|
const generated = await this.createTokenPair(userId, tokenFamily);
|
|
2142
|
-
const expireInSecond =
|
|
2482
|
+
const expireInSecond = timestring3(this.config.jwt.refreshExpiresIn, "s");
|
|
2143
2483
|
const rotated = await this.tokenRepository.rotateRefreshToken({
|
|
2144
2484
|
userId,
|
|
2145
2485
|
token: this.hashToken(generated.refreshToken),
|
|
@@ -2152,6 +2492,9 @@ var TokenService = class TokenService2 {
|
|
|
2152
2492
|
if (!rotated?.length) {
|
|
2153
2493
|
Err7(this.t("errors.refreshTokenInvalid"), 401);
|
|
2154
2494
|
}
|
|
2495
|
+
if (!await this.invalidation.markFamilyIssued(tokenFamily, userId)) {
|
|
2496
|
+
this.rejectRefreshSession();
|
|
2497
|
+
}
|
|
2155
2498
|
return generated;
|
|
2156
2499
|
}
|
|
2157
2500
|
/**
|
|
@@ -2161,6 +2504,7 @@ var TokenService = class TokenService2 {
|
|
|
2161
2504
|
async refreshTokens() {
|
|
2162
2505
|
const { refreshToken, userId, tokenFamily } = this.readRefreshSessionCookie();
|
|
2163
2506
|
const stored = await this.tokenRepository.getByFamily(tokenFamily);
|
|
2507
|
+
await this.assertRefreshFamilyAllowed(tokenFamily, userId);
|
|
2164
2508
|
if (!stored || stored.userId !== userId) {
|
|
2165
2509
|
this.rejectRefreshSession();
|
|
2166
2510
|
}
|
|
@@ -2196,16 +2540,21 @@ var TokenService = class TokenService2 {
|
|
|
2196
2540
|
}
|
|
2197
2541
|
/** Revoke every refresh session for a user (password change/reset, logout-all). */
|
|
2198
2542
|
async revokeAllForUser(userId) {
|
|
2199
|
-
|
|
2543
|
+
const revoked = await this.tokenRepository.revokeAllForUser(userId);
|
|
2544
|
+
if (Array.isArray(revoked)) {
|
|
2545
|
+
await Promise.all(revoked.map((row) => row?.tokenFamily).filter((family) => typeof family === "string" && !!family).map((family) => this.invalidation.markFamilyRevoked(family)));
|
|
2546
|
+
}
|
|
2547
|
+
return revoked;
|
|
2200
2548
|
}
|
|
2201
2549
|
/** Revoke a single refresh session (one family). */
|
|
2202
2550
|
async revokeFamily(tokenFamily) {
|
|
2203
|
-
await this.markFamilyRevoked(tokenFamily);
|
|
2551
|
+
await this.invalidation.markFamilyRevoked(tokenFamily);
|
|
2204
2552
|
return this.tokenRepository.revokeFamily(tokenFamily);
|
|
2205
2553
|
}
|
|
2206
2554
|
/**
|
|
2207
2555
|
* Opportunistic cleanup of expired/abandoned sessions. With one row per
|
|
2208
|
-
* family (no unique userId),
|
|
2556
|
+
* family (no unique userId), expired live rows and revocation tombstones
|
|
2557
|
+
* would otherwise accumulate.
|
|
2209
2558
|
* Best-effort — never let cleanup failure break the calling flow.
|
|
2210
2559
|
*/
|
|
2211
2560
|
async deleteExpiredSessions() {
|
|
@@ -2215,10 +2564,7 @@ var TokenService = class TokenService2 {
|
|
|
2215
2564
|
}
|
|
2216
2565
|
}
|
|
2217
2566
|
async invalidateUserAccessTokens(userId) {
|
|
2218
|
-
|
|
2219
|
-
await this.cache.set(this.sessionVersionKey(userId), String(nextVersion), this.accessTokenTtlMs());
|
|
2220
|
-
await this.cache.del(`auth:user:${userId}`);
|
|
2221
|
-
return nextVersion;
|
|
2567
|
+
return this.invalidation.invalidateAccessTokens(userId);
|
|
2222
2568
|
}
|
|
2223
2569
|
async getUserFromCookie() {
|
|
2224
2570
|
const userId = await this.resolveUserFromCookie();
|
|
@@ -2226,27 +2572,16 @@ var TokenService = class TokenService2 {
|
|
|
2226
2572
|
if (!user) {
|
|
2227
2573
|
Err7(this.t("errors.refreshTokenInvalid"), 401);
|
|
2228
2574
|
}
|
|
2229
|
-
return user;
|
|
2230
|
-
}
|
|
2231
|
-
get revokedFamilyPrefix() {
|
|
2232
|
-
return "auth:revoked-family:";
|
|
2575
|
+
return this.requireActiveUser(user);
|
|
2233
2576
|
}
|
|
2234
2577
|
revokedFamilyKey(tokenFamily) {
|
|
2235
|
-
return
|
|
2236
|
-
}
|
|
2237
|
-
/**
|
|
2238
|
-
* Mark a family as revoked in cache for the access-token TTL, so every
|
|
2239
|
-
* access token minted for that family (not just the presented one) is
|
|
2240
|
-
* rejected by verifyAccessToken until it would have expired anyway.
|
|
2241
|
-
*/
|
|
2242
|
-
async markFamilyRevoked(tokenFamily) {
|
|
2243
|
-
await this.cache.set(this.revokedFamilyKey(tokenFamily), "1", this.accessTokenTtlMs());
|
|
2578
|
+
return this.invalidation.revokedFamilyKey(tokenFamily);
|
|
2244
2579
|
}
|
|
2245
2580
|
/**
|
|
2246
2581
|
* Revoke only the suspect family — NOT the whole user. Bumping the global
|
|
2247
2582
|
* per-user session version here would kill every device's access tokens on a
|
|
2248
|
-
* single family's reuse detection. Instead
|
|
2249
|
-
*
|
|
2583
|
+
* single family's reuse detection. Instead durably mark the family revoked
|
|
2584
|
+
* so database recovery and its access tokens both stop verifying.
|
|
2250
2585
|
*/
|
|
2251
2586
|
async revokeSuspectRefreshFamily(userId, tokenFamily) {
|
|
2252
2587
|
if (tokenFamily) {
|
|
@@ -2258,7 +2593,7 @@ var TokenService = class TokenService2 {
|
|
|
2258
2593
|
}
|
|
2259
2594
|
/**
|
|
2260
2595
|
* Logout the CURRENT session only — blacklist the presented access token,
|
|
2261
|
-
* mark its family revoked
|
|
2596
|
+
* mark its family revoked in cache and durably in the token row. Other
|
|
2262
2597
|
* devices/sessions for the same user keep working. Use a password change or
|
|
2263
2598
|
* reset (revoke-all) to terminate every session.
|
|
2264
2599
|
*
|
|
@@ -2339,7 +2674,7 @@ var TokenService = class TokenService2 {
|
|
|
2339
2674
|
const token = jwt.sign(data, this.config.jwt.refreshSecret, {
|
|
2340
2675
|
expiresIn
|
|
2341
2676
|
});
|
|
2342
|
-
await this.cache.set(`${this.resetTokenPrefix}${userId}`, jti,
|
|
2677
|
+
await this.cache.set(`${this.resetTokenPrefix}${userId}`, jti, timestring3(expiresIn, "ms"));
|
|
2343
2678
|
return { token, userId };
|
|
2344
2679
|
}
|
|
2345
2680
|
/**
|
|
@@ -2358,8 +2693,20 @@ var TokenService = class TokenService2 {
|
|
|
2358
2693
|
return this.generateSetPasswordToken(userId, "invite", "3d");
|
|
2359
2694
|
}
|
|
2360
2695
|
/**
|
|
2361
|
-
* Verify password reset token
|
|
2362
|
-
*
|
|
2696
|
+
* Verify and CONSUME a password reset or invite token.
|
|
2697
|
+
*
|
|
2698
|
+
* Consumption is a single atomic compare-and-delete, so exactly one of any
|
|
2699
|
+
* number of concurrent callers holding the same link is told to proceed. The
|
|
2700
|
+
* earlier `get()` then `del()` pair left a window in which two callers both
|
|
2701
|
+
* read the same jti, both passed, and both went on to set a password.
|
|
2702
|
+
*
|
|
2703
|
+
* The comparison also means a stale token cannot delete the jti of a newer
|
|
2704
|
+
* one that superseded it — the newer link keeps working.
|
|
2705
|
+
*
|
|
2706
|
+
* Callers must finish validating the replacement password BEFORE calling
|
|
2707
|
+
* this: consumption is deliberately irreversible, so a token burned by a
|
|
2708
|
+
* request that then failed validation would cost the user their link for
|
|
2709
|
+
* nothing.
|
|
2363
2710
|
*/
|
|
2364
2711
|
async verifyResetToken(token) {
|
|
2365
2712
|
let decoded;
|
|
@@ -2371,40 +2718,42 @@ var TokenService = class TokenService2 {
|
|
|
2371
2718
|
if (decoded.type !== "reset" && decoded.type !== "invite" || !decoded.jti) {
|
|
2372
2719
|
Err7(this.t("errors.invalidResetToken"));
|
|
2373
2720
|
}
|
|
2721
|
+
const consume = this.cache.compareAndDelete;
|
|
2722
|
+
if (typeof consume !== "function") {
|
|
2723
|
+
Err7.invalidOperation("Password reset requires a cache with atomic compare-and-delete");
|
|
2724
|
+
}
|
|
2374
2725
|
const key = `${this.resetTokenPrefix}${decoded.userId}`;
|
|
2375
|
-
|
|
2376
|
-
if (!storedJti || storedJti !== decoded.jti) {
|
|
2726
|
+
if (!await consume.call(this.cache, key, decoded.jti)) {
|
|
2377
2727
|
Err7(this.t("errors.invalidResetToken"));
|
|
2378
2728
|
}
|
|
2379
|
-
await this.cache.del(key);
|
|
2380
2729
|
return decoded.userId;
|
|
2381
2730
|
}
|
|
2382
2731
|
async getUserSessionVersion(userId) {
|
|
2383
|
-
return this.
|
|
2732
|
+
return this.invalidation.getSessionVersion(userId);
|
|
2384
2733
|
}
|
|
2385
2734
|
};
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2735
|
+
__decorate12([
|
|
2736
|
+
Inject9(AUTH_CONFIG),
|
|
2737
|
+
__metadata12("design:type", Object)
|
|
2389
2738
|
], TokenService.prototype, "config", void 0);
|
|
2390
|
-
|
|
2739
|
+
__decorate12([
|
|
2391
2740
|
I18n5("auth"),
|
|
2392
|
-
|
|
2741
|
+
__metadata12("design:type", Object)
|
|
2393
2742
|
], TokenService.prototype, "t", void 0);
|
|
2394
|
-
TokenService = TokenService_1 =
|
|
2395
|
-
|
|
2396
|
-
|
|
2743
|
+
TokenService = TokenService_1 = __decorate12([
|
|
2744
|
+
Injectable7(),
|
|
2745
|
+
__metadata12("design:paramtypes", [typeof (_a7 = typeof TokenRepository !== "undefined" && TokenRepository) === "function" ? _a7 : Object, typeof (_b5 = typeof CookieManager !== "undefined" && CookieManager) === "function" ? _b5 : Object, typeof (_c2 = typeof CacheService2 !== "undefined" && CacheService2) === "function" ? _c2 : Object, typeof (_d2 = typeof CredentialSetupRequirementRepository !== "undefined" && CredentialSetupRequirementRepository) === "function" ? _d2 : Object, typeof (_e2 = typeof SessionInvalidationService !== "undefined" && SessionInvalidationService) === "function" ? _e2 : Object])
|
|
2397
2746
|
], TokenService);
|
|
2398
2747
|
|
|
2399
2748
|
// src/auth/AuthService.ts
|
|
2400
|
-
import
|
|
2749
|
+
import timestring4 from "timestring";
|
|
2401
2750
|
|
|
2402
2751
|
// src/auth/AuthSessionService.ts
|
|
2403
|
-
import { Injectable as
|
|
2752
|
+
import { Injectable as Injectable9 } from "najm-core";
|
|
2404
2753
|
import { Err as Err9 } from "najm-core";
|
|
2405
2754
|
|
|
2406
2755
|
// src/credentialSetup/CredentialSetupRequirementService.ts
|
|
2407
|
-
import { Injectable as
|
|
2756
|
+
import { Injectable as Injectable8 } from "najm-core";
|
|
2408
2757
|
import { Transaction as Transaction2 } from "najm-database";
|
|
2409
2758
|
|
|
2410
2759
|
// src/identity/temporaryCredential.ts
|
|
@@ -2476,17 +2825,17 @@ function normalizeSetupPurpose(purpose) {
|
|
|
2476
2825
|
__name(normalizeSetupPurpose, "normalizeSetupPurpose");
|
|
2477
2826
|
|
|
2478
2827
|
// src/credentialSetup/CredentialSetupRequirementService.ts
|
|
2479
|
-
var
|
|
2828
|
+
var __decorate13 = function(decorators, target, key, desc) {
|
|
2480
2829
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2481
2830
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2482
2831
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2483
2832
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2484
2833
|
};
|
|
2485
|
-
var
|
|
2834
|
+
var __metadata13 = function(k, v) {
|
|
2486
2835
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2487
2836
|
};
|
|
2488
|
-
var
|
|
2489
|
-
var
|
|
2837
|
+
var _a8;
|
|
2838
|
+
var _b6;
|
|
2490
2839
|
var _c3;
|
|
2491
2840
|
var CredentialSetupRequirementService = class CredentialSetupRequirementService2 {
|
|
2492
2841
|
static {
|
|
@@ -2526,15 +2875,15 @@ var CredentialSetupRequirementService = class CredentialSetupRequirementService2
|
|
|
2526
2875
|
return this.repository.complete(userId, normalizeSetupPurpose(purpose));
|
|
2527
2876
|
}
|
|
2528
2877
|
};
|
|
2529
|
-
|
|
2878
|
+
__decorate13([
|
|
2530
2879
|
Transaction2({ retries: 2 }),
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2880
|
+
__metadata13("design:type", Function),
|
|
2881
|
+
__metadata13("design:paramtypes", [String, String, Object]),
|
|
2882
|
+
__metadata13("design:returntype", typeof (_c3 = typeof Promise !== "undefined" && Promise) === "function" ? _c3 : Object)
|
|
2534
2883
|
], CredentialSetupRequirementService.prototype, "markRequired", null);
|
|
2535
|
-
CredentialSetupRequirementService =
|
|
2536
|
-
|
|
2537
|
-
|
|
2884
|
+
CredentialSetupRequirementService = __decorate13([
|
|
2885
|
+
Injectable8(),
|
|
2886
|
+
__metadata13("design:paramtypes", [typeof (_a8 = typeof CredentialSetupRequirementRepository !== "undefined" && CredentialSetupRequirementRepository) === "function" ? _a8 : Object, typeof (_b6 = typeof TokenService !== "undefined" && TokenService) === "function" ? _b6 : Object])
|
|
2538
2887
|
], CredentialSetupRequirementService);
|
|
2539
2888
|
|
|
2540
2889
|
// src/credentialSetup/errors.ts
|
|
@@ -2560,17 +2909,17 @@ var credentialSetupError = /* @__PURE__ */ __name((code, message, status = 400)
|
|
|
2560
2909
|
}, "credentialSetupError");
|
|
2561
2910
|
|
|
2562
2911
|
// src/auth/AuthSessionService.ts
|
|
2563
|
-
var
|
|
2912
|
+
var __decorate14 = function(decorators, target, key, desc) {
|
|
2564
2913
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2565
2914
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2566
2915
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2567
2916
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2568
2917
|
};
|
|
2569
|
-
var
|
|
2918
|
+
var __metadata14 = function(k, v) {
|
|
2570
2919
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2571
2920
|
};
|
|
2572
|
-
var
|
|
2573
|
-
var
|
|
2921
|
+
var _a9;
|
|
2922
|
+
var _b7;
|
|
2574
2923
|
var _c4;
|
|
2575
2924
|
var _d3;
|
|
2576
2925
|
var AuthSessionService = class AuthSessionService2 {
|
|
@@ -2598,7 +2947,7 @@ var AuthSessionService = class AuthSessionService2 {
|
|
|
2598
2947
|
const generated = await this.tokenService.generateTokens(user.id);
|
|
2599
2948
|
this.cookieManager.setRefreshToken(generated.refreshToken);
|
|
2600
2949
|
await this.userService.updateLastLogin(user.id);
|
|
2601
|
-
const { roles, permissions, sessionVersion } = generated;
|
|
2950
|
+
const { roles, permissions, sessionVersion, tokenFamily } = generated;
|
|
2602
2951
|
this.cookieManager.setSessionCookie({
|
|
2603
2952
|
user: {
|
|
2604
2953
|
id: user.id,
|
|
@@ -2609,39 +2958,40 @@ var AuthSessionService = class AuthSessionService2 {
|
|
|
2609
2958
|
},
|
|
2610
2959
|
roles,
|
|
2611
2960
|
permissions,
|
|
2612
|
-
sessionVersion
|
|
2961
|
+
sessionVersion,
|
|
2962
|
+
tokenFamily
|
|
2613
2963
|
});
|
|
2614
2964
|
const { userId: _userId, tokenFamily: _tokenFamily, roles: _roles, permissions: _permissions, sessionVersion: _sessionVersion, ...tokens } = generated;
|
|
2615
2965
|
return { ...tokens, user };
|
|
2616
2966
|
}
|
|
2617
2967
|
};
|
|
2618
|
-
AuthSessionService =
|
|
2619
|
-
|
|
2620
|
-
|
|
2968
|
+
AuthSessionService = __decorate14([
|
|
2969
|
+
Injectable9(),
|
|
2970
|
+
__metadata14("design:paramtypes", [typeof (_a9 = typeof TokenService !== "undefined" && TokenService) === "function" ? _a9 : Object, typeof (_b7 = typeof UserService !== "undefined" && UserService) === "function" ? _b7 : Object, typeof (_c4 = typeof CookieManager !== "undefined" && CookieManager) === "function" ? _c4 : Object, typeof (_d3 = typeof CredentialSetupRequirementService !== "undefined" && CredentialSetupRequirementService) === "function" ? _d3 : Object])
|
|
2621
2971
|
], AuthSessionService);
|
|
2622
2972
|
|
|
2623
2973
|
// src/credentialSetup/PasswordSetupService.ts
|
|
2624
|
-
import { Inject as
|
|
2974
|
+
import { Inject as Inject11, Injectable as Injectable11 } from "najm-core";
|
|
2625
2975
|
import { I18n as I18n7 } from "najm-i18n";
|
|
2626
2976
|
|
|
2627
2977
|
// src/credentialSetup/CredentialSetupService.ts
|
|
2628
2978
|
import { createHash as createHash2, randomBytes as randomBytes2 } from "crypto";
|
|
2629
2979
|
import { CookieService as CookieService2 } from "najm-cookies";
|
|
2630
|
-
import { Err as Err11, Injectable as
|
|
2980
|
+
import { Err as Err11, Injectable as Injectable10 } from "najm-core";
|
|
2631
2981
|
import { Transaction as Transaction3 } from "najm-database";
|
|
2632
2982
|
import { I18n as I18n6 } from "najm-i18n";
|
|
2633
2983
|
|
|
2634
2984
|
// src/credentialSetup/CredentialSetupRepository.ts
|
|
2635
2985
|
import { and as and3, eq as eq6, gt, isNull as isNull2, lt as lt2 } from "drizzle-orm";
|
|
2636
|
-
import { Err as Err10, Inject as
|
|
2986
|
+
import { Err as Err10, Inject as Inject10, Repository as Repository5 } from "najm-core";
|
|
2637
2987
|
import { DB as DB5 } from "najm-database";
|
|
2638
|
-
var
|
|
2988
|
+
var __decorate15 = function(decorators, target, key, desc) {
|
|
2639
2989
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2640
2990
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2641
2991
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2642
2992
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2643
2993
|
};
|
|
2644
|
-
var
|
|
2994
|
+
var __metadata15 = function(k, v) {
|
|
2645
2995
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2646
2996
|
};
|
|
2647
2997
|
var CredentialSetupRepository = class CredentialSetupRepository2 {
|
|
@@ -2693,33 +3043,33 @@ var CredentialSetupRepository = class CredentialSetupRepository2 {
|
|
|
2693
3043
|
return this.db.delete(this.sessions).where(lt2(this.sessions.expiresAt, (/* @__PURE__ */ new Date()).toISOString())).returning({ userId: this.sessions.userId });
|
|
2694
3044
|
}
|
|
2695
3045
|
};
|
|
2696
|
-
|
|
3046
|
+
__decorate15([
|
|
2697
3047
|
DB5(),
|
|
2698
|
-
|
|
3048
|
+
__metadata15("design:type", Object)
|
|
2699
3049
|
], CredentialSetupRepository.prototype, "db", void 0);
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
3050
|
+
__decorate15([
|
|
3051
|
+
Inject10(AUTH_SCHEMA),
|
|
3052
|
+
__metadata15("design:type", Object)
|
|
2703
3053
|
], CredentialSetupRepository.prototype, "schema", void 0);
|
|
2704
|
-
CredentialSetupRepository =
|
|
3054
|
+
CredentialSetupRepository = __decorate15([
|
|
2705
3055
|
Repository5()
|
|
2706
3056
|
], CredentialSetupRepository);
|
|
2707
3057
|
|
|
2708
3058
|
// src/credentialSetup/CredentialSetupService.ts
|
|
2709
|
-
var
|
|
3059
|
+
var __decorate16 = function(decorators, target, key, desc) {
|
|
2710
3060
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2711
3061
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2712
3062
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2713
3063
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2714
3064
|
};
|
|
2715
|
-
var
|
|
3065
|
+
var __metadata16 = function(k, v) {
|
|
2716
3066
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2717
3067
|
};
|
|
2718
|
-
var
|
|
2719
|
-
var
|
|
3068
|
+
var _a10;
|
|
3069
|
+
var _b8;
|
|
2720
3070
|
var _c5;
|
|
2721
3071
|
var _d4;
|
|
2722
|
-
var
|
|
3072
|
+
var _e3;
|
|
2723
3073
|
var _f2;
|
|
2724
3074
|
var _g2;
|
|
2725
3075
|
var DEFAULT_CREDENTIAL_SETUP_COOKIE_NAME = "najm.credential-setup";
|
|
@@ -2855,48 +3205,48 @@ var CredentialSetupService = class CredentialSetupService2 {
|
|
|
2855
3205
|
});
|
|
2856
3206
|
}
|
|
2857
3207
|
};
|
|
2858
|
-
|
|
3208
|
+
__decorate16([
|
|
2859
3209
|
I18n6("auth"),
|
|
2860
|
-
|
|
3210
|
+
__metadata16("design:type", Object)
|
|
2861
3211
|
], CredentialSetupService.prototype, "t", void 0);
|
|
2862
|
-
|
|
3212
|
+
__decorate16([
|
|
2863
3213
|
Transaction3({ retries: 2 }),
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
3214
|
+
__metadata16("design:type", Function),
|
|
3215
|
+
__metadata16("design:paramtypes", [String, Object]),
|
|
3216
|
+
__metadata16("design:returntype", typeof (_e3 = typeof Promise !== "undefined" && Promise) === "function" ? _e3 : Object)
|
|
2867
3217
|
], CredentialSetupService.prototype, "begin", null);
|
|
2868
|
-
|
|
3218
|
+
__decorate16([
|
|
2869
3219
|
Transaction3({ retries: 2 }),
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
3220
|
+
__metadata16("design:type", Function),
|
|
3221
|
+
__metadata16("design:paramtypes", [Object, Function]),
|
|
3222
|
+
__metadata16("design:returntype", typeof (_f2 = typeof Promise !== "undefined" && Promise) === "function" ? _f2 : Object)
|
|
2873
3223
|
], CredentialSetupService.prototype, "consume", null);
|
|
2874
|
-
|
|
3224
|
+
__decorate16([
|
|
2875
3225
|
Transaction3({ retries: 2 }),
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
3226
|
+
__metadata16("design:type", Function),
|
|
3227
|
+
__metadata16("design:paramtypes", [Object]),
|
|
3228
|
+
__metadata16("design:returntype", typeof (_g2 = typeof Promise !== "undefined" && Promise) === "function" ? _g2 : Object)
|
|
2879
3229
|
], CredentialSetupService.prototype, "cancel", null);
|
|
2880
|
-
CredentialSetupService =
|
|
2881
|
-
|
|
2882
|
-
|
|
3230
|
+
CredentialSetupService = __decorate16([
|
|
3231
|
+
Injectable10(),
|
|
3232
|
+
__metadata16("design:paramtypes", [typeof (_a10 = typeof CredentialSetupRepository !== "undefined" && CredentialSetupRepository) === "function" ? _a10 : Object, typeof (_b8 = typeof TokenService !== "undefined" && TokenService) === "function" ? _b8 : Object, typeof (_c5 = typeof CookieManager !== "undefined" && CookieManager) === "function" ? _c5 : Object, typeof (_d4 = typeof CookieService2 !== "undefined" && CookieService2) === "function" ? _d4 : Object])
|
|
2883
3233
|
], CredentialSetupService);
|
|
2884
3234
|
|
|
2885
3235
|
// src/credentialSetup/PasswordSetupService.ts
|
|
2886
|
-
var
|
|
3236
|
+
var __decorate17 = function(decorators, target, key, desc) {
|
|
2887
3237
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2888
3238
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2889
3239
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2890
3240
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2891
3241
|
};
|
|
2892
|
-
var
|
|
3242
|
+
var __metadata17 = function(k, v) {
|
|
2893
3243
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2894
3244
|
};
|
|
2895
|
-
var
|
|
2896
|
-
var
|
|
3245
|
+
var _a11;
|
|
3246
|
+
var _b9;
|
|
2897
3247
|
var _c6;
|
|
2898
3248
|
var _d5;
|
|
2899
|
-
var
|
|
3249
|
+
var _e4;
|
|
2900
3250
|
var _f3;
|
|
2901
3251
|
var PasswordSetupService = class PasswordSetupService2 {
|
|
2902
3252
|
static {
|
|
@@ -3013,38 +3363,38 @@ var PasswordSetupService = class PasswordSetupService2 {
|
|
|
3013
3363
|
return this.validator.comparePassword(normalized, storedHash);
|
|
3014
3364
|
}
|
|
3015
3365
|
};
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3366
|
+
__decorate17([
|
|
3367
|
+
Inject11(AUTH_CONFIG),
|
|
3368
|
+
__metadata17("design:type", Object)
|
|
3019
3369
|
], PasswordSetupService.prototype, "config", void 0);
|
|
3020
|
-
|
|
3370
|
+
__decorate17([
|
|
3021
3371
|
I18n7("auth"),
|
|
3022
|
-
|
|
3372
|
+
__metadata17("design:type", Object)
|
|
3023
3373
|
], PasswordSetupService.prototype, "t", void 0);
|
|
3024
|
-
PasswordSetupService =
|
|
3025
|
-
|
|
3026
|
-
|
|
3374
|
+
PasswordSetupService = __decorate17([
|
|
3375
|
+
Injectable11(),
|
|
3376
|
+
__metadata17("design:paramtypes", [typeof (_a11 = typeof CredentialSetupService !== "undefined" && CredentialSetupService) === "function" ? _a11 : Object, typeof (_b9 = typeof CredentialSetupRequirementService !== "undefined" && CredentialSetupRequirementService) === "function" ? _b9 : Object, typeof (_c6 = typeof UserService !== "undefined" && UserService) === "function" ? _c6 : Object, typeof (_d5 = typeof UserRepository !== "undefined" && UserRepository) === "function" ? _d5 : Object, typeof (_e4 = typeof UserValidator !== "undefined" && UserValidator) === "function" ? _e4 : Object, typeof (_f3 = typeof EncryptionService !== "undefined" && EncryptionService) === "function" ? _f3 : Object])
|
|
3027
3377
|
], PasswordSetupService);
|
|
3028
3378
|
|
|
3029
3379
|
// src/auth/AuthService.ts
|
|
3030
|
-
var
|
|
3380
|
+
var __decorate18 = function(decorators, target, key, desc) {
|
|
3031
3381
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3032
3382
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3033
3383
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
3034
3384
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3035
3385
|
};
|
|
3036
|
-
var
|
|
3386
|
+
var __metadata18 = function(k, v) {
|
|
3037
3387
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3038
3388
|
};
|
|
3039
|
-
var
|
|
3040
|
-
var
|
|
3389
|
+
var _a12;
|
|
3390
|
+
var _b10;
|
|
3041
3391
|
var _c7;
|
|
3042
3392
|
var _d6;
|
|
3043
|
-
var
|
|
3393
|
+
var _e5;
|
|
3044
3394
|
var _f4;
|
|
3045
3395
|
var _g3;
|
|
3046
3396
|
var _h2;
|
|
3047
|
-
var
|
|
3397
|
+
var _j2;
|
|
3048
3398
|
var _k;
|
|
3049
3399
|
var _l;
|
|
3050
3400
|
var AuthService = class AuthService2 {
|
|
@@ -3083,7 +3433,7 @@ var AuthService = class AuthService2 {
|
|
|
3083
3433
|
return new Date(lockoutUntil).getTime() > Date.now();
|
|
3084
3434
|
}
|
|
3085
3435
|
nextLockoutUntil() {
|
|
3086
|
-
const durationMs =
|
|
3436
|
+
const durationMs = timestring4(this.config.lockout.duration, "ms");
|
|
3087
3437
|
return new Date(Date.now() + durationMs).toISOString();
|
|
3088
3438
|
}
|
|
3089
3439
|
getDummyHash() {
|
|
@@ -3333,7 +3683,8 @@ var AuthService = class AuthService2 {
|
|
|
3333
3683
|
user: { id: user.id, email: user.email, name: user.name, role: user.role, status: user.status ?? void 0 },
|
|
3334
3684
|
roles: generated.roles,
|
|
3335
3685
|
permissions: generated.permissions,
|
|
3336
|
-
sessionVersion: generated.sessionVersion
|
|
3686
|
+
sessionVersion: generated.sessionVersion,
|
|
3687
|
+
tokenFamily: generated.tokenFamily
|
|
3337
3688
|
});
|
|
3338
3689
|
}
|
|
3339
3690
|
const { userId: _userId, tokenFamily: _tokenFamily, roles: _roles, permissions: _permissions, sessionVersion: _sv, ...tokens } = generated;
|
|
@@ -3356,7 +3707,8 @@ var AuthService = class AuthService2 {
|
|
|
3356
3707
|
},
|
|
3357
3708
|
roles: recovered.roles,
|
|
3358
3709
|
permissions: recovered.permissions,
|
|
3359
|
-
sessionVersion: recovered.sessionVersion
|
|
3710
|
+
sessionVersion: recovered.sessionVersion,
|
|
3711
|
+
tokenFamily: recovered.tokenFamily
|
|
3360
3712
|
});
|
|
3361
3713
|
return { recovered: true };
|
|
3362
3714
|
}
|
|
@@ -3408,7 +3760,12 @@ var AuthService = class AuthService2 {
|
|
|
3408
3760
|
const lang = this.i18nService.getCurrentLanguage();
|
|
3409
3761
|
result = { ...user, language: lang };
|
|
3410
3762
|
const token = this.tokenService.decodeAccessToken(authorization.replace(/^Bearer\s+/i, ""));
|
|
3411
|
-
cachePayload =
|
|
3763
|
+
cachePayload = token?.tokenFamily ? {
|
|
3764
|
+
roles: token.roles ?? [],
|
|
3765
|
+
permissions: token.permissions ?? [],
|
|
3766
|
+
sessionVersion: token.sessionVersion ?? 0,
|
|
3767
|
+
tokenFamily: token.tokenFamily
|
|
3768
|
+
} : null;
|
|
3412
3769
|
} else {
|
|
3413
3770
|
result = await this.getUserFromCookie();
|
|
3414
3771
|
}
|
|
@@ -3420,7 +3777,8 @@ var AuthService = class AuthService2 {
|
|
|
3420
3777
|
user: { id: result.id, email: result.email, name: result.name, role: result.role, status: result.status ?? void 0 },
|
|
3421
3778
|
roles: cachePayload.roles,
|
|
3422
3779
|
permissions: cachePayload.permissions,
|
|
3423
|
-
sessionVersion: cachePayload.sessionVersion
|
|
3780
|
+
sessionVersion: cachePayload.sessionVersion,
|
|
3781
|
+
tokenFamily: cachePayload.tokenFamily
|
|
3424
3782
|
});
|
|
3425
3783
|
}
|
|
3426
3784
|
return result;
|
|
@@ -3459,8 +3817,8 @@ var AuthService = class AuthService2 {
|
|
|
3459
3817
|
return { message: this.t("success.passwordChanged") };
|
|
3460
3818
|
}
|
|
3461
3819
|
async resetPassword(token, newPassword) {
|
|
3462
|
-
const userId = await this.tokenService.verifyResetToken(token);
|
|
3463
3820
|
this.userValidator.validatePasswordStrength(newPassword);
|
|
3821
|
+
const userId = await this.tokenService.verifyResetToken(token);
|
|
3464
3822
|
await this.userService.update(userId, { password: newPassword });
|
|
3465
3823
|
await this.tokenService.invalidateUserAccessTokens(userId);
|
|
3466
3824
|
await this.tokenService.revokeAllForUser(userId);
|
|
@@ -3469,39 +3827,39 @@ var AuthService = class AuthService2 {
|
|
|
3469
3827
|
return { message: this.t("success.passwordReset") };
|
|
3470
3828
|
}
|
|
3471
3829
|
};
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3830
|
+
__decorate18([
|
|
3831
|
+
Inject12(AUTH_CONFIG),
|
|
3832
|
+
__metadata18("design:type", Object)
|
|
3475
3833
|
], AuthService.prototype, "config", void 0);
|
|
3476
|
-
|
|
3834
|
+
__decorate18([
|
|
3477
3835
|
I18n8("auth"),
|
|
3478
|
-
|
|
3836
|
+
__metadata18("design:type", Object)
|
|
3479
3837
|
], AuthService.prototype, "t", void 0);
|
|
3480
|
-
|
|
3838
|
+
__decorate18([
|
|
3481
3839
|
Log(),
|
|
3482
|
-
|
|
3840
|
+
__metadata18("design:type", Object)
|
|
3483
3841
|
], AuthService.prototype, "logger", void 0);
|
|
3484
|
-
|
|
3842
|
+
__decorate18([
|
|
3485
3843
|
Transaction4(),
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3844
|
+
__metadata18("design:type", Function),
|
|
3845
|
+
__metadata18("design:paramtypes", [Object]),
|
|
3846
|
+
__metadata18("design:returntype", typeof (_l = typeof Promise !== "undefined" && Promise) === "function" ? _l : Object)
|
|
3489
3847
|
], AuthService.prototype, "provisionWithCredentialSetup", null);
|
|
3490
|
-
AuthService =
|
|
3491
|
-
|
|
3492
|
-
|
|
3848
|
+
AuthService = __decorate18([
|
|
3849
|
+
Injectable12(),
|
|
3850
|
+
__metadata18("design:paramtypes", [typeof (_a12 = typeof TokenService !== "undefined" && TokenService) === "function" ? _a12 : Object, typeof (_b10 = typeof UserService !== "undefined" && UserService) === "function" ? _b10 : Object, typeof (_c7 = typeof UserValidator !== "undefined" && UserValidator) === "function" ? _c7 : Object, typeof (_d6 = typeof EncryptionService !== "undefined" && EncryptionService) === "function" ? _d6 : Object, typeof (_e5 = typeof CookieManager !== "undefined" && CookieManager) === "function" ? _e5 : Object, typeof (_f4 = typeof I18nService2 !== "undefined" && I18nService2) === "function" ? _f4 : Object, typeof (_g3 = typeof EmailService !== "undefined" && EmailService) === "function" ? _g3 : Object, typeof (_h2 = typeof AuthSessionService !== "undefined" && AuthSessionService) === "function" ? _h2 : Object, typeof (_j2 = typeof CredentialSetupRequirementService !== "undefined" && CredentialSetupRequirementService) === "function" ? _j2 : Object, typeof (_k = typeof PasswordSetupService !== "undefined" && PasswordSetupService) === "function" ? _k : Object])
|
|
3493
3851
|
], AuthService);
|
|
3494
3852
|
|
|
3495
3853
|
// src/auth/AuthGuard.ts
|
|
3496
3854
|
import { Service as Service2, User } from "najm-core";
|
|
3497
3855
|
import { createGuard } from "najm-guard";
|
|
3498
|
-
var
|
|
3856
|
+
var __decorate19 = function(decorators, target, key, desc) {
|
|
3499
3857
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3500
3858
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3501
3859
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
3502
3860
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3503
3861
|
};
|
|
3504
|
-
var
|
|
3862
|
+
var __metadata19 = function(k, v) {
|
|
3505
3863
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3506
3864
|
};
|
|
3507
3865
|
var __param3 = function(paramIndex, decorator) {
|
|
@@ -3513,17 +3871,27 @@ var AuthGuard = class AuthGuard2 {
|
|
|
3513
3871
|
static {
|
|
3514
3872
|
__name(this, "AuthGuard");
|
|
3515
3873
|
}
|
|
3874
|
+
/**
|
|
3875
|
+
* A resolved principal is not automatically an authorized one.
|
|
3876
|
+
*
|
|
3877
|
+
* The resolvers ahead of this guard already reject deactivated accounts, so
|
|
3878
|
+
* this is the backstop for anything that publishes a principal by another
|
|
3879
|
+
* route: a truthy user record must still be an active one to pass. Records
|
|
3880
|
+
* whose projection omits `status` are unchanged.
|
|
3881
|
+
*/
|
|
3516
3882
|
canActivate(user) {
|
|
3517
|
-
|
|
3883
|
+
if (!user)
|
|
3884
|
+
return false;
|
|
3885
|
+
return user.status === void 0 || user.status === "active";
|
|
3518
3886
|
}
|
|
3519
3887
|
};
|
|
3520
|
-
|
|
3888
|
+
__decorate19([
|
|
3521
3889
|
__param3(0, User()),
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3890
|
+
__metadata19("design:type", Function),
|
|
3891
|
+
__metadata19("design:paramtypes", [Object]),
|
|
3892
|
+
__metadata19("design:returntype", Boolean)
|
|
3525
3893
|
], AuthGuard.prototype, "canActivate", null);
|
|
3526
|
-
AuthGuard =
|
|
3894
|
+
AuthGuard = __decorate19([
|
|
3527
3895
|
Service2()
|
|
3528
3896
|
], AuthGuard);
|
|
3529
3897
|
var isAuth = createGuard(AuthGuard);
|
|
@@ -3532,13 +3900,13 @@ var isAuth = createGuard(AuthGuard);
|
|
|
3532
3900
|
import { Service as Service3 } from "najm-core";
|
|
3533
3901
|
import { GuardParams, Role as RequestRole } from "najm-core";
|
|
3534
3902
|
import { composeGuards, createGuard as createGuard2 } from "najm-guard";
|
|
3535
|
-
var
|
|
3903
|
+
var __decorate20 = function(decorators, target, key, desc) {
|
|
3536
3904
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3537
3905
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3538
3906
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
3539
3907
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3540
3908
|
};
|
|
3541
|
-
var
|
|
3909
|
+
var __metadata20 = function(k, v) {
|
|
3542
3910
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3543
3911
|
};
|
|
3544
3912
|
var __param4 = function(paramIndex, decorator) {
|
|
@@ -3561,14 +3929,14 @@ var RoleGuard = class RoleGuard2 {
|
|
|
3561
3929
|
return false;
|
|
3562
3930
|
}
|
|
3563
3931
|
};
|
|
3564
|
-
|
|
3932
|
+
__decorate20([
|
|
3565
3933
|
__param4(0, GuardParams()),
|
|
3566
3934
|
__param4(1, RequestRole()),
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3935
|
+
__metadata20("design:type", Function),
|
|
3936
|
+
__metadata20("design:paramtypes", [Object, String]),
|
|
3937
|
+
__metadata20("design:returntype", void 0)
|
|
3570
3938
|
], RoleGuard.prototype, "canActivate", null);
|
|
3571
|
-
RoleGuard =
|
|
3939
|
+
RoleGuard = __decorate20([
|
|
3572
3940
|
Service3()
|
|
3573
3941
|
], RoleGuard);
|
|
3574
3942
|
var Role = createGuard2(RoleGuard);
|
|
@@ -3739,13 +4107,13 @@ var userListQuery = z.object({
|
|
|
3739
4107
|
});
|
|
3740
4108
|
|
|
3741
4109
|
// src/auth/AuthController.ts
|
|
3742
|
-
var
|
|
4110
|
+
var __decorate21 = function(decorators, target, key, desc) {
|
|
3743
4111
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3744
4112
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3745
4113
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
3746
4114
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3747
4115
|
};
|
|
3748
|
-
var
|
|
4116
|
+
var __metadata21 = function(k, v) {
|
|
3749
4117
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3750
4118
|
};
|
|
3751
4119
|
var __param5 = function(paramIndex, decorator) {
|
|
@@ -3753,18 +4121,28 @@ var __param5 = function(paramIndex, decorator) {
|
|
|
3753
4121
|
decorator(target, key, paramIndex);
|
|
3754
4122
|
};
|
|
3755
4123
|
};
|
|
3756
|
-
var
|
|
4124
|
+
var _a13;
|
|
3757
4125
|
var hashKeyPart = /* @__PURE__ */ __name((value) => createHash3("sha256").update(value).digest("base64url").slice(0, 32), "hashKeyPart");
|
|
3758
4126
|
var cookieFingerprint = /* @__PURE__ */ __name(() => (ctx, { clientIp }) => {
|
|
3759
4127
|
const cookie = ctx.req.raw.headers.get("cookie") ?? "";
|
|
3760
4128
|
const fingerprint = cookie ? hashKeyPart(cookie) : "none";
|
|
3761
4129
|
return `${clientIp}:${fingerprint}`;
|
|
3762
4130
|
}, "cookieFingerprint");
|
|
3763
|
-
var
|
|
4131
|
+
var readDeclaredIdentity = /* @__PURE__ */ __name((body, fields) => {
|
|
4132
|
+
if (typeof body !== "object" || body === null || Array.isArray(body))
|
|
4133
|
+
return void 0;
|
|
4134
|
+
for (const field of fields) {
|
|
4135
|
+
const value = body[field];
|
|
4136
|
+
if (typeof value === "string" && value.trim())
|
|
4137
|
+
return value;
|
|
4138
|
+
}
|
|
4139
|
+
return void 0;
|
|
4140
|
+
}, "readDeclaredIdentity");
|
|
4141
|
+
var identityRateLimitKey = /* @__PURE__ */ __name((fields) => async (ctx, keyContext) => {
|
|
3764
4142
|
const ip = keyContext?.clientIp ?? UNRESOLVED_CLIENT_ADDRESS;
|
|
3765
4143
|
try {
|
|
3766
4144
|
const body = await ctx.req.json();
|
|
3767
|
-
const identity = body
|
|
4145
|
+
const identity = readDeclaredIdentity(body, fields);
|
|
3768
4146
|
const normalizedIdentity = getRequestIdentityResolver(ctx)(identity);
|
|
3769
4147
|
if (normalizedIdentity) {
|
|
3770
4148
|
return `${ip}:${hashKeyPart(normalizedIdentity)}`;
|
|
@@ -3772,7 +4150,9 @@ var authIdentityRateLimitKey = /* @__PURE__ */ __name(async (ctx, keyContext) =>
|
|
|
3772
4150
|
} catch {
|
|
3773
4151
|
}
|
|
3774
4152
|
return ip;
|
|
3775
|
-
}, "
|
|
4153
|
+
}, "identityRateLimitKey");
|
|
4154
|
+
var authIdentityRateLimitKey = identityRateLimitKey(["identifier", "email"]);
|
|
4155
|
+
var authEmailRateLimitKey = identityRateLimitKey(["email"]);
|
|
3776
4156
|
var loginRateLimit = resolveAuthLoginRateLimitConfig();
|
|
3777
4157
|
var AuthController = class AuthController2 {
|
|
3778
4158
|
static {
|
|
@@ -3815,7 +4195,7 @@ var AuthController = class AuthController2 {
|
|
|
3815
4195
|
return this.authService.resetPassword(body.token, body.newPassword);
|
|
3816
4196
|
}
|
|
3817
4197
|
};
|
|
3818
|
-
|
|
4198
|
+
__decorate21([
|
|
3819
4199
|
Post("/login"),
|
|
3820
4200
|
RateLimit({
|
|
3821
4201
|
limit: loginRateLimit.limit,
|
|
@@ -3827,105 +4207,105 @@ __decorate20([
|
|
|
3827
4207
|
Validate(loginDto),
|
|
3828
4208
|
ResMsg("auth.success.login"),
|
|
3829
4209
|
__param5(0, Body()),
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
4210
|
+
__metadata21("design:type", Function),
|
|
4211
|
+
__metadata21("design:paramtypes", [Object]),
|
|
4212
|
+
__metadata21("design:returntype", Promise)
|
|
3833
4213
|
], AuthController.prototype, "loginUser", null);
|
|
3834
|
-
|
|
4214
|
+
__decorate21([
|
|
3835
4215
|
Post("/invite"),
|
|
3836
4216
|
isAdmin(),
|
|
3837
4217
|
RateLimit({ limit: 20, window: "15m", key: "user" }),
|
|
3838
4218
|
Validate(inviteUserDto),
|
|
3839
4219
|
ResMsg("auth.success.accountInviteSent"),
|
|
3840
4220
|
__param5(0, Body()),
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
4221
|
+
__metadata21("design:type", Function),
|
|
4222
|
+
__metadata21("design:paramtypes", [Object]),
|
|
4223
|
+
__metadata21("design:returntype", Promise)
|
|
3844
4224
|
], AuthController.prototype, "inviteUser", null);
|
|
3845
|
-
|
|
4225
|
+
__decorate21([
|
|
3846
4226
|
Post("/refresh"),
|
|
3847
4227
|
RateLimit({ limit: 15, window: "15m", key: cookieFingerprint() }),
|
|
3848
4228
|
ResMsg("auth.success.tokenRefreshed"),
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
4229
|
+
__metadata21("design:type", Function),
|
|
4230
|
+
__metadata21("design:paramtypes", []),
|
|
4231
|
+
__metadata21("design:returntype", Promise)
|
|
3852
4232
|
], AuthController.prototype, "refreshTokens", null);
|
|
3853
|
-
|
|
4233
|
+
__decorate21([
|
|
3854
4234
|
Post("/session/recover"),
|
|
3855
4235
|
RateLimit({ limit: 120, window: "1m", key: cookieFingerprint() }),
|
|
3856
4236
|
ResMsg("auth.success.sessionRecovered"),
|
|
3857
4237
|
__param5(0, Headers("x-najm-session-recovery")),
|
|
3858
4238
|
__param5(1, Ctx()),
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
4239
|
+
__metadata21("design:type", Function),
|
|
4240
|
+
__metadata21("design:paramtypes", [String, Object]),
|
|
4241
|
+
__metadata21("design:returntype", Promise)
|
|
3862
4242
|
], AuthController.prototype, "recoverSession", null);
|
|
3863
|
-
|
|
4243
|
+
__decorate21([
|
|
3864
4244
|
Post("/logout"),
|
|
3865
4245
|
__param5(0, User2("id")),
|
|
3866
4246
|
__param5(1, Headers("authorization")),
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
4247
|
+
__metadata21("design:type", Function),
|
|
4248
|
+
__metadata21("design:paramtypes", [String, String]),
|
|
4249
|
+
__metadata21("design:returntype", Promise)
|
|
3870
4250
|
], AuthController.prototype, "logoutUser", null);
|
|
3871
|
-
|
|
4251
|
+
__decorate21([
|
|
3872
4252
|
Post("/change-password"),
|
|
3873
4253
|
isAuth(),
|
|
3874
4254
|
Validate(changePasswordDto),
|
|
3875
4255
|
ResMsg("auth.success.passwordChanged"),
|
|
3876
4256
|
__param5(0, User2("id")),
|
|
3877
4257
|
__param5(1, Body()),
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
4258
|
+
__metadata21("design:type", Function),
|
|
4259
|
+
__metadata21("design:paramtypes", [String, Object]),
|
|
4260
|
+
__metadata21("design:returntype", Promise)
|
|
3881
4261
|
], AuthController.prototype, "changePassword", null);
|
|
3882
|
-
|
|
4262
|
+
__decorate21([
|
|
3883
4263
|
Get("/me"),
|
|
3884
4264
|
RateLimit({ limit: 30, window: "1m", key: cookieFingerprint() }),
|
|
3885
4265
|
ResMsg("auth.users.success.retrieved"),
|
|
3886
4266
|
__param5(0, Headers("authorization")),
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
4267
|
+
__metadata21("design:type", Function),
|
|
4268
|
+
__metadata21("design:paramtypes", [String]),
|
|
4269
|
+
__metadata21("design:returntype", Promise)
|
|
3890
4270
|
], AuthController.prototype, "userProfile", null);
|
|
3891
|
-
|
|
4271
|
+
__decorate21([
|
|
3892
4272
|
Post("/forgot-password"),
|
|
3893
|
-
RateLimit({ limit: 3, window: "15m", key:
|
|
4273
|
+
RateLimit({ limit: 3, window: "15m", key: authEmailRateLimitKey, message: "Too many password reset requests. Please try again later." }),
|
|
3894
4274
|
Validate(resetPasswordDto),
|
|
3895
4275
|
ResMsg("auth.success.passwordResetSent"),
|
|
3896
4276
|
__param5(0, Body()),
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
4277
|
+
__metadata21("design:type", Function),
|
|
4278
|
+
__metadata21("design:paramtypes", [Object]),
|
|
4279
|
+
__metadata21("design:returntype", Promise)
|
|
3900
4280
|
], AuthController.prototype, "forgotPassword", null);
|
|
3901
|
-
|
|
4281
|
+
__decorate21([
|
|
3902
4282
|
Post("/reset-password"),
|
|
3903
4283
|
RateLimit({ limit: 5, window: "15m", key: "ip", message: "Too many password reset attempts. Please try again later." }),
|
|
3904
4284
|
Validate(confirmResetPasswordDto),
|
|
3905
4285
|
ResMsg("auth.success.passwordReset"),
|
|
3906
4286
|
__param5(0, Body()),
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
4287
|
+
__metadata21("design:type", Function),
|
|
4288
|
+
__metadata21("design:paramtypes", [Object]),
|
|
4289
|
+
__metadata21("design:returntype", Promise)
|
|
3910
4290
|
], AuthController.prototype, "resetPassword", null);
|
|
3911
|
-
AuthController =
|
|
4291
|
+
AuthController = __decorate21([
|
|
3912
4292
|
Controller("/auth"),
|
|
3913
|
-
|
|
4293
|
+
__metadata21("design:paramtypes", [typeof (_a13 = typeof AuthService !== "undefined" && AuthService) === "function" ? _a13 : Object])
|
|
3914
4294
|
], AuthController);
|
|
3915
4295
|
|
|
3916
4296
|
// src/auth/AuthResolver.ts
|
|
3917
|
-
import { APP, Container, DI, Inject as
|
|
4297
|
+
import { APP, Container, DI, Inject as Inject13, LOGGER, Meta, Service as Service4 } from "najm-core";
|
|
3918
4298
|
import { USER, ROLE, PERMISSIONS } from "najm-guard";
|
|
3919
|
-
var
|
|
4299
|
+
var __decorate22 = function(decorators, target, key, desc) {
|
|
3920
4300
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3921
4301
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3922
4302
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
3923
4303
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3924
4304
|
};
|
|
3925
|
-
var
|
|
4305
|
+
var __metadata22 = function(k, v) {
|
|
3926
4306
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3927
4307
|
};
|
|
3928
|
-
var
|
|
4308
|
+
var _a14;
|
|
3929
4309
|
var AuthResolver = class AuthResolver2 {
|
|
3930
4310
|
static {
|
|
3931
4311
|
__name(this, "AuthResolver");
|
|
@@ -3976,6 +4356,12 @@ var AuthResolver = class AuthResolver2 {
|
|
|
3976
4356
|
const currentVersion = await tokenService.getSessionVersion(session.user.id);
|
|
3977
4357
|
if ((session.sessionVersion ?? 0) !== currentVersion)
|
|
3978
4358
|
return false;
|
|
4359
|
+
if (!await tokenService.isSessionFamilyLive(session.tokenFamily, session.user.id)) {
|
|
4360
|
+
return false;
|
|
4361
|
+
}
|
|
4362
|
+
const status = session.user.status;
|
|
4363
|
+
if (status !== void 0 && status !== "active")
|
|
4364
|
+
return false;
|
|
3979
4365
|
return {
|
|
3980
4366
|
user: { ...session.user, permissions: session.permissions },
|
|
3981
4367
|
role: session.user.role ?? session.roles[0],
|
|
@@ -4041,32 +4427,32 @@ var AuthResolver = class AuthResolver2 {
|
|
|
4041
4427
|
await authService.warmupPasswordHash();
|
|
4042
4428
|
}
|
|
4043
4429
|
};
|
|
4044
|
-
|
|
4430
|
+
__decorate22([
|
|
4045
4431
|
DI(),
|
|
4046
|
-
|
|
4432
|
+
__metadata22("design:type", typeof (_a14 = typeof Container !== "undefined" && Container) === "function" ? _a14 : Object)
|
|
4047
4433
|
], AuthResolver.prototype, "container", void 0);
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4434
|
+
__decorate22([
|
|
4435
|
+
Inject13(APP),
|
|
4436
|
+
__metadata22("design:type", Object)
|
|
4051
4437
|
], AuthResolver.prototype, "app", void 0);
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4438
|
+
__decorate22([
|
|
4439
|
+
Inject13(LOGGER),
|
|
4440
|
+
__metadata22("design:type", Object)
|
|
4055
4441
|
], AuthResolver.prototype, "log", void 0);
|
|
4056
|
-
AuthResolver =
|
|
4442
|
+
AuthResolver = __decorate22([
|
|
4057
4443
|
Service4(),
|
|
4058
4444
|
Meta({ layer: "plugin", order: 30 })
|
|
4059
4445
|
], AuthResolver);
|
|
4060
4446
|
|
|
4061
4447
|
// src/auth/AuthIdentityContextService.ts
|
|
4062
|
-
import { DI as DI2, Inject as
|
|
4063
|
-
var
|
|
4448
|
+
import { DI as DI2, Inject as Inject14, INJECTION_TYPES, Meta as Meta2, Service as Service5 } from "najm-core";
|
|
4449
|
+
var __decorate23 = function(decorators, target, key, desc) {
|
|
4064
4450
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4065
4451
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4066
4452
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
4067
4453
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4068
4454
|
};
|
|
4069
|
-
var
|
|
4455
|
+
var __metadata23 = function(k, v) {
|
|
4070
4456
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4071
4457
|
};
|
|
4072
4458
|
var __param6 = function(paramIndex, decorator) {
|
|
@@ -4096,28 +4482,28 @@ var AuthIdentityContextService = class AuthIdentityContextService2 {
|
|
|
4096
4482
|
});
|
|
4097
4483
|
}
|
|
4098
4484
|
};
|
|
4099
|
-
|
|
4485
|
+
__decorate23([
|
|
4100
4486
|
DI2(),
|
|
4101
|
-
|
|
4487
|
+
__metadata23("design:type", Object)
|
|
4102
4488
|
], AuthIdentityContextService.prototype, "container", void 0);
|
|
4103
|
-
AuthIdentityContextService =
|
|
4489
|
+
AuthIdentityContextService = __decorate23([
|
|
4104
4490
|
Service5(),
|
|
4105
4491
|
Meta2({ layer: "plugin", order: 14 }),
|
|
4106
|
-
__param6(0,
|
|
4107
|
-
|
|
4492
|
+
__param6(0, Inject14(AUTH_CONFIG)),
|
|
4493
|
+
__metadata23("design:paramtypes", [Object])
|
|
4108
4494
|
], AuthIdentityContextService);
|
|
4109
4495
|
|
|
4110
4496
|
// src/auth/RegistrationController.ts
|
|
4111
4497
|
import { Body as Body2, Controller as Controller2, Post as Post2, ResMsg as ResMsg2 } from "najm-core";
|
|
4112
4498
|
import { RateLimit as RateLimit2 } from "najm-rate";
|
|
4113
4499
|
import { Validate as Validate2 } from "najm-validation";
|
|
4114
|
-
var
|
|
4500
|
+
var __decorate24 = function(decorators, target, key, desc) {
|
|
4115
4501
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4116
4502
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4117
4503
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
4118
4504
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4119
4505
|
};
|
|
4120
|
-
var
|
|
4506
|
+
var __metadata24 = function(k, v) {
|
|
4121
4507
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4122
4508
|
};
|
|
4123
4509
|
var __param7 = function(paramIndex, decorator) {
|
|
@@ -4125,7 +4511,7 @@ var __param7 = function(paramIndex, decorator) {
|
|
|
4125
4511
|
decorator(target, key, paramIndex);
|
|
4126
4512
|
};
|
|
4127
4513
|
};
|
|
4128
|
-
var
|
|
4514
|
+
var _a15;
|
|
4129
4515
|
var RegistrationController = class RegistrationController2 {
|
|
4130
4516
|
static {
|
|
4131
4517
|
__name(this, "RegistrationController");
|
|
@@ -4138,19 +4524,19 @@ var RegistrationController = class RegistrationController2 {
|
|
|
4138
4524
|
return this.authService.registerUser(body);
|
|
4139
4525
|
}
|
|
4140
4526
|
};
|
|
4141
|
-
|
|
4527
|
+
__decorate24([
|
|
4142
4528
|
Post2("/register"),
|
|
4143
|
-
RateLimit2({ limit: 5, window: "15m", key:
|
|
4529
|
+
RateLimit2({ limit: 5, window: "15m", key: authEmailRateLimitKey }),
|
|
4144
4530
|
Validate2(registerDto),
|
|
4145
4531
|
ResMsg2("auth.success.register"),
|
|
4146
4532
|
__param7(0, Body2()),
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4533
|
+
__metadata24("design:type", Function),
|
|
4534
|
+
__metadata24("design:paramtypes", [Object]),
|
|
4535
|
+
__metadata24("design:returntype", Promise)
|
|
4150
4536
|
], RegistrationController.prototype, "registerUser", null);
|
|
4151
|
-
RegistrationController =
|
|
4537
|
+
RegistrationController = __decorate24([
|
|
4152
4538
|
Controller2("/auth"),
|
|
4153
|
-
|
|
4539
|
+
__metadata24("design:paramtypes", [typeof (_a15 = typeof AuthService !== "undefined" && AuthService) === "function" ? _a15 : Object])
|
|
4154
4540
|
], RegistrationController);
|
|
4155
4541
|
|
|
4156
4542
|
// src/auth/runAsUser.ts
|
|
@@ -4301,13 +4687,13 @@ var assignRoleDto = z2.object({
|
|
|
4301
4687
|
});
|
|
4302
4688
|
|
|
4303
4689
|
// src/roles/RoleController.ts
|
|
4304
|
-
var
|
|
4690
|
+
var __decorate25 = function(decorators, target, key, desc) {
|
|
4305
4691
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4306
4692
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4307
4693
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
4308
4694
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4309
4695
|
};
|
|
4310
|
-
var
|
|
4696
|
+
var __metadata25 = function(k, v) {
|
|
4311
4697
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4312
4698
|
};
|
|
4313
4699
|
var __param8 = function(paramIndex, decorator) {
|
|
@@ -4315,7 +4701,7 @@ var __param8 = function(paramIndex, decorator) {
|
|
|
4315
4701
|
decorator(target, key, paramIndex);
|
|
4316
4702
|
};
|
|
4317
4703
|
};
|
|
4318
|
-
var
|
|
4704
|
+
var _a16;
|
|
4319
4705
|
var RoleController = class RoleController2 {
|
|
4320
4706
|
static {
|
|
4321
4707
|
__name(this, "RoleController");
|
|
@@ -4340,35 +4726,35 @@ var RoleController = class RoleController2 {
|
|
|
4340
4726
|
return this.roleService.delete(params.id);
|
|
4341
4727
|
}
|
|
4342
4728
|
};
|
|
4343
|
-
|
|
4729
|
+
__decorate25([
|
|
4344
4730
|
Get2(),
|
|
4345
4731
|
isAdmin(),
|
|
4346
4732
|
ResMsg3("roles.success.retrieved"),
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4733
|
+
__metadata25("design:type", Function),
|
|
4734
|
+
__metadata25("design:paramtypes", []),
|
|
4735
|
+
__metadata25("design:returntype", Promise)
|
|
4350
4736
|
], RoleController.prototype, "getRoles", null);
|
|
4351
|
-
|
|
4737
|
+
__decorate25([
|
|
4352
4738
|
Get2("/:id"),
|
|
4353
4739
|
isAdmin(),
|
|
4354
4740
|
Validate3({ params: roleIdParam }),
|
|
4355
4741
|
ResMsg3("roles.success.retrieved"),
|
|
4356
4742
|
__param8(0, Params()),
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4743
|
+
__metadata25("design:type", Function),
|
|
4744
|
+
__metadata25("design:paramtypes", [Object]),
|
|
4745
|
+
__metadata25("design:returntype", Promise)
|
|
4360
4746
|
], RoleController.prototype, "getRole", null);
|
|
4361
|
-
|
|
4747
|
+
__decorate25([
|
|
4362
4748
|
Post3(),
|
|
4363
4749
|
isAdmin(),
|
|
4364
4750
|
Validate3(createRoleDto),
|
|
4365
4751
|
ResMsg3("roles.success.created"),
|
|
4366
4752
|
__param8(0, Body3()),
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4753
|
+
__metadata25("design:type", Function),
|
|
4754
|
+
__metadata25("design:paramtypes", [Object]),
|
|
4755
|
+
__metadata25("design:returntype", Promise)
|
|
4370
4756
|
], RoleController.prototype, "createRole", null);
|
|
4371
|
-
|
|
4757
|
+
__decorate25([
|
|
4372
4758
|
Put("/:id"),
|
|
4373
4759
|
isAdmin(),
|
|
4374
4760
|
Validate3({
|
|
@@ -4378,34 +4764,34 @@ __decorate24([
|
|
|
4378
4764
|
ResMsg3("roles.success.updated"),
|
|
4379
4765
|
__param8(0, Params()),
|
|
4380
4766
|
__param8(1, Body3()),
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4767
|
+
__metadata25("design:type", Function),
|
|
4768
|
+
__metadata25("design:paramtypes", [Object, Object]),
|
|
4769
|
+
__metadata25("design:returntype", Promise)
|
|
4384
4770
|
], RoleController.prototype, "updateRole", null);
|
|
4385
|
-
|
|
4771
|
+
__decorate25([
|
|
4386
4772
|
Delete("/:id"),
|
|
4387
4773
|
isAdmin(),
|
|
4388
4774
|
Validate3({ params: roleIdParam }),
|
|
4389
4775
|
ResMsg3("roles.success.deleted"),
|
|
4390
4776
|
__param8(0, Params()),
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4777
|
+
__metadata25("design:type", Function),
|
|
4778
|
+
__metadata25("design:paramtypes", [Object]),
|
|
4779
|
+
__metadata25("design:returntype", Promise)
|
|
4394
4780
|
], RoleController.prototype, "deleteRole", null);
|
|
4395
|
-
RoleController =
|
|
4781
|
+
RoleController = __decorate25([
|
|
4396
4782
|
Controller3("/roles"),
|
|
4397
|
-
|
|
4783
|
+
__metadata25("design:paramtypes", [typeof (_a16 = typeof RoleService !== "undefined" && RoleService) === "function" ? _a16 : Object])
|
|
4398
4784
|
], RoleController);
|
|
4399
4785
|
|
|
4400
4786
|
// src/users/UserController.ts
|
|
4401
4787
|
import { Validate as Validate4 } from "najm-validation";
|
|
4402
|
-
var
|
|
4788
|
+
var __decorate26 = function(decorators, target, key, desc) {
|
|
4403
4789
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4404
4790
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4405
4791
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
4406
4792
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4407
4793
|
};
|
|
4408
|
-
var
|
|
4794
|
+
var __metadata26 = function(k, v) {
|
|
4409
4795
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4410
4796
|
};
|
|
4411
4797
|
var __param9 = function(paramIndex, decorator) {
|
|
@@ -4413,7 +4799,7 @@ var __param9 = function(paramIndex, decorator) {
|
|
|
4413
4799
|
decorator(target, key, paramIndex);
|
|
4414
4800
|
};
|
|
4415
4801
|
};
|
|
4416
|
-
var
|
|
4802
|
+
var _a17;
|
|
4417
4803
|
var UserController = class UserController2 {
|
|
4418
4804
|
static {
|
|
4419
4805
|
__name(this, "UserController");
|
|
@@ -4460,75 +4846,75 @@ var UserController = class UserController2 {
|
|
|
4460
4846
|
return this.userService.removeRole(params.userId);
|
|
4461
4847
|
}
|
|
4462
4848
|
};
|
|
4463
|
-
|
|
4849
|
+
__decorate26([
|
|
4464
4850
|
Get3(),
|
|
4465
4851
|
isAdmin(),
|
|
4466
4852
|
Validate4({ query: userListQuery }),
|
|
4467
4853
|
ResMsg4("users.success.retrieved"),
|
|
4468
4854
|
__param9(0, Query()),
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4855
|
+
__metadata26("design:type", Function),
|
|
4856
|
+
__metadata26("design:paramtypes", [Object]),
|
|
4857
|
+
__metadata26("design:returntype", Promise)
|
|
4472
4858
|
], UserController.prototype, "getUsers", null);
|
|
4473
|
-
|
|
4859
|
+
__decorate26([
|
|
4474
4860
|
Get3("/lang"),
|
|
4475
4861
|
isAuth(),
|
|
4476
4862
|
ResMsg4("users.success.retrieved"),
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4863
|
+
__metadata26("design:type", Function),
|
|
4864
|
+
__metadata26("design:paramtypes", []),
|
|
4865
|
+
__metadata26("design:returntype", Promise)
|
|
4480
4866
|
], UserController.prototype, "getLang", null);
|
|
4481
|
-
|
|
4867
|
+
__decorate26([
|
|
4482
4868
|
Post4("/lang/:language"),
|
|
4483
4869
|
isAuth(),
|
|
4484
4870
|
Validate4({ params: languageParam }),
|
|
4485
4871
|
ResMsg4("users.success.updated"),
|
|
4486
4872
|
__param9(0, Params2()),
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4873
|
+
__metadata26("design:type", Function),
|
|
4874
|
+
__metadata26("design:paramtypes", [Object]),
|
|
4875
|
+
__metadata26("design:returntype", Promise)
|
|
4490
4876
|
], UserController.prototype, "updateLang", null);
|
|
4491
|
-
|
|
4877
|
+
__decorate26([
|
|
4492
4878
|
Get3("/:id"),
|
|
4493
4879
|
isAdmin(),
|
|
4494
4880
|
Validate4({ params: userIdParam }),
|
|
4495
4881
|
ResMsg4("users.success.retrieved"),
|
|
4496
4882
|
__param9(0, Params2()),
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4883
|
+
__metadata26("design:type", Function),
|
|
4884
|
+
__metadata26("design:paramtypes", [Object]),
|
|
4885
|
+
__metadata26("design:returntype", Promise)
|
|
4500
4886
|
], UserController.prototype, "getUser", null);
|
|
4501
|
-
|
|
4887
|
+
__decorate26([
|
|
4502
4888
|
Get3("/email/:email"),
|
|
4503
4889
|
isAdmin(),
|
|
4504
4890
|
Validate4({ params: emailParam }),
|
|
4505
4891
|
ResMsg4("users.success.retrieved"),
|
|
4506
4892
|
__param9(0, Params2()),
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4893
|
+
__metadata26("design:type", Function),
|
|
4894
|
+
__metadata26("design:paramtypes", [Object]),
|
|
4895
|
+
__metadata26("design:returntype", Promise)
|
|
4510
4896
|
], UserController.prototype, "getByEmail", null);
|
|
4511
|
-
|
|
4897
|
+
__decorate26([
|
|
4512
4898
|
Get3("/role/:userId"),
|
|
4513
4899
|
isAdmin(),
|
|
4514
4900
|
Validate4({ params: userIdInParam }),
|
|
4515
4901
|
ResMsg4("users.success.retrieved"),
|
|
4516
4902
|
__param9(0, Params2()),
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4903
|
+
__metadata26("design:type", Function),
|
|
4904
|
+
__metadata26("design:paramtypes", [Object]),
|
|
4905
|
+
__metadata26("design:returntype", Promise)
|
|
4520
4906
|
], UserController.prototype, "getRole", null);
|
|
4521
|
-
|
|
4907
|
+
__decorate26([
|
|
4522
4908
|
Post4(),
|
|
4523
4909
|
isAdmin(),
|
|
4524
4910
|
Validate4(createUserDto),
|
|
4525
|
-
ResMsg4("users.success.created"),
|
|
4526
|
-
__param9(0, Body4()),
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4911
|
+
ResMsg4("users.success.created"),
|
|
4912
|
+
__param9(0, Body4()),
|
|
4913
|
+
__metadata26("design:type", Function),
|
|
4914
|
+
__metadata26("design:paramtypes", [Object]),
|
|
4915
|
+
__metadata26("design:returntype", Promise)
|
|
4530
4916
|
], UserController.prototype, "create", null);
|
|
4531
|
-
|
|
4917
|
+
__decorate26([
|
|
4532
4918
|
Put2("/:id"),
|
|
4533
4919
|
isAdmin(),
|
|
4534
4920
|
Validate4({
|
|
@@ -4538,51 +4924,51 @@ __decorate25([
|
|
|
4538
4924
|
ResMsg4("users.success.updated"),
|
|
4539
4925
|
__param9(0, Params2()),
|
|
4540
4926
|
__param9(1, Body4()),
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4927
|
+
__metadata26("design:type", Function),
|
|
4928
|
+
__metadata26("design:paramtypes", [Object, Object]),
|
|
4929
|
+
__metadata26("design:returntype", Promise)
|
|
4544
4930
|
], UserController.prototype, "update", null);
|
|
4545
|
-
|
|
4931
|
+
__decorate26([
|
|
4546
4932
|
Delete2("/:id"),
|
|
4547
4933
|
isAdmin(),
|
|
4548
4934
|
Validate4({ params: userIdParam }),
|
|
4549
4935
|
ResMsg4("users.success.deleted"),
|
|
4550
4936
|
__param9(0, Params2()),
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4937
|
+
__metadata26("design:type", Function),
|
|
4938
|
+
__metadata26("design:paramtypes", [Object]),
|
|
4939
|
+
__metadata26("design:returntype", Promise)
|
|
4554
4940
|
], UserController.prototype, "delete", null);
|
|
4555
|
-
|
|
4941
|
+
__decorate26([
|
|
4556
4942
|
Delete2(),
|
|
4557
4943
|
isAdmin(),
|
|
4558
4944
|
ResMsg4("users.success.allDeleted"),
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4945
|
+
__metadata26("design:type", Function),
|
|
4946
|
+
__metadata26("design:paramtypes", []),
|
|
4947
|
+
__metadata26("design:returntype", Promise)
|
|
4562
4948
|
], UserController.prototype, "deleteAll", null);
|
|
4563
|
-
|
|
4949
|
+
__decorate26([
|
|
4564
4950
|
Post4("/assign/:userId/:roleId"),
|
|
4565
4951
|
isAdmin(),
|
|
4566
4952
|
Validate4({ params: assignRoleParams }),
|
|
4567
4953
|
ResMsg4("users.success.updated"),
|
|
4568
4954
|
__param9(0, Params2()),
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4955
|
+
__metadata26("design:type", Function),
|
|
4956
|
+
__metadata26("design:paramtypes", [Object]),
|
|
4957
|
+
__metadata26("design:returntype", Promise)
|
|
4572
4958
|
], UserController.prototype, "assignRole", null);
|
|
4573
|
-
|
|
4959
|
+
__decorate26([
|
|
4574
4960
|
Delete2("/remove/:userId"),
|
|
4575
4961
|
isAdmin(),
|
|
4576
4962
|
Validate4({ params: userIdInParam }),
|
|
4577
4963
|
ResMsg4("users.success.updated"),
|
|
4578
4964
|
__param9(0, Params2()),
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4965
|
+
__metadata26("design:type", Function),
|
|
4966
|
+
__metadata26("design:paramtypes", [Object]),
|
|
4967
|
+
__metadata26("design:returntype", Promise)
|
|
4582
4968
|
], UserController.prototype, "removeRole", null);
|
|
4583
|
-
UserController =
|
|
4969
|
+
UserController = __decorate26([
|
|
4584
4970
|
Controller4("/users"),
|
|
4585
|
-
|
|
4971
|
+
__metadata26("design:paramtypes", [typeof (_a17 = typeof UserService !== "undefined" && UserService) === "function" ? _a17 : Object])
|
|
4586
4972
|
], UserController);
|
|
4587
4973
|
|
|
4588
4974
|
// src/permissions/index.ts
|
|
@@ -4603,15 +4989,15 @@ __export(permissions_exports, {
|
|
|
4603
4989
|
|
|
4604
4990
|
// src/permissions/PermissionRepository.ts
|
|
4605
4991
|
import { eq as eq7, and as and4 } from "drizzle-orm";
|
|
4606
|
-
import { Repository as Repository6, Inject as
|
|
4992
|
+
import { Repository as Repository6, Inject as Inject15 } from "najm-core";
|
|
4607
4993
|
import { DB as DB6 } from "najm-database";
|
|
4608
|
-
var
|
|
4994
|
+
var __decorate27 = function(decorators, target, key, desc) {
|
|
4609
4995
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4610
4996
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4611
4997
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
4612
4998
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4613
4999
|
};
|
|
4614
|
-
var
|
|
5000
|
+
var __metadata27 = function(k, v) {
|
|
4615
5001
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4616
5002
|
};
|
|
4617
5003
|
var PermissionRepository = class PermissionRepository2 {
|
|
@@ -4689,29 +5075,29 @@ var PermissionRepository = class PermissionRepository2 {
|
|
|
4689
5075
|
return deletedPermissions;
|
|
4690
5076
|
}
|
|
4691
5077
|
};
|
|
4692
|
-
|
|
5078
|
+
__decorate27([
|
|
4693
5079
|
DB6(),
|
|
4694
|
-
|
|
5080
|
+
__metadata27("design:type", Object)
|
|
4695
5081
|
], PermissionRepository.prototype, "db", void 0);
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
5082
|
+
__decorate27([
|
|
5083
|
+
Inject15(AUTH_SCHEMA),
|
|
5084
|
+
__metadata27("design:type", Object)
|
|
4699
5085
|
], PermissionRepository.prototype, "schema", void 0);
|
|
4700
|
-
PermissionRepository =
|
|
5086
|
+
PermissionRepository = __decorate27([
|
|
4701
5087
|
Repository6()
|
|
4702
5088
|
], PermissionRepository);
|
|
4703
5089
|
|
|
4704
5090
|
// src/permissions/PermissionGuards.ts
|
|
4705
|
-
import { Injectable as
|
|
5091
|
+
import { Injectable as Injectable13 } from "najm-core";
|
|
4706
5092
|
import { GuardParams as GuardParams2, User as User3 } from "najm-core";
|
|
4707
5093
|
import { createGuard as createGuard4, composeGuards as composeGuards3 } from "najm-guard";
|
|
4708
|
-
var
|
|
5094
|
+
var __decorate28 = function(decorators, target, key, desc) {
|
|
4709
5095
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4710
5096
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4711
5097
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
4712
5098
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4713
5099
|
};
|
|
4714
|
-
var
|
|
5100
|
+
var __metadata28 = function(k, v) {
|
|
4715
5101
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4716
5102
|
};
|
|
4717
5103
|
var __param10 = function(paramIndex, decorator) {
|
|
@@ -4747,15 +5133,15 @@ var PermissionGuard = class PermissionGuard2 {
|
|
|
4747
5133
|
return false;
|
|
4748
5134
|
}
|
|
4749
5135
|
};
|
|
4750
|
-
|
|
5136
|
+
__decorate28([
|
|
4751
5137
|
__param10(0, GuardParams2()),
|
|
4752
5138
|
__param10(1, User3("permissions")),
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
5139
|
+
__metadata28("design:type", Function),
|
|
5140
|
+
__metadata28("design:paramtypes", [String, Array]),
|
|
5141
|
+
__metadata28("design:returntype", Object)
|
|
4756
5142
|
], PermissionGuard.prototype, "canActivate", null);
|
|
4757
|
-
PermissionGuard =
|
|
4758
|
-
|
|
5143
|
+
PermissionGuard = __decorate28([
|
|
5144
|
+
Injectable13()
|
|
4759
5145
|
], PermissionGuard);
|
|
4760
5146
|
var Permission = createGuard4(PermissionGuard);
|
|
4761
5147
|
var Can = /* @__PURE__ */ __name((permission) => composeGuards3(isAuth(), Permission(permission))(), "Can");
|
|
@@ -4766,23 +5152,23 @@ import { Get as Get4, Post as Post5, Put as Put3, Delete as Delete3, ResMsg as R
|
|
|
4766
5152
|
import { Params as Params3, Body as Body5 } from "najm-core";
|
|
4767
5153
|
|
|
4768
5154
|
// src/permissions/PermissionService.ts
|
|
4769
|
-
import { Injectable as
|
|
5155
|
+
import { Injectable as Injectable15 } from "najm-core";
|
|
4770
5156
|
|
|
4771
5157
|
// src/permissions/PermissionValidator.ts
|
|
4772
|
-
import { Injectable as
|
|
5158
|
+
import { Injectable as Injectable14 } from "najm-core";
|
|
4773
5159
|
import { I18n as I18n9 } from "najm-i18n";
|
|
4774
5160
|
import { Err as Err14 } from "najm-core";
|
|
4775
|
-
var
|
|
5161
|
+
var __decorate29 = function(decorators, target, key, desc) {
|
|
4776
5162
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4777
5163
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4778
5164
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
4779
5165
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4780
5166
|
};
|
|
4781
|
-
var
|
|
5167
|
+
var __metadata29 = function(k, v) {
|
|
4782
5168
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4783
5169
|
};
|
|
4784
|
-
var
|
|
4785
|
-
var
|
|
5170
|
+
var _a18;
|
|
5171
|
+
var _b11;
|
|
4786
5172
|
var PermissionValidator = class PermissionValidator2 {
|
|
4787
5173
|
static {
|
|
4788
5174
|
__name(this, "PermissionValidator");
|
|
@@ -4849,28 +5235,30 @@ var PermissionValidator = class PermissionValidator2 {
|
|
|
4849
5235
|
}
|
|
4850
5236
|
}
|
|
4851
5237
|
};
|
|
4852
|
-
|
|
5238
|
+
__decorate29([
|
|
4853
5239
|
I18n9("permissions"),
|
|
4854
|
-
|
|
5240
|
+
__metadata29("design:type", Object)
|
|
4855
5241
|
], PermissionValidator.prototype, "t", void 0);
|
|
4856
|
-
PermissionValidator =
|
|
4857
|
-
|
|
4858
|
-
|
|
5242
|
+
PermissionValidator = __decorate29([
|
|
5243
|
+
Injectable14(),
|
|
5244
|
+
__metadata29("design:paramtypes", [typeof (_a18 = typeof PermissionRepository !== "undefined" && PermissionRepository) === "function" ? _a18 : Object, typeof (_b11 = typeof RoleValidator !== "undefined" && RoleValidator) === "function" ? _b11 : Object])
|
|
4859
5245
|
], PermissionValidator);
|
|
4860
5246
|
|
|
4861
5247
|
// src/permissions/PermissionService.ts
|
|
4862
|
-
var
|
|
5248
|
+
var __decorate30 = function(decorators, target, key, desc) {
|
|
4863
5249
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4864
5250
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4865
5251
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
4866
5252
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4867
5253
|
};
|
|
4868
|
-
var
|
|
5254
|
+
var __metadata30 = function(k, v) {
|
|
4869
5255
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4870
5256
|
};
|
|
4871
|
-
var
|
|
4872
|
-
var
|
|
5257
|
+
var _a19;
|
|
5258
|
+
var _b12;
|
|
4873
5259
|
var _c8;
|
|
5260
|
+
var _d7;
|
|
5261
|
+
var _e6;
|
|
4874
5262
|
var PermissionService = class PermissionService2 {
|
|
4875
5263
|
static {
|
|
4876
5264
|
__name(this, "PermissionService");
|
|
@@ -4878,10 +5266,30 @@ var PermissionService = class PermissionService2 {
|
|
|
4878
5266
|
permissionRepository;
|
|
4879
5267
|
permissionValidator;
|
|
4880
5268
|
roleService;
|
|
4881
|
-
|
|
5269
|
+
userRepository;
|
|
5270
|
+
sessionInvalidation;
|
|
5271
|
+
constructor(permissionRepository, permissionValidator, roleService, userRepository, sessionInvalidation) {
|
|
4882
5272
|
this.permissionRepository = permissionRepository;
|
|
4883
5273
|
this.permissionValidator = permissionValidator;
|
|
4884
5274
|
this.roleService = roleService;
|
|
5275
|
+
this.userRepository = userRepository;
|
|
5276
|
+
this.sessionInvalidation = sessionInvalidation;
|
|
5277
|
+
}
|
|
5278
|
+
/**
|
|
5279
|
+
* End the sessions of everyone holding a role whose permission set changed.
|
|
5280
|
+
*
|
|
5281
|
+
* Access tokens and signed session snapshots both carry permissions as
|
|
5282
|
+
* claims, so a permission removed from a role stays exercisable until the
|
|
5283
|
+
* sessions that captured it end. This is an infrequent administrative
|
|
5284
|
+
* action, and the work is proportional to the role's membership.
|
|
5285
|
+
*/
|
|
5286
|
+
async invalidateRoleHolders(roleId) {
|
|
5287
|
+
if (!this.userRepository || !this.sessionInvalidation)
|
|
5288
|
+
return;
|
|
5289
|
+
const userIds = await this.userRepository.getIdsByRole(roleId);
|
|
5290
|
+
for (const userId of userIds) {
|
|
5291
|
+
await this.sessionInvalidation.invalidateAccessTokens(userId);
|
|
5292
|
+
}
|
|
4885
5293
|
}
|
|
4886
5294
|
async getAll() {
|
|
4887
5295
|
return await this.permissionRepository.getAll();
|
|
@@ -4918,10 +5326,14 @@ var PermissionService = class PermissionService2 {
|
|
|
4918
5326
|
}
|
|
4919
5327
|
async assignPermissionToRole(roleId, permissionId) {
|
|
4920
5328
|
await this.permissionValidator.checkRoleHasPermission(roleId, permissionId);
|
|
4921
|
-
|
|
5329
|
+
const assigned = await this.permissionRepository.assignPermissionToRole(roleId, permissionId);
|
|
5330
|
+
await this.invalidateRoleHolders(roleId);
|
|
5331
|
+
return assigned;
|
|
4922
5332
|
}
|
|
4923
5333
|
async removePermissionFromRole(roleId, permissionId) {
|
|
4924
|
-
|
|
5334
|
+
const removed = await this.permissionRepository.removePermissionFromRole(roleId, permissionId);
|
|
5335
|
+
await this.invalidateRoleHolders(roleId);
|
|
5336
|
+
return removed;
|
|
4925
5337
|
}
|
|
4926
5338
|
async seedDefaultPermissions(defaultPermissions) {
|
|
4927
5339
|
const created = [];
|
|
@@ -4975,9 +5387,9 @@ var PermissionService = class PermissionService2 {
|
|
|
4975
5387
|
return await this.permissionRepository.deleteAll();
|
|
4976
5388
|
}
|
|
4977
5389
|
};
|
|
4978
|
-
PermissionService =
|
|
4979
|
-
|
|
4980
|
-
|
|
5390
|
+
PermissionService = __decorate30([
|
|
5391
|
+
Injectable15(),
|
|
5392
|
+
__metadata30("design:paramtypes", [typeof (_a19 = typeof PermissionRepository !== "undefined" && PermissionRepository) === "function" ? _a19 : Object, typeof (_b12 = typeof PermissionValidator !== "undefined" && PermissionValidator) === "function" ? _b12 : Object, typeof (_c8 = typeof RoleService !== "undefined" && RoleService) === "function" ? _c8 : Object, typeof (_d7 = typeof UserRepository !== "undefined" && UserRepository) === "function" ? _d7 : Object, typeof (_e6 = typeof SessionInvalidationService !== "undefined" && SessionInvalidationService) === "function" ? _e6 : Object])
|
|
4981
5393
|
], PermissionService);
|
|
4982
5394
|
|
|
4983
5395
|
// src/permissions/PermissionController.ts
|
|
@@ -5010,13 +5422,13 @@ var checkPermissionDto = z3.object({
|
|
|
5010
5422
|
});
|
|
5011
5423
|
|
|
5012
5424
|
// src/permissions/PermissionController.ts
|
|
5013
|
-
var
|
|
5425
|
+
var __decorate31 = function(decorators, target, key, desc) {
|
|
5014
5426
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
5015
5427
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5016
5428
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5017
5429
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
5018
5430
|
};
|
|
5019
|
-
var
|
|
5431
|
+
var __metadata31 = function(k, v) {
|
|
5020
5432
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
5021
5433
|
};
|
|
5022
5434
|
var __param11 = function(paramIndex, decorator) {
|
|
@@ -5024,7 +5436,7 @@ var __param11 = function(paramIndex, decorator) {
|
|
|
5024
5436
|
decorator(target, key, paramIndex);
|
|
5025
5437
|
};
|
|
5026
5438
|
};
|
|
5027
|
-
var
|
|
5439
|
+
var _a20;
|
|
5028
5440
|
var PermissionController = class PermissionController2 {
|
|
5029
5441
|
static {
|
|
5030
5442
|
__name(this, "PermissionController");
|
|
@@ -5070,32 +5482,32 @@ var PermissionController = class PermissionController2 {
|
|
|
5070
5482
|
return this.permissionService.deleteAll();
|
|
5071
5483
|
}
|
|
5072
5484
|
};
|
|
5073
|
-
|
|
5485
|
+
__decorate31([
|
|
5074
5486
|
Get4(),
|
|
5075
5487
|
ResMsg5("permissions.success.retrieved"),
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5488
|
+
__metadata31("design:type", Function),
|
|
5489
|
+
__metadata31("design:paramtypes", []),
|
|
5490
|
+
__metadata31("design:returntype", Promise)
|
|
5079
5491
|
], PermissionController.prototype, "getPermissions", null);
|
|
5080
|
-
|
|
5492
|
+
__decorate31([
|
|
5081
5493
|
Get4("/:id"),
|
|
5082
5494
|
Validate5({ params: permissionIdParam }),
|
|
5083
5495
|
ResMsg5("permissions.success.retrieved"),
|
|
5084
5496
|
__param11(0, Params3()),
|
|
5085
|
-
|
|
5086
|
-
|
|
5087
|
-
|
|
5497
|
+
__metadata31("design:type", Function),
|
|
5498
|
+
__metadata31("design:paramtypes", [Object]),
|
|
5499
|
+
__metadata31("design:returntype", Promise)
|
|
5088
5500
|
], PermissionController.prototype, "getPermission", null);
|
|
5089
|
-
|
|
5501
|
+
__decorate31([
|
|
5090
5502
|
Post5(),
|
|
5091
5503
|
Validate5(createPermissionDto),
|
|
5092
5504
|
ResMsg5({ message: "Permission created successfully", status: 201 }),
|
|
5093
5505
|
__param11(0, Body5()),
|
|
5094
|
-
|
|
5095
|
-
|
|
5096
|
-
|
|
5506
|
+
__metadata31("design:type", Function),
|
|
5507
|
+
__metadata31("design:paramtypes", [Object]),
|
|
5508
|
+
__metadata31("design:returntype", Promise)
|
|
5097
5509
|
], PermissionController.prototype, "create", null);
|
|
5098
|
-
|
|
5510
|
+
__decorate31([
|
|
5099
5511
|
Put3("/:id"),
|
|
5100
5512
|
Validate5({
|
|
5101
5513
|
params: permissionIdParam,
|
|
@@ -5104,72 +5516,73 @@ __decorate30([
|
|
|
5104
5516
|
ResMsg5("permissions.success.updated"),
|
|
5105
5517
|
__param11(0, Params3()),
|
|
5106
5518
|
__param11(1, Body5()),
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5519
|
+
__metadata31("design:type", Function),
|
|
5520
|
+
__metadata31("design:paramtypes", [Object, Object]),
|
|
5521
|
+
__metadata31("design:returntype", Promise)
|
|
5110
5522
|
], PermissionController.prototype, "update", null);
|
|
5111
|
-
|
|
5523
|
+
__decorate31([
|
|
5112
5524
|
Delete3("/:id"),
|
|
5113
5525
|
Validate5({ params: permissionIdParam }),
|
|
5114
5526
|
ResMsg5("permissions.success.deleted"),
|
|
5115
5527
|
__param11(0, Params3()),
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5528
|
+
__metadata31("design:type", Function),
|
|
5529
|
+
__metadata31("design:paramtypes", [Object]),
|
|
5530
|
+
__metadata31("design:returntype", Promise)
|
|
5119
5531
|
], PermissionController.prototype, "delete", null);
|
|
5120
|
-
|
|
5532
|
+
__decorate31([
|
|
5121
5533
|
Get4("/role/:id"),
|
|
5122
5534
|
Validate5({ params: roleIdParam }),
|
|
5123
5535
|
ResMsg5("permissions.success.retrieved"),
|
|
5124
5536
|
__param11(0, Params3()),
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5537
|
+
__metadata31("design:type", Function),
|
|
5538
|
+
__metadata31("design:paramtypes", [Object]),
|
|
5539
|
+
__metadata31("design:returntype", Promise)
|
|
5128
5540
|
], PermissionController.prototype, "getByRole", null);
|
|
5129
|
-
|
|
5541
|
+
__decorate31([
|
|
5130
5542
|
Get4("/roles/:id"),
|
|
5131
5543
|
Validate5({ params: permissionIdParam }),
|
|
5132
5544
|
ResMsg5("permissions.success.retrieved"),
|
|
5133
5545
|
__param11(0, Params3()),
|
|
5134
|
-
|
|
5135
|
-
|
|
5136
|
-
|
|
5546
|
+
__metadata31("design:type", Function),
|
|
5547
|
+
__metadata31("design:paramtypes", [Object]),
|
|
5548
|
+
__metadata31("design:returntype", Promise)
|
|
5137
5549
|
], PermissionController.prototype, "getRolesByPermission", null);
|
|
5138
|
-
|
|
5550
|
+
__decorate31([
|
|
5139
5551
|
Post5("/assign/:roleId/:permissionId"),
|
|
5140
5552
|
Validate5({ params: assignPermissionDto }),
|
|
5141
5553
|
ResMsg5("permissions.success.assigned"),
|
|
5142
5554
|
__param11(0, Params3()),
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5555
|
+
__metadata31("design:type", Function),
|
|
5556
|
+
__metadata31("design:paramtypes", [Object]),
|
|
5557
|
+
__metadata31("design:returntype", Promise)
|
|
5146
5558
|
], PermissionController.prototype, "assignToRole", null);
|
|
5147
|
-
|
|
5559
|
+
__decorate31([
|
|
5148
5560
|
Delete3("/remove/:roleId/:permissionId"),
|
|
5149
5561
|
Validate5({ params: assignPermissionDto }),
|
|
5150
5562
|
ResMsg5("permissions.success.removed"),
|
|
5151
5563
|
__param11(0, Params3()),
|
|
5152
|
-
|
|
5153
|
-
|
|
5154
|
-
|
|
5564
|
+
__metadata31("design:type", Function),
|
|
5565
|
+
__metadata31("design:paramtypes", [Object]),
|
|
5566
|
+
__metadata31("design:returntype", Promise)
|
|
5155
5567
|
], PermissionController.prototype, "removeFromRole", null);
|
|
5156
|
-
|
|
5568
|
+
__decorate31([
|
|
5157
5569
|
Delete3(),
|
|
5158
5570
|
isAdmin(),
|
|
5159
5571
|
ResMsg5("permissions.success.allDeleted"),
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
|
|
5572
|
+
__metadata31("design:type", Function),
|
|
5573
|
+
__metadata31("design:paramtypes", []),
|
|
5574
|
+
__metadata31("design:returntype", Promise)
|
|
5163
5575
|
], PermissionController.prototype, "deleteAll", null);
|
|
5164
|
-
PermissionController =
|
|
5576
|
+
PermissionController = __decorate31([
|
|
5165
5577
|
Controller5("/permissions"),
|
|
5166
5578
|
isAdmin(),
|
|
5167
|
-
|
|
5579
|
+
__metadata31("design:paramtypes", [typeof (_a20 = typeof PermissionService !== "undefined" && PermissionService) === "function" ? _a20 : Object])
|
|
5168
5580
|
], PermissionController);
|
|
5169
5581
|
|
|
5170
5582
|
// src/tokens/index.ts
|
|
5171
5583
|
var tokens_exports = {};
|
|
5172
5584
|
__export(tokens_exports, {
|
|
5585
|
+
SessionInvalidationService: () => SessionInvalidationService,
|
|
5173
5586
|
TokenRepository: () => TokenRepository,
|
|
5174
5587
|
TokenService: () => TokenService,
|
|
5175
5588
|
createTokenDto: () => createTokenDto,
|
|
@@ -5371,15 +5784,15 @@ function own(table, opts) {
|
|
|
5371
5784
|
__name(own, "own");
|
|
5372
5785
|
|
|
5373
5786
|
// src/ownership/configureOwnership.ts
|
|
5374
|
-
import { Injectable as
|
|
5787
|
+
import { Injectable as Injectable16, Inject as Inject16, User as User4, Body as Body6, Params as Params4 } from "najm-core";
|
|
5375
5788
|
import { createGuard as createGuard5, composeGuards as composeGuards4 } from "najm-guard";
|
|
5376
|
-
var
|
|
5789
|
+
var __decorate32 = function(decorators, target, key, desc) {
|
|
5377
5790
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
5378
5791
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5379
5792
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5380
5793
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
5381
5794
|
};
|
|
5382
|
-
var
|
|
5795
|
+
var __metadata32 = function(k, v) {
|
|
5383
5796
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
5384
5797
|
};
|
|
5385
5798
|
var __param12 = function(paramIndex, decorator) {
|
|
@@ -5399,7 +5812,7 @@ function toSingular(plural) {
|
|
|
5399
5812
|
}
|
|
5400
5813
|
__name(toSingular, "toSingular");
|
|
5401
5814
|
function createResourceGuards(ownershipClass, resourceType, resource, options) {
|
|
5402
|
-
var
|
|
5815
|
+
var _a29, _b16;
|
|
5403
5816
|
const writeGuard = options?.adminGuard ?? isAdmin;
|
|
5404
5817
|
let AccessGuard = class AccessGuard {
|
|
5405
5818
|
static {
|
|
@@ -5411,19 +5824,19 @@ function createResourceGuards(ownershipClass, resourceType, resource, options) {
|
|
|
5411
5824
|
return allowed ? { owner: user } : false;
|
|
5412
5825
|
}
|
|
5413
5826
|
};
|
|
5414
|
-
|
|
5415
|
-
|
|
5416
|
-
|
|
5827
|
+
__decorate32([
|
|
5828
|
+
Inject16(ownershipClass),
|
|
5829
|
+
__metadata32("design:type", Object)
|
|
5417
5830
|
], AccessGuard.prototype, "ownership", void 0);
|
|
5418
|
-
|
|
5831
|
+
__decorate32([
|
|
5419
5832
|
__param12(0, User4()),
|
|
5420
5833
|
__param12(1, Params4("id")),
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5834
|
+
__metadata32("design:type", Function),
|
|
5835
|
+
__metadata32("design:paramtypes", [Object, String]),
|
|
5836
|
+
__metadata32("design:returntype", typeof (_a29 = typeof Promise !== "undefined" && Promise) === "function" ? _a29 : Object)
|
|
5424
5837
|
], AccessGuard.prototype, "canActivate", null);
|
|
5425
|
-
AccessGuard =
|
|
5426
|
-
|
|
5838
|
+
AccessGuard = __decorate32([
|
|
5839
|
+
Injectable16()
|
|
5427
5840
|
], AccessGuard);
|
|
5428
5841
|
let ListGuard = class ListGuard {
|
|
5429
5842
|
static {
|
|
@@ -5435,18 +5848,18 @@ function createResourceGuards(ownershipClass, resourceType, resource, options) {
|
|
|
5435
5848
|
return { filter: ids };
|
|
5436
5849
|
}
|
|
5437
5850
|
};
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5851
|
+
__decorate32([
|
|
5852
|
+
Inject16(ownershipClass),
|
|
5853
|
+
__metadata32("design:type", Object)
|
|
5441
5854
|
], ListGuard.prototype, "ownership", void 0);
|
|
5442
|
-
|
|
5855
|
+
__decorate32([
|
|
5443
5856
|
__param12(0, User4()),
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5857
|
+
__metadata32("design:type", Function),
|
|
5858
|
+
__metadata32("design:paramtypes", [Object]),
|
|
5859
|
+
__metadata32("design:returntype", typeof (_b16 = typeof Promise !== "undefined" && Promise) === "function" ? _b16 : Object)
|
|
5447
5860
|
], ListGuard.prototype, "canActivate", null);
|
|
5448
|
-
ListGuard =
|
|
5449
|
-
|
|
5861
|
+
ListGuard = __decorate32([
|
|
5862
|
+
Injectable16()
|
|
5450
5863
|
], ListGuard);
|
|
5451
5864
|
const access = createGuard5(AccessGuard);
|
|
5452
5865
|
const list = createGuard5(ListGuard);
|
|
@@ -5577,11 +5990,11 @@ function configureOwnership(config) {
|
|
|
5577
5990
|
}
|
|
5578
5991
|
}
|
|
5579
5992
|
};
|
|
5580
|
-
GeneratedOwnershipService =
|
|
5581
|
-
|
|
5993
|
+
GeneratedOwnershipService = __decorate32([
|
|
5994
|
+
Injectable16()
|
|
5582
5995
|
], GeneratedOwnershipService);
|
|
5583
5996
|
function bodyGuard(resourceType, bodyField, optional = false) {
|
|
5584
|
-
var
|
|
5997
|
+
var _a29;
|
|
5585
5998
|
let BodyAccessGuard = class BodyAccessGuard {
|
|
5586
5999
|
static {
|
|
5587
6000
|
__name(this, "BodyAccessGuard");
|
|
@@ -5594,19 +6007,19 @@ function configureOwnership(config) {
|
|
|
5594
6007
|
return this.ownership.canAccess(user, resourceType, id);
|
|
5595
6008
|
}
|
|
5596
6009
|
};
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
6010
|
+
__decorate32([
|
|
6011
|
+
Inject16(GeneratedOwnershipService),
|
|
6012
|
+
__metadata32("design:type", GeneratedOwnershipService)
|
|
5600
6013
|
], BodyAccessGuard.prototype, "ownership", void 0);
|
|
5601
|
-
|
|
6014
|
+
__decorate32([
|
|
5602
6015
|
__param12(0, User4()),
|
|
5603
6016
|
__param12(1, Body6()),
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
6017
|
+
__metadata32("design:type", Function),
|
|
6018
|
+
__metadata32("design:paramtypes", [Object, Object]),
|
|
6019
|
+
__metadata32("design:returntype", typeof (_a29 = typeof Promise !== "undefined" && Promise) === "function" ? _a29 : Object)
|
|
5607
6020
|
], BodyAccessGuard.prototype, "canActivate", null);
|
|
5608
|
-
BodyAccessGuard =
|
|
5609
|
-
|
|
6021
|
+
BodyAccessGuard = __decorate32([
|
|
6022
|
+
Injectable16()
|
|
5610
6023
|
], BodyAccessGuard);
|
|
5611
6024
|
return createGuard5(BodyAccessGuard);
|
|
5612
6025
|
}
|
|
@@ -5721,18 +6134,18 @@ __name(Policy, "Policy");
|
|
|
5721
6134
|
// src/ownership/OwnedDecorator.ts
|
|
5722
6135
|
import "reflect-metadata";
|
|
5723
6136
|
import { sql as sql5, and as and5 } from "drizzle-orm";
|
|
5724
|
-
import { Injectable as
|
|
6137
|
+
import { Injectable as Injectable17, Inject as Inject17, DI as DI3, Container as Container2, REQUEST_ID } from "najm-core";
|
|
5725
6138
|
import { USER as USER2 } from "najm-guard";
|
|
5726
|
-
var
|
|
6139
|
+
var __decorate33 = function(decorators, target, key, desc) {
|
|
5727
6140
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
5728
6141
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5729
6142
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5730
6143
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
5731
6144
|
};
|
|
5732
|
-
var
|
|
6145
|
+
var __metadata33 = function(k, v) {
|
|
5733
6146
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
5734
6147
|
};
|
|
5735
|
-
var
|
|
6148
|
+
var _a21;
|
|
5736
6149
|
var OWNED_META = Symbol.for("najm:owned");
|
|
5737
6150
|
var ScopeContext = class ScopeContext2 {
|
|
5738
6151
|
static {
|
|
@@ -5764,18 +6177,18 @@ var ScopeContext = class ScopeContext2 {
|
|
|
5764
6177
|
}
|
|
5765
6178
|
}
|
|
5766
6179
|
};
|
|
5767
|
-
|
|
6180
|
+
__decorate33([
|
|
5768
6181
|
DI3(),
|
|
5769
|
-
|
|
6182
|
+
__metadata33("design:type", typeof (_a21 = typeof Container2 !== "undefined" && Container2) === "function" ? _a21 : Object)
|
|
5770
6183
|
], ScopeContext.prototype, "container", void 0);
|
|
5771
|
-
ScopeContext =
|
|
5772
|
-
|
|
6184
|
+
ScopeContext = __decorate33([
|
|
6185
|
+
Injectable17()
|
|
5773
6186
|
], ScopeContext);
|
|
5774
6187
|
function Owned(token) {
|
|
5775
6188
|
return function(target) {
|
|
5776
6189
|
Reflect.defineMetadata(OWNED_META, token, target);
|
|
5777
6190
|
const proto = target.prototype;
|
|
5778
|
-
|
|
6191
|
+
Inject17(ScopeContext)(proto, "_scopeCtx");
|
|
5779
6192
|
function getUser(self) {
|
|
5780
6193
|
return self._scopeCtx?.getUser() ?? null;
|
|
5781
6194
|
}
|
|
@@ -5985,7 +6398,7 @@ __name(getAuthLocale, "getAuthLocale");
|
|
|
5985
6398
|
var AUTH_SUPPORTED_LANGUAGES = Object.keys(AUTH_LOCALES);
|
|
5986
6399
|
|
|
5987
6400
|
// src/oauth/google/GoogleOAuthProvider.ts
|
|
5988
|
-
import { Inject as
|
|
6401
|
+
import { Inject as Inject19, Injectable as Injectable19 } from "najm-core";
|
|
5989
6402
|
|
|
5990
6403
|
// src/oauth/types.ts
|
|
5991
6404
|
var OAuthFlowError = class extends Error {
|
|
@@ -6003,15 +6416,15 @@ var OAuthFlowError = class extends Error {
|
|
|
6003
6416
|
};
|
|
6004
6417
|
|
|
6005
6418
|
// src/oauth/google/GoogleTokenVerifier.ts
|
|
6006
|
-
import { Inject as
|
|
6419
|
+
import { Inject as Inject18, Injectable as Injectable18 } from "najm-core";
|
|
6007
6420
|
import { createRemoteJWKSet, jwtVerify } from "jose";
|
|
6008
|
-
var
|
|
6421
|
+
var __decorate34 = function(decorators, target, key, desc) {
|
|
6009
6422
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
6010
6423
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6011
6424
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6012
6425
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6013
6426
|
};
|
|
6014
|
-
var
|
|
6427
|
+
var __metadata34 = function(k, v) {
|
|
6015
6428
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
6016
6429
|
};
|
|
6017
6430
|
var GOOGLE_JWKS = createRemoteJWKSet(new URL("https://www.googleapis.com/oauth2/v3/certs"));
|
|
@@ -6063,25 +6476,25 @@ var GoogleTokenVerifier = class GoogleTokenVerifier2 {
|
|
|
6063
6476
|
return google;
|
|
6064
6477
|
}
|
|
6065
6478
|
};
|
|
6066
|
-
|
|
6067
|
-
|
|
6068
|
-
|
|
6479
|
+
__decorate34([
|
|
6480
|
+
Inject18(AUTH_CONFIG),
|
|
6481
|
+
__metadata34("design:type", Object)
|
|
6069
6482
|
], GoogleTokenVerifier.prototype, "config", void 0);
|
|
6070
|
-
GoogleTokenVerifier =
|
|
6071
|
-
|
|
6483
|
+
GoogleTokenVerifier = __decorate34([
|
|
6484
|
+
Injectable18()
|
|
6072
6485
|
], GoogleTokenVerifier);
|
|
6073
6486
|
|
|
6074
6487
|
// src/oauth/google/GoogleOAuthProvider.ts
|
|
6075
|
-
var
|
|
6488
|
+
var __decorate35 = function(decorators, target, key, desc) {
|
|
6076
6489
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
6077
6490
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6078
6491
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6079
6492
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6080
6493
|
};
|
|
6081
|
-
var
|
|
6494
|
+
var __metadata35 = function(k, v) {
|
|
6082
6495
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
6083
6496
|
};
|
|
6084
|
-
var
|
|
6497
|
+
var _a22;
|
|
6085
6498
|
var AUTHORIZATION_ENDPOINT = "https://accounts.google.com/o/oauth2/v2/auth";
|
|
6086
6499
|
var TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token";
|
|
6087
6500
|
var GoogleOAuthProvider = class GoogleOAuthProvider2 {
|
|
@@ -6149,24 +6562,24 @@ var GoogleOAuthProvider = class GoogleOAuthProvider2 {
|
|
|
6149
6562
|
return google;
|
|
6150
6563
|
}
|
|
6151
6564
|
};
|
|
6152
|
-
|
|
6153
|
-
|
|
6154
|
-
|
|
6565
|
+
__decorate35([
|
|
6566
|
+
Inject19(AUTH_CONFIG),
|
|
6567
|
+
__metadata35("design:type", Object)
|
|
6155
6568
|
], GoogleOAuthProvider.prototype, "config", void 0);
|
|
6156
|
-
GoogleOAuthProvider =
|
|
6157
|
-
|
|
6158
|
-
|
|
6569
|
+
GoogleOAuthProvider = __decorate35([
|
|
6570
|
+
Injectable19(),
|
|
6571
|
+
__metadata35("design:paramtypes", [typeof (_a22 = typeof GoogleTokenVerifier !== "undefined" && GoogleTokenVerifier) === "function" ? _a22 : Object])
|
|
6159
6572
|
], GoogleOAuthProvider);
|
|
6160
6573
|
|
|
6161
6574
|
// src/oauth/github/GitHubOAuthProvider.ts
|
|
6162
|
-
import { Inject as
|
|
6163
|
-
var
|
|
6575
|
+
import { Inject as Inject20, Injectable as Injectable20 } from "najm-core";
|
|
6576
|
+
var __decorate36 = function(decorators, target, key, desc) {
|
|
6164
6577
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
6165
6578
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6166
6579
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6167
6580
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6168
6581
|
};
|
|
6169
|
-
var
|
|
6582
|
+
var __metadata36 = function(k, v) {
|
|
6170
6583
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
6171
6584
|
};
|
|
6172
6585
|
var AUTHORIZATION_ENDPOINT2 = "https://github.com/login/oauth/authorize";
|
|
@@ -6282,12 +6695,12 @@ var GitHubOAuthProvider = class GitHubOAuthProvider2 {
|
|
|
6282
6695
|
return github;
|
|
6283
6696
|
}
|
|
6284
6697
|
};
|
|
6285
|
-
|
|
6286
|
-
|
|
6287
|
-
|
|
6698
|
+
__decorate36([
|
|
6699
|
+
Inject20(AUTH_CONFIG),
|
|
6700
|
+
__metadata36("design:type", Object)
|
|
6288
6701
|
], GitHubOAuthProvider.prototype, "config", void 0);
|
|
6289
|
-
GitHubOAuthProvider =
|
|
6290
|
-
|
|
6702
|
+
GitHubOAuthProvider = __decorate36([
|
|
6703
|
+
Injectable20()
|
|
6291
6704
|
], GitHubOAuthProvider);
|
|
6292
6705
|
|
|
6293
6706
|
// src/oauth/GitHubOAuthController.ts
|
|
@@ -6296,24 +6709,24 @@ import { Controller as Controller6, Ctx as Ctx2, Get as Get5, Post as Post6, Que
|
|
|
6296
6709
|
import { RateLimit as RateLimit3 } from "najm-rate";
|
|
6297
6710
|
|
|
6298
6711
|
// src/oauth/OAuthService.ts
|
|
6299
|
-
import { Inject as
|
|
6712
|
+
import { Err as Err15, Inject as Inject23, Injectable as Injectable23, Log as Log2 } from "najm-core";
|
|
6300
6713
|
|
|
6301
6714
|
// src/oauth/OAuthAccountService.ts
|
|
6302
6715
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
6303
|
-
import { Inject as
|
|
6716
|
+
import { Inject as Inject22, Injectable as Injectable21 } from "najm-core";
|
|
6304
6717
|
import { Transaction as Transaction5 } from "najm-database";
|
|
6305
6718
|
|
|
6306
6719
|
// src/oauth/OAuthAccountRepository.ts
|
|
6307
6720
|
import { and as and6, eq as eq9 } from "drizzle-orm";
|
|
6308
|
-
import { Inject as
|
|
6721
|
+
import { Inject as Inject21, Repository as Repository7 } from "najm-core";
|
|
6309
6722
|
import { DB as DB7 } from "najm-database";
|
|
6310
|
-
var
|
|
6723
|
+
var __decorate37 = function(decorators, target, key, desc) {
|
|
6311
6724
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
6312
6725
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6313
6726
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6314
6727
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6315
6728
|
};
|
|
6316
|
-
var
|
|
6729
|
+
var __metadata37 = function(k, v) {
|
|
6317
6730
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
6318
6731
|
};
|
|
6319
6732
|
var OAuthAccountRepository = class OAuthAccountRepository2 {
|
|
@@ -6341,32 +6754,32 @@ var OAuthAccountRepository = class OAuthAccountRepository2 {
|
|
|
6341
6754
|
return account;
|
|
6342
6755
|
}
|
|
6343
6756
|
};
|
|
6344
|
-
|
|
6757
|
+
__decorate37([
|
|
6345
6758
|
DB7(),
|
|
6346
|
-
|
|
6759
|
+
__metadata37("design:type", Object)
|
|
6347
6760
|
], OAuthAccountRepository.prototype, "db", void 0);
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
|
|
6761
|
+
__decorate37([
|
|
6762
|
+
Inject21(AUTH_SCHEMA),
|
|
6763
|
+
__metadata37("design:type", Object)
|
|
6351
6764
|
], OAuthAccountRepository.prototype, "schema", void 0);
|
|
6352
|
-
OAuthAccountRepository =
|
|
6765
|
+
OAuthAccountRepository = __decorate37([
|
|
6353
6766
|
Repository7()
|
|
6354
6767
|
], OAuthAccountRepository);
|
|
6355
6768
|
|
|
6356
6769
|
// src/oauth/OAuthAccountService.ts
|
|
6357
|
-
var
|
|
6770
|
+
var __decorate38 = function(decorators, target, key, desc) {
|
|
6358
6771
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
6359
6772
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6360
6773
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6361
6774
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6362
6775
|
};
|
|
6363
|
-
var
|
|
6776
|
+
var __metadata38 = function(k, v) {
|
|
6364
6777
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
6365
6778
|
};
|
|
6366
|
-
var
|
|
6367
|
-
var
|
|
6779
|
+
var _a23;
|
|
6780
|
+
var _b13;
|
|
6368
6781
|
var _c9;
|
|
6369
|
-
var
|
|
6782
|
+
var _d8;
|
|
6370
6783
|
var OAuthAccountService = class OAuthAccountService2 {
|
|
6371
6784
|
static {
|
|
6372
6785
|
__name(this, "OAuthAccountService");
|
|
@@ -6442,42 +6855,42 @@ var OAuthAccountService = class OAuthAccountService2 {
|
|
|
6442
6855
|
return providerConfig;
|
|
6443
6856
|
}
|
|
6444
6857
|
};
|
|
6445
|
-
|
|
6446
|
-
|
|
6447
|
-
|
|
6858
|
+
__decorate38([
|
|
6859
|
+
Inject22(AUTH_CONFIG),
|
|
6860
|
+
__metadata38("design:type", Object)
|
|
6448
6861
|
], OAuthAccountService.prototype, "config", void 0);
|
|
6449
|
-
|
|
6862
|
+
__decorate38([
|
|
6450
6863
|
Transaction5(),
|
|
6451
|
-
|
|
6452
|
-
|
|
6453
|
-
|
|
6864
|
+
__metadata38("design:type", Function),
|
|
6865
|
+
__metadata38("design:paramtypes", [Object]),
|
|
6866
|
+
__metadata38("design:returntype", typeof (_c9 = typeof Promise !== "undefined" && Promise) === "function" ? _c9 : Object)
|
|
6454
6867
|
], OAuthAccountService.prototype, "resolveForLogin", null);
|
|
6455
|
-
|
|
6868
|
+
__decorate38([
|
|
6456
6869
|
Transaction5(),
|
|
6457
|
-
|
|
6458
|
-
|
|
6459
|
-
|
|
6870
|
+
__metadata38("design:type", Function),
|
|
6871
|
+
__metadata38("design:paramtypes", [String, Object]),
|
|
6872
|
+
__metadata38("design:returntype", typeof (_d8 = typeof Promise !== "undefined" && Promise) === "function" ? _d8 : Object)
|
|
6460
6873
|
], OAuthAccountService.prototype, "linkUser", null);
|
|
6461
|
-
OAuthAccountService =
|
|
6462
|
-
|
|
6463
|
-
|
|
6874
|
+
OAuthAccountService = __decorate38([
|
|
6875
|
+
Injectable21(),
|
|
6876
|
+
__metadata38("design:paramtypes", [typeof (_a23 = typeof OAuthAccountRepository !== "undefined" && OAuthAccountRepository) === "function" ? _a23 : Object, typeof (_b13 = typeof UserService !== "undefined" && UserService) === "function" ? _b13 : Object])
|
|
6464
6877
|
], OAuthAccountService);
|
|
6465
6878
|
|
|
6466
6879
|
// src/oauth/OAuthStateService.ts
|
|
6467
6880
|
import { createHash as createHash4, randomBytes as randomBytes4, timingSafeEqual } from "crypto";
|
|
6468
|
-
import { Injectable as
|
|
6881
|
+
import { Injectable as Injectable22 } from "najm-core";
|
|
6469
6882
|
import { CookieService as CookieService3 } from "najm-cookies";
|
|
6470
|
-
var
|
|
6883
|
+
var __decorate39 = function(decorators, target, key, desc) {
|
|
6471
6884
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
6472
6885
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6473
6886
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6474
6887
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6475
6888
|
};
|
|
6476
|
-
var
|
|
6889
|
+
var __metadata39 = function(k, v) {
|
|
6477
6890
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
6478
6891
|
};
|
|
6479
|
-
var
|
|
6480
|
-
var
|
|
6892
|
+
var _a24;
|
|
6893
|
+
var _b14;
|
|
6481
6894
|
var ATTEMPT_TTL_MS = 10 * 60 * 1e3;
|
|
6482
6895
|
var COOKIE_PREFIX = "najm.oauth.";
|
|
6483
6896
|
var OAuthStateService = class OAuthStateService2 {
|
|
@@ -6566,26 +6979,26 @@ var OAuthStateService = class OAuthStateService2 {
|
|
|
6566
6979
|
return /^[A-Za-z0-9_-]{40,128}$/.test(state);
|
|
6567
6980
|
}
|
|
6568
6981
|
};
|
|
6569
|
-
OAuthStateService =
|
|
6570
|
-
|
|
6571
|
-
|
|
6982
|
+
OAuthStateService = __decorate39([
|
|
6983
|
+
Injectable22(),
|
|
6984
|
+
__metadata39("design:paramtypes", [typeof (_a24 = typeof CookieService3 !== "undefined" && CookieService3) === "function" ? _a24 : Object, typeof (_b14 = typeof EncryptionService !== "undefined" && EncryptionService) === "function" ? _b14 : Object])
|
|
6572
6985
|
], OAuthStateService);
|
|
6573
6986
|
|
|
6574
6987
|
// src/oauth/OAuthService.ts
|
|
6575
|
-
var
|
|
6988
|
+
var __decorate40 = function(decorators, target, key, desc) {
|
|
6576
6989
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
6577
6990
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6578
6991
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6579
6992
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6580
6993
|
};
|
|
6581
|
-
var
|
|
6994
|
+
var __metadata40 = function(k, v) {
|
|
6582
6995
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
6583
6996
|
};
|
|
6584
|
-
var
|
|
6585
|
-
var
|
|
6997
|
+
var _a25;
|
|
6998
|
+
var _b15;
|
|
6586
6999
|
var _c10;
|
|
6587
|
-
var
|
|
6588
|
-
var
|
|
7000
|
+
var _d9;
|
|
7001
|
+
var _e7;
|
|
6589
7002
|
var _f5;
|
|
6590
7003
|
var _g4;
|
|
6591
7004
|
var _h3;
|
|
@@ -6631,16 +7044,47 @@ var OAuthService = class OAuthService2 {
|
|
|
6631
7044
|
finishGitHubCallback(params) {
|
|
6632
7045
|
return this.finishCallback("github", params);
|
|
6633
7046
|
}
|
|
7047
|
+
/**
|
|
7048
|
+
* Turn an expected OAuth start failure into the HTTP response it describes.
|
|
7049
|
+
*
|
|
7050
|
+
* `OAuthFlowError` carries the status it means — 404 for a provider that is
|
|
7051
|
+
* not configured, 400 for a return path the caller chose badly — but it is a
|
|
7052
|
+
* plain Error, so the framework's handler could only classify it as an
|
|
7053
|
+
* unhandled 500. A disabled provider and a bad query string are ordinary
|
|
7054
|
+
* client-visible outcomes, and reporting them as server faults hides real
|
|
7055
|
+
* ones. Only the stable `oauth_*` code crosses the boundary; provider
|
|
7056
|
+
* secrets, state, and codes never appear in it.
|
|
7057
|
+
*
|
|
7058
|
+
* The callback path deliberately does not go through here: it answers with a
|
|
7059
|
+
* redirect carrying the same code, and that contract is unchanged.
|
|
7060
|
+
*/
|
|
7061
|
+
failStart(error) {
|
|
7062
|
+
if (error instanceof OAuthFlowError) {
|
|
7063
|
+
Err15(error.oauthCode, error.status);
|
|
7064
|
+
}
|
|
7065
|
+
throw error;
|
|
7066
|
+
}
|
|
6634
7067
|
startLogin(provider, returnTo) {
|
|
6635
|
-
|
|
6636
|
-
|
|
6637
|
-
|
|
6638
|
-
|
|
6639
|
-
|
|
6640
|
-
|
|
6641
|
-
|
|
7068
|
+
try {
|
|
7069
|
+
this.providerConfig(provider);
|
|
7070
|
+
const { attempt, codeChallenge } = this.state.create({
|
|
7071
|
+
provider,
|
|
7072
|
+
intent: "login",
|
|
7073
|
+
returnTo
|
|
7074
|
+
});
|
|
7075
|
+
return this.provider(provider).authorizationUrl(attempt, codeChallenge);
|
|
7076
|
+
} catch (error) {
|
|
7077
|
+
this.failStart(error);
|
|
7078
|
+
}
|
|
6642
7079
|
}
|
|
6643
7080
|
async startLink(provider, userId, returnTo) {
|
|
7081
|
+
try {
|
|
7082
|
+
return await this.buildLinkStart(provider, userId, returnTo);
|
|
7083
|
+
} catch (error) {
|
|
7084
|
+
this.failStart(error);
|
|
7085
|
+
}
|
|
7086
|
+
}
|
|
7087
|
+
async buildLinkStart(provider, userId, returnTo) {
|
|
6644
7088
|
this.providerConfig(provider);
|
|
6645
7089
|
const user = await this.users.getById(userId);
|
|
6646
7090
|
if (user.status !== "active")
|
|
@@ -6722,27 +7166,27 @@ var OAuthService = class OAuthService2 {
|
|
|
6722
7166
|
return providerConfig;
|
|
6723
7167
|
}
|
|
6724
7168
|
};
|
|
6725
|
-
|
|
6726
|
-
|
|
6727
|
-
|
|
7169
|
+
__decorate40([
|
|
7170
|
+
Inject23(AUTH_CONFIG),
|
|
7171
|
+
__metadata40("design:type", Object)
|
|
6728
7172
|
], OAuthService.prototype, "config", void 0);
|
|
6729
|
-
|
|
7173
|
+
__decorate40([
|
|
6730
7174
|
Log2(),
|
|
6731
|
-
|
|
7175
|
+
__metadata40("design:type", Object)
|
|
6732
7176
|
], OAuthService.prototype, "logger", void 0);
|
|
6733
|
-
OAuthService =
|
|
6734
|
-
|
|
6735
|
-
|
|
7177
|
+
OAuthService = __decorate40([
|
|
7178
|
+
Injectable23(),
|
|
7179
|
+
__metadata40("design:paramtypes", [typeof (_a25 = typeof OAuthStateService !== "undefined" && OAuthStateService) === "function" ? _a25 : Object, typeof (_b15 = typeof GoogleOAuthProvider !== "undefined" && GoogleOAuthProvider) === "function" ? _b15 : Object, typeof (_c10 = typeof GitHubOAuthProvider !== "undefined" && GitHubOAuthProvider) === "function" ? _c10 : Object, typeof (_d9 = typeof OAuthAccountService !== "undefined" && OAuthAccountService) === "function" ? _d9 : Object, typeof (_e7 = typeof AuthSessionService !== "undefined" && AuthSessionService) === "function" ? _e7 : Object, typeof (_f5 = typeof TokenService !== "undefined" && TokenService) === "function" ? _f5 : Object, typeof (_g4 = typeof UserService !== "undefined" && UserService) === "function" ? _g4 : Object, typeof (_h3 = typeof CredentialSetupRequirementService !== "undefined" && CredentialSetupRequirementService) === "function" ? _h3 : Object])
|
|
6736
7180
|
], OAuthService);
|
|
6737
7181
|
|
|
6738
7182
|
// src/oauth/GitHubOAuthController.ts
|
|
6739
|
-
var
|
|
7183
|
+
var __decorate41 = function(decorators, target, key, desc) {
|
|
6740
7184
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
6741
7185
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6742
7186
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6743
7187
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6744
7188
|
};
|
|
6745
|
-
var
|
|
7189
|
+
var __metadata41 = function(k, v) {
|
|
6746
7190
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
6747
7191
|
};
|
|
6748
7192
|
var __param13 = function(paramIndex, decorator) {
|
|
@@ -6750,7 +7194,7 @@ var __param13 = function(paramIndex, decorator) {
|
|
|
6750
7194
|
decorator(target, key, paramIndex);
|
|
6751
7195
|
};
|
|
6752
7196
|
};
|
|
6753
|
-
var
|
|
7197
|
+
var _a26;
|
|
6754
7198
|
var callbackKey = /* @__PURE__ */ __name((ctx, { clientIp }) => {
|
|
6755
7199
|
const state = ctx.req.query("state") ?? "none";
|
|
6756
7200
|
const fingerprint = createHash5("sha256").update(state).digest("base64url").slice(0, 24);
|
|
@@ -6775,52 +7219,52 @@ var GitHubOAuthController = class GitHubOAuthController2 {
|
|
|
6775
7219
|
return this.oauth.startGitHubLink(userId, returnTo);
|
|
6776
7220
|
}
|
|
6777
7221
|
};
|
|
6778
|
-
|
|
7222
|
+
__decorate41([
|
|
6779
7223
|
Get5("/start"),
|
|
6780
7224
|
RateLimit3({ limit: 20, window: "15m", key: "ip" }),
|
|
6781
7225
|
__param13(0, Ctx2()),
|
|
6782
7226
|
__param13(1, Query2("returnTo")),
|
|
6783
|
-
|
|
6784
|
-
|
|
6785
|
-
|
|
7227
|
+
__metadata41("design:type", Function),
|
|
7228
|
+
__metadata41("design:paramtypes", [Object, String]),
|
|
7229
|
+
__metadata41("design:returntype", void 0)
|
|
6786
7230
|
], GitHubOAuthController.prototype, "start", null);
|
|
6787
|
-
|
|
7231
|
+
__decorate41([
|
|
6788
7232
|
Get5("/callback"),
|
|
6789
7233
|
RateLimit3({ limit: 20, window: "15m", key: callbackKey }),
|
|
6790
7234
|
__param13(0, Ctx2()),
|
|
6791
7235
|
__param13(1, Query2("code")),
|
|
6792
7236
|
__param13(2, Query2("state")),
|
|
6793
7237
|
__param13(3, Query2("error")),
|
|
6794
|
-
|
|
6795
|
-
|
|
6796
|
-
|
|
7238
|
+
__metadata41("design:type", Function),
|
|
7239
|
+
__metadata41("design:paramtypes", [Object, String, String, String]),
|
|
7240
|
+
__metadata41("design:returntype", Promise)
|
|
6797
7241
|
], GitHubOAuthController.prototype, "callback", null);
|
|
6798
|
-
|
|
7242
|
+
__decorate41([
|
|
6799
7243
|
Post6("/link"),
|
|
6800
7244
|
isAuth(),
|
|
6801
7245
|
RateLimit3({ limit: 10, window: "15m", key: "user" }),
|
|
6802
7246
|
__param13(0, User5("id")),
|
|
6803
7247
|
__param13(1, Query2("returnTo")),
|
|
6804
|
-
|
|
6805
|
-
|
|
6806
|
-
|
|
7248
|
+
__metadata41("design:type", Function),
|
|
7249
|
+
__metadata41("design:paramtypes", [String, String]),
|
|
7250
|
+
__metadata41("design:returntype", void 0)
|
|
6807
7251
|
], GitHubOAuthController.prototype, "link", null);
|
|
6808
|
-
GitHubOAuthController =
|
|
7252
|
+
GitHubOAuthController = __decorate41([
|
|
6809
7253
|
Controller6("/auth/oauth/github"),
|
|
6810
|
-
|
|
7254
|
+
__metadata41("design:paramtypes", [typeof (_a26 = typeof OAuthService !== "undefined" && OAuthService) === "function" ? _a26 : Object])
|
|
6811
7255
|
], GitHubOAuthController);
|
|
6812
7256
|
|
|
6813
7257
|
// src/oauth/OAuthController.ts
|
|
6814
7258
|
import { createHash as createHash6 } from "crypto";
|
|
6815
7259
|
import { Controller as Controller7, Ctx as Ctx3, Get as Get6, Post as Post7, Query as Query3, User as User6 } from "najm-core";
|
|
6816
7260
|
import { RateLimit as RateLimit4 } from "najm-rate";
|
|
6817
|
-
var
|
|
7261
|
+
var __decorate42 = function(decorators, target, key, desc) {
|
|
6818
7262
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
6819
7263
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6820
7264
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6821
7265
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6822
7266
|
};
|
|
6823
|
-
var
|
|
7267
|
+
var __metadata42 = function(k, v) {
|
|
6824
7268
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
6825
7269
|
};
|
|
6826
7270
|
var __param14 = function(paramIndex, decorator) {
|
|
@@ -6828,7 +7272,7 @@ var __param14 = function(paramIndex, decorator) {
|
|
|
6828
7272
|
decorator(target, key, paramIndex);
|
|
6829
7273
|
};
|
|
6830
7274
|
};
|
|
6831
|
-
var
|
|
7275
|
+
var _a27;
|
|
6832
7276
|
var callbackKey2 = /* @__PURE__ */ __name((ctx, { clientIp }) => {
|
|
6833
7277
|
const ip = clientIp;
|
|
6834
7278
|
const state = ctx.req.query("state") ?? "none";
|
|
@@ -6854,39 +7298,39 @@ var OAuthController = class OAuthController2 {
|
|
|
6854
7298
|
return this.oauth.startGoogleLink(userId, returnTo);
|
|
6855
7299
|
}
|
|
6856
7300
|
};
|
|
6857
|
-
|
|
7301
|
+
__decorate42([
|
|
6858
7302
|
Get6("/start"),
|
|
6859
7303
|
RateLimit4({ limit: 20, window: "15m", key: "ip" }),
|
|
6860
7304
|
__param14(0, Ctx3()),
|
|
6861
7305
|
__param14(1, Query3("returnTo")),
|
|
6862
|
-
|
|
6863
|
-
|
|
6864
|
-
|
|
7306
|
+
__metadata42("design:type", Function),
|
|
7307
|
+
__metadata42("design:paramtypes", [Object, String]),
|
|
7308
|
+
__metadata42("design:returntype", void 0)
|
|
6865
7309
|
], OAuthController.prototype, "start", null);
|
|
6866
|
-
|
|
7310
|
+
__decorate42([
|
|
6867
7311
|
Get6("/callback"),
|
|
6868
7312
|
RateLimit4({ limit: 20, window: "15m", key: callbackKey2 }),
|
|
6869
7313
|
__param14(0, Ctx3()),
|
|
6870
7314
|
__param14(1, Query3("code")),
|
|
6871
7315
|
__param14(2, Query3("state")),
|
|
6872
7316
|
__param14(3, Query3("error")),
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
7317
|
+
__metadata42("design:type", Function),
|
|
7318
|
+
__metadata42("design:paramtypes", [Object, String, String, String]),
|
|
7319
|
+
__metadata42("design:returntype", Promise)
|
|
6876
7320
|
], OAuthController.prototype, "callback", null);
|
|
6877
|
-
|
|
7321
|
+
__decorate42([
|
|
6878
7322
|
Post7("/link"),
|
|
6879
7323
|
isAuth(),
|
|
6880
7324
|
RateLimit4({ limit: 10, window: "15m", key: "user" }),
|
|
6881
7325
|
__param14(0, User6("id")),
|
|
6882
7326
|
__param14(1, Query3("returnTo")),
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
7327
|
+
__metadata42("design:type", Function),
|
|
7328
|
+
__metadata42("design:paramtypes", [String, String]),
|
|
7329
|
+
__metadata42("design:returntype", void 0)
|
|
6886
7330
|
], OAuthController.prototype, "link", null);
|
|
6887
|
-
OAuthController =
|
|
7331
|
+
OAuthController = __decorate42([
|
|
6888
7332
|
Controller7("/auth/oauth/google"),
|
|
6889
|
-
|
|
7333
|
+
__metadata42("design:paramtypes", [typeof (_a27 = typeof OAuthService !== "undefined" && OAuthService) === "function" ? _a27 : Object])
|
|
6890
7334
|
], OAuthController);
|
|
6891
7335
|
|
|
6892
7336
|
// src/oauth/index.ts
|
|
@@ -6915,13 +7359,13 @@ var credentialSetupChangeDto = z5.object({
|
|
|
6915
7359
|
});
|
|
6916
7360
|
|
|
6917
7361
|
// src/credentialSetup/CredentialSetupController.ts
|
|
6918
|
-
var
|
|
7362
|
+
var __decorate43 = function(decorators, target, key, desc) {
|
|
6919
7363
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
6920
7364
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6921
7365
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6922
7366
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6923
7367
|
};
|
|
6924
|
-
var
|
|
7368
|
+
var __metadata43 = function(k, v) {
|
|
6925
7369
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
6926
7370
|
};
|
|
6927
7371
|
var __param15 = function(paramIndex, decorator) {
|
|
@@ -6929,7 +7373,7 @@ var __param15 = function(paramIndex, decorator) {
|
|
|
6929
7373
|
decorator(target, key, paramIndex);
|
|
6930
7374
|
};
|
|
6931
7375
|
};
|
|
6932
|
-
var
|
|
7376
|
+
var _a28;
|
|
6933
7377
|
var CredentialSetupController = class CredentialSetupController2 {
|
|
6934
7378
|
static {
|
|
6935
7379
|
__name(this, "CredentialSetupController");
|
|
@@ -6948,35 +7392,35 @@ var CredentialSetupController = class CredentialSetupController2 {
|
|
|
6948
7392
|
return this.passwords.cancel();
|
|
6949
7393
|
}
|
|
6950
7394
|
};
|
|
6951
|
-
|
|
7395
|
+
__decorate43([
|
|
6952
7396
|
Get7("/setup"),
|
|
6953
7397
|
RateLimit5({ limit: 30, window: "15m", key: "ip" }),
|
|
6954
7398
|
ResMsg6("auth.success.credentialSetupPending"),
|
|
6955
|
-
|
|
6956
|
-
|
|
6957
|
-
|
|
7399
|
+
__metadata43("design:type", Function),
|
|
7400
|
+
__metadata43("design:paramtypes", []),
|
|
7401
|
+
__metadata43("design:returntype", void 0)
|
|
6958
7402
|
], CredentialSetupController.prototype, "status", null);
|
|
6959
|
-
|
|
7403
|
+
__decorate43([
|
|
6960
7404
|
Post8("/change"),
|
|
6961
7405
|
RateLimit5({ limit: 5, window: "15m", key: "ip" }),
|
|
6962
7406
|
Validate6(credentialSetupChangeDto),
|
|
6963
7407
|
ResMsg6("auth.success.credentialSetupPasswordReplaced"),
|
|
6964
7408
|
__param15(0, Body7()),
|
|
6965
|
-
|
|
6966
|
-
|
|
6967
|
-
|
|
7409
|
+
__metadata43("design:type", Function),
|
|
7410
|
+
__metadata43("design:paramtypes", [Object]),
|
|
7411
|
+
__metadata43("design:returntype", void 0)
|
|
6968
7412
|
], CredentialSetupController.prototype, "change", null);
|
|
6969
|
-
|
|
7413
|
+
__decorate43([
|
|
6970
7414
|
Post8("/cancel"),
|
|
6971
7415
|
RateLimit5({ limit: 10, window: "15m", key: "ip" }),
|
|
6972
7416
|
ResMsg6("auth.success.credentialSetupCancelled"),
|
|
6973
|
-
|
|
6974
|
-
|
|
6975
|
-
|
|
7417
|
+
__metadata43("design:type", Function),
|
|
7418
|
+
__metadata43("design:paramtypes", []),
|
|
7419
|
+
__metadata43("design:returntype", void 0)
|
|
6976
7420
|
], CredentialSetupController.prototype, "cancel", null);
|
|
6977
|
-
CredentialSetupController =
|
|
7421
|
+
CredentialSetupController = __decorate43([
|
|
6978
7422
|
Controller8("/auth/credential-setup"),
|
|
6979
|
-
|
|
7423
|
+
__metadata43("design:paramtypes", [typeof (_a28 = typeof PasswordSetupService !== "undefined" && PasswordSetupService) === "function" ? _a28 : Object])
|
|
6980
7424
|
], CredentialSetupController);
|
|
6981
7425
|
|
|
6982
7426
|
// src/credentialSetup/index.ts
|
|
@@ -7023,9 +7467,9 @@ var resolveGoogleConfig = /* @__PURE__ */ __name((config) => {
|
|
|
7023
7467
|
const clientId = google.clientId ?? process.env.GOOGLE_CLIENT_ID ?? "";
|
|
7024
7468
|
const clientSecret = google.clientSecret ?? process.env.GOOGLE_CLIENT_SECRET ?? "";
|
|
7025
7469
|
if (!clientId)
|
|
7026
|
-
throw
|
|
7470
|
+
throw Err16.configRequired("auth.oauth.google", "GOOGLE_CLIENT_ID");
|
|
7027
7471
|
if (!clientSecret)
|
|
7028
|
-
throw
|
|
7472
|
+
throw Err16.configRequired("auth.oauth.google", "GOOGLE_CLIENT_SECRET");
|
|
7029
7473
|
const frontendUrl = config?.frontendUrl ?? process.env.FRONTEND_URL ?? "http://localhost:3000";
|
|
7030
7474
|
const callbackUrl = google.callbackUrl ?? process.env.GOOGLE_CALLBACK_URL ?? `${frontendUrl.replace(/\/$/, "")}/api/auth/oauth/google/callback`;
|
|
7031
7475
|
return {
|
|
@@ -7047,9 +7491,9 @@ var resolveGitHubConfig = /* @__PURE__ */ __name((config) => {
|
|
|
7047
7491
|
const clientId = github.clientId ?? process.env.GITHUB_CLIENT_ID ?? "";
|
|
7048
7492
|
const clientSecret = github.clientSecret ?? process.env.GITHUB_CLIENT_SECRET ?? "";
|
|
7049
7493
|
if (!clientId)
|
|
7050
|
-
throw
|
|
7494
|
+
throw Err16.configRequired("auth.oauth.github", "GITHUB_CLIENT_ID");
|
|
7051
7495
|
if (!clientSecret)
|
|
7052
|
-
throw
|
|
7496
|
+
throw Err16.configRequired("auth.oauth.github", "GITHUB_CLIENT_SECRET");
|
|
7053
7497
|
const frontendUrl = config?.frontendUrl ?? process.env.FRONTEND_URL ?? "http://localhost:3000";
|
|
7054
7498
|
const callbackUrl = github.callbackUrl ?? process.env.GITHUB_CALLBACK_URL ?? `${frontendUrl.replace(/\/$/, "")}/api/auth/oauth/github/callback`;
|
|
7055
7499
|
return {
|
|
@@ -7117,10 +7561,10 @@ var resolveAuthConfig = /* @__PURE__ */ __name((config) => {
|
|
|
7117
7561
|
}
|
|
7118
7562
|
};
|
|
7119
7563
|
if (!finalConfig.jwt.accessSecret) {
|
|
7120
|
-
throw
|
|
7564
|
+
throw Err16.configRequired("auth", "JWT_ACCESS_SECRET");
|
|
7121
7565
|
}
|
|
7122
7566
|
if (!finalConfig.jwt.refreshSecret) {
|
|
7123
|
-
throw
|
|
7567
|
+
throw Err16.configRequired("auth", "JWT_REFRESH_SECRET");
|
|
7124
7568
|
}
|
|
7125
7569
|
return finalConfig;
|
|
7126
7570
|
}, "resolveAuthConfig");
|
|
@@ -7338,6 +7782,7 @@ export {
|
|
|
7338
7782
|
RoleService,
|
|
7339
7783
|
RoleValidator,
|
|
7340
7784
|
ScopeContext,
|
|
7785
|
+
SessionInvalidationService,
|
|
7341
7786
|
TOKEN_STATUS,
|
|
7342
7787
|
TOKEN_TYPE,
|
|
7343
7788
|
TokenRepository,
|
|
@@ -7351,6 +7796,7 @@ export {
|
|
|
7351
7796
|
assignRoleDto,
|
|
7352
7797
|
assignRoleParams,
|
|
7353
7798
|
auth,
|
|
7799
|
+
authEmailRateLimitKey,
|
|
7354
7800
|
authIdentityRateLimitKey,
|
|
7355
7801
|
authSchema,
|
|
7356
7802
|
authSeed,
|