@plyaz/auth 1.0.0 → 1.0.2

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.
Files changed (99) hide show
  1. package/commits.txt +3 -3
  2. package/dist/common/index.cjs +3 -1
  3. package/dist/common/index.cjs.map +1 -1
  4. package/dist/common/index.mjs +3 -1
  5. package/dist/common/index.mjs.map +1 -1
  6. package/dist/index.cjs +424 -154
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.mjs +421 -152
  9. package/dist/index.mjs.map +1 -1
  10. package/package.json +2 -1
  11. package/release_message.txt +28 -0
  12. package/src/adapters/auth-adapter-factory.ts +4 -3
  13. package/src/adapters/auth-adapter.mapper.ts +2 -2
  14. package/src/adapters/base-auth.adapter.ts +17 -9
  15. package/src/adapters/clerk/clerk.adapter.ts +9 -12
  16. package/src/adapters/custom/custom.adapter.ts +19 -10
  17. package/src/adapters/index.ts +0 -1
  18. package/src/adapters/next-auth/authOptions.ts +20 -16
  19. package/src/adapters/next-auth/next-auth.adapter.ts +13 -15
  20. package/src/api/client.ts +4 -6
  21. package/src/audit/audit.logger.ts +19 -10
  22. package/src/client/components/ProtectedRoute.tsx +15 -11
  23. package/src/client/hooks/useAuth.ts +23 -21
  24. package/src/client/hooks/useConnectedAccounts.ts +57 -45
  25. package/src/client/hooks/usePermissions.ts +1 -1
  26. package/src/client/hooks/useRBAC.ts +6 -6
  27. package/src/client/hooks/useSession.ts +5 -5
  28. package/src/client/providers/AuthProvider.tsx +23 -17
  29. package/src/client/store/auth.store.ts +71 -62
  30. package/src/client/utils/storage.ts +45 -18
  31. package/src/common/constants/oauth-providers.ts +10 -7
  32. package/src/common/errors/auth.errors.ts +4 -4
  33. package/src/common/errors/specific-auth-errors.ts +5 -9
  34. package/src/common/regex/index.ts +6 -4
  35. package/src/common/types/auth.types.ts +47 -38
  36. package/src/common/types/index.ts +12 -6
  37. package/src/common/utils/index.ts +15 -11
  38. package/src/core/blacklist/token.blacklist.ts +13 -7
  39. package/src/core/index.ts +2 -2
  40. package/src/core/jwt/jwt.manager.ts +47 -22
  41. package/src/core/session/session.manager.ts +17 -14
  42. package/src/db/repositories/connected-account.repository.ts +120 -78
  43. package/src/db/repositories/role.repository.ts +41 -26
  44. package/src/db/repositories/session.repository.ts +9 -10
  45. package/src/db/repositories/user.repository.ts +105 -91
  46. package/src/flows/index.ts +2 -2
  47. package/src/flows/sign-in.flow.ts +28 -14
  48. package/src/flows/sign-up.flow.ts +31 -20
  49. package/src/index.ts +36 -37
  50. package/src/libs/clerk.helper.ts +6 -7
  51. package/src/libs/supabase.helper.ts +79 -61
  52. package/src/libs/supabaseClient.ts +3 -3
  53. package/src/providers/base/auth-provider.interface.ts +13 -11
  54. package/src/providers/base/index.ts +1 -1
  55. package/src/providers/index.ts +1 -1
  56. package/src/providers/oauth/facebook.provider.ts +63 -39
  57. package/src/providers/oauth/github.provider.ts +14 -10
  58. package/src/providers/oauth/google.provider.ts +39 -28
  59. package/src/providers/oauth/index.ts +1 -1
  60. package/src/rbac/dynamic-roles.ts +88 -54
  61. package/src/rbac/index.ts +4 -4
  62. package/src/rbac/permission-checker.ts +147 -75
  63. package/src/rbac/role-hierarchy.ts +8 -8
  64. package/src/rbac/role.manager.ts +11 -8
  65. package/src/security/csrf/csrf.protection.ts +9 -7
  66. package/src/security/index.ts +2 -2
  67. package/src/security/rate-limiting/auth/auth.controller.ts +2 -4
  68. package/src/security/rate-limiting/auth/rate-limiting.interface.ts +26 -6
  69. package/src/security/rate-limiting/auth.module.ts +1 -2
  70. package/src/server/auth.module.ts +55 -52
  71. package/src/server/decorators/auth.decorator.ts +9 -11
  72. package/src/server/decorators/auth.decorators.ts +8 -9
  73. package/src/server/decorators/current-user.decorator.ts +6 -6
  74. package/src/server/decorators/permission.decorator.ts +17 -9
  75. package/src/server/guards/auth.guard.ts +21 -16
  76. package/src/server/guards/custom-throttler.guard.ts +4 -9
  77. package/src/server/guards/permissions.guard.ts +32 -23
  78. package/src/server/guards/roles.guard.ts +14 -12
  79. package/src/server/middleware/auth.middleware.ts +4 -4
  80. package/src/server/middleware/session.middleware.ts +4 -4
  81. package/src/server/services/account.service.ts +96 -48
  82. package/src/server/services/auth.service.ts +57 -28
  83. package/src/server/services/brute-force.service.ts +24 -19
  84. package/src/server/services/index.ts +1 -1
  85. package/src/server/services/rate-limiter.service.ts +9 -4
  86. package/src/server/services/session.service.ts +84 -48
  87. package/src/server/services/token.service.ts +71 -51
  88. package/src/session/cookie-store.ts +47 -34
  89. package/src/session/enhanced-session-manager.ts +69 -48
  90. package/src/session/index.ts +5 -5
  91. package/src/session/memory-store.ts +37 -30
  92. package/src/session/redis-store.ts +105 -72
  93. package/src/strategies/oauth.strategy.ts +10 -9
  94. package/src/strategies/traditional-auth.strategy.ts +41 -29
  95. package/src/tokens/index.ts +4 -4
  96. package/src/tokens/refresh-token-manager.ts +70 -55
  97. package/src/tokens/token-validator.ts +109 -53
  98. package/vitest.setup.d.ts +2 -2
  99. package/vitest.setup.ts +1 -1
