@digilogiclabs/saas-factory-auth 0.4.3 → 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.
- package/README.md +359 -0
- package/dist/index-BeqpJTCy.d.mts +55 -0
- package/dist/index-BeqpJTCy.d.ts +55 -0
- package/dist/index.d.mts +69 -54
- package/dist/index.d.ts +69 -54
- package/dist/index.js +193 -136
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +194 -137
- package/dist/index.mjs.map +1 -1
- package/dist/native/index.d.mts +53 -0
- package/dist/native/index.d.ts +53 -0
- package/dist/native/index.js +948 -0
- package/dist/native/index.js.map +1 -0
- package/dist/native/index.mjs +940 -0
- package/dist/native/index.mjs.map +1 -0
- package/dist/server/index.d.mts +3 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.js +38 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/index.mjs +35 -0
- package/dist/server/index.mjs.map +1 -0
- package/package.json +60 -48
package/README.md
ADDED
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
# @digilogiclabs/saas-factory-auth
|
|
2
|
+
|
|
3
|
+
A universal authentication package supporting both Next.js web applications and React Native mobile apps. Provides a unified API for multiple authentication providers with zero-configuration setup.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🔐 **Multi-Provider Support**
|
|
8
|
+
- Supabase Authentication
|
|
9
|
+
- Firebase Authentication
|
|
10
|
+
- Auto-detection based on environment variables
|
|
11
|
+
- 📱 **Cross-Platform**
|
|
12
|
+
- Next.js 15+ (App Router)
|
|
13
|
+
- React Native with Expo
|
|
14
|
+
- React 19+ compatible
|
|
15
|
+
- 🚀 **Complete Auth Flows**
|
|
16
|
+
- Email/Password authentication
|
|
17
|
+
- OAuth providers (Google, GitHub, Facebook, Twitter, Discord, Apple)
|
|
18
|
+
- Magic link (passwordless) authentication
|
|
19
|
+
- Password reset
|
|
20
|
+
- 🎯 **Modern Architecture**
|
|
21
|
+
- TypeScript-first
|
|
22
|
+
- Zustand state management
|
|
23
|
+
- Provider factory pattern
|
|
24
|
+
- Proper error handling with typed errors
|
|
25
|
+
- 💾 **Session Management**
|
|
26
|
+
- Automatic token refresh
|
|
27
|
+
- Persistent sessions
|
|
28
|
+
- Custom storage adapters
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install @digilogiclabs/saas-factory-auth
|
|
34
|
+
# or
|
|
35
|
+
yarn add @digilogiclabs/saas-factory-auth
|
|
36
|
+
# or
|
|
37
|
+
pnpm add @digilogiclabs/saas-factory-auth
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Requirements
|
|
41
|
+
|
|
42
|
+
- Next.js 15+ or React Native with Expo
|
|
43
|
+
- React 19+
|
|
44
|
+
- Either Supabase or Firebase project credentials
|
|
45
|
+
|
|
46
|
+
## Quick Start
|
|
47
|
+
|
|
48
|
+
### 1. Configure Environment Variables
|
|
49
|
+
|
|
50
|
+
#### For Supabase:
|
|
51
|
+
```env
|
|
52
|
+
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
|
|
53
|
+
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
#### For Firebase:
|
|
57
|
+
```env
|
|
58
|
+
NEXT_PUBLIC_FIREBASE_API_KEY=your-api-key
|
|
59
|
+
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your-auth-domain
|
|
60
|
+
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your-project-id
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
#### Optional - Explicit Provider Selection:
|
|
64
|
+
```env
|
|
65
|
+
NEXT_PUBLIC_AUTH_PROVIDER=supabase # or 'firebase'
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 2. Wrap Your App with AuthProvider
|
|
69
|
+
|
|
70
|
+
#### Next.js App Router:
|
|
71
|
+
```tsx
|
|
72
|
+
// app/layout.tsx
|
|
73
|
+
import { AuthProvider } from '@digilogiclabs/saas-factory-auth';
|
|
74
|
+
|
|
75
|
+
export default function RootLayout({
|
|
76
|
+
children,
|
|
77
|
+
}: {
|
|
78
|
+
children: React.ReactNode;
|
|
79
|
+
}) {
|
|
80
|
+
return (
|
|
81
|
+
<html lang="en">
|
|
82
|
+
<body>
|
|
83
|
+
<AuthProvider>
|
|
84
|
+
{children}
|
|
85
|
+
</AuthProvider>
|
|
86
|
+
</body>
|
|
87
|
+
</html>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
#### React Native:
|
|
93
|
+
```tsx
|
|
94
|
+
// App.tsx
|
|
95
|
+
import { AuthProvider } from '@digilogiclabs/saas-factory-auth';
|
|
96
|
+
|
|
97
|
+
export default function App() {
|
|
98
|
+
return (
|
|
99
|
+
<AuthProvider>
|
|
100
|
+
{/* Your app components */}
|
|
101
|
+
</AuthProvider>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 3. Use the Auth Hook
|
|
107
|
+
|
|
108
|
+
```tsx
|
|
109
|
+
'use client'; // For Next.js App Router
|
|
110
|
+
|
|
111
|
+
import { useAuth } from '@digilogiclabs/saas-factory-auth';
|
|
112
|
+
|
|
113
|
+
export default function AuthExample() {
|
|
114
|
+
const {
|
|
115
|
+
user,
|
|
116
|
+
loading,
|
|
117
|
+
error,
|
|
118
|
+
signIn,
|
|
119
|
+
signUp,
|
|
120
|
+
signOut,
|
|
121
|
+
signInWithOAuth,
|
|
122
|
+
signInWithMagicLink,
|
|
123
|
+
resetPassword
|
|
124
|
+
} = useAuth();
|
|
125
|
+
|
|
126
|
+
if (loading) return <div>Loading...</div>;
|
|
127
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
128
|
+
|
|
129
|
+
if (user) {
|
|
130
|
+
return (
|
|
131
|
+
<div>
|
|
132
|
+
<p>Welcome, {user.email}!</p>
|
|
133
|
+
<button onClick={() => signOut()}>Sign Out</button>
|
|
134
|
+
</div>
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return (
|
|
139
|
+
<div>
|
|
140
|
+
<button onClick={() => signIn('user@example.com', 'password')}>
|
|
141
|
+
Sign In
|
|
142
|
+
</button>
|
|
143
|
+
<button onClick={() => signInWithOAuth('google')}>
|
|
144
|
+
Sign In with Google
|
|
145
|
+
</button>
|
|
146
|
+
</div>
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## API Reference
|
|
152
|
+
|
|
153
|
+
### `<AuthProvider>`
|
|
154
|
+
|
|
155
|
+
The main provider component that initializes authentication.
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
interface AuthProviderProps {
|
|
159
|
+
children: React.ReactNode;
|
|
160
|
+
onAuthChange?: (event: AuthEvent) => void;
|
|
161
|
+
autoSignIn?: boolean; // Default: true
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### `useAuth()` Hook
|
|
166
|
+
|
|
167
|
+
Returns the complete authentication state and methods:
|
|
168
|
+
|
|
169
|
+
```tsx
|
|
170
|
+
interface AuthStore {
|
|
171
|
+
// State
|
|
172
|
+
user: User | null;
|
|
173
|
+
session: AuthSession | null;
|
|
174
|
+
loading: boolean;
|
|
175
|
+
error: Error | null;
|
|
176
|
+
|
|
177
|
+
// Methods
|
|
178
|
+
signIn: (email: string, password: string) => Promise<void>;
|
|
179
|
+
signUp: (email: string, password: string) => Promise<void>;
|
|
180
|
+
signOut: () => Promise<void>;
|
|
181
|
+
signInWithOAuth: (provider: OAuthProvider, redirectTo?: string) => Promise<void>;
|
|
182
|
+
signInWithMagicLink: (email: string, redirectTo?: string) => Promise<void>;
|
|
183
|
+
resetPassword: (email: string) => Promise<void>;
|
|
184
|
+
getUser: () => Promise<User | null>;
|
|
185
|
+
getSession: () => Promise<AuthSession | null>;
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Types
|
|
190
|
+
|
|
191
|
+
```tsx
|
|
192
|
+
// User object
|
|
193
|
+
interface User {
|
|
194
|
+
id: string;
|
|
195
|
+
email?: string;
|
|
196
|
+
name?: string | null;
|
|
197
|
+
avatar?: string | null;
|
|
198
|
+
[key: string]: any; // Additional metadata
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Session object
|
|
202
|
+
interface AuthSession {
|
|
203
|
+
user: User;
|
|
204
|
+
access_token: string;
|
|
205
|
+
refresh_token?: string;
|
|
206
|
+
expires_at?: number;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// OAuth providers
|
|
210
|
+
type OAuthProvider = 'google' | 'github' | 'facebook' | 'twitter' | 'discord' | 'apple';
|
|
211
|
+
|
|
212
|
+
// Auth events
|
|
213
|
+
enum AuthEvent {
|
|
214
|
+
SIGNED_IN = 'SIGNED_IN',
|
|
215
|
+
SIGNED_OUT = 'SIGNED_OUT',
|
|
216
|
+
TOKEN_REFRESHED = 'TOKEN_REFRESHED',
|
|
217
|
+
USER_UPDATED = 'USER_UPDATED',
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Error Handling
|
|
222
|
+
|
|
223
|
+
The package provides typed errors for better error handling:
|
|
224
|
+
|
|
225
|
+
```tsx
|
|
226
|
+
enum AuthErrorType {
|
|
227
|
+
INVALID_CREDENTIALS = 'INVALID_CREDENTIALS',
|
|
228
|
+
USER_NOT_FOUND = 'USER_NOT_FOUND',
|
|
229
|
+
EMAIL_ALREADY_EXISTS = 'EMAIL_ALREADY_EXISTS',
|
|
230
|
+
WEAK_PASSWORD = 'WEAK_PASSWORD',
|
|
231
|
+
NETWORK_ERROR = 'NETWORK_ERROR',
|
|
232
|
+
PROVIDER_ERROR = 'PROVIDER_ERROR',
|
|
233
|
+
CONFIGURATION_ERROR = 'CONFIGURATION_ERROR',
|
|
234
|
+
VALIDATION_ERROR = 'VALIDATION_ERROR'
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Usage
|
|
238
|
+
const { error } = useAuth();
|
|
239
|
+
if (error?.type === AuthErrorType.INVALID_CREDENTIALS) {
|
|
240
|
+
// Handle invalid credentials
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Advanced Usage
|
|
245
|
+
|
|
246
|
+
### Custom Storage (React Native)
|
|
247
|
+
|
|
248
|
+
For React Native, you can provide a custom storage implementation:
|
|
249
|
+
|
|
250
|
+
```tsx
|
|
251
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
252
|
+
import { AuthProvider } from '@digilogiclabs/saas-factory-auth';
|
|
253
|
+
|
|
254
|
+
const customStorage = {
|
|
255
|
+
getItem: async (key: string) => AsyncStorage.getItem(key),
|
|
256
|
+
setItem: async (key: string, value: string) => AsyncStorage.setItem(key, value),
|
|
257
|
+
removeItem: async (key: string) => AsyncStorage.removeItem(key),
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
// Pass to provider factory if using advanced configuration
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Listen to Auth State Changes
|
|
264
|
+
|
|
265
|
+
```tsx
|
|
266
|
+
<AuthProvider
|
|
267
|
+
onAuthChange={(event) => {
|
|
268
|
+
console.log('Auth event:', event);
|
|
269
|
+
// Handle auth state changes
|
|
270
|
+
}}
|
|
271
|
+
>
|
|
272
|
+
{children}
|
|
273
|
+
</AuthProvider>
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Disable Auto Sign-In
|
|
277
|
+
|
|
278
|
+
```tsx
|
|
279
|
+
<AuthProvider autoSignIn={false}>
|
|
280
|
+
{children}
|
|
281
|
+
</AuthProvider>
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## Provider-Specific Features
|
|
285
|
+
|
|
286
|
+
### Supabase-Specific
|
|
287
|
+
- Row Level Security (RLS) support
|
|
288
|
+
- Realtime subscriptions compatibility
|
|
289
|
+
- Built-in email verification flows
|
|
290
|
+
|
|
291
|
+
### Firebase-Specific
|
|
292
|
+
- Firebase Auth UI compatibility
|
|
293
|
+
- Firestore rules integration
|
|
294
|
+
- Firebase Admin SDK support
|
|
295
|
+
|
|
296
|
+
## Migration Guide
|
|
297
|
+
|
|
298
|
+
### From v0.3.x to v0.4.x
|
|
299
|
+
|
|
300
|
+
1. **Update imports**: Components like `SignIn`, `SignUp`, `OAuthButtons` are no longer provided. Use the `useAuth` hook directly.
|
|
301
|
+
|
|
302
|
+
2. **Update AuthProvider usage**: Remove any configuration props, configuration is now handled via environment variables.
|
|
303
|
+
|
|
304
|
+
3. **Update auth method calls**: All methods now return promises and handle errors internally:
|
|
305
|
+
```tsx
|
|
306
|
+
// Old
|
|
307
|
+
const { data, error } = await signIn(email, password);
|
|
308
|
+
|
|
309
|
+
// New
|
|
310
|
+
try {
|
|
311
|
+
await signIn(email, password);
|
|
312
|
+
} catch (error) {
|
|
313
|
+
// Handle error
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
## Troubleshooting
|
|
318
|
+
|
|
319
|
+
### "Auth provider not initialized"
|
|
320
|
+
Ensure you've wrapped your app with `<AuthProvider>` at the root level.
|
|
321
|
+
|
|
322
|
+
### "Invalid Supabase URL"
|
|
323
|
+
Check that your `NEXT_PUBLIC_SUPABASE_URL` includes the full URL with `https://`.
|
|
324
|
+
|
|
325
|
+
### Network/DNS Errors
|
|
326
|
+
Verify your project credentials and ensure the project is not paused (for Supabase).
|
|
327
|
+
|
|
328
|
+
## Contributing
|
|
329
|
+
|
|
330
|
+
We welcome contributions! Please see our [contributing guide](CONTRIBUTING.md) for details.
|
|
331
|
+
|
|
332
|
+
## Support
|
|
333
|
+
|
|
334
|
+
- [GitHub Issues](https://github.com/DigiLogicLabs/saas-factory-auth/issues)
|
|
335
|
+
- [Documentation](https://github.com/DigiLogicLabs/saas-factory-auth/wiki)
|
|
336
|
+
|
|
337
|
+
## License
|
|
338
|
+
|
|
339
|
+
MIT © [DigiLogic Labs](https://github.com/DigiLogicLabs)
|
|
340
|
+
|
|
341
|
+
## Changelog
|
|
342
|
+
|
|
343
|
+
### v0.4.3 (Latest)
|
|
344
|
+
- Fixed React hooks usage in auth callbacks
|
|
345
|
+
- Improved error handling and network error detection
|
|
346
|
+
- Added proper auth provider initialization in store
|
|
347
|
+
- Enhanced TypeScript types
|
|
348
|
+
|
|
349
|
+
### v0.4.0
|
|
350
|
+
- Complete architecture rewrite
|
|
351
|
+
- Added Firebase support alongside Supabase
|
|
352
|
+
- Implemented provider factory pattern
|
|
353
|
+
- Migrated to Zustand for state management
|
|
354
|
+
- React 19 and Next.js 15 compatibility
|
|
355
|
+
|
|
356
|
+
### v0.3.x
|
|
357
|
+
- Initial Supabase-only implementation
|
|
358
|
+
- Basic authentication flows
|
|
359
|
+
- Component-based architecture
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as _supabase_supabase_js from '@supabase/supabase-js';
|
|
2
|
+
import { ReadonlyRequestCookies } from 'next/dist/server/web/spec-extension/adapters/request-cookies';
|
|
3
|
+
|
|
4
|
+
type Database = {
|
|
5
|
+
public: {
|
|
6
|
+
Tables: {
|
|
7
|
+
profiles: {
|
|
8
|
+
Row: {
|
|
9
|
+
id: string;
|
|
10
|
+
updated_at: string;
|
|
11
|
+
username: string;
|
|
12
|
+
full_name: string;
|
|
13
|
+
avatar_url: string;
|
|
14
|
+
website: string;
|
|
15
|
+
};
|
|
16
|
+
Insert: {
|
|
17
|
+
id: string;
|
|
18
|
+
updated_at?: string;
|
|
19
|
+
username: string;
|
|
20
|
+
full_name?: string;
|
|
21
|
+
avatar_url?: string;
|
|
22
|
+
website?: string;
|
|
23
|
+
};
|
|
24
|
+
Update: {
|
|
25
|
+
id?: string;
|
|
26
|
+
updated_at?: string;
|
|
27
|
+
username?: string;
|
|
28
|
+
full_name?: string;
|
|
29
|
+
avatar_url?: string;
|
|
30
|
+
website?: string;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
Views: {
|
|
35
|
+
[_ in never]: never;
|
|
36
|
+
};
|
|
37
|
+
Functions: {
|
|
38
|
+
[_ in never]: never;
|
|
39
|
+
};
|
|
40
|
+
Enums: {
|
|
41
|
+
[_ in never]: never;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
declare const createSupabaseServerClient: (cookieStore: ReadonlyRequestCookies) => _supabase_supabase_js.SupabaseClient<Database, "public", any>;
|
|
47
|
+
declare function handleEmailVerification(token: string): Promise<{
|
|
48
|
+
success: boolean;
|
|
49
|
+
error?: never;
|
|
50
|
+
} | {
|
|
51
|
+
success: boolean;
|
|
52
|
+
error: unknown;
|
|
53
|
+
}>;
|
|
54
|
+
|
|
55
|
+
export { type Database as D, createSupabaseServerClient as c, handleEmailVerification as h };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as _supabase_supabase_js from '@supabase/supabase-js';
|
|
2
|
+
import { ReadonlyRequestCookies } from 'next/dist/server/web/spec-extension/adapters/request-cookies';
|
|
3
|
+
|
|
4
|
+
type Database = {
|
|
5
|
+
public: {
|
|
6
|
+
Tables: {
|
|
7
|
+
profiles: {
|
|
8
|
+
Row: {
|
|
9
|
+
id: string;
|
|
10
|
+
updated_at: string;
|
|
11
|
+
username: string;
|
|
12
|
+
full_name: string;
|
|
13
|
+
avatar_url: string;
|
|
14
|
+
website: string;
|
|
15
|
+
};
|
|
16
|
+
Insert: {
|
|
17
|
+
id: string;
|
|
18
|
+
updated_at?: string;
|
|
19
|
+
username: string;
|
|
20
|
+
full_name?: string;
|
|
21
|
+
avatar_url?: string;
|
|
22
|
+
website?: string;
|
|
23
|
+
};
|
|
24
|
+
Update: {
|
|
25
|
+
id?: string;
|
|
26
|
+
updated_at?: string;
|
|
27
|
+
username?: string;
|
|
28
|
+
full_name?: string;
|
|
29
|
+
avatar_url?: string;
|
|
30
|
+
website?: string;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
Views: {
|
|
35
|
+
[_ in never]: never;
|
|
36
|
+
};
|
|
37
|
+
Functions: {
|
|
38
|
+
[_ in never]: never;
|
|
39
|
+
};
|
|
40
|
+
Enums: {
|
|
41
|
+
[_ in never]: never;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
declare const createSupabaseServerClient: (cookieStore: ReadonlyRequestCookies) => _supabase_supabase_js.SupabaseClient<Database, "public", any>;
|
|
47
|
+
declare function handleEmailVerification(token: string): Promise<{
|
|
48
|
+
success: boolean;
|
|
49
|
+
error?: never;
|
|
50
|
+
} | {
|
|
51
|
+
success: boolean;
|
|
52
|
+
error: unknown;
|
|
53
|
+
}>;
|
|
54
|
+
|
|
55
|
+
export { type Database as D, createSupabaseServerClient as c, handleEmailVerification as h };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,63 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import * as _supabase_supabase_js from '@supabase/supabase-js';
|
|
3
|
+
import { D as Database } from './index-BeqpJTCy.mjs';
|
|
4
|
+
export { c as createSupabaseServerClient } from './index-BeqpJTCy.mjs';
|
|
3
5
|
import { NextRequest, NextResponse } from 'next/server.js';
|
|
4
|
-
import
|
|
6
|
+
import 'next/dist/server/web/spec-extension/adapters/request-cookies';
|
|
5
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Authentication error types for better error handling
|
|
10
|
+
*/
|
|
11
|
+
declare enum AuthErrorType {
|
|
12
|
+
INVALID_CREDENTIALS = "INVALID_CREDENTIALS",
|
|
13
|
+
USER_NOT_FOUND = "USER_NOT_FOUND",
|
|
14
|
+
EMAIL_ALREADY_EXISTS = "EMAIL_ALREADY_EXISTS",
|
|
15
|
+
WEAK_PASSWORD = "WEAK_PASSWORD",
|
|
16
|
+
NETWORK_ERROR = "NETWORK_ERROR",
|
|
17
|
+
PROVIDER_ERROR = "PROVIDER_ERROR",
|
|
18
|
+
CONFIGURATION_ERROR = "CONFIGURATION_ERROR",
|
|
19
|
+
VALIDATION_ERROR = "VALIDATION_ERROR",
|
|
20
|
+
UNKNOWN = "UNKNOWN"
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Custom authentication error class
|
|
24
|
+
*/
|
|
25
|
+
declare class AuthError extends Error {
|
|
26
|
+
readonly type: AuthErrorType;
|
|
27
|
+
readonly originalError?: unknown | undefined;
|
|
28
|
+
readonly context?: Record<string, unknown> | undefined;
|
|
29
|
+
readonly timestamp: Date;
|
|
30
|
+
readonly code: string;
|
|
31
|
+
constructor(type: AuthErrorType, message: string, originalError?: unknown | undefined, context?: Record<string, unknown> | undefined);
|
|
32
|
+
/**
|
|
33
|
+
* Convert error to JSON for logging/debugging
|
|
34
|
+
*/
|
|
35
|
+
toJSON(): {
|
|
36
|
+
name: string;
|
|
37
|
+
type: AuthErrorType;
|
|
38
|
+
code: string;
|
|
39
|
+
message: string;
|
|
40
|
+
timestamp: string;
|
|
41
|
+
context: Record<string, unknown> | undefined;
|
|
42
|
+
originalError: {
|
|
43
|
+
name: string;
|
|
44
|
+
message: string;
|
|
45
|
+
stack: string | undefined;
|
|
46
|
+
} | {
|
|
47
|
+
message: string;
|
|
48
|
+
name?: never;
|
|
49
|
+
stack?: never;
|
|
50
|
+
} | undefined;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Check if error is of a specific type
|
|
54
|
+
*/
|
|
55
|
+
isType(type: AuthErrorType): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Check if error is retryable
|
|
58
|
+
*/
|
|
59
|
+
isRetryable(): boolean;
|
|
60
|
+
}
|
|
6
61
|
/**
|
|
7
62
|
* OAuth provider types - re-export from types for backward compatibility
|
|
8
63
|
*/
|
|
@@ -21,7 +76,7 @@ interface IAuthProvider {
|
|
|
21
76
|
signIn(email: string, password: string): Promise<{
|
|
22
77
|
user: User | null;
|
|
23
78
|
session: AuthSession | null;
|
|
24
|
-
error:
|
|
79
|
+
error: AuthError | null;
|
|
25
80
|
}>;
|
|
26
81
|
/**
|
|
27
82
|
* Sign up with email and password
|
|
@@ -32,7 +87,7 @@ interface IAuthProvider {
|
|
|
32
87
|
signUp(email: string, password: string): Promise<{
|
|
33
88
|
user: User | null;
|
|
34
89
|
session: AuthSession | null;
|
|
35
|
-
error:
|
|
90
|
+
error: AuthError | null;
|
|
36
91
|
}>;
|
|
37
92
|
/**
|
|
38
93
|
* Sign in with OAuth provider
|
|
@@ -53,7 +108,7 @@ interface IAuthProvider {
|
|
|
53
108
|
* @returns Promise resolving to an object containing error
|
|
54
109
|
*/
|
|
55
110
|
signOut(): Promise<{
|
|
56
|
-
error:
|
|
111
|
+
error: AuthError | null;
|
|
57
112
|
}>;
|
|
58
113
|
/**
|
|
59
114
|
* Get the current authenticated user
|
|
@@ -71,14 +126,16 @@ interface IAuthProvider {
|
|
|
71
126
|
* @returns Promise resolving to an object containing error
|
|
72
127
|
*/
|
|
73
128
|
resetPassword(email: string): Promise<{
|
|
74
|
-
error:
|
|
129
|
+
error: AuthError | null;
|
|
75
130
|
}>;
|
|
76
131
|
/**
|
|
77
132
|
* Listen for authentication state changes
|
|
78
133
|
* @param callback Function called when auth state changes
|
|
79
134
|
* @returns Object containing subscription data for cleanup
|
|
80
135
|
*/
|
|
81
|
-
onAuthStateChange(callback: (event: AuthEvent, session: AuthSession | null) => void):
|
|
136
|
+
onAuthStateChange(callback: (event: AuthEvent, session: AuthSession | null) => void): {
|
|
137
|
+
unsubscribe: () => void;
|
|
138
|
+
};
|
|
82
139
|
/**
|
|
83
140
|
* Validate provider configuration
|
|
84
141
|
* @returns Promise that resolves if configuration is valid
|
|
@@ -95,7 +152,7 @@ interface User {
|
|
|
95
152
|
name?: string | null;
|
|
96
153
|
avatar?: string | null;
|
|
97
154
|
roles?: UserRole[];
|
|
98
|
-
[key: string]:
|
|
155
|
+
[key: string]: unknown;
|
|
99
156
|
}
|
|
100
157
|
/**
|
|
101
158
|
* Authentication session containing user and token information
|
|
@@ -188,7 +245,9 @@ interface AuthStore {
|
|
|
188
245
|
signInWithMagicLink: (email: string, redirectTo?: string) => Promise<void>;
|
|
189
246
|
getUser: () => Promise<User | null>;
|
|
190
247
|
getSession: () => Promise<AuthSession | null>;
|
|
191
|
-
onAuthStateChange: (callback: (event: AuthEvent, session: AuthSession | null) => void) =>
|
|
248
|
+
onAuthStateChange: (callback: (event: AuthEvent, session: AuthSession | null) => void) => {
|
|
249
|
+
unsubscribe: () => void;
|
|
250
|
+
};
|
|
192
251
|
}
|
|
193
252
|
|
|
194
253
|
interface AuthProviderProps {
|
|
@@ -293,55 +352,11 @@ declare class AuthProviderFactory {
|
|
|
293
352
|
static getInstances(): Map<AuthProviderType, IAuthProvider>;
|
|
294
353
|
}
|
|
295
354
|
|
|
296
|
-
|
|
297
|
-
public: {
|
|
298
|
-
Tables: {
|
|
299
|
-
profiles: {
|
|
300
|
-
Row: {
|
|
301
|
-
id: string;
|
|
302
|
-
updated_at: string;
|
|
303
|
-
username: string;
|
|
304
|
-
full_name: string;
|
|
305
|
-
avatar_url: string;
|
|
306
|
-
website: string;
|
|
307
|
-
};
|
|
308
|
-
Insert: {
|
|
309
|
-
id: string;
|
|
310
|
-
updated_at?: string;
|
|
311
|
-
username: string;
|
|
312
|
-
full_name?: string;
|
|
313
|
-
avatar_url?: string;
|
|
314
|
-
website?: string;
|
|
315
|
-
};
|
|
316
|
-
Update: {
|
|
317
|
-
id?: string;
|
|
318
|
-
updated_at?: string;
|
|
319
|
-
username?: string;
|
|
320
|
-
full_name?: string;
|
|
321
|
-
avatar_url?: string;
|
|
322
|
-
website?: string;
|
|
323
|
-
};
|
|
324
|
-
};
|
|
325
|
-
};
|
|
326
|
-
Views: {
|
|
327
|
-
[_ in never]: never;
|
|
328
|
-
};
|
|
329
|
-
Functions: {
|
|
330
|
-
[_ in never]: never;
|
|
331
|
-
};
|
|
332
|
-
Enums: {
|
|
333
|
-
[_ in never]: never;
|
|
334
|
-
};
|
|
335
|
-
};
|
|
336
|
-
};
|
|
337
|
-
|
|
338
|
-
declare const getSupabaseClient: () => _supabase_supabase_js.SupabaseClient<Database, "public", any>;
|
|
355
|
+
declare const createClient: () => _supabase_supabase_js.SupabaseClient<Database, "public", any>;
|
|
339
356
|
|
|
340
357
|
declare function withAuth(request: NextRequest): {
|
|
341
358
|
response: NextResponse<unknown>;
|
|
342
359
|
supabase: _supabase_supabase_js.SupabaseClient<any, "public", any>;
|
|
343
360
|
};
|
|
344
361
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
export { type AuthConfig, AuthEvent, type AuthFormProps, type AuthMode, AuthProvider, AuthProviderFactory, type AuthSession, type AuthStore, type OAuthProvider, type PasswordConfig, type User, type UserRole, createSupabaseServerClient, getSupabaseClient, useAuth, withAuth };
|
|
362
|
+
export { type AuthConfig, AuthEvent, type AuthFormProps, type AuthMode, AuthProvider, AuthProviderFactory, type AuthSession, type AuthStore, type OAuthProvider, type PasswordConfig, type User, type UserRole, createClient as createSupabaseClient, useAuth, withAuth };
|