najm-auth 3.4.0 → 4.0.1
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 +100 -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 +312 -97
- package/dist/index.js +1232 -767
- 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,10 +2693,22 @@ 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
|
-
async
|
|
2711
|
+
async consumeSetPasswordToken(token) {
|
|
2365
2712
|
let decoded;
|
|
2366
2713
|
try {
|
|
2367
2714
|
decoded = jwt.verify(token, this.config.jwt.refreshSecret);
|
|
@@ -2371,40 +2718,53 @@ 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
|
-
|
|
2380
|
-
|
|
2729
|
+
return {
|
|
2730
|
+
userId: decoded.userId,
|
|
2731
|
+
type: decoded.type
|
|
2732
|
+
};
|
|
2733
|
+
}
|
|
2734
|
+
/**
|
|
2735
|
+
* Backward-compatible user-id-only reset/invite token consumption.
|
|
2736
|
+
* Prefer `consumeSetPasswordToken()` when the caller must distinguish an
|
|
2737
|
+
* account invitation from an ordinary password reset.
|
|
2738
|
+
*/
|
|
2739
|
+
async verifyResetToken(token) {
|
|
2740
|
+
return (await this.consumeSetPasswordToken(token)).userId;
|
|
2381
2741
|
}
|
|
2382
2742
|
async getUserSessionVersion(userId) {
|
|
2383
|
-
return this.
|
|
2743
|
+
return this.invalidation.getSessionVersion(userId);
|
|
2384
2744
|
}
|
|
2385
2745
|
};
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2746
|
+
__decorate12([
|
|
2747
|
+
Inject9(AUTH_CONFIG),
|
|
2748
|
+
__metadata12("design:type", Object)
|
|
2389
2749
|
], TokenService.prototype, "config", void 0);
|
|
2390
|
-
|
|
2750
|
+
__decorate12([
|
|
2391
2751
|
I18n5("auth"),
|
|
2392
|
-
|
|
2752
|
+
__metadata12("design:type", Object)
|
|
2393
2753
|
], TokenService.prototype, "t", void 0);
|
|
2394
|
-
TokenService = TokenService_1 =
|
|
2395
|
-
|
|
2396
|
-
|
|
2754
|
+
TokenService = TokenService_1 = __decorate12([
|
|
2755
|
+
Injectable7(),
|
|
2756
|
+
__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
2757
|
], TokenService);
|
|
2398
2758
|
|
|
2399
2759
|
// src/auth/AuthService.ts
|
|
2400
|
-
import
|
|
2760
|
+
import timestring4 from "timestring";
|
|
2401
2761
|
|
|
2402
2762
|
// src/auth/AuthSessionService.ts
|
|
2403
|
-
import { Injectable as
|
|
2763
|
+
import { Injectable as Injectable9 } from "najm-core";
|
|
2404
2764
|
import { Err as Err9 } from "najm-core";
|
|
2405
2765
|
|
|
2406
2766
|
// src/credentialSetup/CredentialSetupRequirementService.ts
|
|
2407
|
-
import { Injectable as
|
|
2767
|
+
import { Injectable as Injectable8 } from "najm-core";
|
|
2408
2768
|
import { Transaction as Transaction2 } from "najm-database";
|
|
2409
2769
|
|
|
2410
2770
|
// src/identity/temporaryCredential.ts
|
|
@@ -2476,17 +2836,17 @@ function normalizeSetupPurpose(purpose) {
|
|
|
2476
2836
|
__name(normalizeSetupPurpose, "normalizeSetupPurpose");
|
|
2477
2837
|
|
|
2478
2838
|
// src/credentialSetup/CredentialSetupRequirementService.ts
|
|
2479
|
-
var
|
|
2839
|
+
var __decorate13 = function(decorators, target, key, desc) {
|
|
2480
2840
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2481
2841
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2482
2842
|
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
2843
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2484
2844
|
};
|
|
2485
|
-
var
|
|
2845
|
+
var __metadata13 = function(k, v) {
|
|
2486
2846
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2487
2847
|
};
|
|
2488
|
-
var
|
|
2489
|
-
var
|
|
2848
|
+
var _a8;
|
|
2849
|
+
var _b6;
|
|
2490
2850
|
var _c3;
|
|
2491
2851
|
var CredentialSetupRequirementService = class CredentialSetupRequirementService2 {
|
|
2492
2852
|
static {
|
|
@@ -2526,15 +2886,15 @@ var CredentialSetupRequirementService = class CredentialSetupRequirementService2
|
|
|
2526
2886
|
return this.repository.complete(userId, normalizeSetupPurpose(purpose));
|
|
2527
2887
|
}
|
|
2528
2888
|
};
|
|
2529
|
-
|
|
2889
|
+
__decorate13([
|
|
2530
2890
|
Transaction2({ retries: 2 }),
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2891
|
+
__metadata13("design:type", Function),
|
|
2892
|
+
__metadata13("design:paramtypes", [String, String, Object]),
|
|
2893
|
+
__metadata13("design:returntype", typeof (_c3 = typeof Promise !== "undefined" && Promise) === "function" ? _c3 : Object)
|
|
2534
2894
|
], CredentialSetupRequirementService.prototype, "markRequired", null);
|
|
2535
|
-
CredentialSetupRequirementService =
|
|
2536
|
-
|
|
2537
|
-
|
|
2895
|
+
CredentialSetupRequirementService = __decorate13([
|
|
2896
|
+
Injectable8(),
|
|
2897
|
+
__metadata13("design:paramtypes", [typeof (_a8 = typeof CredentialSetupRequirementRepository !== "undefined" && CredentialSetupRequirementRepository) === "function" ? _a8 : Object, typeof (_b6 = typeof TokenService !== "undefined" && TokenService) === "function" ? _b6 : Object])
|
|
2538
2898
|
], CredentialSetupRequirementService);
|
|
2539
2899
|
|
|
2540
2900
|
// src/credentialSetup/errors.ts
|
|
@@ -2560,17 +2920,17 @@ var credentialSetupError = /* @__PURE__ */ __name((code, message, status = 400)
|
|
|
2560
2920
|
}, "credentialSetupError");
|
|
2561
2921
|
|
|
2562
2922
|
// src/auth/AuthSessionService.ts
|
|
2563
|
-
var
|
|
2923
|
+
var __decorate14 = function(decorators, target, key, desc) {
|
|
2564
2924
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2565
2925
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2566
2926
|
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
2927
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2568
2928
|
};
|
|
2569
|
-
var
|
|
2929
|
+
var __metadata14 = function(k, v) {
|
|
2570
2930
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2571
2931
|
};
|
|
2572
|
-
var
|
|
2573
|
-
var
|
|
2932
|
+
var _a9;
|
|
2933
|
+
var _b7;
|
|
2574
2934
|
var _c4;
|
|
2575
2935
|
var _d3;
|
|
2576
2936
|
var AuthSessionService = class AuthSessionService2 {
|
|
@@ -2598,7 +2958,7 @@ var AuthSessionService = class AuthSessionService2 {
|
|
|
2598
2958
|
const generated = await this.tokenService.generateTokens(user.id);
|
|
2599
2959
|
this.cookieManager.setRefreshToken(generated.refreshToken);
|
|
2600
2960
|
await this.userService.updateLastLogin(user.id);
|
|
2601
|
-
const { roles, permissions, sessionVersion } = generated;
|
|
2961
|
+
const { roles, permissions, sessionVersion, tokenFamily } = generated;
|
|
2602
2962
|
this.cookieManager.setSessionCookie({
|
|
2603
2963
|
user: {
|
|
2604
2964
|
id: user.id,
|
|
@@ -2609,39 +2969,40 @@ var AuthSessionService = class AuthSessionService2 {
|
|
|
2609
2969
|
},
|
|
2610
2970
|
roles,
|
|
2611
2971
|
permissions,
|
|
2612
|
-
sessionVersion
|
|
2972
|
+
sessionVersion,
|
|
2973
|
+
tokenFamily
|
|
2613
2974
|
});
|
|
2614
2975
|
const { userId: _userId, tokenFamily: _tokenFamily, roles: _roles, permissions: _permissions, sessionVersion: _sessionVersion, ...tokens } = generated;
|
|
2615
2976
|
return { ...tokens, user };
|
|
2616
2977
|
}
|
|
2617
2978
|
};
|
|
2618
|
-
AuthSessionService =
|
|
2619
|
-
|
|
2620
|
-
|
|
2979
|
+
AuthSessionService = __decorate14([
|
|
2980
|
+
Injectable9(),
|
|
2981
|
+
__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
2982
|
], AuthSessionService);
|
|
2622
2983
|
|
|
2623
2984
|
// src/credentialSetup/PasswordSetupService.ts
|
|
2624
|
-
import { Inject as
|
|
2985
|
+
import { Inject as Inject11, Injectable as Injectable11 } from "najm-core";
|
|
2625
2986
|
import { I18n as I18n7 } from "najm-i18n";
|
|
2626
2987
|
|
|
2627
2988
|
// src/credentialSetup/CredentialSetupService.ts
|
|
2628
2989
|
import { createHash as createHash2, randomBytes as randomBytes2 } from "crypto";
|
|
2629
2990
|
import { CookieService as CookieService2 } from "najm-cookies";
|
|
2630
|
-
import { Err as Err11, Injectable as
|
|
2991
|
+
import { Err as Err11, Injectable as Injectable10 } from "najm-core";
|
|
2631
2992
|
import { Transaction as Transaction3 } from "najm-database";
|
|
2632
2993
|
import { I18n as I18n6 } from "najm-i18n";
|
|
2633
2994
|
|
|
2634
2995
|
// src/credentialSetup/CredentialSetupRepository.ts
|
|
2635
2996
|
import { and as and3, eq as eq6, gt, isNull as isNull2, lt as lt2 } from "drizzle-orm";
|
|
2636
|
-
import { Err as Err10, Inject as
|
|
2997
|
+
import { Err as Err10, Inject as Inject10, Repository as Repository5 } from "najm-core";
|
|
2637
2998
|
import { DB as DB5 } from "najm-database";
|
|
2638
|
-
var
|
|
2999
|
+
var __decorate15 = function(decorators, target, key, desc) {
|
|
2639
3000
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2640
3001
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2641
3002
|
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
3003
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2643
3004
|
};
|
|
2644
|
-
var
|
|
3005
|
+
var __metadata15 = function(k, v) {
|
|
2645
3006
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2646
3007
|
};
|
|
2647
3008
|
var CredentialSetupRepository = class CredentialSetupRepository2 {
|
|
@@ -2693,33 +3054,33 @@ var CredentialSetupRepository = class CredentialSetupRepository2 {
|
|
|
2693
3054
|
return this.db.delete(this.sessions).where(lt2(this.sessions.expiresAt, (/* @__PURE__ */ new Date()).toISOString())).returning({ userId: this.sessions.userId });
|
|
2694
3055
|
}
|
|
2695
3056
|
};
|
|
2696
|
-
|
|
3057
|
+
__decorate15([
|
|
2697
3058
|
DB5(),
|
|
2698
|
-
|
|
3059
|
+
__metadata15("design:type", Object)
|
|
2699
3060
|
], CredentialSetupRepository.prototype, "db", void 0);
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
3061
|
+
__decorate15([
|
|
3062
|
+
Inject10(AUTH_SCHEMA),
|
|
3063
|
+
__metadata15("design:type", Object)
|
|
2703
3064
|
], CredentialSetupRepository.prototype, "schema", void 0);
|
|
2704
|
-
CredentialSetupRepository =
|
|
3065
|
+
CredentialSetupRepository = __decorate15([
|
|
2705
3066
|
Repository5()
|
|
2706
3067
|
], CredentialSetupRepository);
|
|
2707
3068
|
|
|
2708
3069
|
// src/credentialSetup/CredentialSetupService.ts
|
|
2709
|
-
var
|
|
3070
|
+
var __decorate16 = function(decorators, target, key, desc) {
|
|
2710
3071
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2711
3072
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2712
3073
|
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
3074
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2714
3075
|
};
|
|
2715
|
-
var
|
|
3076
|
+
var __metadata16 = function(k, v) {
|
|
2716
3077
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2717
3078
|
};
|
|
2718
|
-
var
|
|
2719
|
-
var
|
|
3079
|
+
var _a10;
|
|
3080
|
+
var _b8;
|
|
2720
3081
|
var _c5;
|
|
2721
3082
|
var _d4;
|
|
2722
|
-
var
|
|
3083
|
+
var _e3;
|
|
2723
3084
|
var _f2;
|
|
2724
3085
|
var _g2;
|
|
2725
3086
|
var DEFAULT_CREDENTIAL_SETUP_COOKIE_NAME = "najm.credential-setup";
|
|
@@ -2855,48 +3216,48 @@ var CredentialSetupService = class CredentialSetupService2 {
|
|
|
2855
3216
|
});
|
|
2856
3217
|
}
|
|
2857
3218
|
};
|
|
2858
|
-
|
|
3219
|
+
__decorate16([
|
|
2859
3220
|
I18n6("auth"),
|
|
2860
|
-
|
|
3221
|
+
__metadata16("design:type", Object)
|
|
2861
3222
|
], CredentialSetupService.prototype, "t", void 0);
|
|
2862
|
-
|
|
3223
|
+
__decorate16([
|
|
2863
3224
|
Transaction3({ retries: 2 }),
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
3225
|
+
__metadata16("design:type", Function),
|
|
3226
|
+
__metadata16("design:paramtypes", [String, Object]),
|
|
3227
|
+
__metadata16("design:returntype", typeof (_e3 = typeof Promise !== "undefined" && Promise) === "function" ? _e3 : Object)
|
|
2867
3228
|
], CredentialSetupService.prototype, "begin", null);
|
|
2868
|
-
|
|
3229
|
+
__decorate16([
|
|
2869
3230
|
Transaction3({ retries: 2 }),
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
3231
|
+
__metadata16("design:type", Function),
|
|
3232
|
+
__metadata16("design:paramtypes", [Object, Function]),
|
|
3233
|
+
__metadata16("design:returntype", typeof (_f2 = typeof Promise !== "undefined" && Promise) === "function" ? _f2 : Object)
|
|
2873
3234
|
], CredentialSetupService.prototype, "consume", null);
|
|
2874
|
-
|
|
3235
|
+
__decorate16([
|
|
2875
3236
|
Transaction3({ retries: 2 }),
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
3237
|
+
__metadata16("design:type", Function),
|
|
3238
|
+
__metadata16("design:paramtypes", [Object]),
|
|
3239
|
+
__metadata16("design:returntype", typeof (_g2 = typeof Promise !== "undefined" && Promise) === "function" ? _g2 : Object)
|
|
2879
3240
|
], CredentialSetupService.prototype, "cancel", null);
|
|
2880
|
-
CredentialSetupService =
|
|
2881
|
-
|
|
2882
|
-
|
|
3241
|
+
CredentialSetupService = __decorate16([
|
|
3242
|
+
Injectable10(),
|
|
3243
|
+
__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
3244
|
], CredentialSetupService);
|
|
2884
3245
|
|
|
2885
3246
|
// src/credentialSetup/PasswordSetupService.ts
|
|
2886
|
-
var
|
|
3247
|
+
var __decorate17 = function(decorators, target, key, desc) {
|
|
2887
3248
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2888
3249
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2889
3250
|
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
3251
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2891
3252
|
};
|
|
2892
|
-
var
|
|
3253
|
+
var __metadata17 = function(k, v) {
|
|
2893
3254
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2894
3255
|
};
|
|
2895
|
-
var
|
|
2896
|
-
var
|
|
3256
|
+
var _a11;
|
|
3257
|
+
var _b9;
|
|
2897
3258
|
var _c6;
|
|
2898
3259
|
var _d5;
|
|
2899
|
-
var
|
|
3260
|
+
var _e4;
|
|
2900
3261
|
var _f3;
|
|
2901
3262
|
var PasswordSetupService = class PasswordSetupService2 {
|
|
2902
3263
|
static {
|
|
@@ -3013,38 +3374,38 @@ var PasswordSetupService = class PasswordSetupService2 {
|
|
|
3013
3374
|
return this.validator.comparePassword(normalized, storedHash);
|
|
3014
3375
|
}
|
|
3015
3376
|
};
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3377
|
+
__decorate17([
|
|
3378
|
+
Inject11(AUTH_CONFIG),
|
|
3379
|
+
__metadata17("design:type", Object)
|
|
3019
3380
|
], PasswordSetupService.prototype, "config", void 0);
|
|
3020
|
-
|
|
3381
|
+
__decorate17([
|
|
3021
3382
|
I18n7("auth"),
|
|
3022
|
-
|
|
3383
|
+
__metadata17("design:type", Object)
|
|
3023
3384
|
], PasswordSetupService.prototype, "t", void 0);
|
|
3024
|
-
PasswordSetupService =
|
|
3025
|
-
|
|
3026
|
-
|
|
3385
|
+
PasswordSetupService = __decorate17([
|
|
3386
|
+
Injectable11(),
|
|
3387
|
+
__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
3388
|
], PasswordSetupService);
|
|
3028
3389
|
|
|
3029
3390
|
// src/auth/AuthService.ts
|
|
3030
|
-
var
|
|
3391
|
+
var __decorate18 = function(decorators, target, key, desc) {
|
|
3031
3392
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3032
3393
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3033
3394
|
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
3395
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3035
3396
|
};
|
|
3036
|
-
var
|
|
3397
|
+
var __metadata18 = function(k, v) {
|
|
3037
3398
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3038
3399
|
};
|
|
3039
|
-
var
|
|
3040
|
-
var
|
|
3400
|
+
var _a12;
|
|
3401
|
+
var _b10;
|
|
3041
3402
|
var _c7;
|
|
3042
3403
|
var _d6;
|
|
3043
|
-
var
|
|
3404
|
+
var _e5;
|
|
3044
3405
|
var _f4;
|
|
3045
3406
|
var _g3;
|
|
3046
3407
|
var _h2;
|
|
3047
|
-
var
|
|
3408
|
+
var _j2;
|
|
3048
3409
|
var _k;
|
|
3049
3410
|
var _l;
|
|
3050
3411
|
var AuthService = class AuthService2 {
|
|
@@ -3083,7 +3444,7 @@ var AuthService = class AuthService2 {
|
|
|
3083
3444
|
return new Date(lockoutUntil).getTime() > Date.now();
|
|
3084
3445
|
}
|
|
3085
3446
|
nextLockoutUntil() {
|
|
3086
|
-
const durationMs =
|
|
3447
|
+
const durationMs = timestring4(this.config.lockout.duration, "ms");
|
|
3087
3448
|
return new Date(Date.now() + durationMs).toISOString();
|
|
3088
3449
|
}
|
|
3089
3450
|
getDummyHash() {
|
|
@@ -3333,7 +3694,8 @@ var AuthService = class AuthService2 {
|
|
|
3333
3694
|
user: { id: user.id, email: user.email, name: user.name, role: user.role, status: user.status ?? void 0 },
|
|
3334
3695
|
roles: generated.roles,
|
|
3335
3696
|
permissions: generated.permissions,
|
|
3336
|
-
sessionVersion: generated.sessionVersion
|
|
3697
|
+
sessionVersion: generated.sessionVersion,
|
|
3698
|
+
tokenFamily: generated.tokenFamily
|
|
3337
3699
|
});
|
|
3338
3700
|
}
|
|
3339
3701
|
const { userId: _userId, tokenFamily: _tokenFamily, roles: _roles, permissions: _permissions, sessionVersion: _sv, ...tokens } = generated;
|
|
@@ -3356,7 +3718,8 @@ var AuthService = class AuthService2 {
|
|
|
3356
3718
|
},
|
|
3357
3719
|
roles: recovered.roles,
|
|
3358
3720
|
permissions: recovered.permissions,
|
|
3359
|
-
sessionVersion: recovered.sessionVersion
|
|
3721
|
+
sessionVersion: recovered.sessionVersion,
|
|
3722
|
+
tokenFamily: recovered.tokenFamily
|
|
3360
3723
|
});
|
|
3361
3724
|
return { recovered: true };
|
|
3362
3725
|
}
|
|
@@ -3408,7 +3771,12 @@ var AuthService = class AuthService2 {
|
|
|
3408
3771
|
const lang = this.i18nService.getCurrentLanguage();
|
|
3409
3772
|
result = { ...user, language: lang };
|
|
3410
3773
|
const token = this.tokenService.decodeAccessToken(authorization.replace(/^Bearer\s+/i, ""));
|
|
3411
|
-
cachePayload =
|
|
3774
|
+
cachePayload = token?.tokenFamily ? {
|
|
3775
|
+
roles: token.roles ?? [],
|
|
3776
|
+
permissions: token.permissions ?? [],
|
|
3777
|
+
sessionVersion: token.sessionVersion ?? 0,
|
|
3778
|
+
tokenFamily: token.tokenFamily
|
|
3779
|
+
} : null;
|
|
3412
3780
|
} else {
|
|
3413
3781
|
result = await this.getUserFromCookie();
|
|
3414
3782
|
}
|
|
@@ -3420,7 +3788,8 @@ var AuthService = class AuthService2 {
|
|
|
3420
3788
|
user: { id: result.id, email: result.email, name: result.name, role: result.role, status: result.status ?? void 0 },
|
|
3421
3789
|
roles: cachePayload.roles,
|
|
3422
3790
|
permissions: cachePayload.permissions,
|
|
3423
|
-
sessionVersion: cachePayload.sessionVersion
|
|
3791
|
+
sessionVersion: cachePayload.sessionVersion,
|
|
3792
|
+
tokenFamily: cachePayload.tokenFamily
|
|
3424
3793
|
});
|
|
3425
3794
|
}
|
|
3426
3795
|
return result;
|
|
@@ -3459,49 +3828,57 @@ var AuthService = class AuthService2 {
|
|
|
3459
3828
|
return { message: this.t("success.passwordChanged") };
|
|
3460
3829
|
}
|
|
3461
3830
|
async resetPassword(token, newPassword) {
|
|
3462
|
-
const userId = await this.tokenService.verifyResetToken(token);
|
|
3463
3831
|
this.userValidator.validatePasswordStrength(newPassword);
|
|
3464
|
-
await this.
|
|
3465
|
-
await this.
|
|
3466
|
-
|
|
3832
|
+
const consumed = await this.tokenService.consumeSetPasswordToken(token);
|
|
3833
|
+
const user = await this.userService.getById(consumed.userId);
|
|
3834
|
+
const acceptsInvitation = consumed.type === "invite";
|
|
3835
|
+
await this.userService.update(consumed.userId, {
|
|
3836
|
+
password: newPassword,
|
|
3837
|
+
...acceptsInvitation ? {
|
|
3838
|
+
emailVerified: true,
|
|
3839
|
+
...user.status === "pending" ? { status: "active" } : {}
|
|
3840
|
+
} : {}
|
|
3841
|
+
});
|
|
3842
|
+
await this.tokenService.invalidateUserAccessTokens(consumed.userId);
|
|
3843
|
+
await this.tokenService.revokeAllForUser(consumed.userId);
|
|
3467
3844
|
this.cookieManager.clearRefreshToken();
|
|
3468
3845
|
this.cookieManager.clearSessionCookie();
|
|
3469
3846
|
return { message: this.t("success.passwordReset") };
|
|
3470
3847
|
}
|
|
3471
3848
|
};
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3849
|
+
__decorate18([
|
|
3850
|
+
Inject12(AUTH_CONFIG),
|
|
3851
|
+
__metadata18("design:type", Object)
|
|
3475
3852
|
], AuthService.prototype, "config", void 0);
|
|
3476
|
-
|
|
3853
|
+
__decorate18([
|
|
3477
3854
|
I18n8("auth"),
|
|
3478
|
-
|
|
3855
|
+
__metadata18("design:type", Object)
|
|
3479
3856
|
], AuthService.prototype, "t", void 0);
|
|
3480
|
-
|
|
3857
|
+
__decorate18([
|
|
3481
3858
|
Log(),
|
|
3482
|
-
|
|
3859
|
+
__metadata18("design:type", Object)
|
|
3483
3860
|
], AuthService.prototype, "logger", void 0);
|
|
3484
|
-
|
|
3861
|
+
__decorate18([
|
|
3485
3862
|
Transaction4(),
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3863
|
+
__metadata18("design:type", Function),
|
|
3864
|
+
__metadata18("design:paramtypes", [Object]),
|
|
3865
|
+
__metadata18("design:returntype", typeof (_l = typeof Promise !== "undefined" && Promise) === "function" ? _l : Object)
|
|
3489
3866
|
], AuthService.prototype, "provisionWithCredentialSetup", null);
|
|
3490
|
-
AuthService =
|
|
3491
|
-
|
|
3492
|
-
|
|
3867
|
+
AuthService = __decorate18([
|
|
3868
|
+
Injectable12(),
|
|
3869
|
+
__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
3870
|
], AuthService);
|
|
3494
3871
|
|
|
3495
3872
|
// src/auth/AuthGuard.ts
|
|
3496
3873
|
import { Service as Service2, User } from "najm-core";
|
|
3497
3874
|
import { createGuard } from "najm-guard";
|
|
3498
|
-
var
|
|
3875
|
+
var __decorate19 = function(decorators, target, key, desc) {
|
|
3499
3876
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3500
3877
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3501
3878
|
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
3879
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3503
3880
|
};
|
|
3504
|
-
var
|
|
3881
|
+
var __metadata19 = function(k, v) {
|
|
3505
3882
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3506
3883
|
};
|
|
3507
3884
|
var __param3 = function(paramIndex, decorator) {
|
|
@@ -3513,17 +3890,27 @@ var AuthGuard = class AuthGuard2 {
|
|
|
3513
3890
|
static {
|
|
3514
3891
|
__name(this, "AuthGuard");
|
|
3515
3892
|
}
|
|
3893
|
+
/**
|
|
3894
|
+
* A resolved principal is not automatically an authorized one.
|
|
3895
|
+
*
|
|
3896
|
+
* The resolvers ahead of this guard already reject deactivated accounts, so
|
|
3897
|
+
* this is the backstop for anything that publishes a principal by another
|
|
3898
|
+
* route: a truthy user record must still be an active one to pass. Records
|
|
3899
|
+
* whose projection omits `status` are unchanged.
|
|
3900
|
+
*/
|
|
3516
3901
|
canActivate(user) {
|
|
3517
|
-
|
|
3902
|
+
if (!user)
|
|
3903
|
+
return false;
|
|
3904
|
+
return user.status === void 0 || user.status === "active";
|
|
3518
3905
|
}
|
|
3519
3906
|
};
|
|
3520
|
-
|
|
3907
|
+
__decorate19([
|
|
3521
3908
|
__param3(0, User()),
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3909
|
+
__metadata19("design:type", Function),
|
|
3910
|
+
__metadata19("design:paramtypes", [Object]),
|
|
3911
|
+
__metadata19("design:returntype", Boolean)
|
|
3525
3912
|
], AuthGuard.prototype, "canActivate", null);
|
|
3526
|
-
AuthGuard =
|
|
3913
|
+
AuthGuard = __decorate19([
|
|
3527
3914
|
Service2()
|
|
3528
3915
|
], AuthGuard);
|
|
3529
3916
|
var isAuth = createGuard(AuthGuard);
|
|
@@ -3532,13 +3919,13 @@ var isAuth = createGuard(AuthGuard);
|
|
|
3532
3919
|
import { Service as Service3 } from "najm-core";
|
|
3533
3920
|
import { GuardParams, Role as RequestRole } from "najm-core";
|
|
3534
3921
|
import { composeGuards, createGuard as createGuard2 } from "najm-guard";
|
|
3535
|
-
var
|
|
3922
|
+
var __decorate20 = function(decorators, target, key, desc) {
|
|
3536
3923
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3537
3924
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3538
3925
|
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
3926
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3540
3927
|
};
|
|
3541
|
-
var
|
|
3928
|
+
var __metadata20 = function(k, v) {
|
|
3542
3929
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3543
3930
|
};
|
|
3544
3931
|
var __param4 = function(paramIndex, decorator) {
|
|
@@ -3561,14 +3948,14 @@ var RoleGuard = class RoleGuard2 {
|
|
|
3561
3948
|
return false;
|
|
3562
3949
|
}
|
|
3563
3950
|
};
|
|
3564
|
-
|
|
3951
|
+
__decorate20([
|
|
3565
3952
|
__param4(0, GuardParams()),
|
|
3566
3953
|
__param4(1, RequestRole()),
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3954
|
+
__metadata20("design:type", Function),
|
|
3955
|
+
__metadata20("design:paramtypes", [Object, String]),
|
|
3956
|
+
__metadata20("design:returntype", void 0)
|
|
3570
3957
|
], RoleGuard.prototype, "canActivate", null);
|
|
3571
|
-
RoleGuard =
|
|
3958
|
+
RoleGuard = __decorate20([
|
|
3572
3959
|
Service3()
|
|
3573
3960
|
], RoleGuard);
|
|
3574
3961
|
var Role = createGuard2(RoleGuard);
|
|
@@ -3739,13 +4126,13 @@ var userListQuery = z.object({
|
|
|
3739
4126
|
});
|
|
3740
4127
|
|
|
3741
4128
|
// src/auth/AuthController.ts
|
|
3742
|
-
var
|
|
4129
|
+
var __decorate21 = function(decorators, target, key, desc) {
|
|
3743
4130
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3744
4131
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3745
4132
|
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
4133
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3747
4134
|
};
|
|
3748
|
-
var
|
|
4135
|
+
var __metadata21 = function(k, v) {
|
|
3749
4136
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3750
4137
|
};
|
|
3751
4138
|
var __param5 = function(paramIndex, decorator) {
|
|
@@ -3753,18 +4140,28 @@ var __param5 = function(paramIndex, decorator) {
|
|
|
3753
4140
|
decorator(target, key, paramIndex);
|
|
3754
4141
|
};
|
|
3755
4142
|
};
|
|
3756
|
-
var
|
|
4143
|
+
var _a13;
|
|
3757
4144
|
var hashKeyPart = /* @__PURE__ */ __name((value) => createHash3("sha256").update(value).digest("base64url").slice(0, 32), "hashKeyPart");
|
|
3758
4145
|
var cookieFingerprint = /* @__PURE__ */ __name(() => (ctx, { clientIp }) => {
|
|
3759
4146
|
const cookie = ctx.req.raw.headers.get("cookie") ?? "";
|
|
3760
4147
|
const fingerprint = cookie ? hashKeyPart(cookie) : "none";
|
|
3761
4148
|
return `${clientIp}:${fingerprint}`;
|
|
3762
4149
|
}, "cookieFingerprint");
|
|
3763
|
-
var
|
|
4150
|
+
var readDeclaredIdentity = /* @__PURE__ */ __name((body, fields) => {
|
|
4151
|
+
if (typeof body !== "object" || body === null || Array.isArray(body))
|
|
4152
|
+
return void 0;
|
|
4153
|
+
for (const field of fields) {
|
|
4154
|
+
const value = body[field];
|
|
4155
|
+
if (typeof value === "string" && value.trim())
|
|
4156
|
+
return value;
|
|
4157
|
+
}
|
|
4158
|
+
return void 0;
|
|
4159
|
+
}, "readDeclaredIdentity");
|
|
4160
|
+
var identityRateLimitKey = /* @__PURE__ */ __name((fields) => async (ctx, keyContext) => {
|
|
3764
4161
|
const ip = keyContext?.clientIp ?? UNRESOLVED_CLIENT_ADDRESS;
|
|
3765
4162
|
try {
|
|
3766
4163
|
const body = await ctx.req.json();
|
|
3767
|
-
const identity = body
|
|
4164
|
+
const identity = readDeclaredIdentity(body, fields);
|
|
3768
4165
|
const normalizedIdentity = getRequestIdentityResolver(ctx)(identity);
|
|
3769
4166
|
if (normalizedIdentity) {
|
|
3770
4167
|
return `${ip}:${hashKeyPart(normalizedIdentity)}`;
|
|
@@ -3772,7 +4169,9 @@ var authIdentityRateLimitKey = /* @__PURE__ */ __name(async (ctx, keyContext) =>
|
|
|
3772
4169
|
} catch {
|
|
3773
4170
|
}
|
|
3774
4171
|
return ip;
|
|
3775
|
-
}, "
|
|
4172
|
+
}, "identityRateLimitKey");
|
|
4173
|
+
var authIdentityRateLimitKey = identityRateLimitKey(["identifier", "email"]);
|
|
4174
|
+
var authEmailRateLimitKey = identityRateLimitKey(["email"]);
|
|
3776
4175
|
var loginRateLimit = resolveAuthLoginRateLimitConfig();
|
|
3777
4176
|
var AuthController = class AuthController2 {
|
|
3778
4177
|
static {
|
|
@@ -3815,7 +4214,7 @@ var AuthController = class AuthController2 {
|
|
|
3815
4214
|
return this.authService.resetPassword(body.token, body.newPassword);
|
|
3816
4215
|
}
|
|
3817
4216
|
};
|
|
3818
|
-
|
|
4217
|
+
__decorate21([
|
|
3819
4218
|
Post("/login"),
|
|
3820
4219
|
RateLimit({
|
|
3821
4220
|
limit: loginRateLimit.limit,
|
|
@@ -3827,105 +4226,105 @@ __decorate20([
|
|
|
3827
4226
|
Validate(loginDto),
|
|
3828
4227
|
ResMsg("auth.success.login"),
|
|
3829
4228
|
__param5(0, Body()),
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
4229
|
+
__metadata21("design:type", Function),
|
|
4230
|
+
__metadata21("design:paramtypes", [Object]),
|
|
4231
|
+
__metadata21("design:returntype", Promise)
|
|
3833
4232
|
], AuthController.prototype, "loginUser", null);
|
|
3834
|
-
|
|
4233
|
+
__decorate21([
|
|
3835
4234
|
Post("/invite"),
|
|
3836
4235
|
isAdmin(),
|
|
3837
4236
|
RateLimit({ limit: 20, window: "15m", key: "user" }),
|
|
3838
4237
|
Validate(inviteUserDto),
|
|
3839
4238
|
ResMsg("auth.success.accountInviteSent"),
|
|
3840
4239
|
__param5(0, Body()),
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
4240
|
+
__metadata21("design:type", Function),
|
|
4241
|
+
__metadata21("design:paramtypes", [Object]),
|
|
4242
|
+
__metadata21("design:returntype", Promise)
|
|
3844
4243
|
], AuthController.prototype, "inviteUser", null);
|
|
3845
|
-
|
|
4244
|
+
__decorate21([
|
|
3846
4245
|
Post("/refresh"),
|
|
3847
4246
|
RateLimit({ limit: 15, window: "15m", key: cookieFingerprint() }),
|
|
3848
4247
|
ResMsg("auth.success.tokenRefreshed"),
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
4248
|
+
__metadata21("design:type", Function),
|
|
4249
|
+
__metadata21("design:paramtypes", []),
|
|
4250
|
+
__metadata21("design:returntype", Promise)
|
|
3852
4251
|
], AuthController.prototype, "refreshTokens", null);
|
|
3853
|
-
|
|
4252
|
+
__decorate21([
|
|
3854
4253
|
Post("/session/recover"),
|
|
3855
4254
|
RateLimit({ limit: 120, window: "1m", key: cookieFingerprint() }),
|
|
3856
4255
|
ResMsg("auth.success.sessionRecovered"),
|
|
3857
4256
|
__param5(0, Headers("x-najm-session-recovery")),
|
|
3858
4257
|
__param5(1, Ctx()),
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
4258
|
+
__metadata21("design:type", Function),
|
|
4259
|
+
__metadata21("design:paramtypes", [String, Object]),
|
|
4260
|
+
__metadata21("design:returntype", Promise)
|
|
3862
4261
|
], AuthController.prototype, "recoverSession", null);
|
|
3863
|
-
|
|
4262
|
+
__decorate21([
|
|
3864
4263
|
Post("/logout"),
|
|
3865
4264
|
__param5(0, User2("id")),
|
|
3866
4265
|
__param5(1, Headers("authorization")),
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
4266
|
+
__metadata21("design:type", Function),
|
|
4267
|
+
__metadata21("design:paramtypes", [String, String]),
|
|
4268
|
+
__metadata21("design:returntype", Promise)
|
|
3870
4269
|
], AuthController.prototype, "logoutUser", null);
|
|
3871
|
-
|
|
4270
|
+
__decorate21([
|
|
3872
4271
|
Post("/change-password"),
|
|
3873
4272
|
isAuth(),
|
|
3874
4273
|
Validate(changePasswordDto),
|
|
3875
4274
|
ResMsg("auth.success.passwordChanged"),
|
|
3876
4275
|
__param5(0, User2("id")),
|
|
3877
4276
|
__param5(1, Body()),
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
4277
|
+
__metadata21("design:type", Function),
|
|
4278
|
+
__metadata21("design:paramtypes", [String, Object]),
|
|
4279
|
+
__metadata21("design:returntype", Promise)
|
|
3881
4280
|
], AuthController.prototype, "changePassword", null);
|
|
3882
|
-
|
|
4281
|
+
__decorate21([
|
|
3883
4282
|
Get("/me"),
|
|
3884
4283
|
RateLimit({ limit: 30, window: "1m", key: cookieFingerprint() }),
|
|
3885
4284
|
ResMsg("auth.users.success.retrieved"),
|
|
3886
4285
|
__param5(0, Headers("authorization")),
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
4286
|
+
__metadata21("design:type", Function),
|
|
4287
|
+
__metadata21("design:paramtypes", [String]),
|
|
4288
|
+
__metadata21("design:returntype", Promise)
|
|
3890
4289
|
], AuthController.prototype, "userProfile", null);
|
|
3891
|
-
|
|
4290
|
+
__decorate21([
|
|
3892
4291
|
Post("/forgot-password"),
|
|
3893
|
-
RateLimit({ limit: 3, window: "15m", key:
|
|
4292
|
+
RateLimit({ limit: 3, window: "15m", key: authEmailRateLimitKey, message: "Too many password reset requests. Please try again later." }),
|
|
3894
4293
|
Validate(resetPasswordDto),
|
|
3895
4294
|
ResMsg("auth.success.passwordResetSent"),
|
|
3896
4295
|
__param5(0, Body()),
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
4296
|
+
__metadata21("design:type", Function),
|
|
4297
|
+
__metadata21("design:paramtypes", [Object]),
|
|
4298
|
+
__metadata21("design:returntype", Promise)
|
|
3900
4299
|
], AuthController.prototype, "forgotPassword", null);
|
|
3901
|
-
|
|
4300
|
+
__decorate21([
|
|
3902
4301
|
Post("/reset-password"),
|
|
3903
4302
|
RateLimit({ limit: 5, window: "15m", key: "ip", message: "Too many password reset attempts. Please try again later." }),
|
|
3904
4303
|
Validate(confirmResetPasswordDto),
|
|
3905
4304
|
ResMsg("auth.success.passwordReset"),
|
|
3906
4305
|
__param5(0, Body()),
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
4306
|
+
__metadata21("design:type", Function),
|
|
4307
|
+
__metadata21("design:paramtypes", [Object]),
|
|
4308
|
+
__metadata21("design:returntype", Promise)
|
|
3910
4309
|
], AuthController.prototype, "resetPassword", null);
|
|
3911
|
-
AuthController =
|
|
4310
|
+
AuthController = __decorate21([
|
|
3912
4311
|
Controller("/auth"),
|
|
3913
|
-
|
|
4312
|
+
__metadata21("design:paramtypes", [typeof (_a13 = typeof AuthService !== "undefined" && AuthService) === "function" ? _a13 : Object])
|
|
3914
4313
|
], AuthController);
|
|
3915
4314
|
|
|
3916
4315
|
// src/auth/AuthResolver.ts
|
|
3917
|
-
import { APP, Container, DI, Inject as
|
|
4316
|
+
import { APP, Container, DI, Inject as Inject13, LOGGER, Meta, Service as Service4 } from "najm-core";
|
|
3918
4317
|
import { USER, ROLE, PERMISSIONS } from "najm-guard";
|
|
3919
|
-
var
|
|
4318
|
+
var __decorate22 = function(decorators, target, key, desc) {
|
|
3920
4319
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3921
4320
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3922
4321
|
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
4322
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3924
4323
|
};
|
|
3925
|
-
var
|
|
4324
|
+
var __metadata22 = function(k, v) {
|
|
3926
4325
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
3927
4326
|
};
|
|
3928
|
-
var
|
|
4327
|
+
var _a14;
|
|
3929
4328
|
var AuthResolver = class AuthResolver2 {
|
|
3930
4329
|
static {
|
|
3931
4330
|
__name(this, "AuthResolver");
|
|
@@ -3976,6 +4375,12 @@ var AuthResolver = class AuthResolver2 {
|
|
|
3976
4375
|
const currentVersion = await tokenService.getSessionVersion(session.user.id);
|
|
3977
4376
|
if ((session.sessionVersion ?? 0) !== currentVersion)
|
|
3978
4377
|
return false;
|
|
4378
|
+
if (!await tokenService.isSessionFamilyLive(session.tokenFamily, session.user.id)) {
|
|
4379
|
+
return false;
|
|
4380
|
+
}
|
|
4381
|
+
const status = session.user.status;
|
|
4382
|
+
if (status !== void 0 && status !== "active")
|
|
4383
|
+
return false;
|
|
3979
4384
|
return {
|
|
3980
4385
|
user: { ...session.user, permissions: session.permissions },
|
|
3981
4386
|
role: session.user.role ?? session.roles[0],
|
|
@@ -4041,32 +4446,32 @@ var AuthResolver = class AuthResolver2 {
|
|
|
4041
4446
|
await authService.warmupPasswordHash();
|
|
4042
4447
|
}
|
|
4043
4448
|
};
|
|
4044
|
-
|
|
4449
|
+
__decorate22([
|
|
4045
4450
|
DI(),
|
|
4046
|
-
|
|
4451
|
+
__metadata22("design:type", typeof (_a14 = typeof Container !== "undefined" && Container) === "function" ? _a14 : Object)
|
|
4047
4452
|
], AuthResolver.prototype, "container", void 0);
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4453
|
+
__decorate22([
|
|
4454
|
+
Inject13(APP),
|
|
4455
|
+
__metadata22("design:type", Object)
|
|
4051
4456
|
], AuthResolver.prototype, "app", void 0);
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4457
|
+
__decorate22([
|
|
4458
|
+
Inject13(LOGGER),
|
|
4459
|
+
__metadata22("design:type", Object)
|
|
4055
4460
|
], AuthResolver.prototype, "log", void 0);
|
|
4056
|
-
AuthResolver =
|
|
4461
|
+
AuthResolver = __decorate22([
|
|
4057
4462
|
Service4(),
|
|
4058
4463
|
Meta({ layer: "plugin", order: 30 })
|
|
4059
4464
|
], AuthResolver);
|
|
4060
4465
|
|
|
4061
4466
|
// src/auth/AuthIdentityContextService.ts
|
|
4062
|
-
import { DI as DI2, Inject as
|
|
4063
|
-
var
|
|
4467
|
+
import { DI as DI2, Inject as Inject14, INJECTION_TYPES, Meta as Meta2, Service as Service5 } from "najm-core";
|
|
4468
|
+
var __decorate23 = function(decorators, target, key, desc) {
|
|
4064
4469
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4065
4470
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4066
4471
|
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
4472
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4068
4473
|
};
|
|
4069
|
-
var
|
|
4474
|
+
var __metadata23 = function(k, v) {
|
|
4070
4475
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4071
4476
|
};
|
|
4072
4477
|
var __param6 = function(paramIndex, decorator) {
|
|
@@ -4096,28 +4501,28 @@ var AuthIdentityContextService = class AuthIdentityContextService2 {
|
|
|
4096
4501
|
});
|
|
4097
4502
|
}
|
|
4098
4503
|
};
|
|
4099
|
-
|
|
4504
|
+
__decorate23([
|
|
4100
4505
|
DI2(),
|
|
4101
|
-
|
|
4506
|
+
__metadata23("design:type", Object)
|
|
4102
4507
|
], AuthIdentityContextService.prototype, "container", void 0);
|
|
4103
|
-
AuthIdentityContextService =
|
|
4508
|
+
AuthIdentityContextService = __decorate23([
|
|
4104
4509
|
Service5(),
|
|
4105
4510
|
Meta2({ layer: "plugin", order: 14 }),
|
|
4106
|
-
__param6(0,
|
|
4107
|
-
|
|
4511
|
+
__param6(0, Inject14(AUTH_CONFIG)),
|
|
4512
|
+
__metadata23("design:paramtypes", [Object])
|
|
4108
4513
|
], AuthIdentityContextService);
|
|
4109
4514
|
|
|
4110
4515
|
// src/auth/RegistrationController.ts
|
|
4111
4516
|
import { Body as Body2, Controller as Controller2, Post as Post2, ResMsg as ResMsg2 } from "najm-core";
|
|
4112
4517
|
import { RateLimit as RateLimit2 } from "najm-rate";
|
|
4113
4518
|
import { Validate as Validate2 } from "najm-validation";
|
|
4114
|
-
var
|
|
4519
|
+
var __decorate24 = function(decorators, target, key, desc) {
|
|
4115
4520
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4116
4521
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4117
4522
|
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
4523
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4119
4524
|
};
|
|
4120
|
-
var
|
|
4525
|
+
var __metadata24 = function(k, v) {
|
|
4121
4526
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4122
4527
|
};
|
|
4123
4528
|
var __param7 = function(paramIndex, decorator) {
|
|
@@ -4125,7 +4530,7 @@ var __param7 = function(paramIndex, decorator) {
|
|
|
4125
4530
|
decorator(target, key, paramIndex);
|
|
4126
4531
|
};
|
|
4127
4532
|
};
|
|
4128
|
-
var
|
|
4533
|
+
var _a15;
|
|
4129
4534
|
var RegistrationController = class RegistrationController2 {
|
|
4130
4535
|
static {
|
|
4131
4536
|
__name(this, "RegistrationController");
|
|
@@ -4138,19 +4543,19 @@ var RegistrationController = class RegistrationController2 {
|
|
|
4138
4543
|
return this.authService.registerUser(body);
|
|
4139
4544
|
}
|
|
4140
4545
|
};
|
|
4141
|
-
|
|
4546
|
+
__decorate24([
|
|
4142
4547
|
Post2("/register"),
|
|
4143
|
-
RateLimit2({ limit: 5, window: "15m", key:
|
|
4548
|
+
RateLimit2({ limit: 5, window: "15m", key: authEmailRateLimitKey }),
|
|
4144
4549
|
Validate2(registerDto),
|
|
4145
4550
|
ResMsg2("auth.success.register"),
|
|
4146
4551
|
__param7(0, Body2()),
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4552
|
+
__metadata24("design:type", Function),
|
|
4553
|
+
__metadata24("design:paramtypes", [Object]),
|
|
4554
|
+
__metadata24("design:returntype", Promise)
|
|
4150
4555
|
], RegistrationController.prototype, "registerUser", null);
|
|
4151
|
-
RegistrationController =
|
|
4556
|
+
RegistrationController = __decorate24([
|
|
4152
4557
|
Controller2("/auth"),
|
|
4153
|
-
|
|
4558
|
+
__metadata24("design:paramtypes", [typeof (_a15 = typeof AuthService !== "undefined" && AuthService) === "function" ? _a15 : Object])
|
|
4154
4559
|
], RegistrationController);
|
|
4155
4560
|
|
|
4156
4561
|
// src/auth/runAsUser.ts
|
|
@@ -4301,13 +4706,13 @@ var assignRoleDto = z2.object({
|
|
|
4301
4706
|
});
|
|
4302
4707
|
|
|
4303
4708
|
// src/roles/RoleController.ts
|
|
4304
|
-
var
|
|
4709
|
+
var __decorate25 = function(decorators, target, key, desc) {
|
|
4305
4710
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4306
4711
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4307
4712
|
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
4713
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4309
4714
|
};
|
|
4310
|
-
var
|
|
4715
|
+
var __metadata25 = function(k, v) {
|
|
4311
4716
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4312
4717
|
};
|
|
4313
4718
|
var __param8 = function(paramIndex, decorator) {
|
|
@@ -4315,7 +4720,7 @@ var __param8 = function(paramIndex, decorator) {
|
|
|
4315
4720
|
decorator(target, key, paramIndex);
|
|
4316
4721
|
};
|
|
4317
4722
|
};
|
|
4318
|
-
var
|
|
4723
|
+
var _a16;
|
|
4319
4724
|
var RoleController = class RoleController2 {
|
|
4320
4725
|
static {
|
|
4321
4726
|
__name(this, "RoleController");
|
|
@@ -4340,35 +4745,35 @@ var RoleController = class RoleController2 {
|
|
|
4340
4745
|
return this.roleService.delete(params.id);
|
|
4341
4746
|
}
|
|
4342
4747
|
};
|
|
4343
|
-
|
|
4748
|
+
__decorate25([
|
|
4344
4749
|
Get2(),
|
|
4345
4750
|
isAdmin(),
|
|
4346
4751
|
ResMsg3("roles.success.retrieved"),
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4752
|
+
__metadata25("design:type", Function),
|
|
4753
|
+
__metadata25("design:paramtypes", []),
|
|
4754
|
+
__metadata25("design:returntype", Promise)
|
|
4350
4755
|
], RoleController.prototype, "getRoles", null);
|
|
4351
|
-
|
|
4756
|
+
__decorate25([
|
|
4352
4757
|
Get2("/:id"),
|
|
4353
4758
|
isAdmin(),
|
|
4354
4759
|
Validate3({ params: roleIdParam }),
|
|
4355
4760
|
ResMsg3("roles.success.retrieved"),
|
|
4356
4761
|
__param8(0, Params()),
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4762
|
+
__metadata25("design:type", Function),
|
|
4763
|
+
__metadata25("design:paramtypes", [Object]),
|
|
4764
|
+
__metadata25("design:returntype", Promise)
|
|
4360
4765
|
], RoleController.prototype, "getRole", null);
|
|
4361
|
-
|
|
4766
|
+
__decorate25([
|
|
4362
4767
|
Post3(),
|
|
4363
4768
|
isAdmin(),
|
|
4364
4769
|
Validate3(createRoleDto),
|
|
4365
4770
|
ResMsg3("roles.success.created"),
|
|
4366
4771
|
__param8(0, Body3()),
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4772
|
+
__metadata25("design:type", Function),
|
|
4773
|
+
__metadata25("design:paramtypes", [Object]),
|
|
4774
|
+
__metadata25("design:returntype", Promise)
|
|
4370
4775
|
], RoleController.prototype, "createRole", null);
|
|
4371
|
-
|
|
4776
|
+
__decorate25([
|
|
4372
4777
|
Put("/:id"),
|
|
4373
4778
|
isAdmin(),
|
|
4374
4779
|
Validate3({
|
|
@@ -4378,34 +4783,34 @@ __decorate24([
|
|
|
4378
4783
|
ResMsg3("roles.success.updated"),
|
|
4379
4784
|
__param8(0, Params()),
|
|
4380
4785
|
__param8(1, Body3()),
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4786
|
+
__metadata25("design:type", Function),
|
|
4787
|
+
__metadata25("design:paramtypes", [Object, Object]),
|
|
4788
|
+
__metadata25("design:returntype", Promise)
|
|
4384
4789
|
], RoleController.prototype, "updateRole", null);
|
|
4385
|
-
|
|
4790
|
+
__decorate25([
|
|
4386
4791
|
Delete("/:id"),
|
|
4387
4792
|
isAdmin(),
|
|
4388
4793
|
Validate3({ params: roleIdParam }),
|
|
4389
4794
|
ResMsg3("roles.success.deleted"),
|
|
4390
4795
|
__param8(0, Params()),
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4796
|
+
__metadata25("design:type", Function),
|
|
4797
|
+
__metadata25("design:paramtypes", [Object]),
|
|
4798
|
+
__metadata25("design:returntype", Promise)
|
|
4394
4799
|
], RoleController.prototype, "deleteRole", null);
|
|
4395
|
-
RoleController =
|
|
4800
|
+
RoleController = __decorate25([
|
|
4396
4801
|
Controller3("/roles"),
|
|
4397
|
-
|
|
4802
|
+
__metadata25("design:paramtypes", [typeof (_a16 = typeof RoleService !== "undefined" && RoleService) === "function" ? _a16 : Object])
|
|
4398
4803
|
], RoleController);
|
|
4399
4804
|
|
|
4400
4805
|
// src/users/UserController.ts
|
|
4401
4806
|
import { Validate as Validate4 } from "najm-validation";
|
|
4402
|
-
var
|
|
4807
|
+
var __decorate26 = function(decorators, target, key, desc) {
|
|
4403
4808
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4404
4809
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4405
4810
|
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
4811
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4407
4812
|
};
|
|
4408
|
-
var
|
|
4813
|
+
var __metadata26 = function(k, v) {
|
|
4409
4814
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4410
4815
|
};
|
|
4411
4816
|
var __param9 = function(paramIndex, decorator) {
|
|
@@ -4413,7 +4818,7 @@ var __param9 = function(paramIndex, decorator) {
|
|
|
4413
4818
|
decorator(target, key, paramIndex);
|
|
4414
4819
|
};
|
|
4415
4820
|
};
|
|
4416
|
-
var
|
|
4821
|
+
var _a17;
|
|
4417
4822
|
var UserController = class UserController2 {
|
|
4418
4823
|
static {
|
|
4419
4824
|
__name(this, "UserController");
|
|
@@ -4460,75 +4865,75 @@ var UserController = class UserController2 {
|
|
|
4460
4865
|
return this.userService.removeRole(params.userId);
|
|
4461
4866
|
}
|
|
4462
4867
|
};
|
|
4463
|
-
|
|
4868
|
+
__decorate26([
|
|
4464
4869
|
Get3(),
|
|
4465
4870
|
isAdmin(),
|
|
4466
4871
|
Validate4({ query: userListQuery }),
|
|
4467
4872
|
ResMsg4("users.success.retrieved"),
|
|
4468
4873
|
__param9(0, Query()),
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4874
|
+
__metadata26("design:type", Function),
|
|
4875
|
+
__metadata26("design:paramtypes", [Object]),
|
|
4876
|
+
__metadata26("design:returntype", Promise)
|
|
4472
4877
|
], UserController.prototype, "getUsers", null);
|
|
4473
|
-
|
|
4878
|
+
__decorate26([
|
|
4474
4879
|
Get3("/lang"),
|
|
4475
4880
|
isAuth(),
|
|
4476
4881
|
ResMsg4("users.success.retrieved"),
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4882
|
+
__metadata26("design:type", Function),
|
|
4883
|
+
__metadata26("design:paramtypes", []),
|
|
4884
|
+
__metadata26("design:returntype", Promise)
|
|
4480
4885
|
], UserController.prototype, "getLang", null);
|
|
4481
|
-
|
|
4886
|
+
__decorate26([
|
|
4482
4887
|
Post4("/lang/:language"),
|
|
4483
4888
|
isAuth(),
|
|
4484
4889
|
Validate4({ params: languageParam }),
|
|
4485
4890
|
ResMsg4("users.success.updated"),
|
|
4486
4891
|
__param9(0, Params2()),
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4892
|
+
__metadata26("design:type", Function),
|
|
4893
|
+
__metadata26("design:paramtypes", [Object]),
|
|
4894
|
+
__metadata26("design:returntype", Promise)
|
|
4490
4895
|
], UserController.prototype, "updateLang", null);
|
|
4491
|
-
|
|
4896
|
+
__decorate26([
|
|
4492
4897
|
Get3("/:id"),
|
|
4493
4898
|
isAdmin(),
|
|
4494
4899
|
Validate4({ params: userIdParam }),
|
|
4495
4900
|
ResMsg4("users.success.retrieved"),
|
|
4496
4901
|
__param9(0, Params2()),
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4902
|
+
__metadata26("design:type", Function),
|
|
4903
|
+
__metadata26("design:paramtypes", [Object]),
|
|
4904
|
+
__metadata26("design:returntype", Promise)
|
|
4500
4905
|
], UserController.prototype, "getUser", null);
|
|
4501
|
-
|
|
4906
|
+
__decorate26([
|
|
4502
4907
|
Get3("/email/:email"),
|
|
4503
4908
|
isAdmin(),
|
|
4504
4909
|
Validate4({ params: emailParam }),
|
|
4505
4910
|
ResMsg4("users.success.retrieved"),
|
|
4506
4911
|
__param9(0, Params2()),
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4912
|
+
__metadata26("design:type", Function),
|
|
4913
|
+
__metadata26("design:paramtypes", [Object]),
|
|
4914
|
+
__metadata26("design:returntype", Promise)
|
|
4510
4915
|
], UserController.prototype, "getByEmail", null);
|
|
4511
|
-
|
|
4916
|
+
__decorate26([
|
|
4512
4917
|
Get3("/role/:userId"),
|
|
4513
4918
|
isAdmin(),
|
|
4514
4919
|
Validate4({ params: userIdInParam }),
|
|
4515
4920
|
ResMsg4("users.success.retrieved"),
|
|
4516
4921
|
__param9(0, Params2()),
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4922
|
+
__metadata26("design:type", Function),
|
|
4923
|
+
__metadata26("design:paramtypes", [Object]),
|
|
4924
|
+
__metadata26("design:returntype", Promise)
|
|
4520
4925
|
], UserController.prototype, "getRole", null);
|
|
4521
|
-
|
|
4926
|
+
__decorate26([
|
|
4522
4927
|
Post4(),
|
|
4523
4928
|
isAdmin(),
|
|
4524
4929
|
Validate4(createUserDto),
|
|
4525
|
-
ResMsg4("users.success.created"),
|
|
4526
|
-
__param9(0, Body4()),
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4930
|
+
ResMsg4("users.success.created"),
|
|
4931
|
+
__param9(0, Body4()),
|
|
4932
|
+
__metadata26("design:type", Function),
|
|
4933
|
+
__metadata26("design:paramtypes", [Object]),
|
|
4934
|
+
__metadata26("design:returntype", Promise)
|
|
4530
4935
|
], UserController.prototype, "create", null);
|
|
4531
|
-
|
|
4936
|
+
__decorate26([
|
|
4532
4937
|
Put2("/:id"),
|
|
4533
4938
|
isAdmin(),
|
|
4534
4939
|
Validate4({
|
|
@@ -4538,51 +4943,51 @@ __decorate25([
|
|
|
4538
4943
|
ResMsg4("users.success.updated"),
|
|
4539
4944
|
__param9(0, Params2()),
|
|
4540
4945
|
__param9(1, Body4()),
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4946
|
+
__metadata26("design:type", Function),
|
|
4947
|
+
__metadata26("design:paramtypes", [Object, Object]),
|
|
4948
|
+
__metadata26("design:returntype", Promise)
|
|
4544
4949
|
], UserController.prototype, "update", null);
|
|
4545
|
-
|
|
4950
|
+
__decorate26([
|
|
4546
4951
|
Delete2("/:id"),
|
|
4547
4952
|
isAdmin(),
|
|
4548
4953
|
Validate4({ params: userIdParam }),
|
|
4549
4954
|
ResMsg4("users.success.deleted"),
|
|
4550
4955
|
__param9(0, Params2()),
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4956
|
+
__metadata26("design:type", Function),
|
|
4957
|
+
__metadata26("design:paramtypes", [Object]),
|
|
4958
|
+
__metadata26("design:returntype", Promise)
|
|
4554
4959
|
], UserController.prototype, "delete", null);
|
|
4555
|
-
|
|
4960
|
+
__decorate26([
|
|
4556
4961
|
Delete2(),
|
|
4557
4962
|
isAdmin(),
|
|
4558
4963
|
ResMsg4("users.success.allDeleted"),
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4964
|
+
__metadata26("design:type", Function),
|
|
4965
|
+
__metadata26("design:paramtypes", []),
|
|
4966
|
+
__metadata26("design:returntype", Promise)
|
|
4562
4967
|
], UserController.prototype, "deleteAll", null);
|
|
4563
|
-
|
|
4968
|
+
__decorate26([
|
|
4564
4969
|
Post4("/assign/:userId/:roleId"),
|
|
4565
4970
|
isAdmin(),
|
|
4566
4971
|
Validate4({ params: assignRoleParams }),
|
|
4567
4972
|
ResMsg4("users.success.updated"),
|
|
4568
4973
|
__param9(0, Params2()),
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4974
|
+
__metadata26("design:type", Function),
|
|
4975
|
+
__metadata26("design:paramtypes", [Object]),
|
|
4976
|
+
__metadata26("design:returntype", Promise)
|
|
4572
4977
|
], UserController.prototype, "assignRole", null);
|
|
4573
|
-
|
|
4978
|
+
__decorate26([
|
|
4574
4979
|
Delete2("/remove/:userId"),
|
|
4575
4980
|
isAdmin(),
|
|
4576
4981
|
Validate4({ params: userIdInParam }),
|
|
4577
4982
|
ResMsg4("users.success.updated"),
|
|
4578
4983
|
__param9(0, Params2()),
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4984
|
+
__metadata26("design:type", Function),
|
|
4985
|
+
__metadata26("design:paramtypes", [Object]),
|
|
4986
|
+
__metadata26("design:returntype", Promise)
|
|
4582
4987
|
], UserController.prototype, "removeRole", null);
|
|
4583
|
-
UserController =
|
|
4988
|
+
UserController = __decorate26([
|
|
4584
4989
|
Controller4("/users"),
|
|
4585
|
-
|
|
4990
|
+
__metadata26("design:paramtypes", [typeof (_a17 = typeof UserService !== "undefined" && UserService) === "function" ? _a17 : Object])
|
|
4586
4991
|
], UserController);
|
|
4587
4992
|
|
|
4588
4993
|
// src/permissions/index.ts
|
|
@@ -4603,15 +5008,15 @@ __export(permissions_exports, {
|
|
|
4603
5008
|
|
|
4604
5009
|
// src/permissions/PermissionRepository.ts
|
|
4605
5010
|
import { eq as eq7, and as and4 } from "drizzle-orm";
|
|
4606
|
-
import { Repository as Repository6, Inject as
|
|
5011
|
+
import { Repository as Repository6, Inject as Inject15 } from "najm-core";
|
|
4607
5012
|
import { DB as DB6 } from "najm-database";
|
|
4608
|
-
var
|
|
5013
|
+
var __decorate27 = function(decorators, target, key, desc) {
|
|
4609
5014
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4610
5015
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4611
5016
|
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
5017
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4613
5018
|
};
|
|
4614
|
-
var
|
|
5019
|
+
var __metadata27 = function(k, v) {
|
|
4615
5020
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4616
5021
|
};
|
|
4617
5022
|
var PermissionRepository = class PermissionRepository2 {
|
|
@@ -4689,29 +5094,29 @@ var PermissionRepository = class PermissionRepository2 {
|
|
|
4689
5094
|
return deletedPermissions;
|
|
4690
5095
|
}
|
|
4691
5096
|
};
|
|
4692
|
-
|
|
5097
|
+
__decorate27([
|
|
4693
5098
|
DB6(),
|
|
4694
|
-
|
|
5099
|
+
__metadata27("design:type", Object)
|
|
4695
5100
|
], PermissionRepository.prototype, "db", void 0);
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
5101
|
+
__decorate27([
|
|
5102
|
+
Inject15(AUTH_SCHEMA),
|
|
5103
|
+
__metadata27("design:type", Object)
|
|
4699
5104
|
], PermissionRepository.prototype, "schema", void 0);
|
|
4700
|
-
PermissionRepository =
|
|
5105
|
+
PermissionRepository = __decorate27([
|
|
4701
5106
|
Repository6()
|
|
4702
5107
|
], PermissionRepository);
|
|
4703
5108
|
|
|
4704
5109
|
// src/permissions/PermissionGuards.ts
|
|
4705
|
-
import { Injectable as
|
|
5110
|
+
import { Injectable as Injectable13 } from "najm-core";
|
|
4706
5111
|
import { GuardParams as GuardParams2, User as User3 } from "najm-core";
|
|
4707
5112
|
import { createGuard as createGuard4, composeGuards as composeGuards3 } from "najm-guard";
|
|
4708
|
-
var
|
|
5113
|
+
var __decorate28 = function(decorators, target, key, desc) {
|
|
4709
5114
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4710
5115
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4711
5116
|
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
5117
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4713
5118
|
};
|
|
4714
|
-
var
|
|
5119
|
+
var __metadata28 = function(k, v) {
|
|
4715
5120
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4716
5121
|
};
|
|
4717
5122
|
var __param10 = function(paramIndex, decorator) {
|
|
@@ -4747,15 +5152,15 @@ var PermissionGuard = class PermissionGuard2 {
|
|
|
4747
5152
|
return false;
|
|
4748
5153
|
}
|
|
4749
5154
|
};
|
|
4750
|
-
|
|
5155
|
+
__decorate28([
|
|
4751
5156
|
__param10(0, GuardParams2()),
|
|
4752
5157
|
__param10(1, User3("permissions")),
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
5158
|
+
__metadata28("design:type", Function),
|
|
5159
|
+
__metadata28("design:paramtypes", [String, Array]),
|
|
5160
|
+
__metadata28("design:returntype", Object)
|
|
4756
5161
|
], PermissionGuard.prototype, "canActivate", null);
|
|
4757
|
-
PermissionGuard =
|
|
4758
|
-
|
|
5162
|
+
PermissionGuard = __decorate28([
|
|
5163
|
+
Injectable13()
|
|
4759
5164
|
], PermissionGuard);
|
|
4760
5165
|
var Permission = createGuard4(PermissionGuard);
|
|
4761
5166
|
var Can = /* @__PURE__ */ __name((permission) => composeGuards3(isAuth(), Permission(permission))(), "Can");
|
|
@@ -4766,23 +5171,23 @@ import { Get as Get4, Post as Post5, Put as Put3, Delete as Delete3, ResMsg as R
|
|
|
4766
5171
|
import { Params as Params3, Body as Body5 } from "najm-core";
|
|
4767
5172
|
|
|
4768
5173
|
// src/permissions/PermissionService.ts
|
|
4769
|
-
import { Injectable as
|
|
5174
|
+
import { Injectable as Injectable15 } from "najm-core";
|
|
4770
5175
|
|
|
4771
5176
|
// src/permissions/PermissionValidator.ts
|
|
4772
|
-
import { Injectable as
|
|
5177
|
+
import { Injectable as Injectable14 } from "najm-core";
|
|
4773
5178
|
import { I18n as I18n9 } from "najm-i18n";
|
|
4774
5179
|
import { Err as Err14 } from "najm-core";
|
|
4775
|
-
var
|
|
5180
|
+
var __decorate29 = function(decorators, target, key, desc) {
|
|
4776
5181
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4777
5182
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4778
5183
|
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
5184
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4780
5185
|
};
|
|
4781
|
-
var
|
|
5186
|
+
var __metadata29 = function(k, v) {
|
|
4782
5187
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4783
5188
|
};
|
|
4784
|
-
var
|
|
4785
|
-
var
|
|
5189
|
+
var _a18;
|
|
5190
|
+
var _b11;
|
|
4786
5191
|
var PermissionValidator = class PermissionValidator2 {
|
|
4787
5192
|
static {
|
|
4788
5193
|
__name(this, "PermissionValidator");
|
|
@@ -4849,28 +5254,30 @@ var PermissionValidator = class PermissionValidator2 {
|
|
|
4849
5254
|
}
|
|
4850
5255
|
}
|
|
4851
5256
|
};
|
|
4852
|
-
|
|
5257
|
+
__decorate29([
|
|
4853
5258
|
I18n9("permissions"),
|
|
4854
|
-
|
|
5259
|
+
__metadata29("design:type", Object)
|
|
4855
5260
|
], PermissionValidator.prototype, "t", void 0);
|
|
4856
|
-
PermissionValidator =
|
|
4857
|
-
|
|
4858
|
-
|
|
5261
|
+
PermissionValidator = __decorate29([
|
|
5262
|
+
Injectable14(),
|
|
5263
|
+
__metadata29("design:paramtypes", [typeof (_a18 = typeof PermissionRepository !== "undefined" && PermissionRepository) === "function" ? _a18 : Object, typeof (_b11 = typeof RoleValidator !== "undefined" && RoleValidator) === "function" ? _b11 : Object])
|
|
4859
5264
|
], PermissionValidator);
|
|
4860
5265
|
|
|
4861
5266
|
// src/permissions/PermissionService.ts
|
|
4862
|
-
var
|
|
5267
|
+
var __decorate30 = function(decorators, target, key, desc) {
|
|
4863
5268
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4864
5269
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4865
5270
|
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
5271
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4867
5272
|
};
|
|
4868
|
-
var
|
|
5273
|
+
var __metadata30 = function(k, v) {
|
|
4869
5274
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4870
5275
|
};
|
|
4871
|
-
var
|
|
4872
|
-
var
|
|
5276
|
+
var _a19;
|
|
5277
|
+
var _b12;
|
|
4873
5278
|
var _c8;
|
|
5279
|
+
var _d7;
|
|
5280
|
+
var _e6;
|
|
4874
5281
|
var PermissionService = class PermissionService2 {
|
|
4875
5282
|
static {
|
|
4876
5283
|
__name(this, "PermissionService");
|
|
@@ -4878,10 +5285,30 @@ var PermissionService = class PermissionService2 {
|
|
|
4878
5285
|
permissionRepository;
|
|
4879
5286
|
permissionValidator;
|
|
4880
5287
|
roleService;
|
|
4881
|
-
|
|
5288
|
+
userRepository;
|
|
5289
|
+
sessionInvalidation;
|
|
5290
|
+
constructor(permissionRepository, permissionValidator, roleService, userRepository, sessionInvalidation) {
|
|
4882
5291
|
this.permissionRepository = permissionRepository;
|
|
4883
5292
|
this.permissionValidator = permissionValidator;
|
|
4884
5293
|
this.roleService = roleService;
|
|
5294
|
+
this.userRepository = userRepository;
|
|
5295
|
+
this.sessionInvalidation = sessionInvalidation;
|
|
5296
|
+
}
|
|
5297
|
+
/**
|
|
5298
|
+
* End the sessions of everyone holding a role whose permission set changed.
|
|
5299
|
+
*
|
|
5300
|
+
* Access tokens and signed session snapshots both carry permissions as
|
|
5301
|
+
* claims, so a permission removed from a role stays exercisable until the
|
|
5302
|
+
* sessions that captured it end. This is an infrequent administrative
|
|
5303
|
+
* action, and the work is proportional to the role's membership.
|
|
5304
|
+
*/
|
|
5305
|
+
async invalidateRoleHolders(roleId) {
|
|
5306
|
+
if (!this.userRepository || !this.sessionInvalidation)
|
|
5307
|
+
return;
|
|
5308
|
+
const userIds = await this.userRepository.getIdsByRole(roleId);
|
|
5309
|
+
for (const userId of userIds) {
|
|
5310
|
+
await this.sessionInvalidation.invalidateAccessTokens(userId);
|
|
5311
|
+
}
|
|
4885
5312
|
}
|
|
4886
5313
|
async getAll() {
|
|
4887
5314
|
return await this.permissionRepository.getAll();
|
|
@@ -4918,10 +5345,14 @@ var PermissionService = class PermissionService2 {
|
|
|
4918
5345
|
}
|
|
4919
5346
|
async assignPermissionToRole(roleId, permissionId) {
|
|
4920
5347
|
await this.permissionValidator.checkRoleHasPermission(roleId, permissionId);
|
|
4921
|
-
|
|
5348
|
+
const assigned = await this.permissionRepository.assignPermissionToRole(roleId, permissionId);
|
|
5349
|
+
await this.invalidateRoleHolders(roleId);
|
|
5350
|
+
return assigned;
|
|
4922
5351
|
}
|
|
4923
5352
|
async removePermissionFromRole(roleId, permissionId) {
|
|
4924
|
-
|
|
5353
|
+
const removed = await this.permissionRepository.removePermissionFromRole(roleId, permissionId);
|
|
5354
|
+
await this.invalidateRoleHolders(roleId);
|
|
5355
|
+
return removed;
|
|
4925
5356
|
}
|
|
4926
5357
|
async seedDefaultPermissions(defaultPermissions) {
|
|
4927
5358
|
const created = [];
|
|
@@ -4975,9 +5406,9 @@ var PermissionService = class PermissionService2 {
|
|
|
4975
5406
|
return await this.permissionRepository.deleteAll();
|
|
4976
5407
|
}
|
|
4977
5408
|
};
|
|
4978
|
-
PermissionService =
|
|
4979
|
-
|
|
4980
|
-
|
|
5409
|
+
PermissionService = __decorate30([
|
|
5410
|
+
Injectable15(),
|
|
5411
|
+
__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
5412
|
], PermissionService);
|
|
4982
5413
|
|
|
4983
5414
|
// src/permissions/PermissionController.ts
|
|
@@ -5010,13 +5441,13 @@ var checkPermissionDto = z3.object({
|
|
|
5010
5441
|
});
|
|
5011
5442
|
|
|
5012
5443
|
// src/permissions/PermissionController.ts
|
|
5013
|
-
var
|
|
5444
|
+
var __decorate31 = function(decorators, target, key, desc) {
|
|
5014
5445
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
5015
5446
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5016
5447
|
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
5448
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
5018
5449
|
};
|
|
5019
|
-
var
|
|
5450
|
+
var __metadata31 = function(k, v) {
|
|
5020
5451
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
5021
5452
|
};
|
|
5022
5453
|
var __param11 = function(paramIndex, decorator) {
|
|
@@ -5024,7 +5455,7 @@ var __param11 = function(paramIndex, decorator) {
|
|
|
5024
5455
|
decorator(target, key, paramIndex);
|
|
5025
5456
|
};
|
|
5026
5457
|
};
|
|
5027
|
-
var
|
|
5458
|
+
var _a20;
|
|
5028
5459
|
var PermissionController = class PermissionController2 {
|
|
5029
5460
|
static {
|
|
5030
5461
|
__name(this, "PermissionController");
|
|
@@ -5070,32 +5501,32 @@ var PermissionController = class PermissionController2 {
|
|
|
5070
5501
|
return this.permissionService.deleteAll();
|
|
5071
5502
|
}
|
|
5072
5503
|
};
|
|
5073
|
-
|
|
5504
|
+
__decorate31([
|
|
5074
5505
|
Get4(),
|
|
5075
5506
|
ResMsg5("permissions.success.retrieved"),
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5507
|
+
__metadata31("design:type", Function),
|
|
5508
|
+
__metadata31("design:paramtypes", []),
|
|
5509
|
+
__metadata31("design:returntype", Promise)
|
|
5079
5510
|
], PermissionController.prototype, "getPermissions", null);
|
|
5080
|
-
|
|
5511
|
+
__decorate31([
|
|
5081
5512
|
Get4("/:id"),
|
|
5082
5513
|
Validate5({ params: permissionIdParam }),
|
|
5083
5514
|
ResMsg5("permissions.success.retrieved"),
|
|
5084
5515
|
__param11(0, Params3()),
|
|
5085
|
-
|
|
5086
|
-
|
|
5087
|
-
|
|
5516
|
+
__metadata31("design:type", Function),
|
|
5517
|
+
__metadata31("design:paramtypes", [Object]),
|
|
5518
|
+
__metadata31("design:returntype", Promise)
|
|
5088
5519
|
], PermissionController.prototype, "getPermission", null);
|
|
5089
|
-
|
|
5520
|
+
__decorate31([
|
|
5090
5521
|
Post5(),
|
|
5091
5522
|
Validate5(createPermissionDto),
|
|
5092
5523
|
ResMsg5({ message: "Permission created successfully", status: 201 }),
|
|
5093
5524
|
__param11(0, Body5()),
|
|
5094
|
-
|
|
5095
|
-
|
|
5096
|
-
|
|
5525
|
+
__metadata31("design:type", Function),
|
|
5526
|
+
__metadata31("design:paramtypes", [Object]),
|
|
5527
|
+
__metadata31("design:returntype", Promise)
|
|
5097
5528
|
], PermissionController.prototype, "create", null);
|
|
5098
|
-
|
|
5529
|
+
__decorate31([
|
|
5099
5530
|
Put3("/:id"),
|
|
5100
5531
|
Validate5({
|
|
5101
5532
|
params: permissionIdParam,
|
|
@@ -5104,72 +5535,73 @@ __decorate30([
|
|
|
5104
5535
|
ResMsg5("permissions.success.updated"),
|
|
5105
5536
|
__param11(0, Params3()),
|
|
5106
5537
|
__param11(1, Body5()),
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5538
|
+
__metadata31("design:type", Function),
|
|
5539
|
+
__metadata31("design:paramtypes", [Object, Object]),
|
|
5540
|
+
__metadata31("design:returntype", Promise)
|
|
5110
5541
|
], PermissionController.prototype, "update", null);
|
|
5111
|
-
|
|
5542
|
+
__decorate31([
|
|
5112
5543
|
Delete3("/:id"),
|
|
5113
5544
|
Validate5({ params: permissionIdParam }),
|
|
5114
5545
|
ResMsg5("permissions.success.deleted"),
|
|
5115
5546
|
__param11(0, Params3()),
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5547
|
+
__metadata31("design:type", Function),
|
|
5548
|
+
__metadata31("design:paramtypes", [Object]),
|
|
5549
|
+
__metadata31("design:returntype", Promise)
|
|
5119
5550
|
], PermissionController.prototype, "delete", null);
|
|
5120
|
-
|
|
5551
|
+
__decorate31([
|
|
5121
5552
|
Get4("/role/:id"),
|
|
5122
5553
|
Validate5({ params: roleIdParam }),
|
|
5123
5554
|
ResMsg5("permissions.success.retrieved"),
|
|
5124
5555
|
__param11(0, Params3()),
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5556
|
+
__metadata31("design:type", Function),
|
|
5557
|
+
__metadata31("design:paramtypes", [Object]),
|
|
5558
|
+
__metadata31("design:returntype", Promise)
|
|
5128
5559
|
], PermissionController.prototype, "getByRole", null);
|
|
5129
|
-
|
|
5560
|
+
__decorate31([
|
|
5130
5561
|
Get4("/roles/:id"),
|
|
5131
5562
|
Validate5({ params: permissionIdParam }),
|
|
5132
5563
|
ResMsg5("permissions.success.retrieved"),
|
|
5133
5564
|
__param11(0, Params3()),
|
|
5134
|
-
|
|
5135
|
-
|
|
5136
|
-
|
|
5565
|
+
__metadata31("design:type", Function),
|
|
5566
|
+
__metadata31("design:paramtypes", [Object]),
|
|
5567
|
+
__metadata31("design:returntype", Promise)
|
|
5137
5568
|
], PermissionController.prototype, "getRolesByPermission", null);
|
|
5138
|
-
|
|
5569
|
+
__decorate31([
|
|
5139
5570
|
Post5("/assign/:roleId/:permissionId"),
|
|
5140
5571
|
Validate5({ params: assignPermissionDto }),
|
|
5141
5572
|
ResMsg5("permissions.success.assigned"),
|
|
5142
5573
|
__param11(0, Params3()),
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5574
|
+
__metadata31("design:type", Function),
|
|
5575
|
+
__metadata31("design:paramtypes", [Object]),
|
|
5576
|
+
__metadata31("design:returntype", Promise)
|
|
5146
5577
|
], PermissionController.prototype, "assignToRole", null);
|
|
5147
|
-
|
|
5578
|
+
__decorate31([
|
|
5148
5579
|
Delete3("/remove/:roleId/:permissionId"),
|
|
5149
5580
|
Validate5({ params: assignPermissionDto }),
|
|
5150
5581
|
ResMsg5("permissions.success.removed"),
|
|
5151
5582
|
__param11(0, Params3()),
|
|
5152
|
-
|
|
5153
|
-
|
|
5154
|
-
|
|
5583
|
+
__metadata31("design:type", Function),
|
|
5584
|
+
__metadata31("design:paramtypes", [Object]),
|
|
5585
|
+
__metadata31("design:returntype", Promise)
|
|
5155
5586
|
], PermissionController.prototype, "removeFromRole", null);
|
|
5156
|
-
|
|
5587
|
+
__decorate31([
|
|
5157
5588
|
Delete3(),
|
|
5158
5589
|
isAdmin(),
|
|
5159
5590
|
ResMsg5("permissions.success.allDeleted"),
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
|
|
5591
|
+
__metadata31("design:type", Function),
|
|
5592
|
+
__metadata31("design:paramtypes", []),
|
|
5593
|
+
__metadata31("design:returntype", Promise)
|
|
5163
5594
|
], PermissionController.prototype, "deleteAll", null);
|
|
5164
|
-
PermissionController =
|
|
5595
|
+
PermissionController = __decorate31([
|
|
5165
5596
|
Controller5("/permissions"),
|
|
5166
5597
|
isAdmin(),
|
|
5167
|
-
|
|
5598
|
+
__metadata31("design:paramtypes", [typeof (_a20 = typeof PermissionService !== "undefined" && PermissionService) === "function" ? _a20 : Object])
|
|
5168
5599
|
], PermissionController);
|
|
5169
5600
|
|
|
5170
5601
|
// src/tokens/index.ts
|
|
5171
5602
|
var tokens_exports = {};
|
|
5172
5603
|
__export(tokens_exports, {
|
|
5604
|
+
SessionInvalidationService: () => SessionInvalidationService,
|
|
5173
5605
|
TokenRepository: () => TokenRepository,
|
|
5174
5606
|
TokenService: () => TokenService,
|
|
5175
5607
|
createTokenDto: () => createTokenDto,
|
|
@@ -5371,15 +5803,15 @@ function own(table, opts) {
|
|
|
5371
5803
|
__name(own, "own");
|
|
5372
5804
|
|
|
5373
5805
|
// src/ownership/configureOwnership.ts
|
|
5374
|
-
import { Injectable as
|
|
5806
|
+
import { Injectable as Injectable16, Inject as Inject16, User as User4, Body as Body6, Params as Params4 } from "najm-core";
|
|
5375
5807
|
import { createGuard as createGuard5, composeGuards as composeGuards4 } from "najm-guard";
|
|
5376
|
-
var
|
|
5808
|
+
var __decorate32 = function(decorators, target, key, desc) {
|
|
5377
5809
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
5378
5810
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5379
5811
|
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
5812
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
5381
5813
|
};
|
|
5382
|
-
var
|
|
5814
|
+
var __metadata32 = function(k, v) {
|
|
5383
5815
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
5384
5816
|
};
|
|
5385
5817
|
var __param12 = function(paramIndex, decorator) {
|
|
@@ -5399,7 +5831,7 @@ function toSingular(plural) {
|
|
|
5399
5831
|
}
|
|
5400
5832
|
__name(toSingular, "toSingular");
|
|
5401
5833
|
function createResourceGuards(ownershipClass, resourceType, resource, options) {
|
|
5402
|
-
var
|
|
5834
|
+
var _a29, _b16;
|
|
5403
5835
|
const writeGuard = options?.adminGuard ?? isAdmin;
|
|
5404
5836
|
let AccessGuard = class AccessGuard {
|
|
5405
5837
|
static {
|
|
@@ -5411,19 +5843,19 @@ function createResourceGuards(ownershipClass, resourceType, resource, options) {
|
|
|
5411
5843
|
return allowed ? { owner: user } : false;
|
|
5412
5844
|
}
|
|
5413
5845
|
};
|
|
5414
|
-
|
|
5415
|
-
|
|
5416
|
-
|
|
5846
|
+
__decorate32([
|
|
5847
|
+
Inject16(ownershipClass),
|
|
5848
|
+
__metadata32("design:type", Object)
|
|
5417
5849
|
], AccessGuard.prototype, "ownership", void 0);
|
|
5418
|
-
|
|
5850
|
+
__decorate32([
|
|
5419
5851
|
__param12(0, User4()),
|
|
5420
5852
|
__param12(1, Params4("id")),
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5853
|
+
__metadata32("design:type", Function),
|
|
5854
|
+
__metadata32("design:paramtypes", [Object, String]),
|
|
5855
|
+
__metadata32("design:returntype", typeof (_a29 = typeof Promise !== "undefined" && Promise) === "function" ? _a29 : Object)
|
|
5424
5856
|
], AccessGuard.prototype, "canActivate", null);
|
|
5425
|
-
AccessGuard =
|
|
5426
|
-
|
|
5857
|
+
AccessGuard = __decorate32([
|
|
5858
|
+
Injectable16()
|
|
5427
5859
|
], AccessGuard);
|
|
5428
5860
|
let ListGuard = class ListGuard {
|
|
5429
5861
|
static {
|
|
@@ -5435,18 +5867,18 @@ function createResourceGuards(ownershipClass, resourceType, resource, options) {
|
|
|
5435
5867
|
return { filter: ids };
|
|
5436
5868
|
}
|
|
5437
5869
|
};
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5870
|
+
__decorate32([
|
|
5871
|
+
Inject16(ownershipClass),
|
|
5872
|
+
__metadata32("design:type", Object)
|
|
5441
5873
|
], ListGuard.prototype, "ownership", void 0);
|
|
5442
|
-
|
|
5874
|
+
__decorate32([
|
|
5443
5875
|
__param12(0, User4()),
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5876
|
+
__metadata32("design:type", Function),
|
|
5877
|
+
__metadata32("design:paramtypes", [Object]),
|
|
5878
|
+
__metadata32("design:returntype", typeof (_b16 = typeof Promise !== "undefined" && Promise) === "function" ? _b16 : Object)
|
|
5447
5879
|
], ListGuard.prototype, "canActivate", null);
|
|
5448
|
-
ListGuard =
|
|
5449
|
-
|
|
5880
|
+
ListGuard = __decorate32([
|
|
5881
|
+
Injectable16()
|
|
5450
5882
|
], ListGuard);
|
|
5451
5883
|
const access = createGuard5(AccessGuard);
|
|
5452
5884
|
const list = createGuard5(ListGuard);
|
|
@@ -5577,11 +6009,11 @@ function configureOwnership(config) {
|
|
|
5577
6009
|
}
|
|
5578
6010
|
}
|
|
5579
6011
|
};
|
|
5580
|
-
GeneratedOwnershipService =
|
|
5581
|
-
|
|
6012
|
+
GeneratedOwnershipService = __decorate32([
|
|
6013
|
+
Injectable16()
|
|
5582
6014
|
], GeneratedOwnershipService);
|
|
5583
6015
|
function bodyGuard(resourceType, bodyField, optional = false) {
|
|
5584
|
-
var
|
|
6016
|
+
var _a29;
|
|
5585
6017
|
let BodyAccessGuard = class BodyAccessGuard {
|
|
5586
6018
|
static {
|
|
5587
6019
|
__name(this, "BodyAccessGuard");
|
|
@@ -5594,19 +6026,19 @@ function configureOwnership(config) {
|
|
|
5594
6026
|
return this.ownership.canAccess(user, resourceType, id);
|
|
5595
6027
|
}
|
|
5596
6028
|
};
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
6029
|
+
__decorate32([
|
|
6030
|
+
Inject16(GeneratedOwnershipService),
|
|
6031
|
+
__metadata32("design:type", GeneratedOwnershipService)
|
|
5600
6032
|
], BodyAccessGuard.prototype, "ownership", void 0);
|
|
5601
|
-
|
|
6033
|
+
__decorate32([
|
|
5602
6034
|
__param12(0, User4()),
|
|
5603
6035
|
__param12(1, Body6()),
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
6036
|
+
__metadata32("design:type", Function),
|
|
6037
|
+
__metadata32("design:paramtypes", [Object, Object]),
|
|
6038
|
+
__metadata32("design:returntype", typeof (_a29 = typeof Promise !== "undefined" && Promise) === "function" ? _a29 : Object)
|
|
5607
6039
|
], BodyAccessGuard.prototype, "canActivate", null);
|
|
5608
|
-
BodyAccessGuard =
|
|
5609
|
-
|
|
6040
|
+
BodyAccessGuard = __decorate32([
|
|
6041
|
+
Injectable16()
|
|
5610
6042
|
], BodyAccessGuard);
|
|
5611
6043
|
return createGuard5(BodyAccessGuard);
|
|
5612
6044
|
}
|
|
@@ -5721,18 +6153,18 @@ __name(Policy, "Policy");
|
|
|
5721
6153
|
// src/ownership/OwnedDecorator.ts
|
|
5722
6154
|
import "reflect-metadata";
|
|
5723
6155
|
import { sql as sql5, and as and5 } from "drizzle-orm";
|
|
5724
|
-
import { Injectable as
|
|
6156
|
+
import { Injectable as Injectable17, Inject as Inject17, DI as DI3, Container as Container2, REQUEST_ID } from "najm-core";
|
|
5725
6157
|
import { USER as USER2 } from "najm-guard";
|
|
5726
|
-
var
|
|
6158
|
+
var __decorate33 = function(decorators, target, key, desc) {
|
|
5727
6159
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
5728
6160
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5729
6161
|
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
6162
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
5731
6163
|
};
|
|
5732
|
-
var
|
|
6164
|
+
var __metadata33 = function(k, v) {
|
|
5733
6165
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
5734
6166
|
};
|
|
5735
|
-
var
|
|
6167
|
+
var _a21;
|
|
5736
6168
|
var OWNED_META = Symbol.for("najm:owned");
|
|
5737
6169
|
var ScopeContext = class ScopeContext2 {
|
|
5738
6170
|
static {
|
|
@@ -5764,18 +6196,18 @@ var ScopeContext = class ScopeContext2 {
|
|
|
5764
6196
|
}
|
|
5765
6197
|
}
|
|
5766
6198
|
};
|
|
5767
|
-
|
|
6199
|
+
__decorate33([
|
|
5768
6200
|
DI3(),
|
|
5769
|
-
|
|
6201
|
+
__metadata33("design:type", typeof (_a21 = typeof Container2 !== "undefined" && Container2) === "function" ? _a21 : Object)
|
|
5770
6202
|
], ScopeContext.prototype, "container", void 0);
|
|
5771
|
-
ScopeContext =
|
|
5772
|
-
|
|
6203
|
+
ScopeContext = __decorate33([
|
|
6204
|
+
Injectable17()
|
|
5773
6205
|
], ScopeContext);
|
|
5774
6206
|
function Owned(token) {
|
|
5775
6207
|
return function(target) {
|
|
5776
6208
|
Reflect.defineMetadata(OWNED_META, token, target);
|
|
5777
6209
|
const proto = target.prototype;
|
|
5778
|
-
|
|
6210
|
+
Inject17(ScopeContext)(proto, "_scopeCtx");
|
|
5779
6211
|
function getUser(self) {
|
|
5780
6212
|
return self._scopeCtx?.getUser() ?? null;
|
|
5781
6213
|
}
|
|
@@ -5985,7 +6417,7 @@ __name(getAuthLocale, "getAuthLocale");
|
|
|
5985
6417
|
var AUTH_SUPPORTED_LANGUAGES = Object.keys(AUTH_LOCALES);
|
|
5986
6418
|
|
|
5987
6419
|
// src/oauth/google/GoogleOAuthProvider.ts
|
|
5988
|
-
import { Inject as
|
|
6420
|
+
import { Inject as Inject19, Injectable as Injectable19 } from "najm-core";
|
|
5989
6421
|
|
|
5990
6422
|
// src/oauth/types.ts
|
|
5991
6423
|
var OAuthFlowError = class extends Error {
|
|
@@ -6003,15 +6435,15 @@ var OAuthFlowError = class extends Error {
|
|
|
6003
6435
|
};
|
|
6004
6436
|
|
|
6005
6437
|
// src/oauth/google/GoogleTokenVerifier.ts
|
|
6006
|
-
import { Inject as
|
|
6438
|
+
import { Inject as Inject18, Injectable as Injectable18 } from "najm-core";
|
|
6007
6439
|
import { createRemoteJWKSet, jwtVerify } from "jose";
|
|
6008
|
-
var
|
|
6440
|
+
var __decorate34 = function(decorators, target, key, desc) {
|
|
6009
6441
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
6010
6442
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6011
6443
|
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
6444
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6013
6445
|
};
|
|
6014
|
-
var
|
|
6446
|
+
var __metadata34 = function(k, v) {
|
|
6015
6447
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
6016
6448
|
};
|
|
6017
6449
|
var GOOGLE_JWKS = createRemoteJWKSet(new URL("https://www.googleapis.com/oauth2/v3/certs"));
|
|
@@ -6063,25 +6495,25 @@ var GoogleTokenVerifier = class GoogleTokenVerifier2 {
|
|
|
6063
6495
|
return google;
|
|
6064
6496
|
}
|
|
6065
6497
|
};
|
|
6066
|
-
|
|
6067
|
-
|
|
6068
|
-
|
|
6498
|
+
__decorate34([
|
|
6499
|
+
Inject18(AUTH_CONFIG),
|
|
6500
|
+
__metadata34("design:type", Object)
|
|
6069
6501
|
], GoogleTokenVerifier.prototype, "config", void 0);
|
|
6070
|
-
GoogleTokenVerifier =
|
|
6071
|
-
|
|
6502
|
+
GoogleTokenVerifier = __decorate34([
|
|
6503
|
+
Injectable18()
|
|
6072
6504
|
], GoogleTokenVerifier);
|
|
6073
6505
|
|
|
6074
6506
|
// src/oauth/google/GoogleOAuthProvider.ts
|
|
6075
|
-
var
|
|
6507
|
+
var __decorate35 = function(decorators, target, key, desc) {
|
|
6076
6508
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
6077
6509
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6078
6510
|
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
6511
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6080
6512
|
};
|
|
6081
|
-
var
|
|
6513
|
+
var __metadata35 = function(k, v) {
|
|
6082
6514
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
6083
6515
|
};
|
|
6084
|
-
var
|
|
6516
|
+
var _a22;
|
|
6085
6517
|
var AUTHORIZATION_ENDPOINT = "https://accounts.google.com/o/oauth2/v2/auth";
|
|
6086
6518
|
var TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token";
|
|
6087
6519
|
var GoogleOAuthProvider = class GoogleOAuthProvider2 {
|
|
@@ -6149,24 +6581,24 @@ var GoogleOAuthProvider = class GoogleOAuthProvider2 {
|
|
|
6149
6581
|
return google;
|
|
6150
6582
|
}
|
|
6151
6583
|
};
|
|
6152
|
-
|
|
6153
|
-
|
|
6154
|
-
|
|
6584
|
+
__decorate35([
|
|
6585
|
+
Inject19(AUTH_CONFIG),
|
|
6586
|
+
__metadata35("design:type", Object)
|
|
6155
6587
|
], GoogleOAuthProvider.prototype, "config", void 0);
|
|
6156
|
-
GoogleOAuthProvider =
|
|
6157
|
-
|
|
6158
|
-
|
|
6588
|
+
GoogleOAuthProvider = __decorate35([
|
|
6589
|
+
Injectable19(),
|
|
6590
|
+
__metadata35("design:paramtypes", [typeof (_a22 = typeof GoogleTokenVerifier !== "undefined" && GoogleTokenVerifier) === "function" ? _a22 : Object])
|
|
6159
6591
|
], GoogleOAuthProvider);
|
|
6160
6592
|
|
|
6161
6593
|
// src/oauth/github/GitHubOAuthProvider.ts
|
|
6162
|
-
import { Inject as
|
|
6163
|
-
var
|
|
6594
|
+
import { Inject as Inject20, Injectable as Injectable20 } from "najm-core";
|
|
6595
|
+
var __decorate36 = function(decorators, target, key, desc) {
|
|
6164
6596
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
6165
6597
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6166
6598
|
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
6599
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6168
6600
|
};
|
|
6169
|
-
var
|
|
6601
|
+
var __metadata36 = function(k, v) {
|
|
6170
6602
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
6171
6603
|
};
|
|
6172
6604
|
var AUTHORIZATION_ENDPOINT2 = "https://github.com/login/oauth/authorize";
|
|
@@ -6282,12 +6714,12 @@ var GitHubOAuthProvider = class GitHubOAuthProvider2 {
|
|
|
6282
6714
|
return github;
|
|
6283
6715
|
}
|
|
6284
6716
|
};
|
|
6285
|
-
|
|
6286
|
-
|
|
6287
|
-
|
|
6717
|
+
__decorate36([
|
|
6718
|
+
Inject20(AUTH_CONFIG),
|
|
6719
|
+
__metadata36("design:type", Object)
|
|
6288
6720
|
], GitHubOAuthProvider.prototype, "config", void 0);
|
|
6289
|
-
GitHubOAuthProvider =
|
|
6290
|
-
|
|
6721
|
+
GitHubOAuthProvider = __decorate36([
|
|
6722
|
+
Injectable20()
|
|
6291
6723
|
], GitHubOAuthProvider);
|
|
6292
6724
|
|
|
6293
6725
|
// src/oauth/GitHubOAuthController.ts
|
|
@@ -6296,24 +6728,24 @@ import { Controller as Controller6, Ctx as Ctx2, Get as Get5, Post as Post6, Que
|
|
|
6296
6728
|
import { RateLimit as RateLimit3 } from "najm-rate";
|
|
6297
6729
|
|
|
6298
6730
|
// src/oauth/OAuthService.ts
|
|
6299
|
-
import { Inject as
|
|
6731
|
+
import { Err as Err15, Inject as Inject23, Injectable as Injectable23, Log as Log2 } from "najm-core";
|
|
6300
6732
|
|
|
6301
6733
|
// src/oauth/OAuthAccountService.ts
|
|
6302
6734
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
6303
|
-
import { Inject as
|
|
6735
|
+
import { Inject as Inject22, Injectable as Injectable21 } from "najm-core";
|
|
6304
6736
|
import { Transaction as Transaction5 } from "najm-database";
|
|
6305
6737
|
|
|
6306
6738
|
// src/oauth/OAuthAccountRepository.ts
|
|
6307
6739
|
import { and as and6, eq as eq9 } from "drizzle-orm";
|
|
6308
|
-
import { Inject as
|
|
6740
|
+
import { Inject as Inject21, Repository as Repository7 } from "najm-core";
|
|
6309
6741
|
import { DB as DB7 } from "najm-database";
|
|
6310
|
-
var
|
|
6742
|
+
var __decorate37 = function(decorators, target, key, desc) {
|
|
6311
6743
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
6312
6744
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6313
6745
|
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
6746
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6315
6747
|
};
|
|
6316
|
-
var
|
|
6748
|
+
var __metadata37 = function(k, v) {
|
|
6317
6749
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
6318
6750
|
};
|
|
6319
6751
|
var OAuthAccountRepository = class OAuthAccountRepository2 {
|
|
@@ -6341,32 +6773,32 @@ var OAuthAccountRepository = class OAuthAccountRepository2 {
|
|
|
6341
6773
|
return account;
|
|
6342
6774
|
}
|
|
6343
6775
|
};
|
|
6344
|
-
|
|
6776
|
+
__decorate37([
|
|
6345
6777
|
DB7(),
|
|
6346
|
-
|
|
6778
|
+
__metadata37("design:type", Object)
|
|
6347
6779
|
], OAuthAccountRepository.prototype, "db", void 0);
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
|
|
6780
|
+
__decorate37([
|
|
6781
|
+
Inject21(AUTH_SCHEMA),
|
|
6782
|
+
__metadata37("design:type", Object)
|
|
6351
6783
|
], OAuthAccountRepository.prototype, "schema", void 0);
|
|
6352
|
-
OAuthAccountRepository =
|
|
6784
|
+
OAuthAccountRepository = __decorate37([
|
|
6353
6785
|
Repository7()
|
|
6354
6786
|
], OAuthAccountRepository);
|
|
6355
6787
|
|
|
6356
6788
|
// src/oauth/OAuthAccountService.ts
|
|
6357
|
-
var
|
|
6789
|
+
var __decorate38 = function(decorators, target, key, desc) {
|
|
6358
6790
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
6359
6791
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6360
6792
|
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
6793
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6362
6794
|
};
|
|
6363
|
-
var
|
|
6795
|
+
var __metadata38 = function(k, v) {
|
|
6364
6796
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
6365
6797
|
};
|
|
6366
|
-
var
|
|
6367
|
-
var
|
|
6798
|
+
var _a23;
|
|
6799
|
+
var _b13;
|
|
6368
6800
|
var _c9;
|
|
6369
|
-
var
|
|
6801
|
+
var _d8;
|
|
6370
6802
|
var OAuthAccountService = class OAuthAccountService2 {
|
|
6371
6803
|
static {
|
|
6372
6804
|
__name(this, "OAuthAccountService");
|
|
@@ -6442,42 +6874,42 @@ var OAuthAccountService = class OAuthAccountService2 {
|
|
|
6442
6874
|
return providerConfig;
|
|
6443
6875
|
}
|
|
6444
6876
|
};
|
|
6445
|
-
|
|
6446
|
-
|
|
6447
|
-
|
|
6877
|
+
__decorate38([
|
|
6878
|
+
Inject22(AUTH_CONFIG),
|
|
6879
|
+
__metadata38("design:type", Object)
|
|
6448
6880
|
], OAuthAccountService.prototype, "config", void 0);
|
|
6449
|
-
|
|
6881
|
+
__decorate38([
|
|
6450
6882
|
Transaction5(),
|
|
6451
|
-
|
|
6452
|
-
|
|
6453
|
-
|
|
6883
|
+
__metadata38("design:type", Function),
|
|
6884
|
+
__metadata38("design:paramtypes", [Object]),
|
|
6885
|
+
__metadata38("design:returntype", typeof (_c9 = typeof Promise !== "undefined" && Promise) === "function" ? _c9 : Object)
|
|
6454
6886
|
], OAuthAccountService.prototype, "resolveForLogin", null);
|
|
6455
|
-
|
|
6887
|
+
__decorate38([
|
|
6456
6888
|
Transaction5(),
|
|
6457
|
-
|
|
6458
|
-
|
|
6459
|
-
|
|
6889
|
+
__metadata38("design:type", Function),
|
|
6890
|
+
__metadata38("design:paramtypes", [String, Object]),
|
|
6891
|
+
__metadata38("design:returntype", typeof (_d8 = typeof Promise !== "undefined" && Promise) === "function" ? _d8 : Object)
|
|
6460
6892
|
], OAuthAccountService.prototype, "linkUser", null);
|
|
6461
|
-
OAuthAccountService =
|
|
6462
|
-
|
|
6463
|
-
|
|
6893
|
+
OAuthAccountService = __decorate38([
|
|
6894
|
+
Injectable21(),
|
|
6895
|
+
__metadata38("design:paramtypes", [typeof (_a23 = typeof OAuthAccountRepository !== "undefined" && OAuthAccountRepository) === "function" ? _a23 : Object, typeof (_b13 = typeof UserService !== "undefined" && UserService) === "function" ? _b13 : Object])
|
|
6464
6896
|
], OAuthAccountService);
|
|
6465
6897
|
|
|
6466
6898
|
// src/oauth/OAuthStateService.ts
|
|
6467
6899
|
import { createHash as createHash4, randomBytes as randomBytes4, timingSafeEqual } from "crypto";
|
|
6468
|
-
import { Injectable as
|
|
6900
|
+
import { Injectable as Injectable22 } from "najm-core";
|
|
6469
6901
|
import { CookieService as CookieService3 } from "najm-cookies";
|
|
6470
|
-
var
|
|
6902
|
+
var __decorate39 = function(decorators, target, key, desc) {
|
|
6471
6903
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
6472
6904
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6473
6905
|
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
6906
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6475
6907
|
};
|
|
6476
|
-
var
|
|
6908
|
+
var __metadata39 = function(k, v) {
|
|
6477
6909
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
6478
6910
|
};
|
|
6479
|
-
var
|
|
6480
|
-
var
|
|
6911
|
+
var _a24;
|
|
6912
|
+
var _b14;
|
|
6481
6913
|
var ATTEMPT_TTL_MS = 10 * 60 * 1e3;
|
|
6482
6914
|
var COOKIE_PREFIX = "najm.oauth.";
|
|
6483
6915
|
var OAuthStateService = class OAuthStateService2 {
|
|
@@ -6566,26 +6998,26 @@ var OAuthStateService = class OAuthStateService2 {
|
|
|
6566
6998
|
return /^[A-Za-z0-9_-]{40,128}$/.test(state);
|
|
6567
6999
|
}
|
|
6568
7000
|
};
|
|
6569
|
-
OAuthStateService =
|
|
6570
|
-
|
|
6571
|
-
|
|
7001
|
+
OAuthStateService = __decorate39([
|
|
7002
|
+
Injectable22(),
|
|
7003
|
+
__metadata39("design:paramtypes", [typeof (_a24 = typeof CookieService3 !== "undefined" && CookieService3) === "function" ? _a24 : Object, typeof (_b14 = typeof EncryptionService !== "undefined" && EncryptionService) === "function" ? _b14 : Object])
|
|
6572
7004
|
], OAuthStateService);
|
|
6573
7005
|
|
|
6574
7006
|
// src/oauth/OAuthService.ts
|
|
6575
|
-
var
|
|
7007
|
+
var __decorate40 = function(decorators, target, key, desc) {
|
|
6576
7008
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
6577
7009
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6578
7010
|
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
7011
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6580
7012
|
};
|
|
6581
|
-
var
|
|
7013
|
+
var __metadata40 = function(k, v) {
|
|
6582
7014
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
6583
7015
|
};
|
|
6584
|
-
var
|
|
6585
|
-
var
|
|
7016
|
+
var _a25;
|
|
7017
|
+
var _b15;
|
|
6586
7018
|
var _c10;
|
|
6587
|
-
var
|
|
6588
|
-
var
|
|
7019
|
+
var _d9;
|
|
7020
|
+
var _e7;
|
|
6589
7021
|
var _f5;
|
|
6590
7022
|
var _g4;
|
|
6591
7023
|
var _h3;
|
|
@@ -6631,16 +7063,47 @@ var OAuthService = class OAuthService2 {
|
|
|
6631
7063
|
finishGitHubCallback(params) {
|
|
6632
7064
|
return this.finishCallback("github", params);
|
|
6633
7065
|
}
|
|
7066
|
+
/**
|
|
7067
|
+
* Turn an expected OAuth start failure into the HTTP response it describes.
|
|
7068
|
+
*
|
|
7069
|
+
* `OAuthFlowError` carries the status it means — 404 for a provider that is
|
|
7070
|
+
* not configured, 400 for a return path the caller chose badly — but it is a
|
|
7071
|
+
* plain Error, so the framework's handler could only classify it as an
|
|
7072
|
+
* unhandled 500. A disabled provider and a bad query string are ordinary
|
|
7073
|
+
* client-visible outcomes, and reporting them as server faults hides real
|
|
7074
|
+
* ones. Only the stable `oauth_*` code crosses the boundary; provider
|
|
7075
|
+
* secrets, state, and codes never appear in it.
|
|
7076
|
+
*
|
|
7077
|
+
* The callback path deliberately does not go through here: it answers with a
|
|
7078
|
+
* redirect carrying the same code, and that contract is unchanged.
|
|
7079
|
+
*/
|
|
7080
|
+
failStart(error) {
|
|
7081
|
+
if (error instanceof OAuthFlowError) {
|
|
7082
|
+
Err15(error.oauthCode, error.status);
|
|
7083
|
+
}
|
|
7084
|
+
throw error;
|
|
7085
|
+
}
|
|
6634
7086
|
startLogin(provider, returnTo) {
|
|
6635
|
-
|
|
6636
|
-
|
|
6637
|
-
|
|
6638
|
-
|
|
6639
|
-
|
|
6640
|
-
|
|
6641
|
-
|
|
7087
|
+
try {
|
|
7088
|
+
this.providerConfig(provider);
|
|
7089
|
+
const { attempt, codeChallenge } = this.state.create({
|
|
7090
|
+
provider,
|
|
7091
|
+
intent: "login",
|
|
7092
|
+
returnTo
|
|
7093
|
+
});
|
|
7094
|
+
return this.provider(provider).authorizationUrl(attempt, codeChallenge);
|
|
7095
|
+
} catch (error) {
|
|
7096
|
+
this.failStart(error);
|
|
7097
|
+
}
|
|
6642
7098
|
}
|
|
6643
7099
|
async startLink(provider, userId, returnTo) {
|
|
7100
|
+
try {
|
|
7101
|
+
return await this.buildLinkStart(provider, userId, returnTo);
|
|
7102
|
+
} catch (error) {
|
|
7103
|
+
this.failStart(error);
|
|
7104
|
+
}
|
|
7105
|
+
}
|
|
7106
|
+
async buildLinkStart(provider, userId, returnTo) {
|
|
6644
7107
|
this.providerConfig(provider);
|
|
6645
7108
|
const user = await this.users.getById(userId);
|
|
6646
7109
|
if (user.status !== "active")
|
|
@@ -6722,27 +7185,27 @@ var OAuthService = class OAuthService2 {
|
|
|
6722
7185
|
return providerConfig;
|
|
6723
7186
|
}
|
|
6724
7187
|
};
|
|
6725
|
-
|
|
6726
|
-
|
|
6727
|
-
|
|
7188
|
+
__decorate40([
|
|
7189
|
+
Inject23(AUTH_CONFIG),
|
|
7190
|
+
__metadata40("design:type", Object)
|
|
6728
7191
|
], OAuthService.prototype, "config", void 0);
|
|
6729
|
-
|
|
7192
|
+
__decorate40([
|
|
6730
7193
|
Log2(),
|
|
6731
|
-
|
|
7194
|
+
__metadata40("design:type", Object)
|
|
6732
7195
|
], OAuthService.prototype, "logger", void 0);
|
|
6733
|
-
OAuthService =
|
|
6734
|
-
|
|
6735
|
-
|
|
7196
|
+
OAuthService = __decorate40([
|
|
7197
|
+
Injectable23(),
|
|
7198
|
+
__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
7199
|
], OAuthService);
|
|
6737
7200
|
|
|
6738
7201
|
// src/oauth/GitHubOAuthController.ts
|
|
6739
|
-
var
|
|
7202
|
+
var __decorate41 = function(decorators, target, key, desc) {
|
|
6740
7203
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
6741
7204
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6742
7205
|
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
7206
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6744
7207
|
};
|
|
6745
|
-
var
|
|
7208
|
+
var __metadata41 = function(k, v) {
|
|
6746
7209
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
6747
7210
|
};
|
|
6748
7211
|
var __param13 = function(paramIndex, decorator) {
|
|
@@ -6750,7 +7213,7 @@ var __param13 = function(paramIndex, decorator) {
|
|
|
6750
7213
|
decorator(target, key, paramIndex);
|
|
6751
7214
|
};
|
|
6752
7215
|
};
|
|
6753
|
-
var
|
|
7216
|
+
var _a26;
|
|
6754
7217
|
var callbackKey = /* @__PURE__ */ __name((ctx, { clientIp }) => {
|
|
6755
7218
|
const state = ctx.req.query("state") ?? "none";
|
|
6756
7219
|
const fingerprint = createHash5("sha256").update(state).digest("base64url").slice(0, 24);
|
|
@@ -6775,52 +7238,52 @@ var GitHubOAuthController = class GitHubOAuthController2 {
|
|
|
6775
7238
|
return this.oauth.startGitHubLink(userId, returnTo);
|
|
6776
7239
|
}
|
|
6777
7240
|
};
|
|
6778
|
-
|
|
7241
|
+
__decorate41([
|
|
6779
7242
|
Get5("/start"),
|
|
6780
7243
|
RateLimit3({ limit: 20, window: "15m", key: "ip" }),
|
|
6781
7244
|
__param13(0, Ctx2()),
|
|
6782
7245
|
__param13(1, Query2("returnTo")),
|
|
6783
|
-
|
|
6784
|
-
|
|
6785
|
-
|
|
7246
|
+
__metadata41("design:type", Function),
|
|
7247
|
+
__metadata41("design:paramtypes", [Object, String]),
|
|
7248
|
+
__metadata41("design:returntype", void 0)
|
|
6786
7249
|
], GitHubOAuthController.prototype, "start", null);
|
|
6787
|
-
|
|
7250
|
+
__decorate41([
|
|
6788
7251
|
Get5("/callback"),
|
|
6789
7252
|
RateLimit3({ limit: 20, window: "15m", key: callbackKey }),
|
|
6790
7253
|
__param13(0, Ctx2()),
|
|
6791
7254
|
__param13(1, Query2("code")),
|
|
6792
7255
|
__param13(2, Query2("state")),
|
|
6793
7256
|
__param13(3, Query2("error")),
|
|
6794
|
-
|
|
6795
|
-
|
|
6796
|
-
|
|
7257
|
+
__metadata41("design:type", Function),
|
|
7258
|
+
__metadata41("design:paramtypes", [Object, String, String, String]),
|
|
7259
|
+
__metadata41("design:returntype", Promise)
|
|
6797
7260
|
], GitHubOAuthController.prototype, "callback", null);
|
|
6798
|
-
|
|
7261
|
+
__decorate41([
|
|
6799
7262
|
Post6("/link"),
|
|
6800
7263
|
isAuth(),
|
|
6801
7264
|
RateLimit3({ limit: 10, window: "15m", key: "user" }),
|
|
6802
7265
|
__param13(0, User5("id")),
|
|
6803
7266
|
__param13(1, Query2("returnTo")),
|
|
6804
|
-
|
|
6805
|
-
|
|
6806
|
-
|
|
7267
|
+
__metadata41("design:type", Function),
|
|
7268
|
+
__metadata41("design:paramtypes", [String, String]),
|
|
7269
|
+
__metadata41("design:returntype", void 0)
|
|
6807
7270
|
], GitHubOAuthController.prototype, "link", null);
|
|
6808
|
-
GitHubOAuthController =
|
|
7271
|
+
GitHubOAuthController = __decorate41([
|
|
6809
7272
|
Controller6("/auth/oauth/github"),
|
|
6810
|
-
|
|
7273
|
+
__metadata41("design:paramtypes", [typeof (_a26 = typeof OAuthService !== "undefined" && OAuthService) === "function" ? _a26 : Object])
|
|
6811
7274
|
], GitHubOAuthController);
|
|
6812
7275
|
|
|
6813
7276
|
// src/oauth/OAuthController.ts
|
|
6814
7277
|
import { createHash as createHash6 } from "crypto";
|
|
6815
7278
|
import { Controller as Controller7, Ctx as Ctx3, Get as Get6, Post as Post7, Query as Query3, User as User6 } from "najm-core";
|
|
6816
7279
|
import { RateLimit as RateLimit4 } from "najm-rate";
|
|
6817
|
-
var
|
|
7280
|
+
var __decorate42 = function(decorators, target, key, desc) {
|
|
6818
7281
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
6819
7282
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6820
7283
|
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
7284
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6822
7285
|
};
|
|
6823
|
-
var
|
|
7286
|
+
var __metadata42 = function(k, v) {
|
|
6824
7287
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
6825
7288
|
};
|
|
6826
7289
|
var __param14 = function(paramIndex, decorator) {
|
|
@@ -6828,7 +7291,7 @@ var __param14 = function(paramIndex, decorator) {
|
|
|
6828
7291
|
decorator(target, key, paramIndex);
|
|
6829
7292
|
};
|
|
6830
7293
|
};
|
|
6831
|
-
var
|
|
7294
|
+
var _a27;
|
|
6832
7295
|
var callbackKey2 = /* @__PURE__ */ __name((ctx, { clientIp }) => {
|
|
6833
7296
|
const ip = clientIp;
|
|
6834
7297
|
const state = ctx.req.query("state") ?? "none";
|
|
@@ -6854,39 +7317,39 @@ var OAuthController = class OAuthController2 {
|
|
|
6854
7317
|
return this.oauth.startGoogleLink(userId, returnTo);
|
|
6855
7318
|
}
|
|
6856
7319
|
};
|
|
6857
|
-
|
|
7320
|
+
__decorate42([
|
|
6858
7321
|
Get6("/start"),
|
|
6859
7322
|
RateLimit4({ limit: 20, window: "15m", key: "ip" }),
|
|
6860
7323
|
__param14(0, Ctx3()),
|
|
6861
7324
|
__param14(1, Query3("returnTo")),
|
|
6862
|
-
|
|
6863
|
-
|
|
6864
|
-
|
|
7325
|
+
__metadata42("design:type", Function),
|
|
7326
|
+
__metadata42("design:paramtypes", [Object, String]),
|
|
7327
|
+
__metadata42("design:returntype", void 0)
|
|
6865
7328
|
], OAuthController.prototype, "start", null);
|
|
6866
|
-
|
|
7329
|
+
__decorate42([
|
|
6867
7330
|
Get6("/callback"),
|
|
6868
7331
|
RateLimit4({ limit: 20, window: "15m", key: callbackKey2 }),
|
|
6869
7332
|
__param14(0, Ctx3()),
|
|
6870
7333
|
__param14(1, Query3("code")),
|
|
6871
7334
|
__param14(2, Query3("state")),
|
|
6872
7335
|
__param14(3, Query3("error")),
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
7336
|
+
__metadata42("design:type", Function),
|
|
7337
|
+
__metadata42("design:paramtypes", [Object, String, String, String]),
|
|
7338
|
+
__metadata42("design:returntype", Promise)
|
|
6876
7339
|
], OAuthController.prototype, "callback", null);
|
|
6877
|
-
|
|
7340
|
+
__decorate42([
|
|
6878
7341
|
Post7("/link"),
|
|
6879
7342
|
isAuth(),
|
|
6880
7343
|
RateLimit4({ limit: 10, window: "15m", key: "user" }),
|
|
6881
7344
|
__param14(0, User6("id")),
|
|
6882
7345
|
__param14(1, Query3("returnTo")),
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
7346
|
+
__metadata42("design:type", Function),
|
|
7347
|
+
__metadata42("design:paramtypes", [String, String]),
|
|
7348
|
+
__metadata42("design:returntype", void 0)
|
|
6886
7349
|
], OAuthController.prototype, "link", null);
|
|
6887
|
-
OAuthController =
|
|
7350
|
+
OAuthController = __decorate42([
|
|
6888
7351
|
Controller7("/auth/oauth/google"),
|
|
6889
|
-
|
|
7352
|
+
__metadata42("design:paramtypes", [typeof (_a27 = typeof OAuthService !== "undefined" && OAuthService) === "function" ? _a27 : Object])
|
|
6890
7353
|
], OAuthController);
|
|
6891
7354
|
|
|
6892
7355
|
// src/oauth/index.ts
|
|
@@ -6915,13 +7378,13 @@ var credentialSetupChangeDto = z5.object({
|
|
|
6915
7378
|
});
|
|
6916
7379
|
|
|
6917
7380
|
// src/credentialSetup/CredentialSetupController.ts
|
|
6918
|
-
var
|
|
7381
|
+
var __decorate43 = function(decorators, target, key, desc) {
|
|
6919
7382
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
6920
7383
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6921
7384
|
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
7385
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6923
7386
|
};
|
|
6924
|
-
var
|
|
7387
|
+
var __metadata43 = function(k, v) {
|
|
6925
7388
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
6926
7389
|
};
|
|
6927
7390
|
var __param15 = function(paramIndex, decorator) {
|
|
@@ -6929,7 +7392,7 @@ var __param15 = function(paramIndex, decorator) {
|
|
|
6929
7392
|
decorator(target, key, paramIndex);
|
|
6930
7393
|
};
|
|
6931
7394
|
};
|
|
6932
|
-
var
|
|
7395
|
+
var _a28;
|
|
6933
7396
|
var CredentialSetupController = class CredentialSetupController2 {
|
|
6934
7397
|
static {
|
|
6935
7398
|
__name(this, "CredentialSetupController");
|
|
@@ -6948,35 +7411,35 @@ var CredentialSetupController = class CredentialSetupController2 {
|
|
|
6948
7411
|
return this.passwords.cancel();
|
|
6949
7412
|
}
|
|
6950
7413
|
};
|
|
6951
|
-
|
|
7414
|
+
__decorate43([
|
|
6952
7415
|
Get7("/setup"),
|
|
6953
7416
|
RateLimit5({ limit: 30, window: "15m", key: "ip" }),
|
|
6954
7417
|
ResMsg6("auth.success.credentialSetupPending"),
|
|
6955
|
-
|
|
6956
|
-
|
|
6957
|
-
|
|
7418
|
+
__metadata43("design:type", Function),
|
|
7419
|
+
__metadata43("design:paramtypes", []),
|
|
7420
|
+
__metadata43("design:returntype", void 0)
|
|
6958
7421
|
], CredentialSetupController.prototype, "status", null);
|
|
6959
|
-
|
|
7422
|
+
__decorate43([
|
|
6960
7423
|
Post8("/change"),
|
|
6961
7424
|
RateLimit5({ limit: 5, window: "15m", key: "ip" }),
|
|
6962
7425
|
Validate6(credentialSetupChangeDto),
|
|
6963
7426
|
ResMsg6("auth.success.credentialSetupPasswordReplaced"),
|
|
6964
7427
|
__param15(0, Body7()),
|
|
6965
|
-
|
|
6966
|
-
|
|
6967
|
-
|
|
7428
|
+
__metadata43("design:type", Function),
|
|
7429
|
+
__metadata43("design:paramtypes", [Object]),
|
|
7430
|
+
__metadata43("design:returntype", void 0)
|
|
6968
7431
|
], CredentialSetupController.prototype, "change", null);
|
|
6969
|
-
|
|
7432
|
+
__decorate43([
|
|
6970
7433
|
Post8("/cancel"),
|
|
6971
7434
|
RateLimit5({ limit: 10, window: "15m", key: "ip" }),
|
|
6972
7435
|
ResMsg6("auth.success.credentialSetupCancelled"),
|
|
6973
|
-
|
|
6974
|
-
|
|
6975
|
-
|
|
7436
|
+
__metadata43("design:type", Function),
|
|
7437
|
+
__metadata43("design:paramtypes", []),
|
|
7438
|
+
__metadata43("design:returntype", void 0)
|
|
6976
7439
|
], CredentialSetupController.prototype, "cancel", null);
|
|
6977
|
-
CredentialSetupController =
|
|
7440
|
+
CredentialSetupController = __decorate43([
|
|
6978
7441
|
Controller8("/auth/credential-setup"),
|
|
6979
|
-
|
|
7442
|
+
__metadata43("design:paramtypes", [typeof (_a28 = typeof PasswordSetupService !== "undefined" && PasswordSetupService) === "function" ? _a28 : Object])
|
|
6980
7443
|
], CredentialSetupController);
|
|
6981
7444
|
|
|
6982
7445
|
// src/credentialSetup/index.ts
|
|
@@ -7023,9 +7486,9 @@ var resolveGoogleConfig = /* @__PURE__ */ __name((config) => {
|
|
|
7023
7486
|
const clientId = google.clientId ?? process.env.GOOGLE_CLIENT_ID ?? "";
|
|
7024
7487
|
const clientSecret = google.clientSecret ?? process.env.GOOGLE_CLIENT_SECRET ?? "";
|
|
7025
7488
|
if (!clientId)
|
|
7026
|
-
throw
|
|
7489
|
+
throw Err16.configRequired("auth.oauth.google", "GOOGLE_CLIENT_ID");
|
|
7027
7490
|
if (!clientSecret)
|
|
7028
|
-
throw
|
|
7491
|
+
throw Err16.configRequired("auth.oauth.google", "GOOGLE_CLIENT_SECRET");
|
|
7029
7492
|
const frontendUrl = config?.frontendUrl ?? process.env.FRONTEND_URL ?? "http://localhost:3000";
|
|
7030
7493
|
const callbackUrl = google.callbackUrl ?? process.env.GOOGLE_CALLBACK_URL ?? `${frontendUrl.replace(/\/$/, "")}/api/auth/oauth/google/callback`;
|
|
7031
7494
|
return {
|
|
@@ -7047,9 +7510,9 @@ var resolveGitHubConfig = /* @__PURE__ */ __name((config) => {
|
|
|
7047
7510
|
const clientId = github.clientId ?? process.env.GITHUB_CLIENT_ID ?? "";
|
|
7048
7511
|
const clientSecret = github.clientSecret ?? process.env.GITHUB_CLIENT_SECRET ?? "";
|
|
7049
7512
|
if (!clientId)
|
|
7050
|
-
throw
|
|
7513
|
+
throw Err16.configRequired("auth.oauth.github", "GITHUB_CLIENT_ID");
|
|
7051
7514
|
if (!clientSecret)
|
|
7052
|
-
throw
|
|
7515
|
+
throw Err16.configRequired("auth.oauth.github", "GITHUB_CLIENT_SECRET");
|
|
7053
7516
|
const frontendUrl = config?.frontendUrl ?? process.env.FRONTEND_URL ?? "http://localhost:3000";
|
|
7054
7517
|
const callbackUrl = github.callbackUrl ?? process.env.GITHUB_CALLBACK_URL ?? `${frontendUrl.replace(/\/$/, "")}/api/auth/oauth/github/callback`;
|
|
7055
7518
|
return {
|
|
@@ -7117,10 +7580,10 @@ var resolveAuthConfig = /* @__PURE__ */ __name((config) => {
|
|
|
7117
7580
|
}
|
|
7118
7581
|
};
|
|
7119
7582
|
if (!finalConfig.jwt.accessSecret) {
|
|
7120
|
-
throw
|
|
7583
|
+
throw Err16.configRequired("auth", "JWT_ACCESS_SECRET");
|
|
7121
7584
|
}
|
|
7122
7585
|
if (!finalConfig.jwt.refreshSecret) {
|
|
7123
|
-
throw
|
|
7586
|
+
throw Err16.configRequired("auth", "JWT_REFRESH_SECRET");
|
|
7124
7587
|
}
|
|
7125
7588
|
return finalConfig;
|
|
7126
7589
|
}, "resolveAuthConfig");
|
|
@@ -7338,6 +7801,7 @@ export {
|
|
|
7338
7801
|
RoleService,
|
|
7339
7802
|
RoleValidator,
|
|
7340
7803
|
ScopeContext,
|
|
7804
|
+
SessionInvalidationService,
|
|
7341
7805
|
TOKEN_STATUS,
|
|
7342
7806
|
TOKEN_TYPE,
|
|
7343
7807
|
TokenRepository,
|
|
@@ -7351,6 +7815,7 @@ export {
|
|
|
7351
7815
|
assignRoleDto,
|
|
7352
7816
|
assignRoleParams,
|
|
7353
7817
|
auth,
|
|
7818
|
+
authEmailRateLimitKey,
|
|
7354
7819
|
authIdentityRateLimitKey,
|
|
7355
7820
|
authSchema,
|
|
7356
7821
|
authSeed,
|