@@ -12,7 +12,7 @@ export class TokenBlacklist {
12
12
  async add(tokenId: string, expiresAt: number): Promise<void> {
13
13
  const ttl = Math.max(0, expiresAt - Date.now());
14
14
  this.blacklistedTokens.set(tokenId, Date.now() + ttl);
15
-
15
+
16
16
  // Auto-cleanup expired tokens
17
17
  globalThis.setTimeout(() => {
18
18
  this.blacklistedTokens.delete(tokenId);
@@ -26,26 +26,32 @@ export class TokenBlacklist {
26
26
  async isBlacklisted(tokenId: string): Promise<boolean> {
27
27
  const expiry = this.blacklistedTokens.get(tokenId);
28
28
  if (!expiry) return false;
29
-
29
+
30
30
  if (expiry < Date.now()) {
31
31
  this.blacklistedTokens.delete(tokenId);
32
32
  return false;
33
33
  }
34
-
34
+
35
35
  return true;
36
36
  }
37
37
 
38
- async blacklistAllUserTokens(userId: string, issuedBefore: number): Promise<void> {
38
+ async blacklistAllUserTokens(
39
+ userId: string,
40
+ issuedBefore: number,
41
+ ): Promise<void> {
39
42
  // In production, this would use Redis with a user-specific key
40
43
  // For now, we'll use a simple approach
41
44
  const userKey = `user:${userId}:blacklist_before`;
42
45
  this.blacklistedTokens.set(userKey, issuedBefore);
43
46
  }
44
47
 
45
- async isUserTokenBlacklisted(userId: string, tokenIssuedAt: number): Promise<boolean> {
48
+ async isUserTokenBlacklisted(
49
+ userId: string,
50
+ tokenIssuedAt: number,
51
+ ): Promise<boolean> {
46
52
  const userKey = `user:${userId}:blacklist_before`;
47
53
  const blacklistBefore = this.blacklistedTokens.get(userKey);
48
-
54
+
49
55
  return blacklistBefore ? tokenIssuedAt < blacklistBefore : false;
50
56
  }
51
57
 
@@ -57,4 +63,4 @@ export class TokenBlacklist {
57
63
  }
58
64
  });
59
65
  }
60
- }
66
+ }
package/src/core/index.ts CHANGED
@@ -1,2 +1,2 @@
1
- export * from './jwt/jwt.manager';
2
- export * from './session/session.manager';
1
+ export * from "./jwt/jwt.manager";
2
+ export * from "./session/session.manager";
@@ -1,5 +1,5 @@
1
1
  import { sign, verify, type JwtPayload, type SignOptions } from "jsonwebtoken";
2
- import type { AuthTokens } from '@plyaz/types';
2
+ import type { AuthTokens } from "@plyaz/types";
3
3
  import { NUMERIX } from "@plyaz/config";
4
4
 
5
5
  // Define the token payload interface
@@ -12,7 +12,6 @@ export interface TokenPayload extends JwtPayload {
12
12
  // Define the StringValue type to match what jsonwebtoken expects
13
13
  type StringValue = `${number}s` | `${number}m` | `${number}h` | `${number}d`;
14
14
 
15
-
16
15
  export class JwtManager {
17
16
  private config: {
18
17
  privateKey: string;
@@ -24,7 +23,7 @@ export class JwtManager {
24
23
 
25
24
  constructor(
26
25
  config: typeof JwtManager.prototype.config,
27
- algorithm: "RS256" | "HS256" | "ES256" | "HS512"
26
+ algorithm: "RS256" | "HS256" | "ES256" | "HS512",
28
27
  ) {
29
28
  this.config = config;
30
29
  this.algorithm = algorithm;
@@ -35,7 +34,7 @@ export class JwtManager {
35
34
  // -------------------
36
35
  private generateToken(
37
36
  payload: Omit<TokenPayload, "iss" | "aud" | "iat" | "exp">,
38
- expiresIn: string | number = "1h"
37
+ expiresIn: string | number = "1h",
39
38
  ): string {
40
39
  const signOptions: SignOptions = {
41
40
  algorithm: this.algorithm,
@@ -50,20 +49,31 @@ export class JwtManager {
50
49
  generateTokens(
51
50
  user: { id: string },
52
51
  accessTokenExpiry: string | number = "1h",
53
- refreshTokenExpiry: string | number = "7d"
52
+ refreshTokenExpiry: string | number = "7d",
54
53
  ): AuthTokens {
55
- const accessToken = this.generateToken({ sub: user.id, type: "access" }, accessTokenExpiry);
56
- const refreshToken = this.generateToken({ sub: user.id, type: "refresh" }, refreshTokenExpiry);
54
+ const accessToken = this.generateToken(
55
+ { sub: user.id, type: "access" },
56
+ accessTokenExpiry,
57
+ );
58
+ const refreshToken = this.generateToken(
59
+ { sub: user.id, type: "refresh" },
60
+ refreshTokenExpiry,
61
+ );
57
62
 
58
63
  // Calculate the actual expiration time in seconds
59
64
  let expiresIn: number;
60
- if (typeof accessTokenExpiry === 'string') {
65
+ if (typeof accessTokenExpiry === "string") {
61
66
  // Parse time strings like "1h", "30m", etc.
62
67
  const match = accessTokenExpiry.match(/^(\d+)([smhd])$/);
63
68
  if (match) {
64
69
  const value = globalThis.parseInt(match[1], NUMERIX.TEN);
65
70
  const unit = match[2];
66
- const multipliers: Record<string, number> = { s: 1, m: 60, h: 3600, d: 86400 };
71
+ const multipliers: Record<string, number> = {
72
+ s: 1,
73
+ m: 60,
74
+ h: 3600,
75
+ d: 86400,
76
+ };
67
77
  expiresIn = value * multipliers[unit];
68
78
  } else {
69
79
  expiresIn = NUMERIX.THIRTY_SIX_HUNDERD; // Default to 1 hour
@@ -72,48 +82,63 @@ export class JwtManager {
72
82
  expiresIn = accessTokenExpiry;
73
83
  }
74
84
 
75
- return {
76
- accessToken,
85
+ return {
86
+ accessToken,
77
87
  refreshToken,
78
88
  expiresIn,
79
- tokenType: "Bearer"
89
+ tokenType: "Bearer",
80
90
  };
81
91
  }
82
92
 
83
93
  // Generate access token
84
- generateAccessToken(userId: string, expiresIn: string | number = "1h"): string {
94
+ generateAccessToken(
95
+ userId: string,
96
+ expiresIn: string | number = "1h",
97
+ ): string {
85
98
  return this.generateToken({ sub: userId, type: "access" }, expiresIn);
86
99
  }
87
100
 
88
101
  // Generate refresh token
89
- generateRefreshToken(userId: string, expiresIn: string | number = "7d"): string {
102
+ generateRefreshToken(
103
+ userId: string,
104
+ expiresIn: string | number = "7d",
105
+ ): string {
90
106
  return this.generateToken({ sub: userId, type: "refresh" }, expiresIn);
91
107
  }
92
108
 
93
109
  // Generate verification token (email confirmation)
94
- generateVerificationToken(userId: string, expiresIn: string | number = "24h"): string {
110
+ generateVerificationToken(
111
+ userId: string,
112
+ expiresIn: string | number = "24h",
113
+ ): string {
95
114
  return this.generateToken({ sub: userId, type: "verification" }, expiresIn);
96
115
  }
97
116
 
98
117
  // -------------------
99
118
  // Token Verification
100
119
  // -------------------
101
- private verifyToken(token: string, tokenType: "access" | "refresh" | "verification"): TokenPayload {
120
+ private verifyToken(
121
+ token: string,
122
+ tokenType: "access" | "refresh" | "verification",
123
+ ): TokenPayload {
102
124
  const decoded = verify(token, this.config.publicKey, {
103
125
  algorithms: [this.algorithm],
104
126
  issuer: this.config.issuer,
105
127
  audience: this.config.audience,
106
128
  });
107
129
 
108
- if (typeof decoded === "string") throw new Error(`Invalid ${tokenType} token payload`);
109
-
130
+ if (typeof decoded === "string")
131
+ throw new Error(`Invalid ${tokenType} token payload`);
132
+
110
133
  const payload = decoded as JwtPayload;
111
-
134
+
112
135
  // Verify the token type
113
136
  if (payload.type !== tokenType) {
114
- throw new Error(`Invalid token type. Expected ${tokenType}, got ${payload.type}`);
137
+ throw new Error(
138
+ `Invalid token type. Expected ${tokenType}, got ${payload.type}`,
139
+ );
115
140
  }
116
-
141
+
117
142
  return payload as TokenPayload;
118
143
  }
119
144
 
@@ -128,4 +153,4 @@ export class JwtManager {
128
153
  verifyVerificationToken(token: string): TokenPayload {
129
154
  return this.verifyToken(token, "verification");
130
155
  }
131
- }
156
+ }
@@ -1,22 +1,27 @@
1
-
2
- import type { Session, SessionRepository, SessionConfig, CreateSessionData } from '@plyaz/types';
3
-
4
-
1
+ import type {
2
+ Session,
3
+ SessionRepository,
4
+ SessionConfig,
5
+ CreateSessionData,
6
+ } from "@plyaz/types";
5
7
 
6
8
  export class SessionManager {
7
9
  constructor(
8
10
  private sessionRepo: SessionRepository,
9
- private config: SessionConfig
11
+ private config: SessionConfig,
10
12
  ) {}
11
13
 
12
- async createSession(userId: string, deviceInfo: Record<string,unknown>): Promise<Session> {
14
+ async createSession(
15
+ userId: string,
16
+ deviceInfo: Record<string, unknown>,
17
+ ): Promise<Session> {
13
18
  await this.enforceSessionLimits(userId);
14
-
19
+
15
20
  const sessionData: CreateSessionData = {
16
21
  userId,
17
- provider: 'default',
22
+ provider: "default",
18
23
  expiresAt: new Date(Date.now() + this.config.sessionTTL),
19
- metadata:deviceInfo,
24
+ metadata: deviceInfo,
20
25
  };
21
26
 
22
27
  return this.sessionRepo.create(sessionData);
@@ -45,12 +50,10 @@ export class SessionManager {
45
50
  private async enforceSessionLimits(userId: string): Promise<void> {
46
51
  const sessions = await this.sessionRepo.findByUserId(userId);
47
52
  if (sessions.length >= this.config.maxConcurrentSessions) {
48
- const oldestSession = sessions.sort((a, b) =>
49
- a.lastActivityAt.getTime() - b.lastActivityAt.getTime()
53
+ const oldestSession = sessions.sort(
54
+ (a, b) => a.lastActivityAt.getTime() - b.lastActivityAt.getTime(),
50
55
  )[0];
51
56
  await this.sessionRepo.delete(oldestSession.id);
52
57
  }
53
58
  }
54
-
55
-
56
- }
59
+ }