@plyaz/auth 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/.github/pull_request_template.md +71 -0
  2. package/.github/workflows/deploy.yml +9 -0
  3. package/.github/workflows/publish.yml +14 -0
  4. package/.github/workflows/security.yml +20 -0
  5. package/README.md +89 -0
  6. package/commits.txt +5 -0
  7. package/dist/common/index.cjs +48 -0
  8. package/dist/common/index.cjs.map +1 -0
  9. package/dist/common/index.mjs +43 -0
  10. package/dist/common/index.mjs.map +1 -0
  11. package/dist/index.cjs +20411 -0
  12. package/dist/index.cjs.map +1 -0
  13. package/dist/index.mjs +5139 -0
  14. package/dist/index.mjs.map +1 -0
  15. package/eslint.config.mjs +13 -0
  16. package/index.html +13 -0
  17. package/package.json +141 -0
  18. package/src/adapters/auth-adapter-factory.ts +26 -0
  19. package/src/adapters/auth-adapter.mapper.ts +53 -0
  20. package/src/adapters/base-auth.adapter.ts +119 -0
  21. package/src/adapters/clerk/clerk.adapter.ts +204 -0
  22. package/src/adapters/custom/custom.adapter.ts +119 -0
  23. package/src/adapters/index.ts +4 -0
  24. package/src/adapters/next-auth/authOptions.ts +81 -0
  25. package/src/adapters/next-auth/next-auth.adapter.ts +211 -0
  26. package/src/api/client.ts +37 -0
  27. package/src/audit/audit.logger.ts +52 -0
  28. package/src/client/components/ProtectedRoute.tsx +37 -0
  29. package/src/client/hooks/useAuth.ts +128 -0
  30. package/src/client/hooks/useConnectedAccounts.ts +108 -0
  31. package/src/client/hooks/usePermissions.ts +36 -0
  32. package/src/client/hooks/useRBAC.ts +36 -0
  33. package/src/client/hooks/useSession.ts +18 -0
  34. package/src/client/providers/AuthProvider.tsx +104 -0
  35. package/src/client/store/auth.store.ts +306 -0
  36. package/src/client/utils/storage.ts +70 -0
  37. package/src/common/constants/oauth-providers.ts +49 -0
  38. package/src/common/errors/auth.errors.ts +64 -0
  39. package/src/common/errors/specific-auth-errors.ts +201 -0
  40. package/src/common/index.ts +19 -0
  41. package/src/common/regex/index.ts +27 -0
  42. package/src/common/types/auth.types.ts +641 -0
  43. package/src/common/types/index.ts +297 -0
  44. package/src/common/utils/index.ts +84 -0
  45. package/src/core/blacklist/token.blacklist.ts +60 -0
  46. package/src/core/index.ts +2 -0
  47. package/src/core/jwt/jwt.manager.ts +131 -0
  48. package/src/core/session/session.manager.ts +56 -0
  49. package/src/db/repositories/connected-account.repository.ts +415 -0
  50. package/src/db/repositories/role.repository.ts +519 -0
  51. package/src/db/repositories/session.repository.ts +308 -0
  52. package/src/db/repositories/user.repository.ts +320 -0
  53. package/src/flows/index.ts +2 -0
  54. package/src/flows/sign-in.flow.ts +106 -0
  55. package/src/flows/sign-up.flow.ts +121 -0
  56. package/src/index.ts +54 -0
  57. package/src/libs/clerk.helper.ts +36 -0
  58. package/src/libs/supabase.helper.ts +255 -0
  59. package/src/libs/supabaseClient.ts +6 -0
  60. package/src/providers/base/auth-provider.interface.ts +42 -0
  61. package/src/providers/base/index.ts +1 -0
  62. package/src/providers/index.ts +2 -0
  63. package/src/providers/oauth/facebook.provider.ts +97 -0
  64. package/src/providers/oauth/github.provider.ts +148 -0
  65. package/src/providers/oauth/google.provider.ts +126 -0
  66. package/src/providers/oauth/index.ts +3 -0
  67. package/src/rbac/dynamic-roles.ts +552 -0
  68. package/src/rbac/index.ts +4 -0
  69. package/src/rbac/permission-checker.ts +464 -0
  70. package/src/rbac/role-hierarchy.ts +545 -0
  71. package/src/rbac/role.manager.ts +75 -0
  72. package/src/security/csrf/csrf.protection.ts +37 -0
  73. package/src/security/index.ts +3 -0
  74. package/src/security/rate-limiting/auth/auth.controller.ts +12 -0
  75. package/src/security/rate-limiting/auth/rate-limiting.interface.ts +67 -0
  76. package/src/security/rate-limiting/auth.module.ts +32 -0
  77. package/src/server/auth.module.ts +158 -0
  78. package/src/server/decorators/auth.decorator.ts +43 -0
  79. package/src/server/decorators/auth.decorators.ts +31 -0
  80. package/src/server/decorators/current-user.decorator.ts +49 -0
  81. package/src/server/decorators/permission.decorator.ts +49 -0
  82. package/src/server/guards/auth.guard.ts +56 -0
  83. package/src/server/guards/custom-throttler.guard.ts +46 -0
  84. package/src/server/guards/permissions.guard.ts +115 -0
  85. package/src/server/guards/roles.guard.ts +31 -0
  86. package/src/server/middleware/auth.middleware.ts +46 -0
  87. package/src/server/middleware/index.ts +2 -0
  88. package/src/server/middleware/middleware.ts +11 -0
  89. package/src/server/middleware/session.middleware.ts +255 -0
  90. package/src/server/services/account.service.ts +269 -0
  91. package/src/server/services/auth.service.ts +79 -0
  92. package/src/server/services/brute-force.service.ts +98 -0
  93. package/src/server/services/index.ts +15 -0
  94. package/src/server/services/rate-limiter.service.ts +60 -0
  95. package/src/server/services/session.service.ts +287 -0
  96. package/src/server/services/token.service.ts +262 -0
  97. package/src/session/cookie-store.ts +255 -0
  98. package/src/session/enhanced-session-manager.ts +406 -0
  99. package/src/session/index.ts +14 -0
  100. package/src/session/memory-store.ts +320 -0
  101. package/src/session/redis-store.ts +443 -0
  102. package/src/strategies/oauth.strategy.ts +128 -0
  103. package/src/strategies/traditional-auth.strategy.ts +116 -0
  104. package/src/tokens/index.ts +4 -0
  105. package/src/tokens/refresh-token-manager.ts +448 -0
  106. package/src/tokens/token-validator.ts +311 -0
  107. package/tsconfig.build.json +28 -0
  108. package/tsconfig.json +38 -0
  109. package/tsup.config.mjs +28 -0
  110. package/vitest.config.mjs +16 -0
  111. package/vitest.setup.d.ts +2 -0
  112. package/vitest.setup.d.ts.map +1 -0
  113. package/vitest.setup.ts +1 -0
