@xbg.solutions/bpsk-utils-firebase-auth 1.2.3
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/lib/index.d.ts +13 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +20 -0
- package/lib/index.js.map +1 -0
- package/lib/services/auth/auth.service.d.ts +89 -0
- package/lib/services/auth/auth.service.d.ts.map +1 -0
- package/lib/services/auth/auth.service.js +615 -0
- package/lib/services/auth/auth.service.js.map +1 -0
- package/lib/services/auth/email-link.d.ts +99 -0
- package/lib/services/auth/email-link.d.ts.map +1 -0
- package/lib/services/auth/email-link.js +715 -0
- package/lib/services/auth/email-link.js.map +1 -0
- package/lib/services/auth/index.d.ts +15 -0
- package/lib/services/auth/index.d.ts.map +1 -0
- package/lib/services/auth/index.js +18 -0
- package/lib/services/auth/index.js.map +1 -0
- package/lib/services/auth/phone-auth.d.ts +65 -0
- package/lib/services/auth/phone-auth.d.ts.map +1 -0
- package/lib/services/auth/phone-auth.js +150 -0
- package/lib/services/auth/phone-auth.js.map +1 -0
- package/lib/services/auth/user-creation.d.ts +17 -0
- package/lib/services/auth/user-creation.d.ts.map +1 -0
- package/lib/services/auth/user-creation.js +39 -0
- package/lib/services/auth/user-creation.js.map +1 -0
- package/lib/services/token/index.d.ts +29 -0
- package/lib/services/token/index.d.ts.map +1 -0
- package/lib/services/token/index.js +20 -0
- package/lib/services/token/index.js.map +1 -0
- package/lib/services/token/token.service.d.ts +57 -0
- package/lib/services/token/token.service.d.ts.map +1 -0
- package/lib/services/token/token.service.js +554 -0
- package/lib/services/token/token.service.js.map +1 -0
- package/lib/stores/auth.service.d.ts +6 -0
- package/lib/stores/auth.service.d.ts.map +1 -0
- package/lib/stores/auth.service.js +6 -0
- package/lib/stores/auth.service.js.map +1 -0
- package/lib/stores/auth.store.d.ts +56 -0
- package/lib/stores/auth.store.d.ts.map +1 -0
- package/lib/stores/auth.store.js +64 -0
- package/lib/stores/auth.store.js.map +1 -0
- package/lib/stores/token.store.d.ts +41 -0
- package/lib/stores/token.store.d.ts.map +1 -0
- package/lib/stores/token.store.js +36 -0
- package/lib/stores/token.store.js.map +1 -0
- package/lib/stores/user-creation.d.ts +8 -0
- package/lib/stores/user-creation.d.ts.map +1 -0
- package/lib/stores/user-creation.js +11 -0
- package/lib/stores/user-creation.js.map +1 -0
- package/lib/utils/auth-guard.d.ts +58 -0
- package/lib/utils/auth-guard.d.ts.map +1 -0
- package/lib/utils/auth-guard.js +109 -0
- package/lib/utils/auth-guard.js.map +1 -0
- package/lib/utils/signout.d.ts +82 -0
- package/lib/utils/signout.d.ts.map +1 -0
- package/lib/utils/signout.js +168 -0
- package/lib/utils/signout.js.map +1 -0
- package/lib/utils/tokens.d.ts +136 -0
- package/lib/utils/tokens.d.ts.map +1 -0
- package/lib/utils/tokens.js +479 -0
- package/lib/utils/tokens.js.map +1 -0
- package/package.json +31 -0
|
@@ -0,0 +1,615 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/lib/services/auth/auth.service.ts
|
|
3
|
+
* Authentication Service
|
|
4
|
+
*
|
|
5
|
+
* Core service for managing authentication state and operations:
|
|
6
|
+
* - Initializing and managing auth state
|
|
7
|
+
* - Integrating with Firebase Auth
|
|
8
|
+
* - Connecting email link and phone authentication methods
|
|
9
|
+
* - Integrating with token service
|
|
10
|
+
* - Emitting auth-related events
|
|
11
|
+
*/
|
|
12
|
+
import { get } from 'svelte/store';
|
|
13
|
+
import { safeGetCurrentUser, subscribeToAuthChanges, signOutUser } from '@xbg.solutions/bpsk-core';
|
|
14
|
+
import { loggerService } from '@xbg.solutions/bpsk-core';
|
|
15
|
+
import { tokenService } from '../token/token.service';
|
|
16
|
+
import { publish, subscribe } from '@xbg.solutions/bpsk-core';
|
|
17
|
+
import { normalizeError, withErrorHandling } from '@xbg.solutions/bpsk-core';
|
|
18
|
+
import { authStore } from '../../stores/auth.store';
|
|
19
|
+
import { AUTH_EVENTS, AUTH_ROUTES_LEGACY as AUTH_ROUTES } from '@xbg.solutions/bpsk-core';
|
|
20
|
+
import { extractClaims } from '../../utils/tokens';
|
|
21
|
+
import { goto } from '$app/navigation';
|
|
22
|
+
// Import authentication method services
|
|
23
|
+
import emailLinkService from './email-link';
|
|
24
|
+
import phoneAuthService from './phone-auth';
|
|
25
|
+
// Create a context-aware logger
|
|
26
|
+
const authLogger = loggerService.withContext('AuthService');
|
|
27
|
+
/**
|
|
28
|
+
* Creates an auth service instance
|
|
29
|
+
* @returns Auth service instance
|
|
30
|
+
*/
|
|
31
|
+
export function createAuthService() {
|
|
32
|
+
// Auth state change unsubscribe function
|
|
33
|
+
let unsubscribeFromAuthChanges = null;
|
|
34
|
+
// Event subscriptions
|
|
35
|
+
let eventSubscriptions = [];
|
|
36
|
+
/**
|
|
37
|
+
* Initializes the auth service
|
|
38
|
+
* @returns A promise that resolves when initialization is complete
|
|
39
|
+
*/
|
|
40
|
+
const initialize = async () => {
|
|
41
|
+
authLogger.info('Initializing auth service');
|
|
42
|
+
// Initialize store with default state
|
|
43
|
+
authStore.update(state => ({
|
|
44
|
+
...state,
|
|
45
|
+
isInitialized: false,
|
|
46
|
+
isInitializing: true,
|
|
47
|
+
error: null
|
|
48
|
+
}));
|
|
49
|
+
try {
|
|
50
|
+
// Check for an existing user
|
|
51
|
+
const { success, data: currentUser } = await safeGetCurrentUser();
|
|
52
|
+
if (success && currentUser) {
|
|
53
|
+
// Get ID token from Firebase
|
|
54
|
+
const idToken = await currentUser.getIdToken();
|
|
55
|
+
// Process token through token service
|
|
56
|
+
await tokenService.processToken(idToken);
|
|
57
|
+
// Extract claims from token
|
|
58
|
+
const claims = extractClaims(idToken);
|
|
59
|
+
// Try to extract custom attributes from user object directly
|
|
60
|
+
try {
|
|
61
|
+
const userObj = currentUser.toJSON ? currentUser.toJSON() : currentUser;
|
|
62
|
+
// Cast to any to access potential Firebase-specific properties
|
|
63
|
+
// that may not be in the type definition
|
|
64
|
+
const userObjAny = userObj;
|
|
65
|
+
// Check for customAttributes
|
|
66
|
+
if (userObjAny.customAttributes) {
|
|
67
|
+
const customAttrs = typeof userObjAny.customAttributes === 'string'
|
|
68
|
+
? JSON.parse(userObjAny.customAttributes)
|
|
69
|
+
: userObjAny.customAttributes;
|
|
70
|
+
Object.assign(claims, customAttrs);
|
|
71
|
+
authLogger.info('Initial setup: Added custom attributes from user.customAttributes');
|
|
72
|
+
}
|
|
73
|
+
// Check for customClaims
|
|
74
|
+
if (userObjAny.customClaims) {
|
|
75
|
+
const customClaims = typeof userObjAny.customClaims === 'string'
|
|
76
|
+
? JSON.parse(userObjAny.customClaims)
|
|
77
|
+
: userObjAny.customClaims;
|
|
78
|
+
Object.assign(claims, customClaims);
|
|
79
|
+
authLogger.info('Initial setup: Added custom claims from user.customClaims');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch (e) {
|
|
83
|
+
authLogger.warn('Initial setup: Failed to extract additional custom attributes', {
|
|
84
|
+
error: e instanceof Error ? e.message : String(e)
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
// Determine auth method
|
|
88
|
+
const authMethod = determineAuthMethod(currentUser);
|
|
89
|
+
// Update auth store
|
|
90
|
+
authStore.update(state => ({
|
|
91
|
+
...state,
|
|
92
|
+
isAuthenticated: true,
|
|
93
|
+
user: currentUser,
|
|
94
|
+
claims,
|
|
95
|
+
authMethod,
|
|
96
|
+
lastAuthenticated: Date.now()
|
|
97
|
+
}));
|
|
98
|
+
// Emit auth state changed event
|
|
99
|
+
publishAuthStateChange();
|
|
100
|
+
}
|
|
101
|
+
// Subscribe to Firebase auth state changes
|
|
102
|
+
setupAuthStateListener();
|
|
103
|
+
// Subscribe to relevant events
|
|
104
|
+
registerEventListeners();
|
|
105
|
+
// Mark as initialized
|
|
106
|
+
authStore.update(state => ({
|
|
107
|
+
...state,
|
|
108
|
+
isInitialized: true,
|
|
109
|
+
isInitializing: false
|
|
110
|
+
}));
|
|
111
|
+
authLogger.info('Auth service initialized');
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
const normalizedError = normalizeError(error, 'Failed to initialize auth service');
|
|
115
|
+
authLogger.error('Auth service initialization failed', normalizedError);
|
|
116
|
+
// Update store with error
|
|
117
|
+
authStore.update(state => ({
|
|
118
|
+
...state,
|
|
119
|
+
isInitialized: false,
|
|
120
|
+
isInitializing: false,
|
|
121
|
+
error: normalizedError
|
|
122
|
+
}));
|
|
123
|
+
// Re-throw error for upstream handling
|
|
124
|
+
throw normalizedError;
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* Sets up listener for Firebase Auth state changes
|
|
129
|
+
*/
|
|
130
|
+
const setupAuthStateListener = () => {
|
|
131
|
+
// Clear any existing subscription
|
|
132
|
+
if (unsubscribeFromAuthChanges) {
|
|
133
|
+
unsubscribeFromAuthChanges();
|
|
134
|
+
unsubscribeFromAuthChanges = null;
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
// Subscribe to auth state changes - convert to async IIFE
|
|
138
|
+
(async () => {
|
|
139
|
+
const unsubscribe = await subscribeToAuthChanges(async (user) => {
|
|
140
|
+
authLogger.info('Auth state changed', { isAuthenticated: !!user });
|
|
141
|
+
if (user) {
|
|
142
|
+
// User is signed in
|
|
143
|
+
try {
|
|
144
|
+
// Get fresh ID token
|
|
145
|
+
const idToken = await user.getIdToken();
|
|
146
|
+
// Process the token through token service
|
|
147
|
+
await tokenService.processToken(idToken);
|
|
148
|
+
// Extract claims from the token
|
|
149
|
+
const claims = extractClaims(idToken);
|
|
150
|
+
// Attempt to extract custom attributes directly from the user object if available
|
|
151
|
+
try {
|
|
152
|
+
// Check if the user object has custom claims data we can access directly
|
|
153
|
+
const userObj = user.toJSON ? user.toJSON() : user;
|
|
154
|
+
// Cast to any to access potential Firebase-specific properties
|
|
155
|
+
const userObjAny = userObj;
|
|
156
|
+
// Look for customAttributes or customClaims that might be in the user object
|
|
157
|
+
if (userObjAny.customAttributes) {
|
|
158
|
+
const customAttrs = typeof userObjAny.customAttributes === 'string'
|
|
159
|
+
? JSON.parse(userObjAny.customAttributes)
|
|
160
|
+
: userObjAny.customAttributes;
|
|
161
|
+
Object.assign(claims, customAttrs);
|
|
162
|
+
authLogger.info('Added custom attributes from user.customAttributes');
|
|
163
|
+
}
|
|
164
|
+
// Firebase sometimes stores custom claims here too
|
|
165
|
+
if (userObjAny.customClaims) {
|
|
166
|
+
const customClaims = typeof userObjAny.customClaims === 'string'
|
|
167
|
+
? JSON.parse(userObjAny.customClaims)
|
|
168
|
+
: userObjAny.customClaims;
|
|
169
|
+
Object.assign(claims, customClaims);
|
|
170
|
+
authLogger.info('Added custom claims from user.customClaims');
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
catch (e) {
|
|
174
|
+
authLogger.warn('Failed to extract additional custom attributes', {
|
|
175
|
+
error: e instanceof Error ? e.message : String(e)
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
// Determine auth method
|
|
179
|
+
const authMethod = determineAuthMethod(user);
|
|
180
|
+
// Update auth store
|
|
181
|
+
authStore.update(state => ({
|
|
182
|
+
...state,
|
|
183
|
+
isAuthenticated: true,
|
|
184
|
+
user,
|
|
185
|
+
claims,
|
|
186
|
+
authMethod,
|
|
187
|
+
lastAuthenticated: Date.now(),
|
|
188
|
+
isLoading: false,
|
|
189
|
+
error: null
|
|
190
|
+
}));
|
|
191
|
+
// Publish state change event
|
|
192
|
+
publishAuthStateChange();
|
|
193
|
+
// Publish login success event
|
|
194
|
+
publish(AUTH_EVENTS.LOGIN_SUCCESS, {
|
|
195
|
+
user,
|
|
196
|
+
claims,
|
|
197
|
+
method: authMethod
|
|
198
|
+
}, 'AuthService');
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
authLogger.error('Failed to process authentication token', error instanceof Error ? error : new Error(String(error)));
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
// User is signed out
|
|
206
|
+
// Clear token state
|
|
207
|
+
tokenService.clearTokenState();
|
|
208
|
+
// Update auth store
|
|
209
|
+
authStore.update(state => ({
|
|
210
|
+
...state,
|
|
211
|
+
isAuthenticated: false,
|
|
212
|
+
user: null,
|
|
213
|
+
claims: null,
|
|
214
|
+
authMethod: null,
|
|
215
|
+
isLoading: false
|
|
216
|
+
}));
|
|
217
|
+
// Publish state change event
|
|
218
|
+
publishAuthStateChange();
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
// Assign the unsubscribe function to our module variable
|
|
222
|
+
unsubscribeFromAuthChanges = unsubscribe;
|
|
223
|
+
})().catch(error => {
|
|
224
|
+
authLogger.error('Failed to set up auth state listener async initialization', error instanceof Error ? error : new Error(String(error)));
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
authLogger.error('Failed to set up auth state listener', error instanceof Error ? error : new Error(String(error)));
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
/**
|
|
232
|
+
* Registers event listeners for auth-related events
|
|
233
|
+
*/
|
|
234
|
+
const registerEventListeners = () => {
|
|
235
|
+
// Clear any existing subscriptions
|
|
236
|
+
unregisterEventListeners();
|
|
237
|
+
// Subscribe to relevant events
|
|
238
|
+
eventSubscriptions = [
|
|
239
|
+
// Listen for logout events to sign out from Firebase
|
|
240
|
+
subscribe(AUTH_EVENTS.LOGOUT, handleLogoutEvent)
|
|
241
|
+
];
|
|
242
|
+
};
|
|
243
|
+
/**
|
|
244
|
+
* Unregisters all event listeners
|
|
245
|
+
*/
|
|
246
|
+
const unregisterEventListeners = () => {
|
|
247
|
+
// Call all unsubscribe functions
|
|
248
|
+
eventSubscriptions.forEach(unsubscribe => unsubscribe());
|
|
249
|
+
eventSubscriptions = [];
|
|
250
|
+
};
|
|
251
|
+
/**
|
|
252
|
+
* Handles logout events
|
|
253
|
+
*/
|
|
254
|
+
const handleLogoutEvent = async () => {
|
|
255
|
+
await logout();
|
|
256
|
+
};
|
|
257
|
+
/**
|
|
258
|
+
* Determines the authentication method used by a user
|
|
259
|
+
* @param user Firebase user object
|
|
260
|
+
* @returns The authentication method used
|
|
261
|
+
*/
|
|
262
|
+
const determineAuthMethod = (user) => {
|
|
263
|
+
if (!user)
|
|
264
|
+
return null;
|
|
265
|
+
// Check the providerData array to determine the auth method
|
|
266
|
+
const providers = user.providerData || [];
|
|
267
|
+
if (providers.length === 0) {
|
|
268
|
+
// User authenticated with a link without a provider record
|
|
269
|
+
return 'emailLink';
|
|
270
|
+
}
|
|
271
|
+
const provider = providers[0] || {};
|
|
272
|
+
const providerId = provider.providerId;
|
|
273
|
+
if (providerId === 'phone') {
|
|
274
|
+
return 'phoneNumber';
|
|
275
|
+
}
|
|
276
|
+
else if (providerId === 'password' || providerId === 'email') {
|
|
277
|
+
return 'emailLink';
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
// External providers (Google, Facebook, etc.)
|
|
281
|
+
return 'federation';
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
/**
|
|
285
|
+
* Quick little guard to check if the error has a firebaseCode
|
|
286
|
+
*/
|
|
287
|
+
function hasFirebaseCode(error) {
|
|
288
|
+
return error && typeof error.firebaseCode === 'string';
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Publishes auth state change event
|
|
292
|
+
*/
|
|
293
|
+
const publishAuthStateChange = () => {
|
|
294
|
+
const state = get(authStore);
|
|
295
|
+
publish(AUTH_EVENTS.STATE_CHANGED, {
|
|
296
|
+
isAuthenticated: state.isAuthenticated,
|
|
297
|
+
user: state.user,
|
|
298
|
+
claims: state.claims,
|
|
299
|
+
authMethod: state.authMethod
|
|
300
|
+
}, 'AuthService');
|
|
301
|
+
};
|
|
302
|
+
/**
|
|
303
|
+
* Sends an authentication link to an email address
|
|
304
|
+
* @param email Email address to send link to
|
|
305
|
+
* @param options Additional options for email link authentication
|
|
306
|
+
* @returns Promise resolving to authentication result
|
|
307
|
+
*/
|
|
308
|
+
const sendEmailLink = async (email, options = {}) => {
|
|
309
|
+
authStore.update(state => ({ ...state, isLoading: true }));
|
|
310
|
+
try {
|
|
311
|
+
const result = await emailLinkService.sendEmailLink({
|
|
312
|
+
email,
|
|
313
|
+
...options,
|
|
314
|
+
rememberEmail: true
|
|
315
|
+
});
|
|
316
|
+
authStore.update(state => ({ ...state, isLoading: false }));
|
|
317
|
+
return result;
|
|
318
|
+
}
|
|
319
|
+
catch (error) {
|
|
320
|
+
authStore.update(state => ({
|
|
321
|
+
...state,
|
|
322
|
+
isLoading: false,
|
|
323
|
+
error: normalizeError(error, 'Failed to send email link')
|
|
324
|
+
}));
|
|
325
|
+
throw error;
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
/**
|
|
329
|
+
* Verifies an email authentication link
|
|
330
|
+
* @param options Options for email link verification
|
|
331
|
+
* @returns Promise resolving to authentication result
|
|
332
|
+
*/
|
|
333
|
+
const verifyEmailLink = async (options = {}) => {
|
|
334
|
+
authLogger.info('Verifying email link with options', { returnUrl: options.returnUrl });
|
|
335
|
+
authStore.update(state => ({ ...state, isLoading: true }));
|
|
336
|
+
try {
|
|
337
|
+
const result = await emailLinkService.verifyEmailLink(options);
|
|
338
|
+
// Auth state will be updated by Firebase auth state change listener
|
|
339
|
+
authStore.update(state => ({ ...state, isLoading: false }));
|
|
340
|
+
// If already authenticated but got an invalid action code error,
|
|
341
|
+
// it might be a reload after successful verification
|
|
342
|
+
if (!result.success &&
|
|
343
|
+
result.error && hasFirebaseCode(result.error) &&
|
|
344
|
+
result.error.firebaseCode === 'auth/invalid-action-code' &&
|
|
345
|
+
isAuthenticated()) {
|
|
346
|
+
authLogger.info('Link already used but user is authenticated, redirecting');
|
|
347
|
+
// Convert string-based returnUrl to a proper URL object if needed
|
|
348
|
+
let targetRoute = options.returnUrl || AUTH_ROUTES.SUCCESS;
|
|
349
|
+
// If targetRoute starts with protected, replace with protected
|
|
350
|
+
if (targetRoute.startsWith('/protected')) {
|
|
351
|
+
targetRoute = targetRoute.replace('/protected', '/protected');
|
|
352
|
+
}
|
|
353
|
+
// Redirect to the protected area
|
|
354
|
+
setTimeout(() => {
|
|
355
|
+
goto(targetRoute);
|
|
356
|
+
}, 100);
|
|
357
|
+
return {
|
|
358
|
+
success: true,
|
|
359
|
+
method: 'emailLink'
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
// Normal success flow
|
|
363
|
+
if (result.success) {
|
|
364
|
+
// Convert string-based returnUrl to a proper URL object if needed
|
|
365
|
+
let targetRoute = options.returnUrl || AUTH_ROUTES.SUCCESS;
|
|
366
|
+
// If targetRoute starts with protected, replace with protected
|
|
367
|
+
if (targetRoute.startsWith('/protected')) {
|
|
368
|
+
targetRoute = targetRoute.replace('/protected', '/protected');
|
|
369
|
+
}
|
|
370
|
+
authLogger.info('Email link verification successful, redirecting to', { targetRoute });
|
|
371
|
+
// Add a small delay to ensure auth state is fully processed
|
|
372
|
+
setTimeout(() => {
|
|
373
|
+
goto(targetRoute);
|
|
374
|
+
}, 100);
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
authLogger.warn('Email link verification failed', { error: result.error });
|
|
378
|
+
}
|
|
379
|
+
return result;
|
|
380
|
+
}
|
|
381
|
+
catch (error) {
|
|
382
|
+
const normalizedError = normalizeError(error, 'Failed to verify email link');
|
|
383
|
+
authLogger.error('Error verifying email link', normalizedError);
|
|
384
|
+
authStore.update(state => ({
|
|
385
|
+
...state,
|
|
386
|
+
isLoading: false,
|
|
387
|
+
error: normalizedError
|
|
388
|
+
}));
|
|
389
|
+
// Don't redirect to unauthorized page for invalid-action-code errors if user is authenticated
|
|
390
|
+
if (hasFirebaseCode(normalizedError) &&
|
|
391
|
+
normalizedError.firebaseCode === 'auth/invalid-action-code' &&
|
|
392
|
+
isAuthenticated()) {
|
|
393
|
+
// This is likely a page reload after successful verification
|
|
394
|
+
return {
|
|
395
|
+
success: false,
|
|
396
|
+
error: normalizedError,
|
|
397
|
+
method: 'emailLink'
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
// Navigate to unauthorized route on failure
|
|
401
|
+
goto(AUTH_ROUTES.UNAUTHORIZED);
|
|
402
|
+
throw error;
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
/**
|
|
406
|
+
* Sends a verification code to a phone number
|
|
407
|
+
* @param phoneNumber Phone number to send code to
|
|
408
|
+
* @param recaptchaVerifier reCAPTCHA verifier instance
|
|
409
|
+
* @returns Promise resolving to object with verificationId
|
|
410
|
+
*/
|
|
411
|
+
const sendPhoneCode = async (phoneNumber, recaptchaVerifier) => {
|
|
412
|
+
authStore.update(state => ({ ...state, isLoading: true }));
|
|
413
|
+
try {
|
|
414
|
+
const result = await phoneAuthService.sendPhoneCode({
|
|
415
|
+
phoneNumber,
|
|
416
|
+
recaptchaVerifier
|
|
417
|
+
});
|
|
418
|
+
authStore.update(state => ({ ...state, isLoading: false }));
|
|
419
|
+
return result;
|
|
420
|
+
}
|
|
421
|
+
catch (error) {
|
|
422
|
+
authStore.update(state => ({
|
|
423
|
+
...state,
|
|
424
|
+
isLoading: false,
|
|
425
|
+
error: normalizeError(error, 'Failed to send phone verification code')
|
|
426
|
+
}));
|
|
427
|
+
throw error;
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
/**
|
|
431
|
+
* Verifies a phone code and signs in the user
|
|
432
|
+
* @param verificationCode Verification code received by SMS
|
|
433
|
+
* @param verificationId Verification ID received when sending the code
|
|
434
|
+
* @returns Promise resolving to authentication result
|
|
435
|
+
*/
|
|
436
|
+
const verifyPhoneCode = async (verificationCode, verificationId) => {
|
|
437
|
+
authStore.update(state => ({ ...state, isLoading: true }));
|
|
438
|
+
try {
|
|
439
|
+
const result = await phoneAuthService.verifyPhoneCode({
|
|
440
|
+
verificationCode,
|
|
441
|
+
verificationId
|
|
442
|
+
});
|
|
443
|
+
// Auth state will be updated by Firebase auth state change listener
|
|
444
|
+
authStore.update(state => ({ ...state, isLoading: false }));
|
|
445
|
+
// Navigate to success route if verification was successful
|
|
446
|
+
if (result.success) {
|
|
447
|
+
goto(AUTH_ROUTES.SUCCESS);
|
|
448
|
+
}
|
|
449
|
+
return result;
|
|
450
|
+
}
|
|
451
|
+
catch (error) {
|
|
452
|
+
authStore.update(state => ({
|
|
453
|
+
...state,
|
|
454
|
+
isLoading: false,
|
|
455
|
+
error: normalizeError(error, 'Failed to verify phone code')
|
|
456
|
+
}));
|
|
457
|
+
// Navigate to unauthorized route on failure
|
|
458
|
+
goto(AUTH_ROUTES.UNAUTHORIZED);
|
|
459
|
+
throw error;
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
/**
|
|
463
|
+
* Logs out the current user
|
|
464
|
+
* @returns Promise resolving when logout is complete
|
|
465
|
+
*/
|
|
466
|
+
const logout = async () => {
|
|
467
|
+
authStore.update(state => ({ ...state, isLoading: true }));
|
|
468
|
+
try {
|
|
469
|
+
// Clear stored email before Firebase signout
|
|
470
|
+
// This ensures email is cleared even if Firebase signout fails
|
|
471
|
+
try {
|
|
472
|
+
// Using direct import reference instead of dynamic import
|
|
473
|
+
const { clearStoredEmail } = await import('../auth/email-link');
|
|
474
|
+
// Use the consistent clearStoredEmail function that handles all storage types
|
|
475
|
+
const cleared = clearStoredEmail();
|
|
476
|
+
authLogger.info('Cleared stored email during logout', { success: cleared });
|
|
477
|
+
}
|
|
478
|
+
catch (err) {
|
|
479
|
+
authLogger.warn('Failed to clear stored email during logout', err instanceof Error ? err : new Error(String(err)));
|
|
480
|
+
}
|
|
481
|
+
// Publish logout event BEFORE signout
|
|
482
|
+
// This ensures subscribers react before Firebase changes state
|
|
483
|
+
publish(AUTH_EVENTS.LOGOUT, {}, 'AuthService');
|
|
484
|
+
authLogger.info('Published logout event');
|
|
485
|
+
// Sign out from Firebase
|
|
486
|
+
await signOutUser();
|
|
487
|
+
authLogger.info('Firebase signout successful');
|
|
488
|
+
// Update auth store immediately, don't wait for listener
|
|
489
|
+
// This makes the UI respond immediately
|
|
490
|
+
authStore.update(state => ({
|
|
491
|
+
...state,
|
|
492
|
+
isLoading: false,
|
|
493
|
+
isAuthenticated: false,
|
|
494
|
+
user: null,
|
|
495
|
+
claims: null,
|
|
496
|
+
authMethod: null
|
|
497
|
+
}));
|
|
498
|
+
// Navigate to logged out page
|
|
499
|
+
// Use window.location.replace for deterministic navigation
|
|
500
|
+
// with a timestamp parameter to prevent caching
|
|
501
|
+
authLogger.info('Redirecting to logged out page');
|
|
502
|
+
// Force reload to ensure all state is cleared
|
|
503
|
+
window.location.replace(`/?logout=true&ts=${Date.now()}`);
|
|
504
|
+
}
|
|
505
|
+
catch (error) {
|
|
506
|
+
const normalizedError = normalizeError(error, 'Failed to log out');
|
|
507
|
+
authLogger.error('Logout failed', normalizedError);
|
|
508
|
+
authStore.update(state => ({
|
|
509
|
+
...state,
|
|
510
|
+
isLoading: false,
|
|
511
|
+
error: normalizedError
|
|
512
|
+
}));
|
|
513
|
+
// Force navigation even after error - using replace for a full reload
|
|
514
|
+
// Add error parameter to help with debugging
|
|
515
|
+
window.location.replace(`/?logout=true&error=1&ts=${Date.now()}`);
|
|
516
|
+
throw normalizedError;
|
|
517
|
+
}
|
|
518
|
+
};
|
|
519
|
+
/**
|
|
520
|
+
* Checks if a user is authenticated
|
|
521
|
+
* @returns Whether the user is authenticated
|
|
522
|
+
*/
|
|
523
|
+
const isAuthenticated = () => {
|
|
524
|
+
return get(authStore).isAuthenticated;
|
|
525
|
+
};
|
|
526
|
+
/**
|
|
527
|
+
* Gets the current user
|
|
528
|
+
* @returns The current user or null if not authenticated
|
|
529
|
+
*/
|
|
530
|
+
const getCurrentUser = () => {
|
|
531
|
+
return get(authStore).user;
|
|
532
|
+
};
|
|
533
|
+
/**
|
|
534
|
+
* Gets the current user claims
|
|
535
|
+
* @returns The current user claims or null if not authenticated
|
|
536
|
+
*/
|
|
537
|
+
const getUserClaims = () => {
|
|
538
|
+
return get(authStore).claims;
|
|
539
|
+
};
|
|
540
|
+
/**
|
|
541
|
+
* Checks if the current user has a specific role
|
|
542
|
+
* @param role Role to check for
|
|
543
|
+
* @returns Whether the user has the specified role
|
|
544
|
+
*/
|
|
545
|
+
const userHasRole = (role) => {
|
|
546
|
+
const claims = getUserClaims();
|
|
547
|
+
if (!claims || !claims.roles)
|
|
548
|
+
return false;
|
|
549
|
+
return Array.isArray(claims.roles)
|
|
550
|
+
? claims.roles.includes(role)
|
|
551
|
+
: claims.roles === role;
|
|
552
|
+
};
|
|
553
|
+
/**
|
|
554
|
+
* Checks if the current user has any of the specified roles
|
|
555
|
+
* @param roles Roles to check for
|
|
556
|
+
* @returns Whether the user has any of the specified roles
|
|
557
|
+
*/
|
|
558
|
+
const userHasAnyRole = (roles) => {
|
|
559
|
+
return roles.some(role => userHasRole(role));
|
|
560
|
+
};
|
|
561
|
+
/**
|
|
562
|
+
* Destroys the auth service instance
|
|
563
|
+
* This should be called when the application is shutting down
|
|
564
|
+
*/
|
|
565
|
+
const destroy = () => {
|
|
566
|
+
// Unsubscribe from auth changes
|
|
567
|
+
if (unsubscribeFromAuthChanges) {
|
|
568
|
+
unsubscribeFromAuthChanges();
|
|
569
|
+
unsubscribeFromAuthChanges = null;
|
|
570
|
+
}
|
|
571
|
+
// Unregister event listeners
|
|
572
|
+
unregisterEventListeners();
|
|
573
|
+
authLogger.info('Auth service destroyed');
|
|
574
|
+
};
|
|
575
|
+
// Return the public API
|
|
576
|
+
return {
|
|
577
|
+
initialize,
|
|
578
|
+
sendEmailLink,
|
|
579
|
+
verifyEmailLink,
|
|
580
|
+
sendPhoneCode,
|
|
581
|
+
verifyPhoneCode,
|
|
582
|
+
logout,
|
|
583
|
+
isAuthenticated,
|
|
584
|
+
getCurrentUser,
|
|
585
|
+
getUserClaims,
|
|
586
|
+
userHasRole,
|
|
587
|
+
userHasAnyRole,
|
|
588
|
+
destroy
|
|
589
|
+
};
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Create a singleton instance of the auth service
|
|
593
|
+
*/
|
|
594
|
+
export const authService = createAuthService();
|
|
595
|
+
/**
|
|
596
|
+
* Safe version of sending email link with error handling
|
|
597
|
+
*/
|
|
598
|
+
export const safeSendEmailLink = withErrorHandling(async (email, options = {}) => authService.sendEmailLink(email, options));
|
|
599
|
+
/**
|
|
600
|
+
* Safe version of verifying email link with error handling
|
|
601
|
+
*/
|
|
602
|
+
export const safeVerifyEmailLink = withErrorHandling(async (options = {}) => authService.verifyEmailLink(options));
|
|
603
|
+
/**
|
|
604
|
+
* Safe version of sending phone code with error handling
|
|
605
|
+
*/
|
|
606
|
+
export const safeSendPhoneCode = withErrorHandling(async (phoneNumber, recaptchaVerifier) => authService.sendPhoneCode(phoneNumber, recaptchaVerifier));
|
|
607
|
+
/**
|
|
608
|
+
* Safe version of verifying phone code with error handling
|
|
609
|
+
*/
|
|
610
|
+
export const safeVerifyPhoneCode = withErrorHandling(async (verificationCode, verificationId) => authService.verifyPhoneCode(verificationCode, verificationId));
|
|
611
|
+
/**
|
|
612
|
+
* Safe version of logout with error handling
|
|
613
|
+
*/
|
|
614
|
+
export const safeLogout = withErrorHandling(async () => authService.logout());
|
|
615
|
+
//# sourceMappingURL=auth.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.service.js","sourceRoot":"","sources":["../../../src/services/auth/auth.service.ts"],"names":[],"mappings":"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"}
|