@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.
- package/commits.txt +3 -3
- 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 +424 -154
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +421 -152
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
- package/release_message.txt +28 -0
- 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
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
class StorageManager {
|
|
8
8
|
private get storage() {
|
|
9
|
-
return typeof globalThis !==
|
|
9
|
+
return typeof globalThis !== "undefined" ? globalThis.localStorage : null;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
getItem(key: string): string | null {
|
|
@@ -14,12 +14,21 @@ class StorageManager {
|
|
|
14
14
|
try {
|
|
15
15
|
return this.storage.getItem(key);
|
|
16
16
|
} catch (error) {
|
|
17
|
-
if (
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
if (
|
|
18
|
+
error instanceof DOMException &&
|
|
19
|
+
error.name === "QuotaExceededError"
|
|
20
|
+
) {
|
|
21
|
+
globalThis.console.warn("localStorage quota exceeded:", error);
|
|
22
|
+
} else if (
|
|
23
|
+
error instanceof DOMException &&
|
|
24
|
+
error.name === "SecurityError"
|
|
25
|
+
) {
|
|
26
|
+
globalThis.console.warn(
|
|
27
|
+
"localStorage access denied (private browsing):",
|
|
28
|
+
error,
|
|
29
|
+
);
|
|
21
30
|
} else {
|
|
22
|
-
|
|
31
|
+
globalThis.console.warn("localStorage.getItem failed:", error);
|
|
23
32
|
}
|
|
24
33
|
return null;
|
|
25
34
|
}
|
|
@@ -30,12 +39,24 @@ class StorageManager {
|
|
|
30
39
|
try {
|
|
31
40
|
this.storage.setItem(key, value);
|
|
32
41
|
} catch (error) {
|
|
33
|
-
if (
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
42
|
+
if (
|
|
43
|
+
error instanceof DOMException &&
|
|
44
|
+
error.name === "QuotaExceededError"
|
|
45
|
+
) {
|
|
46
|
+
globalThis.console.warn(
|
|
47
|
+
"localStorage quota exceeded, cannot save:",
|
|
48
|
+
error,
|
|
49
|
+
);
|
|
50
|
+
} else if (
|
|
51
|
+
error instanceof DOMException &&
|
|
52
|
+
error.name === "SecurityError"
|
|
53
|
+
) {
|
|
54
|
+
globalThis.console.warn(
|
|
55
|
+
"localStorage access denied (private browsing):",
|
|
56
|
+
error,
|
|
57
|
+
);
|
|
37
58
|
} else {
|
|
38
|
-
|
|
59
|
+
globalThis.console.warn("localStorage.setItem failed:", error);
|
|
39
60
|
}
|
|
40
61
|
}
|
|
41
62
|
}
|
|
@@ -45,10 +66,13 @@ class StorageManager {
|
|
|
45
66
|
try {
|
|
46
67
|
this.storage.removeItem(key);
|
|
47
68
|
} catch (error) {
|
|
48
|
-
if (error instanceof DOMException && error.name ===
|
|
49
|
-
|
|
69
|
+
if (error instanceof DOMException && error.name === "SecurityError") {
|
|
70
|
+
globalThis.console.warn(
|
|
71
|
+
"localStorage access denied (private browsing):",
|
|
72
|
+
error,
|
|
73
|
+
);
|
|
50
74
|
} else {
|
|
51
|
-
|
|
75
|
+
globalThis.console.warn("localStorage.removeItem failed:", error);
|
|
52
76
|
}
|
|
53
77
|
}
|
|
54
78
|
}
|
|
@@ -58,13 +82,16 @@ class StorageManager {
|
|
|
58
82
|
try {
|
|
59
83
|
this.storage.clear();
|
|
60
84
|
} catch (error) {
|
|
61
|
-
if (error instanceof DOMException && error.name ===
|
|
62
|
-
globalThis.
|
|
85
|
+
if (error instanceof DOMException && error.name === "SecurityError") {
|
|
86
|
+
globalThis.console.warn(
|
|
87
|
+
"localStorage access denied (private browsing):",
|
|
88
|
+
error,
|
|
89
|
+
);
|
|
63
90
|
} else {
|
|
64
|
-
|
|
91
|
+
globalThis.console.warn("localStorage.clear failed:", error);
|
|
65
92
|
}
|
|
66
93
|
}
|
|
67
94
|
}
|
|
68
95
|
}
|
|
69
96
|
|
|
70
|
-
export const storage = new StorageManager();
|
|
97
|
+
export const storage = new StorageManager();
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
// /**
|
|
2
2
|
// * @fileoverview OAuth provider constants for @plyaz/auth
|
|
3
3
|
// * @module @plyaz/auth/constants/oauth-providers
|
|
4
|
-
// *
|
|
4
|
+
// *
|
|
5
5
|
// * @description
|
|
6
6
|
// * Defines supported OAuth providers and their configurations.
|
|
7
7
|
// * Used by adapters, strategies, and frontend components to handle
|
|
8
8
|
// * OAuth authentication flows. Provides standardized provider names
|
|
9
9
|
// * and metadata for consistent provider handling.
|
|
10
|
-
// *
|
|
10
|
+
// *
|
|
11
11
|
// * @example
|
|
12
12
|
// * ```typescript
|
|
13
13
|
// * import { OAUTH_PROVIDERS, OAuthProviderConfig } from '@plyaz/auth';
|
|
14
|
-
// *
|
|
14
|
+
// *
|
|
15
15
|
// * const googleConfig = OAUTH_PROVIDER_CONFIGS[OAUTH_PROVIDERS.GOOGLE];
|
|
16
16
|
// * const authUrl = `${googleConfig.authUrl}?client_id=${clientId}`;
|
|
17
17
|
// * ```
|
|
@@ -21,13 +21,14 @@ import { OAUTH_PROVIDER_CONFIGS } from "@plyaz/config";
|
|
|
21
21
|
import type { OAuthProvider, OAuthProviderConfig } from "@plyaz/types";
|
|
22
22
|
import { OAUTH_PROVIDERS } from "@plyaz/types";
|
|
23
23
|
|
|
24
|
-
|
|
25
24
|
/**
|
|
26
25
|
* Get OAuth provider configuration by provider name
|
|
27
26
|
* @param provider - OAuth provider name
|
|
28
27
|
* @returns Provider configuration or null if not found
|
|
29
28
|
*/
|
|
30
|
-
export function getOAuthProviderConfig(
|
|
29
|
+
export function getOAuthProviderConfig(
|
|
30
|
+
provider: string,
|
|
31
|
+
): OAuthProviderConfig | null {
|
|
31
32
|
return OAUTH_PROVIDER_CONFIGS[provider as OAuthProvider] || null;
|
|
32
33
|
}
|
|
33
34
|
|
|
@@ -36,7 +37,9 @@ export function getOAuthProviderConfig(provider: string): OAuthProviderConfig |
|
|
|
36
37
|
* @param provider - Provider name to check
|
|
37
38
|
* @returns True if provider is supported
|
|
38
39
|
*/
|
|
39
|
-
export function isOAuthProviderSupported(
|
|
40
|
+
export function isOAuthProviderSupported(
|
|
41
|
+
provider: string,
|
|
42
|
+
): provider is OAuthProvider {
|
|
40
43
|
return Object.values(OAUTH_PROVIDERS).includes(provider as OAuthProvider);
|
|
41
44
|
}
|
|
42
45
|
|
|
@@ -46,4 +49,4 @@ export function isOAuthProviderSupported(provider: string): provider is OAuthPro
|
|
|
46
49
|
*/
|
|
47
50
|
export function getSupportedOAuthProviders(): OAuthProvider[] {
|
|
48
51
|
return Object.values(OAUTH_PROVIDERS);
|
|
49
|
-
}
|
|
52
|
+
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
// /**
|
|
2
2
|
// * @fileoverview Authentication error classes for @plyaz/auth
|
|
3
3
|
// * @module @plyaz/auth/errors
|
|
4
|
-
// *
|
|
4
|
+
// *
|
|
5
5
|
// * @description
|
|
6
6
|
// * Defines custom error classes for authentication and authorization failures.
|
|
7
7
|
// * These errors provide structured error information for proper error handling
|
|
8
8
|
// * throughout the authentication system. Includes both specific error classes
|
|
9
9
|
// * and legacy compatibility classes.
|
|
10
|
-
// *
|
|
10
|
+
// *
|
|
11
11
|
// * @example
|
|
12
12
|
// * ```typescript
|
|
13
13
|
// * import { InvalidCredentialsError, TokenExpiredError } from '@plyaz/auth';
|
|
14
|
-
// *
|
|
14
|
+
// *
|
|
15
15
|
// * throw new InvalidCredentialsError('Invalid email or password');
|
|
16
16
|
// * throw new TokenExpiredError('Access token has expired');
|
|
17
17
|
// * ```
|
|
@@ -61,4 +61,4 @@
|
|
|
61
61
|
// constructor(message = 'User not found') {
|
|
62
62
|
// super(message, 'USER_NOT_FOUND');
|
|
63
63
|
// }
|
|
64
|
-
// }
|
|
64
|
+
// }
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
// /**
|
|
2
2
|
// * @fileoverview Specific authentication error classes for @plyaz/auth
|
|
3
3
|
// * @module @plyaz/auth/errors/specific-auth-errors
|
|
4
|
-
// *
|
|
4
|
+
// *
|
|
5
5
|
// * @description
|
|
6
6
|
// * Defines specific error classes for different authentication failure scenarios.
|
|
7
7
|
// * Each error class provides structured error information including error codes,
|
|
8
8
|
// * HTTP status codes, and localized messages. Used throughout the auth system
|
|
9
9
|
// * for consistent error handling and user feedback.
|
|
10
|
-
// *
|
|
10
|
+
// *
|
|
11
11
|
// * @example
|
|
12
12
|
// * ```typescript
|
|
13
13
|
// * import { InvalidCredentialsError, TokenExpiredError } from '@plyaz/auth';
|
|
14
|
-
// *
|
|
14
|
+
// *
|
|
15
15
|
// * // Throw specific error
|
|
16
16
|
// * throw new InvalidCredentialsError('Invalid email or password');
|
|
17
|
-
// *
|
|
17
|
+
// *
|
|
18
18
|
// * // Handle specific error
|
|
19
19
|
// * if (error instanceof TokenExpiredError) {
|
|
20
20
|
// * // Refresh token logic
|
|
@@ -24,8 +24,6 @@
|
|
|
24
24
|
|
|
25
25
|
// import { AUTH_ERROR_CODES, ERROR_CODE_TO_HTTP_STATUS } from "@plyaz/types";
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
27
|
// /**
|
|
30
28
|
// * Base authentication error class
|
|
31
29
|
// * Provides common error structure for all auth-related errors
|
|
@@ -49,7 +47,7 @@
|
|
|
49
47
|
// this.code = code;
|
|
50
48
|
// this.statusCode = statusCode;
|
|
51
49
|
// this.context = context;
|
|
52
|
-
|
|
50
|
+
|
|
53
51
|
// // Maintain proper stack trace
|
|
54
52
|
// if (Error.captureStackTrace) {
|
|
55
53
|
// Error.captureStackTrace(this, this.constructor);
|
|
@@ -197,5 +195,3 @@
|
|
|
197
195
|
// );
|
|
198
196
|
// }
|
|
199
197
|
// }
|
|
200
|
-
|
|
201
|
-
|
|
@@ -11,17 +11,19 @@ export const PASSWORD_REGEX = {
|
|
|
11
11
|
HAS_LOWERCASE: /[a-z]/,
|
|
12
12
|
HAS_NUMBER: /\d/,
|
|
13
13
|
HAS_SPECIAL: /[!@#$%^&*(),.?":{}|<>]/,
|
|
14
|
-
STRONG: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*(),.?":{}|<>]).{8,}
|
|
14
|
+
STRONG: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*(),.?":{}|<>]).{8,}$/,
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
export const PHONE_REGEX = /^\+?[1-9]\d{1,14}$/;
|
|
18
18
|
|
|
19
19
|
export const USERNAME_REGEX = /^[a-zA-Z0-9_]{3,20}$/;
|
|
20
20
|
|
|
21
|
-
export const URL_REGEX =
|
|
21
|
+
export const URL_REGEX =
|
|
22
|
+
/^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)$/;
|
|
22
23
|
|
|
23
24
|
export const JWT_REGEX = /^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/;
|
|
24
25
|
|
|
25
|
-
export const UUID_REGEX =
|
|
26
|
+
export const UUID_REGEX =
|
|
27
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
26
28
|
|
|
27
|
-
export const WALLET_ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/;
|
|
29
|
+
export const WALLET_ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Core authentication types and interfaces for @plyaz/auth
|
|
3
3
|
* @module @plyaz/auth/types
|
|
4
|
-
*
|
|
4
|
+
*
|
|
5
5
|
* @description
|
|
6
6
|
* Defines all TypeScript interfaces, enums, and types for the authentication system.
|
|
7
7
|
* Includes B2C (public) and B2B (backoffice) user types, sessions, RBAC, and provider adapters.
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
*/
|
|
19
19
|
export enum USER_ROLE_STATUS {
|
|
20
20
|
/** Role is active and grants permissions */
|
|
21
|
-
ACTIVE =
|
|
21
|
+
ACTIVE = "ACTIVE",
|
|
22
22
|
/** Role is inactive (temporarily disabled) */
|
|
23
|
-
INACTIVE =
|
|
23
|
+
INACTIVE = "INACTIVE",
|
|
24
24
|
/** Role is suspended (user violation) */
|
|
25
|
-
SUSPENDED =
|
|
25
|
+
SUSPENDED = "SUSPENDED",
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
/**
|
|
@@ -31,17 +31,17 @@ export enum USER_ROLE_STATUS {
|
|
|
31
31
|
*/
|
|
32
32
|
export enum AUTHPROVIDER {
|
|
33
33
|
/** Email/password authentication */
|
|
34
|
-
EMAIL =
|
|
34
|
+
EMAIL = "EMAIL",
|
|
35
35
|
/** Clerk authentication */
|
|
36
|
-
CLERK =
|
|
36
|
+
CLERK = "CLERK",
|
|
37
37
|
/** Google OAuth */
|
|
38
|
-
GOOGLE =
|
|
38
|
+
GOOGLE = "GOOGLE",
|
|
39
39
|
/** Facebook OAuth */
|
|
40
|
-
FACEBOOK =
|
|
40
|
+
FACEBOOK = "FACEBOOK",
|
|
41
41
|
/** Apple Sign In */
|
|
42
|
-
APPLE =
|
|
42
|
+
APPLE = "APPLE",
|
|
43
43
|
/** Web3 wallet authentication */
|
|
44
|
-
WEB3 =
|
|
44
|
+
WEB3 = "WEB3",
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
/**
|
|
@@ -50,9 +50,9 @@ export enum AUTHPROVIDER {
|
|
|
50
50
|
*/
|
|
51
51
|
export enum TOKENTYPE {
|
|
52
52
|
/** Bearer token */
|
|
53
|
-
BEARER =
|
|
53
|
+
BEARER = "Bearer",
|
|
54
54
|
/** JSON Web Token */
|
|
55
|
-
JWT =
|
|
55
|
+
JWT = "JWT",
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
// ============================================
|
|
@@ -62,7 +62,7 @@ export enum TOKENTYPE {
|
|
|
62
62
|
/**
|
|
63
63
|
* B2C User (public schema)
|
|
64
64
|
* Represents platform users: fans, athletes, clubs, scouts, agents
|
|
65
|
-
*
|
|
65
|
+
*
|
|
66
66
|
* @interface User
|
|
67
67
|
* @property {string} id - Unique user identifier (UUID)
|
|
68
68
|
* @property {string} email - User email address (unique)
|
|
@@ -102,7 +102,7 @@ export interface User {
|
|
|
102
102
|
/**
|
|
103
103
|
* B2B User (backoffice schema)
|
|
104
104
|
* Represents internal staff: admins, moderators, support, finance, compliance
|
|
105
|
-
*
|
|
105
|
+
*
|
|
106
106
|
* @interface BackofficeUser
|
|
107
107
|
* @property {string} id - Unique user identifier (UUID)
|
|
108
108
|
* @property {string} email - User email address (unique)
|
|
@@ -151,7 +151,7 @@ export interface BackofficeUser {
|
|
|
151
151
|
/**
|
|
152
152
|
* B2C Session (public schema)
|
|
153
153
|
* Tracks authenticated user sessions with device and activity info
|
|
154
|
-
*
|
|
154
|
+
*
|
|
155
155
|
* @interface Session
|
|
156
156
|
*/
|
|
157
157
|
export interface Session {
|
|
@@ -170,7 +170,7 @@ export interface Session {
|
|
|
170
170
|
/**
|
|
171
171
|
* B2B Session (backoffice schema)
|
|
172
172
|
* Tracks authenticated backoffice user sessions
|
|
173
|
-
*
|
|
173
|
+
*
|
|
174
174
|
* @interface BackofficeSession
|
|
175
175
|
*/
|
|
176
176
|
export interface BackofficeSession {
|
|
@@ -194,7 +194,7 @@ export interface BackofficeSession {
|
|
|
194
194
|
* Connected Account (provider linking)
|
|
195
195
|
* Links external OAuth/Web3 provider accounts to users
|
|
196
196
|
* Supports OAuth providers (Clerk, Google, etc.) and Web3 wallets
|
|
197
|
-
*
|
|
197
|
+
*
|
|
198
198
|
* @interface ConnectedAccount
|
|
199
199
|
*/
|
|
200
200
|
export interface ConnectedAccount {
|
|
@@ -233,7 +233,7 @@ export interface ConnectedAccount {
|
|
|
233
233
|
|
|
234
234
|
/**
|
|
235
235
|
* Authentication tokens returned after successful login
|
|
236
|
-
*
|
|
236
|
+
*
|
|
237
237
|
* @interface AuthTokens
|
|
238
238
|
*/
|
|
239
239
|
export interface AuthTokens {
|
|
@@ -248,7 +248,7 @@ export interface AuthTokens {
|
|
|
248
248
|
/**
|
|
249
249
|
* B2C Role (public schema)
|
|
250
250
|
* Defines user roles: FAN, ATHLETE, SCOUT, AGENT, CLUB, DEVELOPER, ADMIN
|
|
251
|
-
*
|
|
251
|
+
*
|
|
252
252
|
* @interface Role
|
|
253
253
|
*/
|
|
254
254
|
export interface Role {
|
|
@@ -270,7 +270,7 @@ export interface Role {
|
|
|
270
270
|
/**
|
|
271
271
|
* B2B Role (backoffice schema)
|
|
272
272
|
* Defines staff roles: SUPER_ADMIN, ADMIN, MODERATOR, FINANCE, COMPLIANCE, SUPPORT
|
|
273
|
-
*
|
|
273
|
+
*
|
|
274
274
|
* @interface BackofficeRole
|
|
275
275
|
*/
|
|
276
276
|
export interface BackofficeRole {
|
|
@@ -295,7 +295,7 @@ export interface BackofficeRole {
|
|
|
295
295
|
/**
|
|
296
296
|
* Permission (backoffice only)
|
|
297
297
|
* Fine-grained permissions for backoffice users
|
|
298
|
-
*
|
|
298
|
+
*
|
|
299
299
|
* @interface Permission
|
|
300
300
|
*/
|
|
301
301
|
export interface Permission {
|
|
@@ -315,7 +315,7 @@ export interface Permission {
|
|
|
315
315
|
/**
|
|
316
316
|
* Role-Permission mapping (backoffice only)
|
|
317
317
|
* Links permissions to roles
|
|
318
|
-
*
|
|
318
|
+
*
|
|
319
319
|
* @interface RolePermission
|
|
320
320
|
*/
|
|
321
321
|
export interface RolePermission {
|
|
@@ -330,7 +330,7 @@ export interface RolePermission {
|
|
|
330
330
|
/**
|
|
331
331
|
* User-Permission mapping (backoffice only)
|
|
332
332
|
* Grants/revokes specific permissions to users
|
|
333
|
-
*
|
|
333
|
+
*
|
|
334
334
|
* @interface UserPermission
|
|
335
335
|
*/
|
|
336
336
|
export interface UserPermission {
|
|
@@ -347,7 +347,7 @@ export interface UserPermission {
|
|
|
347
347
|
/**
|
|
348
348
|
* B2C User-Role assignment
|
|
349
349
|
* Links users to roles with status tracking
|
|
350
|
-
*
|
|
350
|
+
*
|
|
351
351
|
* @interface UserRole
|
|
352
352
|
*/
|
|
353
353
|
export interface UserRole {
|
|
@@ -367,7 +367,7 @@ export interface UserRole {
|
|
|
367
367
|
/**
|
|
368
368
|
* B2B User-Role assignment
|
|
369
369
|
* Links backoffice users to roles
|
|
370
|
-
*
|
|
370
|
+
*
|
|
371
371
|
* @interface BackofficeUserRole
|
|
372
372
|
*/
|
|
373
373
|
export interface BackofficeUserRole {
|
|
@@ -391,7 +391,7 @@ export interface BackofficeUserRole {
|
|
|
391
391
|
/**
|
|
392
392
|
* Authentication provider adapter interface
|
|
393
393
|
* Defines contract for provider-agnostic authentication
|
|
394
|
-
*
|
|
394
|
+
*
|
|
395
395
|
* @interface AuthProviderAdapter
|
|
396
396
|
* @example
|
|
397
397
|
* ```typescript
|
|
@@ -404,20 +404,20 @@ export interface BackofficeUserRole {
|
|
|
404
404
|
*/
|
|
405
405
|
export interface AuthProviderAdapter {
|
|
406
406
|
name: string;
|
|
407
|
-
|
|
407
|
+
|
|
408
408
|
verifyToken(token: string): Promise<VerifiedToken>;
|
|
409
|
-
|
|
409
|
+
|
|
410
410
|
getUserInfo(token: string): Promise<ProviderUserInfo>;
|
|
411
|
-
|
|
411
|
+
|
|
412
412
|
refreshToken?(refreshToken: string): Promise<AuthTokens>;
|
|
413
|
-
|
|
413
|
+
|
|
414
414
|
revokeToken?(token: string): Promise<void>;
|
|
415
415
|
}
|
|
416
416
|
|
|
417
417
|
/**
|
|
418
418
|
* Verified token result
|
|
419
419
|
* Returned after successful token verification
|
|
420
|
-
*
|
|
420
|
+
*
|
|
421
421
|
* @interface VerifiedToken
|
|
422
422
|
*/
|
|
423
423
|
export interface VerifiedToken {
|
|
@@ -432,7 +432,7 @@ export interface VerifiedToken {
|
|
|
432
432
|
/**
|
|
433
433
|
* Provider user information
|
|
434
434
|
* User profile data from external provider
|
|
435
|
-
*
|
|
435
|
+
*
|
|
436
436
|
* @interface ProviderUserInfo
|
|
437
437
|
*/
|
|
438
438
|
export interface ProviderUserInfo {
|
|
@@ -453,13 +453,16 @@ export interface ProviderUserInfo {
|
|
|
453
453
|
/**
|
|
454
454
|
* User repository interface
|
|
455
455
|
* Defines data access methods for user management
|
|
456
|
-
*
|
|
456
|
+
*
|
|
457
457
|
* @interface UserRepository
|
|
458
458
|
*/
|
|
459
459
|
export interface UserRepository {
|
|
460
460
|
findById(id: string): Promise<User | null>;
|
|
461
461
|
findByEmail(email: string): Promise<User | null>;
|
|
462
|
-
findByProviderAccount(
|
|
462
|
+
findByProviderAccount(
|
|
463
|
+
provider: string,
|
|
464
|
+
providerAccountId: string,
|
|
465
|
+
): Promise<User | null>;
|
|
463
466
|
findByCredentials(email: string, passwordHash: string): Promise<User | null>;
|
|
464
467
|
create(data: CreateUserData): Promise<User>;
|
|
465
468
|
update(id: string, data: UpdateUserData): Promise<User>;
|
|
@@ -469,7 +472,7 @@ export interface UserRepository {
|
|
|
469
472
|
/**
|
|
470
473
|
* Session repository interface
|
|
471
474
|
* Defines data access methods for session management
|
|
472
|
-
*
|
|
475
|
+
*
|
|
473
476
|
* @interface SessionRepository
|
|
474
477
|
*/
|
|
475
478
|
export interface SessionRepository {
|
|
@@ -485,15 +488,21 @@ export interface SessionRepository {
|
|
|
485
488
|
/**
|
|
486
489
|
* Connected account repository interface
|
|
487
490
|
* Defines data access methods for provider account linking
|
|
488
|
-
*
|
|
491
|
+
*
|
|
489
492
|
* @interface ConnectedAccountRepository
|
|
490
493
|
*/
|
|
491
494
|
export interface ConnectedAccountRepository {
|
|
492
495
|
create(data: CreateConnectedAccountData): Promise<ConnectedAccount>;
|
|
493
496
|
findById(id: string): Promise<ConnectedAccount | null>;
|
|
494
497
|
findByUserId(userId: string): Promise<ConnectedAccount[]>;
|
|
495
|
-
findByProvider(
|
|
496
|
-
|
|
498
|
+
findByProvider(
|
|
499
|
+
provider: string,
|
|
500
|
+
providerAccountId: string,
|
|
501
|
+
): Promise<ConnectedAccount | null>;
|
|
502
|
+
update(
|
|
503
|
+
id: string,
|
|
504
|
+
data: UpdateConnectedAccountData,
|
|
505
|
+
): Promise<ConnectedAccount>;
|
|
497
506
|
delete(id: string): Promise<void>;
|
|
498
507
|
}
|
|
499
508
|
|
|
@@ -28,12 +28,18 @@ export type DeepPartial<T> = {
|
|
|
28
28
|
/**
|
|
29
29
|
* User account status enumeration
|
|
30
30
|
*/
|
|
31
|
-
export type UserStatus =
|
|
31
|
+
export type UserStatus = "active" | "inactive" | "suspended" | "pending";
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* Available permission actions for RBAC
|
|
35
35
|
*/
|
|
36
|
-
export type PermissionAction =
|
|
36
|
+
export type PermissionAction =
|
|
37
|
+
| "create"
|
|
38
|
+
| "read"
|
|
39
|
+
| "update"
|
|
40
|
+
| "delete"
|
|
41
|
+
| "manage"
|
|
42
|
+
| "*";
|
|
37
43
|
|
|
38
44
|
/**
|
|
39
45
|
* Resource type identifier (e.g., 'users', 'posts', 'campaigns')
|
|
@@ -76,7 +82,7 @@ export interface AuthEvent {
|
|
|
76
82
|
* Generic callback function for authentication events
|
|
77
83
|
* @template T - The data type passed to the callback
|
|
78
84
|
*/
|
|
79
|
-
export type AuthCallback<T
|
|
85
|
+
export type AuthCallback<T> = (data: T) => void | Promise<void>;
|
|
80
86
|
|
|
81
87
|
/**
|
|
82
88
|
* Error callback function type
|
|
@@ -155,7 +161,7 @@ export interface SortParams {
|
|
|
155
161
|
/** Field to sort by */
|
|
156
162
|
field: string;
|
|
157
163
|
/** Sort order */
|
|
158
|
-
order:
|
|
164
|
+
order: "asc" | "desc";
|
|
159
165
|
}
|
|
160
166
|
|
|
161
167
|
/**
|
|
@@ -222,7 +228,7 @@ export interface ValidationRule {
|
|
|
222
228
|
/** Whether the field is required */
|
|
223
229
|
required?: boolean;
|
|
224
230
|
/** Expected data type */
|
|
225
|
-
type?:
|
|
231
|
+
type?: "string" | "number" | "boolean" | "email" | "url";
|
|
226
232
|
/** Minimum length for strings */
|
|
227
233
|
minLength?: number;
|
|
228
234
|
/** Maximum length for strings */
|
|
@@ -294,4 +300,4 @@ export interface PerformanceMetrics {
|
|
|
294
300
|
cpu: number;
|
|
295
301
|
/** Measurement timestamp */
|
|
296
302
|
timestamp: Date;
|
|
297
|
-
}
|
|
303
|
+
}
|
|
@@ -15,8 +15,9 @@ import { NUMERIX } from "@plyaz/config";
|
|
|
15
15
|
* ```
|
|
16
16
|
*/
|
|
17
17
|
export function generateRandomString(length: number = 32): string {
|
|
18
|
-
const chars =
|
|
19
|
-
|
|
18
|
+
const chars =
|
|
19
|
+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
20
|
+
let result = "";
|
|
20
21
|
for (let i = 0; i < length; i++) {
|
|
21
22
|
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
22
23
|
}
|
|
@@ -45,7 +46,7 @@ export function generateSecureId(): string {
|
|
|
45
46
|
* ```
|
|
46
47
|
*/
|
|
47
48
|
export function sleep(ms: number): Promise<void> {
|
|
48
|
-
return new Promise(resolve => globalThis.setTimeout(resolve, ms));
|
|
49
|
+
return new Promise((resolve) => globalThis.setTimeout(resolve, ms));
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
/**
|
|
@@ -61,24 +62,27 @@ export function sleep(ms: number): Promise<void> {
|
|
|
61
62
|
*/
|
|
62
63
|
export function maskSensitiveData(
|
|
63
64
|
data: unknown,
|
|
64
|
-
sensitiveFields: string[] = [
|
|
65
|
+
sensitiveFields: string[] = ["password", "token", "secret"],
|
|
65
66
|
): unknown {
|
|
66
|
-
if (typeof data !==
|
|
67
|
+
if (typeof data !== "object" || data === null) {
|
|
67
68
|
return data;
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
// Type assertion to allow indexing by string
|
|
71
|
-
const masked: Record<string, string> = {
|
|
72
|
-
|
|
72
|
+
const masked: Record<string, string> = {
|
|
73
|
+
...(data as Record<string, string>),
|
|
74
|
+
};
|
|
75
|
+
const four = 4;
|
|
73
76
|
for (const field of sensitiveFields) {
|
|
74
77
|
if (field in masked) {
|
|
75
78
|
const value = masked[field];
|
|
76
|
-
if (typeof value ===
|
|
77
|
-
masked[field] =
|
|
79
|
+
if (typeof value === "string" && value.length > 0) {
|
|
80
|
+
masked[field] =
|
|
81
|
+
value.substring(0, four) +
|
|
82
|
+
"*".repeat(Math.max(0, value.length - four));
|
|
78
83
|
}
|
|
79
84
|
}
|
|
80
85
|
}
|
|
81
|
-
|
|
86
|
+
|
|
82
87
|
return masked;
|
|
83
88
|
}
|
|
84
|
-
|