@@ -0,0 +1,36 @@
1
+ import { useAuth } from './useAuth';
2
+
3
+ export interface UseRBACReturn {
4
+ hasRole: (role: string) => boolean;
5
+ hasAnyRole: (roles: string[]) => boolean;
6
+ hasAllRoles: (roles: string[]) => boolean;
7
+ userRoles: string[];
8
+ isAdmin: boolean;
9
+ isModerator: boolean;
10
+ }
11
+
12
+ export const useRBAC = (): UseRBACReturn => {
13
+ const { user } = useAuth();
14
+ const userRoles = user?.roles ?? [];
15
+
16
+ const hasRole = (role: string): boolean => {
17
+ return userRoles.includes(role);
18
+ };
19
+
20
+ const hasAnyRole = (roles: string[]): boolean => {
21
+ return roles.some(role => userRoles.includes(role));
22
+ };
23
+
24
+ const hasAllRoles = (roles: string[]): boolean => {
25
+ return roles.every(role => userRoles.includes(role));
26
+ };
27
+
28
+ return {
29
+ hasRole,
30
+ hasAnyRole,
31
+ hasAllRoles,
32
+ userRoles,
33
+ isAdmin: hasRole('ADMIN'),
34
+ isModerator: hasRole('MODERATOR')
35
+ };
36
+ };
@@ -0,0 +1,18 @@
1
+ import type { Session } from "@plyaz/types";
2
+ import { useAuthStore } from "../store/auth.store";
3
+
4
+ export function useSession() : {
5
+ session: Session | null;
6
+ isValid: boolean;
7
+ expiresAt: Date | null;
8
+ refresh: () => Promise<void>;
9
+ } {
10
+ const store = useAuthStore();
11
+
12
+ return {
13
+ session: store.session,
14
+ isValid: !!store.session,
15
+ expiresAt: store.sessionExpiry,
16
+ refresh: store.refreshTokens,
17
+ };
18
+ }
@@ -0,0 +1,104 @@
1
+ import type { ReactNode } from "react";
2
+ import { createContext } from "react";
3
+ import type { UseAuthReturn } from "../hooks/useAuth";
4
+ import { useAuthStore } from "../store/auth.store";
5
+ import type {
6
+ AuthCredentials,
7
+ AUTHPROVIDER,
8
+ ConnectedAccount,
9
+ AuthAdapterUser,
10
+ AuthSession,
11
+ Tokens
12
+ } from "@plyaz/types";
13
+
14
+ /**
15
+ * React context for authentication.
16
+ * Provides user, loading, error states and authentication functions.
17
+ */
18
+ export const AuthContext = createContext<UseAuthReturn | null>(null);
19
+
20
+ /**
21
+ * AuthProvider component that wraps your app.
22
+ * Uses Zustand store for all authentication state and actions.
23
+ *
24
+ * @param children React children components
25
+ */
26
+ export function AuthProvider({ children }: { children: ReactNode }): ReactNode {
27
+ const store = useAuthStore();
28
+
29
+ // Wrap actions in a helper to handle loading and errors
30
+ const handleAuthAction = async <T,>(
31
+ action: () => Promise<T>
32
+ ): Promise<T> => {
33
+ store.setLoading(true);
34
+ store.setError(null);
35
+
36
+ try {
37
+ const result = await action();
38
+ return result;
39
+ } catch (err: unknown) {
40
+ const errorMessage =
41
+ err instanceof Error ? err.message : "Authentication failed";
42
+ store.setError(errorMessage);
43
+ throw err;
44
+ } finally {
45
+ store.setLoading(false);
46
+ }
47
+ };
48
+
49
+ // Create the auth context value
50
+ const authValue = {
51
+ user: store.user,
52
+ isAuthenticated: store.isAuthenticated,
53
+ isLoading: store.isLoading,
54
+ error: store.error,
55
+
56
+ // Auth API actions wrapped with handleAuthAction
57
+ signIn: async (provider?: AUTHPROVIDER, credentials?: AuthCredentials): Promise<{
58
+ user: AuthAdapterUser;
59
+ session: AuthSession;
60
+ tokens: Tokens;
61
+ }> => {
62
+ return handleAuthAction(() => store.signIn(provider, credentials));
63
+ },
64
+
65
+ signUp: async (provider: AUTHPROVIDER, credentials:unknown, data?:unknown) => {
66
+ return handleAuthAction(() => store.signUp(provider, data));
67
+ },
68
+
69
+ signOut: async (): Promise<void> => {
70
+ return handleAuthAction(() => store.signOut());
71
+ },
72
+
73
+ linkAccount: async (userId:string,provider:AUTHPROVIDER,data:ConnectedAccount): Promise<void |ConnectedAccount> => {
74
+ return handleAuthAction(async () => {
75
+ // Create a minimal ConnectedAccount object with only required properties
76
+ const connectedAccount: ConnectedAccount = {
77
+
78
+ ...data,
79
+ userId,
80
+ provider,
81
+ providerType: "",
82
+ providerAccountId: "",
83
+ isPrimary: false,
84
+ isVerified: false,
85
+ isActive: false,
86
+ linkedAt: new Date(),
87
+ createdAt: new Date(),
88
+ updatedAt: new Date()
89
+ };
90
+ store.addConnectedAccount(connectedAccount);
91
+ });
92
+ },
93
+
94
+ unlinkAccount: async (id: string): Promise<void> => {
95
+ return handleAuthAction(async () => store.removeConnectedAccount(id));
96
+ },
97
+ };
98
+
99
+ return (
100
+ <AuthContext.Provider value={authValue}>
101
+ {children}
102
+ </AuthContext.Provider>
103
+ );
104
+ }
@@ -0,0 +1,306 @@
1
+
2
+ import type { AuthAdapterUser, AuthCredentials, AUTHPROVIDER, AuthSession, AuthTokens,AuthUser,ConnectedAccount, Session, Tokens, } from "@plyaz/types";
3
+ import { create } from "zustand";
4
+ import { persist, subscribeWithSelector } from "zustand/middleware";
5
+ import type { AuthPermissions } from "../hooks/useAuth";
6
+
7
+
8
+ interface AuthState {
9
+ // User & Authentication
10
+ user: AuthPermissions | null;
11
+ tokens: AuthTokens | null;
12
+ isAuthenticated: boolean;
13
+ isLoading: boolean;
14
+
15
+ // Session Management
16
+ session: Session | null;
17
+ sessionExpiry: Date | null;
18
+
19
+ // Connected Accounts
20
+ connectedAccounts: ConnectedAccount[];
21
+
22
+ // Permissions & Roles
23
+ permissions: string[];
24
+ roles: string[];
25
+
26
+ // UI State
27
+ lastActivity: Date | null;
28
+ rememberMe: boolean;
29
+
30
+ // Error State
31
+ error: string | null;
32
+ }
33
+
34
+
35
+
36
+ export interface AuthActions {
37
+ // User Management
38
+ setUser: (user: AuthUser | null) => void;
39
+ updateUser: (updates: Partial<AuthUser>) => void;
40
+
41
+ // Token Management
42
+ setTokens: (tokens: AuthTokens | null) => void;
43
+ refreshTokens: () => Promise<void>;
44
+
45
+ // Session Management
46
+ setSession: (session: Session | null) => void;
47
+ updateLastActivity: () => void;
48
+
49
+ // Connected Accounts
50
+ setConnectedAccounts: (accounts: ConnectedAccount[]) => void;
51
+ addConnectedAccount: (account: ConnectedAccount) => void;
52
+ removeConnectedAccount: (accountId: string) => void;
53
+
54
+ // Permissions & Roles
55
+ setPermissions: (permissions: string[]) => void;
56
+ setRoles: (roles: string[]) => void;
57
+ hasPermission: (permission: string) => boolean;
58
+ hasRole: (role: string) => boolean;
59
+
60
+ // Authentication Actions
61
+ signIn: (provider?: AUTHPROVIDER, credentials?: AuthCredentials) => Promise<{
62
+ user: AuthAdapterUser;
63
+ session: AuthSession;
64
+ tokens: Tokens;
65
+ }>;
66
+ signUp: (provider: AUTHPROVIDER, data?: unknown) => Promise<void>;
67
+ signOut: () => Promise<void>;
68
+
69
+ // State Management
70
+ setLoading: (loading: boolean) => void;
71
+ setError: (error: string | null) => void;
72
+ clearError: () => void;
73
+
74
+ // Utility
75
+ reset: () => void;
76
+ }
77
+
78
+ const initialState: AuthState = {
79
+ user: null,
80
+ tokens: null,
81
+ isAuthenticated: false,
82
+ isLoading: true,
83
+ session: null,
84
+ sessionExpiry: null,
85
+ connectedAccounts: [],
86
+ permissions: [],
87
+ roles: [],
88
+ lastActivity: null,
89
+ rememberMe: false,
90
+ error: null,
91
+ };
92
+
93
+ export const useAuthStore = create<AuthState & AuthActions>()(
94
+ subscribeWithSelector(
95
+ persist(
96
+ // eslint-disable-next-line max-lines-per-function
97
+ (set, get) => ({
98
+ ...initialState,
99
+
100
+ // User Management
101
+ setUser: (user) =>
102
+ set({
103
+ user,
104
+ isAuthenticated: !!user,
105
+ error: null,
106
+ }),
107
+
108
+ updateUser: (updates) => {
109
+ const { user } = get();
110
+ if (user) {
111
+ set({ user: { ...user, ...updates } });
112
+ }
113
+ },
114
+
115
+ // Token Management
116
+ setTokens: (tokens) => set({ tokens }),
117
+
118
+ refreshTokens: async () => {
119
+ const { tokens } = get();
120
+ if (!tokens?.refreshToken) return;
121
+
122
+ try {
123
+ const response = await globalThis.fetch("/api/auth/refresh", {
124
+ method: "POST",
125
+ headers: { "Content-Type": "application/json" },
126
+ body: JSON.stringify({ refreshToken: tokens.refreshToken }),
127
+ });
128
+
129
+ if (response.ok) {
130
+ const newTokens = (await response.json()) as AuthTokens;
131
+ set({ tokens: newTokens });
132
+ } else {
133
+ // Refresh failed, sign out
134
+ await get().signOut();
135
+ }
136
+ } catch (error: unknown) {
137
+ globalThis.console.log(error)
138
+ await get().signOut();
139
+ }
140
+ },
141
+
142
+ // Session Management
143
+ setSession: (session) =>
144
+ set({
145
+ session,
146
+ sessionExpiry: session?.expiresAt
147
+ ? new Date(session.expiresAt)
148
+ : null,
149
+ }),
150
+
151
+ updateLastActivity: () => set({ lastActivity: new Date() }),
152
+
153
+ // Connected Accounts
154
+ setConnectedAccounts: (connectedAccounts) => set({ connectedAccounts }),
155
+
156
+ addConnectedAccount: (account) => {
157
+ const { connectedAccounts } = get();
158
+ set({ connectedAccounts: [...connectedAccounts, account] });
159
+ },
160
+
161
+ removeConnectedAccount: (accountId) => {
162
+ const { connectedAccounts } = get();
163
+ set({
164
+ connectedAccounts: connectedAccounts.filter(
165
+ (acc) => acc.id !== accountId
166
+ ),
167
+ });
168
+ },
169
+
170
+ // Permissions & Roles
171
+ setPermissions: (permissions) => set({ permissions }),
172
+ setRoles: (roles) => set({ roles }),
173
+
174
+ hasPermission: (permission) => {
175
+ const { permissions } = get();
176
+ return permissions.includes(permission);
177
+ },
178
+
179
+ hasRole: (role) => {
180
+ const { roles } = get();
181
+ return roles.includes(role);
182
+ },
183
+
184
+ // Authentication Actions
185
+ signUp: async (provider, data?: unknown) => {
186
+ set({ isLoading: true, error: null });
187
+ try {
188
+ const endpoint = provider
189
+ ? `/api/auth/signup/${provider}`
190
+ : "/api/auth/signup";
191
+ const response = await globalThis.fetch(endpoint, {
192
+ method: "POST",
193
+ headers: { "Content-Type": "application/json" },
194
+ body: JSON.stringify(data),
195
+ });
196
+
197
+ if (!response.ok) {
198
+ const errorData = (await response.json()) as { message?: string };
199
+ throw new Error(errorData.message ?? "Sign up failed");
200
+ }
201
+
202
+ const responseData = (await response.json()) as {
203
+ user: AuthUser;
204
+ tokens: AuthTokens;
205
+ session: Session;
206
+ };
207
+ const { user, tokens, session } = responseData;
208
+ set({
209
+ user,
210
+ tokens,
211
+ session,
212
+ isAuthenticated: true,
213
+ lastActivity: new Date(),
214
+ });
215
+ } catch (error: unknown) {
216
+ const errorMessage =
217
+ error instanceof Error ? error.message : "Sign up failed";
218
+ set({ error: errorMessage });
219
+ } finally {
220
+ set({ isLoading: false });
221
+ }
222
+ },
223
+ signIn: async (provider, credentials) => {
224
+ set({ isLoading: true, error: null });
225
+ try {
226
+ const endpoint = provider
227
+ ? `/api/auth/signin/${provider}`
228
+ : "/api/auth/signin";
229
+ const response = await globalThis.fetch(endpoint, {
230
+ method: "POST",
231
+ headers: { "Content-Type": "application/json" },
232
+ body: JSON.stringify(credentials),
233
+ });
234
+
235
+ if (!response.ok) {
236
+ const errorData = (await response.json()) as { message?: string };
237
+ throw new Error(errorData.message ?? "Sign in failed");
238
+ }
239
+
240
+ const data = (await response.json()) as {
241
+ user: AuthUser;
242
+ tokens: AuthTokens;
243
+ session: Session;
244
+ };
245
+ const { user, tokens, session } = data;
246
+
247
+ // Update the store state
248
+ set({
249
+ user,
250
+ tokens,
251
+ session,
252
+ isAuthenticated: true,
253
+ lastActivity: new Date(),
254
+ });
255
+
256
+ // Return the expected object with proper types
257
+ return {
258
+ user: user as AuthAdapterUser, // Cast to match expected type
259
+ session: session as AuthSession, // Cast to match expected type
260
+ tokens: tokens as Tokens, // Cast to match expected type
261
+ };
262
+ } catch (error: unknown) {
263
+ const errorMessage =
264
+ error instanceof Error ? error.message : "Sign in failed";
265
+ set({ error: errorMessage });
266
+ // Re-throw the error to maintain the Promise rejection
267
+ throw error;
268
+ } finally {
269
+ set({ isLoading: false });
270
+ }
271
+ },
272
+
273
+ signOut: async () => {
274
+ set({ isLoading: true });
275
+ try {
276
+ await globalThis.fetch("/api/auth/signout", { method: "POST" });
277
+ set(initialState);
278
+ } catch (error: unknown) {
279
+ const errorMessage =
280
+ error instanceof Error ? error.message : "Sign out failed";
281
+ set({ error: errorMessage });
282
+ } finally {
283
+ set({ isLoading: false });
284
+ }
285
+ },
286
+
287
+ // State Management
288
+ setLoading: (isLoading) => set({ isLoading }),
289
+ setError: (error) => set({ error }),
290
+ clearError: () => set({ error: null }),
291
+
292
+ // Utility
293
+ reset: () => set(initialState),
294
+ }),
295
+ {
296
+ name: "auth-storage",
297
+ partialize: (state) => ({
298
+ user: state.user,
299
+ tokens: state.tokens,
300
+ rememberMe: state.rememberMe,
301
+ connectedAccounts: state.connectedAccounts,
302
+ }),
303
+ }
304
+ )
305
+ )
306
+ );
@@ -0,0 +1,70 @@
1
+ /* eslint-disable @typescript-eslint/explicit-function-return-type */
2
+ /**
3
+ * @fileoverview Storage utility for client-side operations
4
+ * @module @plyaz/auth/client/utils/storage
5
+ */
6
+
7
+ class StorageManager {
8
+ private get storage() {
9
+ return typeof globalThis !== 'undefined' ? (globalThis ).localStorage : null;
10
+ }
11
+
12
+ getItem(key: string): string | null {
13
+ if (!this.storage) return null;
14
+ try {
15
+ return this.storage.getItem(key);
16
+ } catch (error) {
17
+ if (error instanceof DOMException && error.name === 'QuotaExceededError') {
18
+ globalThis.console.warn('localStorage quota exceeded:', error);
19
+ } else if (error instanceof DOMException && error.name === 'SecurityError') {
20
+ globalThis.console.warn('localStorage access denied (private browsing):', error);
21
+ } else {
22
+ globalThis.console.warn('localStorage.getItem failed:', error);
23
+ }
24
+ return null;
25
+ }
26
+ }
27
+
28
+ setItem(key: string, value: string): void {
29
+ if (!this.storage) return;
30
+ try {
31
+ this.storage.setItem(key, value);
32
+ } catch (error) {
33
+ if (error instanceof DOMException && error.name === 'QuotaExceededError') {
34
+ globalThis.console.warn('localStorage quota exceeded, cannot save:', error);
35
+ } else if (error instanceof DOMException && error.name === 'SecurityError') {
36
+ globalThis.console.warn('localStorage access denied (private browsing):', error);
37
+ } else {
38
+ globalThis.console.warn('localStorage.setItem failed:', error);
39
+ }
40
+ }
41
+ }
42
+
43
+ removeItem(key: string): void {
44
+ if (!this.storage) return;
45
+ try {
46
+ this.storage.removeItem(key);
47
+ } catch (error) {
48
+ if (error instanceof DOMException && error.name === 'SecurityError') {
49
+ globalThis.console.warn('localStorage access denied (private browsing):', error);
50
+ } else {
51
+ globalThis.console.warn('localStorage.removeItem failed:', error);
52
+ }
53
+ }
54
+ }
55
+
56
+ clear(): void {
57
+ if (!this.storage) return;
58
+ try {
59
+ this.storage.clear();
60
+ } catch (error) {
61
+ if (error instanceof DOMException && error.name === 'SecurityError') {
62
+ globalThis. console.warn('localStorage access denied (private browsing):', error);
63
+ } else {
64
+ globalThis.console.warn('localStorage.clear failed:', error);
65
+ }
66
+ }
67
+ }
68
+ }
69
+
70
+ export const storage = new StorageManager();
@@ -0,0 +1,49 @@
1
+ // /**
2
+ // * @fileoverview OAuth provider constants for @plyaz/auth
3
+ // * @module @plyaz/auth/constants/oauth-providers
4
+ // *
5
+ // * @description
6
+ // * Defines supported OAuth providers and their configurations.
7
+ // * Used by adapters, strategies, and frontend components to handle
8
+ // * OAuth authentication flows. Provides standardized provider names
9
+ // * and metadata for consistent provider handling.
10
+ // *
11
+ // * @example
12
+ // * ```typescript
13
+ // * import { OAUTH_PROVIDERS, OAuthProviderConfig } from '@plyaz/auth';
14
+ // *
15
+ // * const googleConfig = OAUTH_PROVIDER_CONFIGS[OAUTH_PROVIDERS.GOOGLE];
16
+ // * const authUrl = `${googleConfig.authUrl}?client_id=${clientId}`;
17
+ // * ```
18
+ // */
19
+
20
+ import { OAUTH_PROVIDER_CONFIGS } from "@plyaz/config";
21
+ import type { OAuthProvider, OAuthProviderConfig } from "@plyaz/types";
22
+ import { OAUTH_PROVIDERS } from "@plyaz/types";
23
+
24
+
25
+ /**
26
+ * Get OAuth provider configuration by provider name
27
+ * @param provider - OAuth provider name
28
+ * @returns Provider configuration or null if not found
29
+ */
30
+ export function getOAuthProviderConfig(provider: string): OAuthProviderConfig | null {
31
+ return OAUTH_PROVIDER_CONFIGS[provider as OAuthProvider] || null;
32
+ }
33
+
34
+ /**
35
+ * Check if provider is supported
36
+ * @param provider - Provider name to check
37
+ * @returns True if provider is supported
38
+ */
39
+ export function isOAuthProviderSupported(provider: string): provider is OAuthProvider {
40
+ return Object.values(OAUTH_PROVIDERS).includes(provider as OAuthProvider);
41
+ }
42
+
43
+ /**
44
+ * Get all supported OAuth provider names
45
+ * @returns Array of supported provider names
46
+ */
47
+ export function getSupportedOAuthProviders(): OAuthProvider[] {
48
+ return Object.values(OAUTH_PROVIDERS);
49
+ }
@@ -0,0 +1,64 @@
1
+ // /**
2
+ // * @fileoverview Authentication error classes for @plyaz/auth
3
+ // * @module @plyaz/auth/errors
4
+ // *
5
+ // * @description
6
+ // * Defines custom error classes for authentication and authorization failures.
7
+ // * These errors provide structured error information for proper error handling
8
+ // * throughout the authentication system. Includes both specific error classes
9
+ // * and legacy compatibility classes.
10
+ // *
11
+ // * @example
12
+ // * ```typescript
13
+ // * import { InvalidCredentialsError, TokenExpiredError } from '@plyaz/auth';
14
+ // *
15
+ // * throw new InvalidCredentialsError('Invalid email or password');
16
+ // * throw new TokenExpiredError('Access token has expired');
17
+ // * ```
18
+ // */
19
+
20
+ // // Re-export all specific error classes
21
+
22
+ // // Legacy error classes for backward compatibility
23
+ // export class AuthError extends Error {
24
+ // constructor(message: string, public code: string) {
25
+ // super(message);
26
+ // this.name = 'AuthError';
27
+ // }
28
+ // }
29
+
30
+ // export class AuthenticationError extends AuthError {
31
+ // constructor(message = 'Authentication failed') {
32
+ // super(message, 'AUTH_FAILED');
33
+ // }
34
+ // }
35
+
36
+ // export class AuthorizationError extends AuthError {
37
+ // constructor(message = 'Access denied') {
38
+ // super(message, 'ACCESS_DENIED');
39
+ // }
40
+ // }
41
+
42
+ // export class TokenExpiredError extends AuthError {
43
+ // constructor(message = 'Token has expired') {
44
+ // super(message, 'TOKEN_EXPIRED');
45
+ // }
46
+ // }
47
+
48
+ // export class InvalidTokenError extends AuthError {
49
+ // constructor(message = 'Invalid token') {
50
+ // super(message, 'INVALID_TOKEN');
51
+ // }
52
+ // }
53
+
54
+ // export class SessionNotFoundError extends AuthError {
55
+ // constructor(message = 'Session not found') {
56
+ // super(message, 'SESSION_NOT_FOUND');
57
+ // }
58
+ // }
59
+
60
+ // export class UserNotFoundError extends AuthError {
61
+ // constructor(message = 'User not found') {
62
+ // super(message, 'USER_NOT_FOUND');
63
+ // }
64
+ // }