@plyaz/auth 1.0.0 → 1.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/commits.txt +2 -2
- package/dist/common/index.cjs +3 -1
- package/dist/common/index.cjs.map +1 -1
- package/dist/common/index.mjs +3 -1
- package/dist/common/index.mjs.map +1 -1
- package/dist/index.cjs +421 -152
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +421 -152
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/adapters/auth-adapter-factory.ts +4 -3
- package/src/adapters/auth-adapter.mapper.ts +2 -2
- package/src/adapters/base-auth.adapter.ts +17 -9
- package/src/adapters/clerk/clerk.adapter.ts +9 -12
- package/src/adapters/custom/custom.adapter.ts +19 -10
- package/src/adapters/index.ts +0 -1
- package/src/adapters/next-auth/authOptions.ts +20 -16
- package/src/adapters/next-auth/next-auth.adapter.ts +13 -15
- package/src/api/client.ts +4 -6
- package/src/audit/audit.logger.ts +19 -10
- package/src/client/components/ProtectedRoute.tsx +15 -11
- package/src/client/hooks/useAuth.ts +23 -21
- package/src/client/hooks/useConnectedAccounts.ts +57 -45
- package/src/client/hooks/usePermissions.ts +1 -1
- package/src/client/hooks/useRBAC.ts +6 -6
- package/src/client/hooks/useSession.ts +5 -5
- package/src/client/providers/AuthProvider.tsx +23 -17
- package/src/client/store/auth.store.ts +71 -62
- package/src/client/utils/storage.ts +45 -18
- package/src/common/constants/oauth-providers.ts +10 -7
- package/src/common/errors/auth.errors.ts +4 -4
- package/src/common/errors/specific-auth-errors.ts +5 -9
- package/src/common/regex/index.ts +6 -4
- package/src/common/types/auth.types.ts +47 -38
- package/src/common/types/index.ts +12 -6
- package/src/common/utils/index.ts +15 -11
- package/src/core/blacklist/token.blacklist.ts +13 -7
- package/src/core/index.ts +2 -2
- package/src/core/jwt/jwt.manager.ts +47 -22
- package/src/core/session/session.manager.ts +17 -14
- package/src/db/repositories/connected-account.repository.ts +120 -78
- package/src/db/repositories/role.repository.ts +41 -26
- package/src/db/repositories/session.repository.ts +9 -10
- package/src/db/repositories/user.repository.ts +105 -91
- package/src/flows/index.ts +2 -2
- package/src/flows/sign-in.flow.ts +28 -14
- package/src/flows/sign-up.flow.ts +31 -20
- package/src/index.ts +36 -37
- package/src/libs/clerk.helper.ts +6 -7
- package/src/libs/supabase.helper.ts +79 -61
- package/src/libs/supabaseClient.ts +3 -3
- package/src/providers/base/auth-provider.interface.ts +13 -11
- package/src/providers/base/index.ts +1 -1
- package/src/providers/index.ts +1 -1
- package/src/providers/oauth/facebook.provider.ts +63 -39
- package/src/providers/oauth/github.provider.ts +14 -10
- package/src/providers/oauth/google.provider.ts +39 -28
- package/src/providers/oauth/index.ts +1 -1
- package/src/rbac/dynamic-roles.ts +88 -54
- package/src/rbac/index.ts +4 -4
- package/src/rbac/permission-checker.ts +147 -75
- package/src/rbac/role-hierarchy.ts +8 -8
- package/src/rbac/role.manager.ts +11 -8
- package/src/security/csrf/csrf.protection.ts +9 -7
- package/src/security/index.ts +2 -2
- package/src/security/rate-limiting/auth/auth.controller.ts +2 -4
- package/src/security/rate-limiting/auth/rate-limiting.interface.ts +26 -6
- package/src/security/rate-limiting/auth.module.ts +1 -2
- package/src/server/auth.module.ts +55 -52
- package/src/server/decorators/auth.decorator.ts +9 -11
- package/src/server/decorators/auth.decorators.ts +8 -9
- package/src/server/decorators/current-user.decorator.ts +6 -6
- package/src/server/decorators/permission.decorator.ts +17 -9
- package/src/server/guards/auth.guard.ts +21 -16
- package/src/server/guards/custom-throttler.guard.ts +4 -9
- package/src/server/guards/permissions.guard.ts +32 -23
- package/src/server/guards/roles.guard.ts +14 -12
- package/src/server/middleware/auth.middleware.ts +4 -4
- package/src/server/middleware/session.middleware.ts +4 -4
- package/src/server/services/account.service.ts +96 -48
- package/src/server/services/auth.service.ts +57 -28
- package/src/server/services/brute-force.service.ts +24 -19
- package/src/server/services/index.ts +1 -1
- package/src/server/services/rate-limiter.service.ts +9 -4
- package/src/server/services/session.service.ts +84 -48
- package/src/server/services/token.service.ts +71 -51
- package/src/session/cookie-store.ts +47 -34
- package/src/session/enhanced-session-manager.ts +69 -48
- package/src/session/index.ts +5 -5
- package/src/session/memory-store.ts +37 -30
- package/src/session/redis-store.ts +105 -72
- package/src/strategies/oauth.strategy.ts +10 -9
- package/src/strategies/traditional-auth.strategy.ts +41 -29
- package/src/tokens/index.ts +4 -4
- package/src/tokens/refresh-token-manager.ts +70 -55
- package/src/tokens/token-validator.ts +109 -53
- package/vitest.setup.d.ts +2 -2
- package/vitest.setup.ts +1 -1
package/dist/index.cjs
CHANGED
|
@@ -94,7 +94,9 @@ function maskSensitiveData(data, sensitiveFields = ["password", "token", "secret
|
|
|
94
94
|
if (typeof data !== "object" || data === null) {
|
|
95
95
|
return data;
|
|
96
96
|
}
|
|
97
|
-
const masked = {
|
|
97
|
+
const masked = {
|
|
98
|
+
...data
|
|
99
|
+
};
|
|
98
100
|
const four = 4;
|
|
99
101
|
for (const field of sensitiveFields) {
|
|
100
102
|
if (field in masked) {
|
|
@@ -128,15 +130,26 @@ var JwtManager = class {
|
|
|
128
130
|
return jsonwebtoken.sign(payload, this.config.privateKey, signOptions);
|
|
129
131
|
}
|
|
130
132
|
generateTokens(user, accessTokenExpiry = "1h", refreshTokenExpiry = "7d") {
|
|
131
|
-
const accessToken = this.generateToken(
|
|
132
|
-
|
|
133
|
+
const accessToken = this.generateToken(
|
|
134
|
+
{ sub: user.id, type: "access" },
|
|
135
|
+
accessTokenExpiry
|
|
136
|
+
);
|
|
137
|
+
const refreshToken = this.generateToken(
|
|
138
|
+
{ sub: user.id, type: "refresh" },
|
|
139
|
+
refreshTokenExpiry
|
|
140
|
+
);
|
|
133
141
|
let expiresIn;
|
|
134
142
|
if (typeof accessTokenExpiry === "string") {
|
|
135
143
|
const match = accessTokenExpiry.match(/^(\d+)([smhd])$/);
|
|
136
144
|
if (match) {
|
|
137
145
|
const value = globalThis.parseInt(match[1], config$1.NUMERIX.TEN);
|
|
138
146
|
const unit = match[2];
|
|
139
|
-
const multipliers = {
|
|
147
|
+
const multipliers = {
|
|
148
|
+
s: 1,
|
|
149
|
+
m: 60,
|
|
150
|
+
h: 3600,
|
|
151
|
+
d: 86400
|
|
152
|
+
};
|
|
140
153
|
expiresIn = value * multipliers[unit];
|
|
141
154
|
} else {
|
|
142
155
|
expiresIn = config$1.NUMERIX.THIRTY_SIX_HUNDERD;
|
|
@@ -172,10 +185,13 @@ var JwtManager = class {
|
|
|
172
185
|
issuer: this.config.issuer,
|
|
173
186
|
audience: this.config.audience
|
|
174
187
|
});
|
|
175
|
-
if (typeof decoded === "string")
|
|
188
|
+
if (typeof decoded === "string")
|
|
189
|
+
throw new Error(`Invalid ${tokenType} token payload`);
|
|
176
190
|
const payload = decoded;
|
|
177
191
|
if (payload.type !== tokenType) {
|
|
178
|
-
throw new Error(
|
|
192
|
+
throw new Error(
|
|
193
|
+
`Invalid token type. Expected ${tokenType}, got ${payload.type}`
|
|
194
|
+
);
|
|
179
195
|
}
|
|
180
196
|
return payload;
|
|
181
197
|
}
|
|
@@ -327,17 +343,44 @@ var PermissionChecker = class {
|
|
|
327
343
|
}
|
|
328
344
|
}
|
|
329
345
|
const userPermissions = await this.getUserPermissions(userId);
|
|
330
|
-
const directResult = this.checkDirectPermission(
|
|
346
|
+
const directResult = this.checkDirectPermission(
|
|
347
|
+
userPermissions,
|
|
348
|
+
resource,
|
|
349
|
+
action,
|
|
350
|
+
context
|
|
351
|
+
);
|
|
331
352
|
if (directResult.granted) {
|
|
332
|
-
return this.cacheAndReturn(
|
|
353
|
+
return this.cacheAndReturn(
|
|
354
|
+
userId,
|
|
355
|
+
resource,
|
|
356
|
+
action,
|
|
357
|
+
context,
|
|
358
|
+
directResult
|
|
359
|
+
);
|
|
333
360
|
}
|
|
334
|
-
const roleResult = await this.checkRoleBasedPermission(
|
|
361
|
+
const roleResult = await this.checkRoleBasedPermission(
|
|
362
|
+
userId,
|
|
363
|
+
resource,
|
|
364
|
+
action,
|
|
365
|
+
context
|
|
366
|
+
);
|
|
335
367
|
if (roleResult.granted) {
|
|
336
368
|
return this.cacheAndReturn(userId, resource, action, context, roleResult);
|
|
337
369
|
}
|
|
338
|
-
const wildcardResult = this.checkWildcardPermission(
|
|
370
|
+
const wildcardResult = this.checkWildcardPermission(
|
|
371
|
+
userPermissions,
|
|
372
|
+
resource,
|
|
373
|
+
action,
|
|
374
|
+
context
|
|
375
|
+
);
|
|
339
376
|
if (wildcardResult.granted) {
|
|
340
|
-
return this.cacheAndReturn(
|
|
377
|
+
return this.cacheAndReturn(
|
|
378
|
+
userId,
|
|
379
|
+
resource,
|
|
380
|
+
action,
|
|
381
|
+
context,
|
|
382
|
+
wildcardResult
|
|
383
|
+
);
|
|
341
384
|
}
|
|
342
385
|
const deniedResult = {
|
|
343
386
|
granted: false,
|
|
@@ -441,7 +484,10 @@ var PermissionChecker = class {
|
|
|
441
484
|
for (const permission of permissions) {
|
|
442
485
|
if (permission.resource === resource && permission.action === action) {
|
|
443
486
|
if (permission.conditions && Object.keys(permission.conditions).length > 0) {
|
|
444
|
-
const conditionsMet = this.evaluateConditions(
|
|
487
|
+
const conditionsMet = this.evaluateConditions(
|
|
488
|
+
permission.conditions,
|
|
489
|
+
context
|
|
490
|
+
);
|
|
445
491
|
if (conditionsMet) {
|
|
446
492
|
return {
|
|
447
493
|
granted: true,
|
|
@@ -480,7 +526,12 @@ var PermissionChecker = class {
|
|
|
480
526
|
const userRoles = await this.getUserRoles(userId);
|
|
481
527
|
for (const role of userRoles) {
|
|
482
528
|
const rolePermissions = await this.getRolePermissions(role.id);
|
|
483
|
-
const result = this.checkDirectPermission(
|
|
529
|
+
const result = this.checkDirectPermission(
|
|
530
|
+
rolePermissions,
|
|
531
|
+
resource,
|
|
532
|
+
action,
|
|
533
|
+
context
|
|
534
|
+
);
|
|
484
535
|
if (result.granted) {
|
|
485
536
|
return {
|
|
486
537
|
...result,
|
|
@@ -508,7 +559,10 @@ var PermissionChecker = class {
|
|
|
508
559
|
const actionMatch = permission.action === "*" || permission.action === action;
|
|
509
560
|
if (resourceMatch && actionMatch) {
|
|
510
561
|
if (permission.conditions && Object.keys(permission.conditions).length > 0) {
|
|
511
|
-
const conditionsMet = this.evaluateConditions(
|
|
562
|
+
const conditionsMet = this.evaluateConditions(
|
|
563
|
+
permission.conditions,
|
|
564
|
+
context
|
|
565
|
+
);
|
|
512
566
|
if (conditionsMet) {
|
|
513
567
|
return {
|
|
514
568
|
granted: true,
|
|
@@ -16479,7 +16533,11 @@ var DynamicRoles = class {
|
|
|
16479
16533
|
for (const [conditionType, conditionValue] of Object.entries(conditions)) {
|
|
16480
16534
|
const evaluator = this.conditionEvaluators.get(conditionType);
|
|
16481
16535
|
if (evaluator) {
|
|
16482
|
-
const result = await evaluator(
|
|
16536
|
+
const result = await evaluator(
|
|
16537
|
+
userId,
|
|
16538
|
+
{ [conditionType]: conditionValue },
|
|
16539
|
+
context
|
|
16540
|
+
);
|
|
16483
16541
|
if (!result) {
|
|
16484
16542
|
return false;
|
|
16485
16543
|
}
|
|
@@ -16499,7 +16557,9 @@ var DynamicRoles = class {
|
|
|
16499
16557
|
async enforceAssignmentLimits(userId) {
|
|
16500
16558
|
const userAssignments = this.getUserAssignments(userId, false);
|
|
16501
16559
|
if (userAssignments.length >= this.config.maxAssignmentsPerUser) {
|
|
16502
|
-
throw new Error(
|
|
16560
|
+
throw new Error(
|
|
16561
|
+
`Maximum assignments per user exceeded: ${this.config.maxAssignmentsPerUser}`
|
|
16562
|
+
);
|
|
16503
16563
|
}
|
|
16504
16564
|
}
|
|
16505
16565
|
/**
|
|
@@ -16515,9 +16575,12 @@ var DynamicRoles = class {
|
|
|
16515
16575
|
* @private
|
|
16516
16576
|
*/
|
|
16517
16577
|
startCleanupTimer() {
|
|
16518
|
-
this.cleanupTimer = globalThis.setInterval(
|
|
16519
|
-
|
|
16520
|
-
|
|
16578
|
+
this.cleanupTimer = globalThis.setInterval(
|
|
16579
|
+
async () => {
|
|
16580
|
+
await this.cleanupExpiredAssignments();
|
|
16581
|
+
},
|
|
16582
|
+
config$1.NUMERIX.FIVE * config$1.NUMERIX.SIXTY * config$1.NUMERIX.THOUSAND
|
|
16583
|
+
);
|
|
16521
16584
|
}
|
|
16522
16585
|
/**
|
|
16523
16586
|
* Emit role assigned event
|
|
@@ -16615,10 +16678,17 @@ exports.AuthService = class AuthService {
|
|
|
16615
16678
|
}
|
|
16616
16679
|
async signIn(email3, password, deviceInfo) {
|
|
16617
16680
|
const user = await this.traditionalAuth.authenticate(email3, password);
|
|
16618
|
-
const session = await this.sessionManager.createSession(
|
|
16681
|
+
const session = await this.sessionManager.createSession(
|
|
16682
|
+
user.id,
|
|
16683
|
+
deviceInfo
|
|
16684
|
+
);
|
|
16619
16685
|
const tokens = this.jwtManager.generateTokens(user);
|
|
16620
16686
|
await this.userRepo.updateLastLogin(user.id);
|
|
16621
|
-
return {
|
|
16687
|
+
return {
|
|
16688
|
+
user,
|
|
16689
|
+
tokens: { ...tokens, refreshToken: tokens.refreshToken ?? "" },
|
|
16690
|
+
session
|
|
16691
|
+
};
|
|
16622
16692
|
}
|
|
16623
16693
|
async signUp(userData, password) {
|
|
16624
16694
|
const passwordHash = await this.traditionalAuth.hashPassword(password);
|
|
@@ -16650,11 +16720,22 @@ exports.AuthService = class AuthService {
|
|
|
16650
16720
|
return this.userRepo.findById(userId);
|
|
16651
16721
|
}
|
|
16652
16722
|
async oauthSignIn(profile, accessToken, refreshToken, deviceInfo) {
|
|
16653
|
-
const user = await this.oauthAuth.authenticate(
|
|
16654
|
-
|
|
16723
|
+
const user = await this.oauthAuth.authenticate(
|
|
16724
|
+
profile,
|
|
16725
|
+
accessToken,
|
|
16726
|
+
refreshToken
|
|
16727
|
+
);
|
|
16728
|
+
const session = await this.sessionManager.createSession(
|
|
16729
|
+
user.id,
|
|
16730
|
+
deviceInfo ?? {}
|
|
16731
|
+
);
|
|
16655
16732
|
const tokens = this.jwtManager.generateTokens(user);
|
|
16656
16733
|
await this.userRepo.updateLastLogin(user.id);
|
|
16657
|
-
return {
|
|
16734
|
+
return {
|
|
16735
|
+
user,
|
|
16736
|
+
tokens: { ...tokens, refreshToken: tokens.refreshToken ?? "" },
|
|
16737
|
+
session
|
|
16738
|
+
};
|
|
16658
16739
|
}
|
|
16659
16740
|
};
|
|
16660
16741
|
_init3 = __decoratorStart();
|
|
@@ -16679,8 +16760,13 @@ var _SessionService = class _SessionService {
|
|
|
16679
16760
|
async createSession(userContext, sessionData = {}) {
|
|
16680
16761
|
this.logger.debug(`Creating session for user: ${userContext.userId}`);
|
|
16681
16762
|
try {
|
|
16682
|
-
const session = await this.sessionManager.createSession(
|
|
16683
|
-
|
|
16763
|
+
const session = await this.sessionManager.createSession(
|
|
16764
|
+
userContext,
|
|
16765
|
+
sessionData
|
|
16766
|
+
);
|
|
16767
|
+
this.logger.log(
|
|
16768
|
+
`Session created: ${session.id} for user: ${userContext.userId}`
|
|
16769
|
+
);
|
|
16684
16770
|
this.emitEvent(AUTH_EVENTS.SESSION_CREATED, {
|
|
16685
16771
|
userId: userContext.userId,
|
|
16686
16772
|
sessionId: session.id,
|
|
@@ -16688,7 +16774,10 @@ var _SessionService = class _SessionService {
|
|
|
16688
16774
|
});
|
|
16689
16775
|
return session;
|
|
16690
16776
|
} catch (error48) {
|
|
16691
|
-
this.logger.error(
|
|
16777
|
+
this.logger.error(
|
|
16778
|
+
`Failed to create session for user: ${userContext.userId}`,
|
|
16779
|
+
error48
|
|
16780
|
+
);
|
|
16692
16781
|
throw error48;
|
|
16693
16782
|
}
|
|
16694
16783
|
}
|
|
@@ -16792,7 +16881,10 @@ var _SessionService = class _SessionService {
|
|
|
16792
16881
|
timestamp: /* @__PURE__ */ new Date()
|
|
16793
16882
|
});
|
|
16794
16883
|
} catch (error48) {
|
|
16795
|
-
this.logger.error(
|
|
16884
|
+
this.logger.error(
|
|
16885
|
+
`Failed to invalidate all sessions for user: ${userId}`,
|
|
16886
|
+
error48
|
|
16887
|
+
);
|
|
16796
16888
|
throw error48;
|
|
16797
16889
|
}
|
|
16798
16890
|
}
|
|
@@ -16806,7 +16898,10 @@ var _SessionService = class _SessionService {
|
|
|
16806
16898
|
try {
|
|
16807
16899
|
return await this.sessionManager.detectConcurrentSessions(userId);
|
|
16808
16900
|
} catch (error48) {
|
|
16809
|
-
this.logger.error(
|
|
16901
|
+
this.logger.error(
|
|
16902
|
+
`Failed to detect concurrent sessions for user: ${userId}`,
|
|
16903
|
+
error48
|
|
16904
|
+
);
|
|
16810
16905
|
throw error48;
|
|
16811
16906
|
}
|
|
16812
16907
|
}
|
|
@@ -16820,7 +16915,10 @@ var _SessionService = class _SessionService {
|
|
|
16820
16915
|
try {
|
|
16821
16916
|
return await this.sessionManager.generateCsrfToken(sessionId);
|
|
16822
16917
|
} catch (error48) {
|
|
16823
|
-
this.logger.error(
|
|
16918
|
+
this.logger.error(
|
|
16919
|
+
`Failed to generate CSRF token for session: ${sessionId}`,
|
|
16920
|
+
error48
|
|
16921
|
+
);
|
|
16824
16922
|
throw error48;
|
|
16825
16923
|
}
|
|
16826
16924
|
}
|
|
@@ -16833,13 +16931,19 @@ var _SessionService = class _SessionService {
|
|
|
16833
16931
|
async validateCsrfToken(sessionId, token) {
|
|
16834
16932
|
this.logger.debug(`Validating CSRF token for session: ${sessionId}`);
|
|
16835
16933
|
try {
|
|
16836
|
-
const isValid = await this.sessionManager.validateCsrfToken(
|
|
16934
|
+
const isValid = await this.sessionManager.validateCsrfToken(
|
|
16935
|
+
sessionId,
|
|
16936
|
+
token
|
|
16937
|
+
);
|
|
16837
16938
|
if (!isValid) {
|
|
16838
16939
|
this.logger.warn(`Invalid CSRF token for session: ${sessionId}`);
|
|
16839
16940
|
}
|
|
16840
16941
|
return isValid;
|
|
16841
16942
|
} catch (error48) {
|
|
16842
|
-
this.logger.error(
|
|
16943
|
+
this.logger.error(
|
|
16944
|
+
`Failed to validate CSRF token for session: ${sessionId}`,
|
|
16945
|
+
error48
|
|
16946
|
+
);
|
|
16843
16947
|
return false;
|
|
16844
16948
|
}
|
|
16845
16949
|
}
|
|
@@ -16852,7 +16956,10 @@ var _SessionService = class _SessionService {
|
|
|
16852
16956
|
try {
|
|
16853
16957
|
return await this.sessionManager.shouldRefreshSession(sessionId);
|
|
16854
16958
|
} catch (error48) {
|
|
16855
|
-
this.logger.error(
|
|
16959
|
+
this.logger.error(
|
|
16960
|
+
`Failed to check if session needs refresh: ${sessionId}`,
|
|
16961
|
+
error48
|
|
16962
|
+
);
|
|
16856
16963
|
return false;
|
|
16857
16964
|
}
|
|
16858
16965
|
}
|
|
@@ -16904,7 +17011,9 @@ var _TokenService = class _TokenService {
|
|
|
16904
17011
|
try {
|
|
16905
17012
|
const result = await this.tokenValidator.validateAccessToken(token);
|
|
16906
17013
|
if (!result.valid) {
|
|
16907
|
-
this.logger.warn(
|
|
17014
|
+
this.logger.warn(
|
|
17015
|
+
`Access token validation failed: ${result.error?.message}`
|
|
17016
|
+
);
|
|
16908
17017
|
}
|
|
16909
17018
|
return result;
|
|
16910
17019
|
} catch (error48) {
|
|
@@ -16928,7 +17037,9 @@ var _TokenService = class _TokenService {
|
|
|
16928
17037
|
try {
|
|
16929
17038
|
const result = await this.tokenValidator.validateRefreshToken(token);
|
|
16930
17039
|
if (!result.valid) {
|
|
16931
|
-
this.logger.warn(
|
|
17040
|
+
this.logger.warn(
|
|
17041
|
+
`Refresh token validation failed: ${result.error?.message}`
|
|
17042
|
+
);
|
|
16932
17043
|
}
|
|
16933
17044
|
return result;
|
|
16934
17045
|
} catch (error48) {
|
|
@@ -16962,7 +17073,10 @@ var _TokenService = class _TokenService {
|
|
|
16962
17073
|
this.logger.log(`Token pair generated for user: ${userId}`);
|
|
16963
17074
|
return tokenPair;
|
|
16964
17075
|
} catch (error48) {
|
|
16965
|
-
this.logger.error(
|
|
17076
|
+
this.logger.error(
|
|
17077
|
+
`Failed to generate token pair for user: ${userId}`,
|
|
17078
|
+
error48
|
|
17079
|
+
);
|
|
16966
17080
|
throw error48;
|
|
16967
17081
|
}
|
|
16968
17082
|
}
|
|
@@ -17012,7 +17126,10 @@ var _TokenService = class _TokenService {
|
|
|
17012
17126
|
await this.refreshTokenManager.revokeAllUserTokens(userId);
|
|
17013
17127
|
this.logger.log(`All tokens revoked for user: ${userId}`);
|
|
17014
17128
|
} catch (error48) {
|
|
17015
|
-
this.logger.error(
|
|
17129
|
+
this.logger.error(
|
|
17130
|
+
`Failed to revoke all tokens for user: ${userId}`,
|
|
17131
|
+
error48
|
|
17132
|
+
);
|
|
17016
17133
|
throw error48;
|
|
17017
17134
|
}
|
|
17018
17135
|
}
|
|
@@ -17026,7 +17143,10 @@ var _TokenService = class _TokenService {
|
|
|
17026
17143
|
await this.refreshTokenManager.revokeSessionTokens(sessionId);
|
|
17027
17144
|
this.logger.log(`Tokens revoked for session: ${sessionId}`);
|
|
17028
17145
|
} catch (error48) {
|
|
17029
|
-
this.logger.error(
|
|
17146
|
+
this.logger.error(
|
|
17147
|
+
`Failed to revoke tokens for session: ${sessionId}`,
|
|
17148
|
+
error48
|
|
17149
|
+
);
|
|
17030
17150
|
throw error48;
|
|
17031
17151
|
}
|
|
17032
17152
|
}
|
|
@@ -17122,7 +17242,10 @@ var _AccountService = class _AccountService {
|
|
|
17122
17242
|
});
|
|
17123
17243
|
return connectedAccount;
|
|
17124
17244
|
} catch (error48) {
|
|
17125
|
-
this.logger.error(
|
|
17245
|
+
this.logger.error(
|
|
17246
|
+
`Failed to link ${provider} account for user: ${userId}`,
|
|
17247
|
+
error48
|
|
17248
|
+
);
|
|
17126
17249
|
throw error48;
|
|
17127
17250
|
}
|
|
17128
17251
|
}
|
|
@@ -17150,7 +17273,10 @@ var _AccountService = class _AccountService {
|
|
|
17150
17273
|
timestamp: /* @__PURE__ */ new Date()
|
|
17151
17274
|
});
|
|
17152
17275
|
} catch (error48) {
|
|
17153
|
-
this.logger.error(
|
|
17276
|
+
this.logger.error(
|
|
17277
|
+
`Failed to unlink account ${accountId} for user: ${userId}`,
|
|
17278
|
+
error48
|
|
17279
|
+
);
|
|
17154
17280
|
throw error48;
|
|
17155
17281
|
}
|
|
17156
17282
|
}
|
|
@@ -17174,16 +17300,23 @@ var _AccountService = class _AccountService {
|
|
|
17174
17300
|
* @param accountId - Account identifier to set as primary
|
|
17175
17301
|
*/
|
|
17176
17302
|
async setPrimary(userId, accountId) {
|
|
17177
|
-
this.logger.debug(
|
|
17303
|
+
this.logger.debug(
|
|
17304
|
+
`Setting primary account ${accountId} for user: ${userId}`
|
|
17305
|
+
);
|
|
17178
17306
|
try {
|
|
17179
17307
|
const account = await this.accountRepository.findById(accountId);
|
|
17180
17308
|
if (account?.userId !== userId) {
|
|
17181
17309
|
throw new Error("Account not found or does not belong to user");
|
|
17182
17310
|
}
|
|
17183
17311
|
await this.accountRepository.setPrimary(userId, accountId);
|
|
17184
|
-
this.logger.log(
|
|
17312
|
+
this.logger.log(
|
|
17313
|
+
`Primary account set to ${accountId} for user: ${userId}`
|
|
17314
|
+
);
|
|
17185
17315
|
} catch (error48) {
|
|
17186
|
-
this.logger.error(
|
|
17316
|
+
this.logger.error(
|
|
17317
|
+
`Failed to set primary account ${accountId} for user: ${userId}`,
|
|
17318
|
+
error48
|
|
17319
|
+
);
|
|
17187
17320
|
throw error48;
|
|
17188
17321
|
}
|
|
17189
17322
|
}
|
|
@@ -17197,7 +17330,10 @@ var _AccountService = class _AccountService {
|
|
|
17197
17330
|
try {
|
|
17198
17331
|
return await this.accountRepository.findPrimary(userId);
|
|
17199
17332
|
} catch (error48) {
|
|
17200
|
-
this.logger.error(
|
|
17333
|
+
this.logger.error(
|
|
17334
|
+
`Failed to get primary account for user: ${userId}`,
|
|
17335
|
+
error48
|
|
17336
|
+
);
|
|
17201
17337
|
throw error48;
|
|
17202
17338
|
}
|
|
17203
17339
|
}
|
|
@@ -17208,11 +17344,19 @@ var _AccountService = class _AccountService {
|
|
|
17208
17344
|
* @returns Connected account or null
|
|
17209
17345
|
*/
|
|
17210
17346
|
async findByProvider(provider, providerAccountId) {
|
|
17211
|
-
this.logger.debug(
|
|
17347
|
+
this.logger.debug(
|
|
17348
|
+
`Finding account by provider: ${provider}, ID: ${providerAccountId}`
|
|
17349
|
+
);
|
|
17212
17350
|
try {
|
|
17213
|
-
return await this.accountRepository.findByProvider(
|
|
17351
|
+
return await this.accountRepository.findByProvider(
|
|
17352
|
+
provider,
|
|
17353
|
+
providerAccountId
|
|
17354
|
+
);
|
|
17214
17355
|
} catch (error48) {
|
|
17215
|
-
this.logger.error(
|
|
17356
|
+
this.logger.error(
|
|
17357
|
+
`Failed to find account by provider: ${provider}`,
|
|
17358
|
+
error48
|
|
17359
|
+
);
|
|
17216
17360
|
throw error48;
|
|
17217
17361
|
}
|
|
17218
17362
|
}
|
|
@@ -17225,10 +17369,17 @@ var _AccountService = class _AccountService {
|
|
|
17225
17369
|
async updateTokens(accountId, accessToken, refreshToken) {
|
|
17226
17370
|
this.logger.debug(`Updating tokens for account: ${accountId}`);
|
|
17227
17371
|
try {
|
|
17228
|
-
await this.accountRepository.updateTokens(
|
|
17372
|
+
await this.accountRepository.updateTokens(
|
|
17373
|
+
accountId,
|
|
17374
|
+
accessToken,
|
|
17375
|
+
refreshToken
|
|
17376
|
+
);
|
|
17229
17377
|
this.logger.log(`Tokens updated for account: ${accountId}`);
|
|
17230
17378
|
} catch (error48) {
|
|
17231
|
-
this.logger.error(
|
|
17379
|
+
this.logger.error(
|
|
17380
|
+
`Failed to update tokens for account: ${accountId}`,
|
|
17381
|
+
error48
|
|
17382
|
+
);
|
|
17232
17383
|
throw error48;
|
|
17233
17384
|
}
|
|
17234
17385
|
}
|
|
@@ -17256,9 +17407,14 @@ var _AccountService = class _AccountService {
|
|
|
17256
17407
|
this.logger.debug(`Checking if user ${userId} has ${provider} account`);
|
|
17257
17408
|
try {
|
|
17258
17409
|
const accounts = await this.accountRepository.findByUserId(userId);
|
|
17259
|
-
return accounts.some(
|
|
17410
|
+
return accounts.some(
|
|
17411
|
+
(account) => account.provider === provider && account.isActive
|
|
17412
|
+
);
|
|
17260
17413
|
} catch (error48) {
|
|
17261
|
-
this.logger.error(
|
|
17414
|
+
this.logger.error(
|
|
17415
|
+
`Failed to check provider account for user: ${userId}`,
|
|
17416
|
+
error48
|
|
17417
|
+
);
|
|
17262
17418
|
return false;
|
|
17263
17419
|
}
|
|
17264
17420
|
}
|
|
@@ -17273,7 +17429,10 @@ var _AccountService = class _AccountService {
|
|
|
17273
17429
|
const accounts = await this.accountRepository.findByUserId(userId);
|
|
17274
17430
|
return accounts.filter((account) => account.isActive).length;
|
|
17275
17431
|
} catch (error48) {
|
|
17276
|
-
this.logger.error(
|
|
17432
|
+
this.logger.error(
|
|
17433
|
+
`Failed to get account count for user: ${userId}`,
|
|
17434
|
+
error48
|
|
17435
|
+
);
|
|
17277
17436
|
return 0;
|
|
17278
17437
|
}
|
|
17279
17438
|
}
|
|
@@ -17310,7 +17469,10 @@ var _BruteForceService = class _BruteForceService {
|
|
|
17310
17469
|
}
|
|
17311
17470
|
static {
|
|
17312
17471
|
// 30 min
|
|
17313
|
-
this.USER_PROGRESSIVE_DELAYS = {
|
|
17472
|
+
this.USER_PROGRESSIVE_DELAYS = {
|
|
17473
|
+
4: 5e3,
|
|
17474
|
+
5: 5e3
|
|
17475
|
+
};
|
|
17314
17476
|
}
|
|
17315
17477
|
static {
|
|
17316
17478
|
this.IP_HARD_LIMIT = 10;
|
|
@@ -17411,7 +17573,12 @@ exports.RateLimiterService = class RateLimiterService {
|
|
|
17411
17573
|
}
|
|
17412
17574
|
if (requests > options.limit && options.blockMs) {
|
|
17413
17575
|
const blockUntil = Date.now() + options.blockMs;
|
|
17414
|
-
await this.redis.set(
|
|
17576
|
+
await this.redis.set(
|
|
17577
|
+
blockKey,
|
|
17578
|
+
blockUntil.toString(),
|
|
17579
|
+
"PX",
|
|
17580
|
+
options.blockMs
|
|
17581
|
+
);
|
|
17415
17582
|
await this.redis.del(rateKey);
|
|
17416
17583
|
return true;
|
|
17417
17584
|
}
|
|
@@ -17695,7 +17862,9 @@ var CookieStore = class {
|
|
|
17695
17862
|
*/
|
|
17696
17863
|
setCookie(sessionId, data, ttlSeconds) {
|
|
17697
17864
|
const encryptedData = this.encrypt(JSON.stringify(data));
|
|
17698
|
-
globalThis.console.log(
|
|
17865
|
+
globalThis.console.log(
|
|
17866
|
+
`Setting cookie: ${this.config.cookieName}=${encryptedData}; Max-Age=${ttlSeconds}`
|
|
17867
|
+
);
|
|
17699
17868
|
}
|
|
17700
17869
|
/**
|
|
17701
17870
|
* Clear HTTP cookie (mock implementation)
|
|
@@ -17901,7 +18070,9 @@ var MemoryStore = class {
|
|
|
17901
18070
|
async enforceSessionLimits(userId) {
|
|
17902
18071
|
const userSessions = await this.getByUserId(userId);
|
|
17903
18072
|
if (userSessions.length >= this.config.maxSessionsPerUser) {
|
|
17904
|
-
userSessions.sort(
|
|
18073
|
+
userSessions.sort(
|
|
18074
|
+
(a, b) => a.lastActivityAt.getTime() - b.lastActivityAt.getTime()
|
|
18075
|
+
);
|
|
17905
18076
|
const sessionsToRemove = userSessions.length - this.config.maxSessionsPerUser + 1;
|
|
17906
18077
|
for (let i = 0; i < sessionsToRemove; i++) {
|
|
17907
18078
|
await this.delete(userSessions[i].id);
|
|
@@ -17958,7 +18129,11 @@ var RedisStore = class {
|
|
|
17958
18129
|
const serializedData = this.serialize(data);
|
|
17959
18130
|
await this.client.set(key, serializedData, ttlSeconds);
|
|
17960
18131
|
const userSessionsTTL = Math.max(ttlSeconds, this.config.defaultTTL);
|
|
17961
|
-
await this.client.set(
|
|
18132
|
+
await this.client.set(
|
|
18133
|
+
`${userSessionsKey}${sessionId}`,
|
|
18134
|
+
"1",
|
|
18135
|
+
userSessionsTTL
|
|
18136
|
+
);
|
|
17962
18137
|
}
|
|
17963
18138
|
/**
|
|
17964
18139
|
* Retrieve session data from Redis
|
|
@@ -18007,7 +18182,10 @@ var RedisStore = class {
|
|
|
18007
18182
|
const userSessionKeys = await this.client.keys(userSessionsPattern);
|
|
18008
18183
|
let deletedCount = 0;
|
|
18009
18184
|
for (const userSessionKey of userSessionKeys) {
|
|
18010
|
-
const sessionId = userSessionKey.replace(
|
|
18185
|
+
const sessionId = userSessionKey.replace(
|
|
18186
|
+
this.getUserSessionsKey(userId),
|
|
18187
|
+
""
|
|
18188
|
+
);
|
|
18011
18189
|
const sessionKey = this.getSessionKey(sessionId);
|
|
18012
18190
|
const sessionDeleted = await this.client.del(sessionKey);
|
|
18013
18191
|
await this.client.del(userSessionKey);
|
|
@@ -18025,7 +18203,10 @@ var RedisStore = class {
|
|
|
18025
18203
|
const data = await this.get(sessionId);
|
|
18026
18204
|
if (data) {
|
|
18027
18205
|
data.lastActivityAt = /* @__PURE__ */ new Date();
|
|
18028
|
-
const remainingTTL = Math.max(
|
|
18206
|
+
const remainingTTL = Math.max(
|
|
18207
|
+
0,
|
|
18208
|
+
Math.floor((data.expiresAt.getTime() - Date.now()) / config$1.NUMERIX.THOUSAND)
|
|
18209
|
+
);
|
|
18029
18210
|
if (remainingTTL > 0) {
|
|
18030
18211
|
await this.set(sessionId, data, remainingTTL);
|
|
18031
18212
|
}
|
|
@@ -18051,7 +18232,10 @@ var RedisStore = class {
|
|
|
18051
18232
|
const userSessionKeys = await this.client.keys(userSessionsPattern);
|
|
18052
18233
|
const sessions = [];
|
|
18053
18234
|
for (const userSessionKey of userSessionKeys) {
|
|
18054
|
-
const sessionId = userSessionKey.replace(
|
|
18235
|
+
const sessionId = userSessionKey.replace(
|
|
18236
|
+
this.getUserSessionsKey(userId),
|
|
18237
|
+
""
|
|
18238
|
+
);
|
|
18055
18239
|
const sessionData = await this.get(sessionId);
|
|
18056
18240
|
if (sessionData) {
|
|
18057
18241
|
sessions.push(sessionData);
|
|
@@ -18146,7 +18330,9 @@ var RedisStore = class {
|
|
|
18146
18330
|
async enforceSessionLimits(userId) {
|
|
18147
18331
|
const userSessions = await this.getByUserId(userId);
|
|
18148
18332
|
if (userSessions.length >= this.config.maxSessionsPerUser) {
|
|
18149
|
-
userSessions.sort(
|
|
18333
|
+
userSessions.sort(
|
|
18334
|
+
(a, b) => a.lastActivityAt.getTime() - b.lastActivityAt.getTime()
|
|
18335
|
+
);
|
|
18150
18336
|
const sessionsToRemove = userSessions.length - this.config.maxSessionsPerUser + 1;
|
|
18151
18337
|
for (let i = 0; i < sessionsToRemove; i++) {
|
|
18152
18338
|
await this.delete(userSessions[i].id);
|
|
@@ -18238,7 +18424,9 @@ var EnhancedSessionManager = class {
|
|
|
18238
18424
|
const sessionId = this.generateSessionId();
|
|
18239
18425
|
await this.enforceSessionLimits(userContext.userId);
|
|
18240
18426
|
const now = /* @__PURE__ */ new Date();
|
|
18241
|
-
const expiresAt = new Date(
|
|
18427
|
+
const expiresAt = new Date(
|
|
18428
|
+
now.getTime() + this.config.sessionTTL * config$1.NUMERIX.THOUSAND
|
|
18429
|
+
);
|
|
18242
18430
|
const session = {
|
|
18243
18431
|
id: sessionId,
|
|
18244
18432
|
userId: userContext.userId,
|
|
@@ -18303,7 +18491,12 @@ var EnhancedSessionManager = class {
|
|
|
18303
18491
|
...updates,
|
|
18304
18492
|
lastActivityAt: /* @__PURE__ */ new Date()
|
|
18305
18493
|
};
|
|
18306
|
-
const remainingTTL = Math.max(
|
|
18494
|
+
const remainingTTL = Math.max(
|
|
18495
|
+
0,
|
|
18496
|
+
Math.floor(
|
|
18497
|
+
(updatedSession.expiresAt.getTime() - Date.now()) / config$1.NUMERIX.THOUSAND
|
|
18498
|
+
)
|
|
18499
|
+
);
|
|
18307
18500
|
if (remainingTTL <= 0) {
|
|
18308
18501
|
throw new Error("Session has expired");
|
|
18309
18502
|
}
|
|
@@ -18331,7 +18524,9 @@ var EnhancedSessionManager = class {
|
|
|
18331
18524
|
throw new Error("Session not found");
|
|
18332
18525
|
}
|
|
18333
18526
|
const now = /* @__PURE__ */ new Date();
|
|
18334
|
-
const newExpiresAt = new Date(
|
|
18527
|
+
const newExpiresAt = new Date(
|
|
18528
|
+
now.getTime() + this.config.sessionTTL * config$1.NUMERIX.THOUSAND
|
|
18529
|
+
);
|
|
18335
18530
|
const refreshedSession = {
|
|
18336
18531
|
...sessionData,
|
|
18337
18532
|
expiresAt: newExpiresAt,
|
|
@@ -18371,7 +18566,9 @@ var EnhancedSessionManager = class {
|
|
|
18371
18566
|
*/
|
|
18372
18567
|
async detectConcurrentSessions(userId) {
|
|
18373
18568
|
const sessionDataArray = await this.store.getByUserId(userId);
|
|
18374
|
-
return sessionDataArray.map(
|
|
18569
|
+
return sessionDataArray.map(
|
|
18570
|
+
(sessionData) => this.mapSessionDataToSession(sessionData)
|
|
18571
|
+
);
|
|
18375
18572
|
}
|
|
18376
18573
|
/**
|
|
18377
18574
|
* Apply maximum session policy for a user
|
|
@@ -18380,7 +18577,9 @@ var EnhancedSessionManager = class {
|
|
|
18380
18577
|
async enforceSessionLimits(userId) {
|
|
18381
18578
|
const userSessions = await this.store.getByUserId(userId);
|
|
18382
18579
|
if (userSessions.length >= this.config.maxConcurrentSessions) {
|
|
18383
|
-
userSessions.sort(
|
|
18580
|
+
userSessions.sort(
|
|
18581
|
+
(a, b) => a.lastActivityAt.getTime() - b.lastActivityAt.getTime()
|
|
18582
|
+
);
|
|
18384
18583
|
const sessionsToRemove = userSessions.length - this.config.maxConcurrentSessions + 1;
|
|
18385
18584
|
for (let i = 0; i < sessionsToRemove; i++) {
|
|
18386
18585
|
await this.deleteSession(userSessions[i].id);
|
|
@@ -18495,7 +18694,8 @@ async function createUser(email3, authProvider, data, password) {
|
|
|
18495
18694
|
roles: data?.roles ?? [],
|
|
18496
18695
|
password_hash: passwordHash
|
|
18497
18696
|
}).select("*").single();
|
|
18498
|
-
if (error48 || !user)
|
|
18697
|
+
if (error48 || !user)
|
|
18698
|
+
throw new Error(error48?.message ?? "Failed to create user");
|
|
18499
18699
|
return user;
|
|
18500
18700
|
}
|
|
18501
18701
|
__name(createUser, "createUser");
|
|
@@ -18513,7 +18713,9 @@ async function createUserSession(userId, deviceInfo) {
|
|
|
18513
18713
|
const thirtyTwo = 32;
|
|
18514
18714
|
const accessToken = crypto.randomBytes(thirtyTwo).toString("hex");
|
|
18515
18715
|
const tokenHash = await bcrypt__default.default.hash(accessToken, config$1.NUMERIX.TEN);
|
|
18516
|
-
const expiresAt = new Date(
|
|
18716
|
+
const expiresAt = new Date(
|
|
18717
|
+
Date.now() + config$1.NUMERIX.THOUSAND * config$1.NUMERIX.SIXTY * config$1.NUMERIX.SIXTY * config$1.NUMERIX.TWENTY_FOUR
|
|
18718
|
+
);
|
|
18517
18719
|
const { data, error: error48 } = await supabase.from("sessions").insert({
|
|
18518
18720
|
user_id: userId,
|
|
18519
18721
|
token_hash: tokenHash,
|
|
@@ -18521,7 +18723,8 @@ async function createUserSession(userId, deviceInfo) {
|
|
|
18521
18723
|
expires_at: expiresAt,
|
|
18522
18724
|
last_active_at: /* @__PURE__ */ new Date()
|
|
18523
18725
|
}).select("*").single();
|
|
18524
|
-
if (error48 || !data)
|
|
18726
|
+
if (error48 || !data)
|
|
18727
|
+
throw new Error(error48?.message ?? "Failed to create session");
|
|
18525
18728
|
return {
|
|
18526
18729
|
id: data.id,
|
|
18527
18730
|
userId: data.user_id,
|
|
@@ -18559,13 +18762,16 @@ async function refreshSessionDB(sessionId) {
|
|
|
18559
18762
|
const thirtyTwo = 32;
|
|
18560
18763
|
const accessToken = crypto.randomBytes(thirtyTwo).toString("hex");
|
|
18561
18764
|
const tokenHash = await bcrypt__default.default.hash(accessToken, config$1.NUMERIX.TEN);
|
|
18562
|
-
const expiresAt = new Date(
|
|
18765
|
+
const expiresAt = new Date(
|
|
18766
|
+
Date.now() + config$1.NUMERIX.THOUSAND * config$1.NUMERIX.SIXTY * config$1.NUMERIX.SIXTY * config$1.NUMERIX.TWENTY_FOUR
|
|
18767
|
+
);
|
|
18563
18768
|
const { data, error: error48 } = await supabase.from("sessions").update({
|
|
18564
18769
|
token_hash: tokenHash,
|
|
18565
18770
|
expires_at: expiresAt,
|
|
18566
18771
|
last_active_at: /* @__PURE__ */ new Date()
|
|
18567
18772
|
}).eq("id", sessionId).select("*").single();
|
|
18568
|
-
if (error48 || !data)
|
|
18773
|
+
if (error48 || !data)
|
|
18774
|
+
throw new Error(error48?.message ?? "Failed to refresh session");
|
|
18569
18775
|
return {
|
|
18570
18776
|
id: data.id,
|
|
18571
18777
|
userId: data.user_id,
|
|
@@ -18655,12 +18861,7 @@ var ClerkAdapter = class extends BaseAuthProviderAdapter {
|
|
|
18655
18861
|
* @param deviceInfo - Optional device metadata
|
|
18656
18862
|
*/
|
|
18657
18863
|
async signUp(provider, credentials, data) {
|
|
18658
|
-
await createUser(
|
|
18659
|
-
credentials.email,
|
|
18660
|
-
provider,
|
|
18661
|
-
data,
|
|
18662
|
-
credentials.password
|
|
18663
|
-
);
|
|
18864
|
+
await createUser(credentials.email, provider, data, credentials.password);
|
|
18664
18865
|
}
|
|
18665
18866
|
/**
|
|
18666
18867
|
* Sign out a user.
|
|
@@ -18905,7 +19106,10 @@ var CustomAdapter = class extends BaseAuthProviderAdapter {
|
|
|
18905
19106
|
return { user, session, tokens: { accessToken: session.accessToken } };
|
|
18906
19107
|
}
|
|
18907
19108
|
async signUp(provider, credentials, data, deviceInfo) {
|
|
18908
|
-
const userFindByEmail = await findUserByEmailProvider(
|
|
19109
|
+
const userFindByEmail = await findUserByEmailProvider(
|
|
19110
|
+
data?.email ?? "",
|
|
19111
|
+
provider
|
|
19112
|
+
);
|
|
18909
19113
|
if (userFindByEmail) {
|
|
18910
19114
|
throw new errors.DatabasePackageError("User already register");
|
|
18911
19115
|
}
|
|
@@ -18986,14 +19190,26 @@ var TraditionalAuthStrategy = class {
|
|
|
18986
19190
|
const SALT_LENGTH = 32;
|
|
18987
19191
|
const HASH_LENGTH = 64;
|
|
18988
19192
|
const salt = crypto.randomBytes(SALT_LENGTH).toString("hex");
|
|
18989
|
-
const hash2 = crypto.pbkdf2Sync(
|
|
19193
|
+
const hash2 = crypto.pbkdf2Sync(
|
|
19194
|
+
password,
|
|
19195
|
+
salt,
|
|
19196
|
+
config$1.NUMERIX.THOUSAND,
|
|
19197
|
+
HASH_LENGTH,
|
|
19198
|
+
"sha512"
|
|
19199
|
+
).toString("hex");
|
|
18990
19200
|
return `pbkdf2$${salt}$${hash2}`;
|
|
18991
19201
|
}
|
|
18992
19202
|
async verifyPassword(password, hash2) {
|
|
18993
19203
|
const HASH_LENGTH = 64;
|
|
18994
19204
|
if (hash2.startsWith("pbkdf2$")) {
|
|
18995
19205
|
const [, salt, storedHash] = hash2.split("$");
|
|
18996
|
-
const computedHash = crypto.pbkdf2Sync(
|
|
19206
|
+
const computedHash = crypto.pbkdf2Sync(
|
|
19207
|
+
password,
|
|
19208
|
+
salt,
|
|
19209
|
+
config$1.NUMERIX.THOUSAND,
|
|
19210
|
+
HASH_LENGTH,
|
|
19211
|
+
"sha512"
|
|
19212
|
+
).toString("hex");
|
|
18997
19213
|
return computedHash === storedHash;
|
|
18998
19214
|
}
|
|
18999
19215
|
return false;
|
|
@@ -19144,22 +19360,29 @@ var FacebookProvider = class extends BaseAuthProvider {
|
|
|
19144
19360
|
__name(this, "FacebookProvider");
|
|
19145
19361
|
}
|
|
19146
19362
|
async authenticate(credentials) {
|
|
19147
|
-
const tokenResponse = await this.exchangeCodeForTokens(
|
|
19363
|
+
const tokenResponse = await this.exchangeCodeForTokens(
|
|
19364
|
+
credentials.code
|
|
19365
|
+
);
|
|
19148
19366
|
const userProfile = await this.getUserProfile(tokenResponse.access_token);
|
|
19149
19367
|
const tokens = {
|
|
19150
19368
|
accessToken: tokenResponse.access_token,
|
|
19151
19369
|
refreshToken: tokenResponse.refresh_token,
|
|
19152
|
-
expiresAt: new Date(
|
|
19370
|
+
expiresAt: new Date(
|
|
19371
|
+
Date.now() + tokenResponse.expires_in * config$1.NUMERIX.THOUSAND
|
|
19372
|
+
),
|
|
19153
19373
|
expiresIn: 0,
|
|
19154
19374
|
tokenType: ""
|
|
19155
19375
|
};
|
|
19156
19376
|
return { user: userProfile, tokens };
|
|
19157
19377
|
}
|
|
19158
19378
|
async refreshToken(refreshToken) {
|
|
19159
|
-
const response = await globalThis.fetch(
|
|
19160
|
-
|
|
19161
|
-
|
|
19162
|
-
|
|
19379
|
+
const response = await globalThis.fetch(
|
|
19380
|
+
"https://graph.facebook.com/v18.0/oauth/access_token",
|
|
19381
|
+
{
|
|
19382
|
+
method: "GET",
|
|
19383
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" }
|
|
19384
|
+
}
|
|
19385
|
+
);
|
|
19163
19386
|
const data = await response.json();
|
|
19164
19387
|
return {
|
|
19165
19388
|
accessToken: data.access_token,
|
|
@@ -19170,12 +19393,17 @@ var FacebookProvider = class extends BaseAuthProvider {
|
|
|
19170
19393
|
};
|
|
19171
19394
|
}
|
|
19172
19395
|
async revokeToken(token) {
|
|
19173
|
-
await globalThis.fetch(
|
|
19174
|
-
|
|
19175
|
-
|
|
19396
|
+
await globalThis.fetch(
|
|
19397
|
+
`https://graph.facebook.com/v18.0/me/permissions?access_token=${token}`,
|
|
19398
|
+
{
|
|
19399
|
+
method: "DELETE"
|
|
19400
|
+
}
|
|
19401
|
+
);
|
|
19176
19402
|
}
|
|
19177
19403
|
async getUserProfile(accessToken) {
|
|
19178
|
-
const response = await globalThis.fetch(
|
|
19404
|
+
const response = await globalThis.fetch(
|
|
19405
|
+
`https://graph.facebook.com/v18.0/me?fields=id,name,email,picture&access_token=${accessToken}`
|
|
19406
|
+
);
|
|
19179
19407
|
const profile = await response.json();
|
|
19180
19408
|
return {
|
|
19181
19409
|
id: profile.id,
|
|
@@ -19204,10 +19432,13 @@ var FacebookProvider = class extends BaseAuthProvider {
|
|
|
19204
19432
|
return `https://www.facebook.com/v18.0/dialog/oauth?${params.toString()}`;
|
|
19205
19433
|
}
|
|
19206
19434
|
async exchangeCodeForTokens(code) {
|
|
19207
|
-
const response = await globalThis.fetch(
|
|
19208
|
-
|
|
19209
|
-
|
|
19210
|
-
|
|
19435
|
+
const response = await globalThis.fetch(
|
|
19436
|
+
"https://graph.facebook.com/v18.0/oauth/access_token",
|
|
19437
|
+
{
|
|
19438
|
+
method: "GET",
|
|
19439
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" }
|
|
19440
|
+
}
|
|
19441
|
+
);
|
|
19211
19442
|
globalThis.console.log(code);
|
|
19212
19443
|
return await response.json();
|
|
19213
19444
|
}
|
|
@@ -19258,7 +19489,9 @@ var GitHubProvider = class extends BaseAuthProvider {
|
|
|
19258
19489
|
return {
|
|
19259
19490
|
accessToken: data.access_token,
|
|
19260
19491
|
refreshToken: data.refresh_token ?? refreshToken,
|
|
19261
|
-
expiresAt: new Date(
|
|
19492
|
+
expiresAt: new Date(
|
|
19493
|
+
Date.now() + (data.expires_in ?? config$1.NUMERIX.THIRTY_SIX_HUNDERD) * config$1.NUMERIX.THOUSAND
|
|
19494
|
+
),
|
|
19262
19495
|
expiresIn: 0,
|
|
19263
19496
|
tokenType: ""
|
|
19264
19497
|
};
|
|
@@ -19344,23 +19577,28 @@ var GoogleProvider = class extends BaseAuthProvider {
|
|
|
19344
19577
|
const tokens = {
|
|
19345
19578
|
accessToken: tokenResponse.access_token,
|
|
19346
19579
|
refreshToken: tokenResponse.refresh_token,
|
|
19347
|
-
expiresAt: new Date(
|
|
19580
|
+
expiresAt: new Date(
|
|
19581
|
+
Date.now() + tokenResponse.expires_in * config$1.NUMERIX.THOUSAND
|
|
19582
|
+
),
|
|
19348
19583
|
expiresIn: 0,
|
|
19349
19584
|
tokenType: ""
|
|
19350
19585
|
};
|
|
19351
19586
|
return { user: userProfile, tokens };
|
|
19352
19587
|
}
|
|
19353
19588
|
async refreshToken(refreshToken) {
|
|
19354
|
-
const response = await globalThis.fetch(
|
|
19355
|
-
|
|
19356
|
-
|
|
19357
|
-
|
|
19358
|
-
|
|
19359
|
-
|
|
19360
|
-
|
|
19361
|
-
|
|
19362
|
-
|
|
19363
|
-
|
|
19589
|
+
const response = await globalThis.fetch(
|
|
19590
|
+
"https://oauth2.googleapis.com/token",
|
|
19591
|
+
{
|
|
19592
|
+
method: "POST",
|
|
19593
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
19594
|
+
body: new URLSearchParams({
|
|
19595
|
+
client_id: this.config.clientId,
|
|
19596
|
+
client_secret: this.config.clientSecret,
|
|
19597
|
+
refresh_token: refreshToken,
|
|
19598
|
+
grant_type: "refresh_token"
|
|
19599
|
+
})
|
|
19600
|
+
}
|
|
19601
|
+
);
|
|
19364
19602
|
const data = await response.json();
|
|
19365
19603
|
return {
|
|
19366
19604
|
accessToken: data.access_token,
|
|
@@ -19371,9 +19609,12 @@ var GoogleProvider = class extends BaseAuthProvider {
|
|
|
19371
19609
|
};
|
|
19372
19610
|
}
|
|
19373
19611
|
async revokeToken(token) {
|
|
19374
|
-
await globalThis.fetch(
|
|
19375
|
-
|
|
19376
|
-
|
|
19612
|
+
await globalThis.fetch(
|
|
19613
|
+
`https://oauth2.googleapis.com/revoke?token=${token}`,
|
|
19614
|
+
{
|
|
19615
|
+
method: "POST"
|
|
19616
|
+
}
|
|
19617
|
+
);
|
|
19377
19618
|
}
|
|
19378
19619
|
async getUserProfile(accessToken) {
|
|
19379
19620
|
const response = await globalThis.fetch(
|
|
@@ -19398,17 +19639,20 @@ var GoogleProvider = class extends BaseAuthProvider {
|
|
|
19398
19639
|
};
|
|
19399
19640
|
}
|
|
19400
19641
|
async exchangeCodeForTokens(code) {
|
|
19401
|
-
const response = await globalThis.fetch(
|
|
19402
|
-
|
|
19403
|
-
|
|
19404
|
-
|
|
19405
|
-
|
|
19406
|
-
|
|
19407
|
-
|
|
19408
|
-
|
|
19409
|
-
|
|
19410
|
-
|
|
19411
|
-
|
|
19642
|
+
const response = await globalThis.fetch(
|
|
19643
|
+
"https://oauth2.googleapis.com/token",
|
|
19644
|
+
{
|
|
19645
|
+
method: "POST",
|
|
19646
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
19647
|
+
body: new URLSearchParams({
|
|
19648
|
+
client_id: this.config.clientId,
|
|
19649
|
+
client_secret: this.config.clientSecret,
|
|
19650
|
+
code,
|
|
19651
|
+
grant_type: "authorization_code",
|
|
19652
|
+
redirect_uri: this.config.redirectUri
|
|
19653
|
+
})
|
|
19654
|
+
}
|
|
19655
|
+
);
|
|
19412
19656
|
return await response.json();
|
|
19413
19657
|
}
|
|
19414
19658
|
getAuthUrl() {
|
|
@@ -19435,7 +19679,10 @@ var SignInFlow = class {
|
|
|
19435
19679
|
__name(this, "SignInFlow");
|
|
19436
19680
|
}
|
|
19437
19681
|
async execute(credentials) {
|
|
19438
|
-
const isValid = await this.validateCredentials(
|
|
19682
|
+
const isValid = await this.validateCredentials(
|
|
19683
|
+
credentials.email,
|
|
19684
|
+
credentials.password
|
|
19685
|
+
);
|
|
19439
19686
|
if (!isValid) {
|
|
19440
19687
|
throw new Error("Invalid credentials");
|
|
19441
19688
|
}
|
|
@@ -19448,7 +19695,9 @@ var SignInFlow = class {
|
|
|
19448
19695
|
const thirty2 = 30;
|
|
19449
19696
|
await this.sessionManager.createSession({
|
|
19450
19697
|
userId: user.id,
|
|
19451
|
-
expiresAt: new Date(
|
|
19698
|
+
expiresAt: new Date(
|
|
19699
|
+
Date.now() + thirty2 * config$1.NUMERIX.TWENTY_FOUR * config$1.NUMERIX.SIXTY * config$1.NUMERIX.SIXTY * config$1.NUMERIX.THOUSAND
|
|
19700
|
+
),
|
|
19452
19701
|
// 30 days
|
|
19453
19702
|
metadata: { rememberMe: true }
|
|
19454
19703
|
});
|
|
@@ -19531,7 +19780,10 @@ var SignUpFlow = class {
|
|
|
19531
19780
|
}
|
|
19532
19781
|
async verifyEmail(token) {
|
|
19533
19782
|
const payload = await this.jwtManager.verifyToken(token);
|
|
19534
|
-
const user = await this.userRepository.updateEmailVerification(
|
|
19783
|
+
const user = await this.userRepository.updateEmailVerification(
|
|
19784
|
+
payload.userId,
|
|
19785
|
+
true
|
|
19786
|
+
);
|
|
19535
19787
|
if (!user) {
|
|
19536
19788
|
throw new Error("User not found");
|
|
19537
19789
|
}
|
|
@@ -19551,7 +19803,10 @@ exports.AuthGuard = class AuthGuard {
|
|
|
19551
19803
|
}
|
|
19552
19804
|
// Explicit return type for canActivate
|
|
19553
19805
|
async canActivate(context) {
|
|
19554
|
-
const isPublic = this.reflector.get(
|
|
19806
|
+
const isPublic = this.reflector.get(
|
|
19807
|
+
"isPublic",
|
|
19808
|
+
context.getHandler()
|
|
19809
|
+
);
|
|
19555
19810
|
if (isPublic) return true;
|
|
19556
19811
|
const request = context.switchToHttp().getRequest();
|
|
19557
19812
|
const token = this.extractToken(request);
|
|
@@ -19595,7 +19850,10 @@ exports.RolesGuard = class RolesGuard {
|
|
|
19595
19850
|
__name(this, "RolesGuard");
|
|
19596
19851
|
}
|
|
19597
19852
|
async canActivate(context) {
|
|
19598
|
-
const requiredRoles = this.reflector.get(
|
|
19853
|
+
const requiredRoles = this.reflector.get(
|
|
19854
|
+
"roles",
|
|
19855
|
+
context.getHandler()
|
|
19856
|
+
);
|
|
19599
19857
|
if (!requiredRoles) return true;
|
|
19600
19858
|
const request = context.switchToHttp().getRequest();
|
|
19601
19859
|
const user = request.user;
|
|
@@ -19626,11 +19884,12 @@ exports.PermissionsGuard = class PermissionsGuard {
|
|
|
19626
19884
|
if (!permissionMetadata) return true;
|
|
19627
19885
|
const user = request.user;
|
|
19628
19886
|
if (!user) {
|
|
19629
|
-
throw new errors.AuthenticationError(
|
|
19630
|
-
"AUTH_INVALID_CREDENTIALS"
|
|
19631
|
-
);
|
|
19887
|
+
throw new errors.AuthenticationError("AUTH_INVALID_CREDENTIALS");
|
|
19632
19888
|
}
|
|
19633
|
-
const permissionContext = this.buildPermissionContext(
|
|
19889
|
+
const permissionContext = this.buildPermissionContext(
|
|
19890
|
+
request,
|
|
19891
|
+
permissionMetadata
|
|
19892
|
+
);
|
|
19634
19893
|
const result = await this.permissionChecker.checkPermission(
|
|
19635
19894
|
user.sub ?? user.userId ?? "",
|
|
19636
19895
|
permissionMetadata.resource,
|
|
@@ -19638,18 +19897,13 @@ exports.PermissionsGuard = class PermissionsGuard {
|
|
|
19638
19897
|
permissionContext
|
|
19639
19898
|
);
|
|
19640
19899
|
if (!result.granted) {
|
|
19641
|
-
throw new errors.AuthenticationError(
|
|
19642
|
-
"AUTH_INSUFFICIENT_PERMISSIONS"
|
|
19643
|
-
);
|
|
19900
|
+
throw new errors.AuthenticationError("AUTH_INSUFFICIENT_PERMISSIONS");
|
|
19644
19901
|
}
|
|
19645
19902
|
request.permissionResult = result;
|
|
19646
19903
|
return true;
|
|
19647
19904
|
}
|
|
19648
19905
|
getPermissionMetadata(context) {
|
|
19649
|
-
const permissionData = this.reflector.get(
|
|
19650
|
-
"permission",
|
|
19651
|
-
context.getHandler()
|
|
19652
|
-
);
|
|
19906
|
+
const permissionData = this.reflector.get("permission", context.getHandler());
|
|
19653
19907
|
if (!permissionData) return null;
|
|
19654
19908
|
if (Array.isArray(permissionData)) {
|
|
19655
19909
|
return { resource: permissionData[0], action: permissionData[1] };
|
|
@@ -19669,7 +19923,12 @@ exports.PermissionsGuard = class PermissionsGuard {
|
|
|
19669
19923
|
}
|
|
19670
19924
|
}
|
|
19671
19925
|
if (request.body) {
|
|
19672
|
-
const relevantBodyFields = [
|
|
19926
|
+
const relevantBodyFields = [
|
|
19927
|
+
"ownerId",
|
|
19928
|
+
"organizationId",
|
|
19929
|
+
"teamId",
|
|
19930
|
+
"projectId"
|
|
19931
|
+
];
|
|
19673
19932
|
for (const field of relevantBodyFields) {
|
|
19674
19933
|
if (request.body[field]) context[field] = request.body[field];
|
|
19675
19934
|
}
|
|
@@ -19682,9 +19941,7 @@ _init12 = __decoratorStart();
|
|
|
19682
19941
|
exports.PermissionsGuard = __decorateElement(_init12, 0, "PermissionsGuard", _PermissionsGuard_decorators, exports.PermissionsGuard);
|
|
19683
19942
|
__runInitializers(_init12, 1, exports.PermissionsGuard);
|
|
19684
19943
|
var IS_PUBLIC_KEY = "isPublic";
|
|
19685
|
-
var Auth = /* @__PURE__ */ __name(() => common.applyDecorators(
|
|
19686
|
-
common.UseGuards(exports.AuthGuard)
|
|
19687
|
-
), "Auth");
|
|
19944
|
+
var Auth = /* @__PURE__ */ __name(() => common.applyDecorators(common.UseGuards(exports.AuthGuard)), "Auth");
|
|
19688
19945
|
var Public = /* @__PURE__ */ __name(() => common.SetMetadata(IS_PUBLIC_KEY, true), "Public");
|
|
19689
19946
|
var Roles = /* @__PURE__ */ __name((...roles) => common.SetMetadata("roles", roles), "Roles");
|
|
19690
19947
|
var Permissions = /* @__PURE__ */ __name((...permissions) => common.SetMetadata("permissions", permissions), "Permissions");
|
|
@@ -20202,7 +20459,9 @@ function useAuth() {
|
|
|
20202
20459
|
});
|
|
20203
20460
|
}, "linkAccount"),
|
|
20204
20461
|
unlinkAccount: /* @__PURE__ */ __name(async (accountId) => {
|
|
20205
|
-
return handleAuthAction(
|
|
20462
|
+
return handleAuthAction(
|
|
20463
|
+
async () => store.removeConnectedAccount(accountId)
|
|
20464
|
+
);
|
|
20206
20465
|
}, "unlinkAccount")
|
|
20207
20466
|
};
|
|
20208
20467
|
}
|
|
@@ -20265,9 +20524,12 @@ var useConnectedAccounts = /* @__PURE__ */ __name(() => {
|
|
|
20265
20524
|
const unlinkAccount = /* @__PURE__ */ __name(async (accountId) => {
|
|
20266
20525
|
setIsLoading(true);
|
|
20267
20526
|
try {
|
|
20268
|
-
const response = await globalThis.fetch(
|
|
20269
|
-
|
|
20270
|
-
|
|
20527
|
+
const response = await globalThis.fetch(
|
|
20528
|
+
`/api/auth/accounts/${accountId}/unlink`,
|
|
20529
|
+
{
|
|
20530
|
+
method: "DELETE"
|
|
20531
|
+
}
|
|
20532
|
+
);
|
|
20271
20533
|
if (!response.ok) throw new Error("Failed to unlink account");
|
|
20272
20534
|
setAccounts((prev) => prev.filter((acc) => acc.id !== accountId));
|
|
20273
20535
|
} finally {
|
|
@@ -20277,14 +20539,19 @@ var useConnectedAccounts = /* @__PURE__ */ __name(() => {
|
|
|
20277
20539
|
const setPrimaryAccount = /* @__PURE__ */ __name(async (accountId) => {
|
|
20278
20540
|
setIsLoading(true);
|
|
20279
20541
|
try {
|
|
20280
|
-
const response = await globalThis.fetch(
|
|
20281
|
-
|
|
20282
|
-
|
|
20542
|
+
const response = await globalThis.fetch(
|
|
20543
|
+
`/api/auth/accounts/${accountId}/primary`,
|
|
20544
|
+
{
|
|
20545
|
+
method: "PUT"
|
|
20546
|
+
}
|
|
20547
|
+
);
|
|
20283
20548
|
if (!response.ok) throw new Error("Failed to set primary account");
|
|
20284
|
-
setAccounts(
|
|
20285
|
-
|
|
20286
|
-
|
|
20287
|
-
|
|
20549
|
+
setAccounts(
|
|
20550
|
+
(prev) => prev.map((acc) => ({
|
|
20551
|
+
...acc,
|
|
20552
|
+
isPrimary: acc.id === accountId
|
|
20553
|
+
}))
|
|
20554
|
+
);
|
|
20288
20555
|
} finally {
|
|
20289
20556
|
setIsLoading(false);
|
|
20290
20557
|
}
|
|
@@ -20346,7 +20613,9 @@ var ProtectedRoute = /* @__PURE__ */ __name(({
|
|
|
20346
20613
|
}
|
|
20347
20614
|
if (requiredRoles.length > 0 && user) {
|
|
20348
20615
|
const userRoles = user.roles ?? [];
|
|
20349
|
-
const hasRequiredRole = requiredRoles.some(
|
|
20616
|
+
const hasRequiredRole = requiredRoles.some(
|
|
20617
|
+
(role) => userRoles.includes(role)
|
|
20618
|
+
);
|
|
20350
20619
|
if (!hasRequiredRole) {
|
|
20351
20620
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
20352
20621
|
"Access denied. Required roles: ",
|