@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.
Files changed (61) hide show
  1. package/lib/index.d.ts +13 -0
  2. package/lib/index.d.ts.map +1 -0
  3. package/lib/index.js +20 -0
  4. package/lib/index.js.map +1 -0
  5. package/lib/services/auth/auth.service.d.ts +89 -0
  6. package/lib/services/auth/auth.service.d.ts.map +1 -0
  7. package/lib/services/auth/auth.service.js +615 -0
  8. package/lib/services/auth/auth.service.js.map +1 -0
  9. package/lib/services/auth/email-link.d.ts +99 -0
  10. package/lib/services/auth/email-link.d.ts.map +1 -0
  11. package/lib/services/auth/email-link.js +715 -0
  12. package/lib/services/auth/email-link.js.map +1 -0
  13. package/lib/services/auth/index.d.ts +15 -0
  14. package/lib/services/auth/index.d.ts.map +1 -0
  15. package/lib/services/auth/index.js +18 -0
  16. package/lib/services/auth/index.js.map +1 -0
  17. package/lib/services/auth/phone-auth.d.ts +65 -0
  18. package/lib/services/auth/phone-auth.d.ts.map +1 -0
  19. package/lib/services/auth/phone-auth.js +150 -0
  20. package/lib/services/auth/phone-auth.js.map +1 -0
  21. package/lib/services/auth/user-creation.d.ts +17 -0
  22. package/lib/services/auth/user-creation.d.ts.map +1 -0
  23. package/lib/services/auth/user-creation.js +39 -0
  24. package/lib/services/auth/user-creation.js.map +1 -0
  25. package/lib/services/token/index.d.ts +29 -0
  26. package/lib/services/token/index.d.ts.map +1 -0
  27. package/lib/services/token/index.js +20 -0
  28. package/lib/services/token/index.js.map +1 -0
  29. package/lib/services/token/token.service.d.ts +57 -0
  30. package/lib/services/token/token.service.d.ts.map +1 -0
  31. package/lib/services/token/token.service.js +554 -0
  32. package/lib/services/token/token.service.js.map +1 -0
  33. package/lib/stores/auth.service.d.ts +6 -0
  34. package/lib/stores/auth.service.d.ts.map +1 -0
  35. package/lib/stores/auth.service.js +6 -0
  36. package/lib/stores/auth.service.js.map +1 -0
  37. package/lib/stores/auth.store.d.ts +56 -0
  38. package/lib/stores/auth.store.d.ts.map +1 -0
  39. package/lib/stores/auth.store.js +64 -0
  40. package/lib/stores/auth.store.js.map +1 -0
  41. package/lib/stores/token.store.d.ts +41 -0
  42. package/lib/stores/token.store.d.ts.map +1 -0
  43. package/lib/stores/token.store.js +36 -0
  44. package/lib/stores/token.store.js.map +1 -0
  45. package/lib/stores/user-creation.d.ts +8 -0
  46. package/lib/stores/user-creation.d.ts.map +1 -0
  47. package/lib/stores/user-creation.js +11 -0
  48. package/lib/stores/user-creation.js.map +1 -0
  49. package/lib/utils/auth-guard.d.ts +58 -0
  50. package/lib/utils/auth-guard.d.ts.map +1 -0
  51. package/lib/utils/auth-guard.js +109 -0
  52. package/lib/utils/auth-guard.js.map +1 -0
  53. package/lib/utils/signout.d.ts +82 -0
  54. package/lib/utils/signout.d.ts.map +1 -0
  55. package/lib/utils/signout.js +168 -0
  56. package/lib/utils/signout.js.map +1 -0
  57. package/lib/utils/tokens.d.ts +136 -0
  58. package/lib/utils/tokens.d.ts.map +1 -0
  59. package/lib/utils/tokens.js +479 -0
  60. package/lib/utils/tokens.js.map +1 -0
  61. package/package.json +31 -0
@@ -0,0 +1,64 @@
1
+ /**
2
+ * src/lib/stores/auth.store.ts
3
+ * Auth Store
4
+ *
5
+ * A Svelte store for managing authentication state with support for:
6
+ * - User authentication status
7
+ * - Authentication method tracking
8
+ * - Loading states for authentication operations
9
+ * - Error handling for authentication failures
10
+ */
11
+ import { writable, get } from 'svelte/store';
12
+ /**
13
+ * Initial state for the auth store
14
+ */
15
+ const initialState = {
16
+ isInitialized: false,
17
+ isInitializing: false,
18
+ isAuthenticated: false,
19
+ isLoading: false,
20
+ user: null,
21
+ claims: null,
22
+ authMethod: null,
23
+ lastAuthenticated: null,
24
+ error: null
25
+ };
26
+ /**
27
+ * Creates the auth store
28
+ */
29
+ function createAuthStore() {
30
+ const store = writable(initialState);
31
+ // Add helpers to read auth state more safely
32
+ const safeGet = () => {
33
+ try {
34
+ return get(store);
35
+ }
36
+ catch (error) {
37
+ console.error('Error accessing auth store:', error);
38
+ return initialState;
39
+ }
40
+ };
41
+ // Extend store with useful methods
42
+ return {
43
+ ...store,
44
+ safeGet,
45
+ getUser: () => safeGet().user,
46
+ getClaims: () => safeGet().claims,
47
+ isAuthenticated: () => safeGet().isAuthenticated,
48
+ isLoading: () => safeGet().isLoading || safeGet().isInitializing,
49
+ hasRole: (role) => {
50
+ const claims = safeGet().claims;
51
+ if (!claims || !claims.roles)
52
+ return false;
53
+ return Array.isArray(claims.roles)
54
+ ? claims.roles.includes(role)
55
+ : claims.roles === role;
56
+ },
57
+ reset: () => store.set(initialState)
58
+ };
59
+ }
60
+ /**
61
+ * Auth store singleton instance
62
+ */
63
+ export const authStore = createAuthStore();
64
+ //# sourceMappingURL=auth.store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.store.js","sourceRoot":"","sources":["../../src/stores/auth.store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAkC7C;;GAEG;AACH,MAAM,YAAY,GAAc;IAC9B,aAAa,EAAE,KAAK;IACpB,cAAc,EAAE,KAAK;IACrB,eAAe,EAAE,KAAK;IACtB,SAAS,EAAE,KAAK;IAChB,IAAI,EAAE,IAAI;IACV,MAAM,EAAE,IAAI;IACZ,UAAU,EAAE,IAAI;IAChB,iBAAiB,EAAE,IAAI;IACvB,KAAK,EAAE,IAAI;CACZ,CAAC;AAEF;;GAEG;AACH,SAAS,eAAe;IACtB,MAAM,KAAK,GAAG,QAAQ,CAAY,YAAY,CAAC,CAAC;IAEhD,6CAA6C;IAC7C,MAAM,OAAO,GAAG,GAAc,EAAE;QAC9B,IAAI,CAAC;YACH,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;YACpD,OAAO,YAAY,CAAC;QACtB,CAAC;IACH,CAAC,CAAC;IAEF,mCAAmC;IACnC,OAAO;QACL,GAAG,KAAK;QACR,OAAO;QACP,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI;QAC7B,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,MAAM;QACjC,eAAe,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,eAAe;QAChD,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,SAAS,IAAI,OAAO,EAAE,CAAC,cAAc;QAChE,OAAO,EAAE,CAAC,IAAY,EAAE,EAAE;YACxB,MAAM,MAAM,GAAG,OAAO,EAAE,CAAC,MAAM,CAAC;YAChC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK;gBAAE,OAAO,KAAK,CAAC;YAE3C,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;gBAChC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAC7B,CAAC,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC;QAC5B,CAAC;QACD,KAAK,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC;KACrC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,eAAe,EAAE,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * src/lib/stores/token.store.ts
3
+ * Token Store
4
+ *
5
+ * A Svelte store for managing authentication token state with support for:
6
+ * - Token storage and retrieval
7
+ * - Decoded token information
8
+ * - User claims and roles
9
+ * - Authentication state tracking
10
+ */
11
+ import type { DecodedToken, TokenRole } from '@xbg.solutions/bpsk-core';
12
+ import type { FirebaseUserClaims } from '@xbg.solutions/bpsk-core';
13
+ import type { AppError } from '@xbg.solutions/bpsk-core';
14
+ /**
15
+ * Token store state
16
+ */
17
+ export interface TokenState {
18
+ /** Whether the token service is initialized */
19
+ isInitialized: boolean;
20
+ /** Whether the token service is initializing */
21
+ isInitializing: boolean;
22
+ /** The current token */
23
+ token: string | null;
24
+ /** Decoded token information */
25
+ decodedToken: DecodedToken | null;
26
+ /** Extracted user claims */
27
+ claims: FirebaseUserClaims | null;
28
+ /** User roles */
29
+ roles: TokenRole[];
30
+ /** Whether the user is authenticated */
31
+ isAuthenticated: boolean;
32
+ /** Timestamp when the token was last updated */
33
+ lastUpdated: number | null;
34
+ /** Any error that occurred during token operations */
35
+ error: AppError | null;
36
+ }
37
+ /**
38
+ * Token store singleton instance
39
+ */
40
+ export declare const tokenStore: import("svelte/store").Writable<TokenState>;
41
+ //# sourceMappingURL=token.store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.store.d.ts","sourceRoot":"","sources":["../../src/stores/token.store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,+CAA+C;IAC/C,aAAa,EAAE,OAAO,CAAC;IACvB,gDAAgD;IAChD,cAAc,EAAE,OAAO,CAAC;IACxB,wBAAwB;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,gCAAgC;IAChC,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAClC,4BAA4B;IAC5B,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAClC,iBAAiB;IACjB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,wCAAwC;IACxC,eAAe,EAAE,OAAO,CAAC;IACzB,gDAAgD;IAChD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,sDAAsD;IACtD,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;CACxB;AAwBD;;GAEG;AACH,eAAO,MAAM,UAAU,6CAAqB,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * src/lib/stores/token.store.ts
3
+ * Token Store
4
+ *
5
+ * A Svelte store for managing authentication token state with support for:
6
+ * - Token storage and retrieval
7
+ * - Decoded token information
8
+ * - User claims and roles
9
+ * - Authentication state tracking
10
+ */
11
+ import { writable } from 'svelte/store';
12
+ /**
13
+ * Initial state for the token store
14
+ */
15
+ const initialState = {
16
+ isInitialized: false,
17
+ isInitializing: false,
18
+ token: null,
19
+ decodedToken: null,
20
+ claims: null,
21
+ roles: [],
22
+ isAuthenticated: false,
23
+ lastUpdated: null,
24
+ error: null
25
+ };
26
+ /**
27
+ * Creates the token store
28
+ */
29
+ function createTokenStore() {
30
+ return writable(initialState);
31
+ }
32
+ /**
33
+ * Token store singleton instance
34
+ */
35
+ export const tokenStore = createTokenStore();
36
+ //# sourceMappingURL=token.store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.store.js","sourceRoot":"","sources":["../../src/stores/token.store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AA6BxC;;GAEG;AACH,MAAM,YAAY,GAAe;IAC/B,aAAa,EAAE,KAAK;IACpB,cAAc,EAAE,KAAK;IACrB,KAAK,EAAE,IAAI;IACX,YAAY,EAAE,IAAI;IAClB,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,EAAE;IACT,eAAe,EAAE,KAAK;IACtB,WAAW,EAAE,IAAI;IACjB,KAAK,EAAE,IAAI;CACZ,CAAC;AAEF;;GAEG;AACH,SAAS,gBAAgB;IACvB,OAAO,QAAQ,CAAa,YAAY,CAAC,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,gBAAgB,EAAE,CAAC"}
@@ -0,0 +1,8 @@
1
+ export interface UserCreationState {
2
+ isCreating: boolean;
3
+ lastCreated: string | null;
4
+ error: string | null;
5
+ }
6
+ export declare const userCreationStore: import("svelte/store").Writable<UserCreationState>;
7
+ export declare const ensureUserExists: (uid: string) => Promise<boolean>;
8
+ //# sourceMappingURL=user-creation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-creation.d.ts","sourceRoot":"","sources":["../../src/stores/user-creation.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,iBAAiB,oDAI5B,CAAC;AAGH,eAAO,MAAM,gBAAgB,GAAU,KAAK,MAAM,qBAEjD,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { writable } from 'svelte/store';
2
+ export const userCreationStore = writable({
3
+ isCreating: false,
4
+ lastCreated: null,
5
+ error: null
6
+ });
7
+ // Placeholder function that tests expect
8
+ export const ensureUserExists = async (uid) => {
9
+ return true;
10
+ };
11
+ //# sourceMappingURL=user-creation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-creation.js","sourceRoot":"","sources":["../../src/stores/user-creation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAQxC,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAoB;IAC3D,UAAU,EAAE,KAAK;IACjB,WAAW,EAAE,IAAI;IACjB,KAAK,EAAE,IAAI;CACZ,CAAC,CAAC;AAEH,yCAAyC;AACzC,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,GAAW,EAAE,EAAE;IACpD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * src/lib/utils/auth-guard.ts
3
+ * Authentication Guard Utility
4
+ *
5
+ * Provides route protection based on authentication state.
6
+ * Used in +layout.ts and +page.ts files to protect routes,
7
+ * redirecting unauthenticated users as needed.
8
+ */
9
+ /**
10
+ * Options for route guarding
11
+ */
12
+ export type GuardOptions = {
13
+ /** Redirect URL for unauthenticated users */
14
+ redirectTo?: string;
15
+ /** Whether to include the original URL as a return parameter */
16
+ includeReturnUrl?: boolean;
17
+ /** Required roles for access (user must have ALL these roles) */
18
+ requiredRoles?: string[];
19
+ /** Required any roles for access (user must have ANY of these roles) */
20
+ requiredAnyRoles?: string[];
21
+ /** Return parameter name (default: 'returnUrl') */
22
+ returnUrlParam?: string;
23
+ };
24
+ /**
25
+ * Guards a route based on authentication state
26
+ * @param options Guard options
27
+ * @returns An object with status, redirect, and error information
28
+ */
29
+ export declare function guardRoute(options?: GuardOptions): {
30
+ status: string;
31
+ redirect: string;
32
+ error: string;
33
+ } | {
34
+ status: string;
35
+ redirect: null;
36
+ error: null;
37
+ };
38
+ /**
39
+ * Server-side compatible guard for SvelteKit load functions
40
+ *
41
+ * @param event SvelteKit load event with url and cookies
42
+ * @param options Guard options
43
+ * @returns A redirect object or null if authorized
44
+ */
45
+ export declare function guardRouteServer(event: any, options?: GuardOptions): {
46
+ status: number;
47
+ redirect: string;
48
+ } | null;
49
+ /**
50
+ * Redirects to unauthorized page when access is forbidden
51
+ */
52
+ export declare function redirectToUnauthorized(): void;
53
+ /**
54
+ * Redirects to sign in page
55
+ * @param returnUrl Optional URL to return to after sign in
56
+ */
57
+ export declare function redirectToSignIn(returnUrl?: string): void;
58
+ //# sourceMappingURL=auth-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-guard.d.ts","sourceRoot":"","sources":["../../src/utils/auth-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,mDAAmD;IACnD,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,YAAiB;;;;;;;;EA6DpD;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,GAAE,YAAiB;;;SA6BtE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,SAErC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,CAAC,EAAE,MAAM,QAQlD"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * src/lib/utils/auth-guard.ts
3
+ * Authentication Guard Utility
4
+ *
5
+ * Provides route protection based on authentication state.
6
+ * Used in +layout.ts and +page.ts files to protect routes,
7
+ * redirecting unauthenticated users as needed.
8
+ */
9
+ import { goto } from '$app/navigation';
10
+ import { authService } from '../services/auth';
11
+ import { AUTH_ROUTES_LEGACY as AUTH_ROUTES } from '@xbg.solutions/bpsk-core';
12
+ /**
13
+ * Guards a route based on authentication state
14
+ * @param options Guard options
15
+ * @returns An object with status, redirect, and error information
16
+ */
17
+ export function guardRoute(options = {}) {
18
+ const { redirectTo = AUTH_ROUTES.SIGN_IN, includeReturnUrl = true, requiredRoles = [], requiredAnyRoles = [], returnUrlParam = 'returnUrl' } = options;
19
+ // Check if user is authenticated
20
+ const isAuthenticated = authService.isAuthenticated();
21
+ if (!isAuthenticated) {
22
+ // User is not authenticated - redirect to sign in
23
+ let redirectUrl = redirectTo;
24
+ // Add original URL as return parameter if requested
25
+ if (includeReturnUrl) {
26
+ const currentUrl = window.location.pathname + window.location.search;
27
+ redirectUrl += `?${returnUrlParam}=${encodeURIComponent(currentUrl)}`;
28
+ }
29
+ return {
30
+ status: 'unauthenticated',
31
+ redirect: redirectUrl,
32
+ error: 'User is not authenticated'
33
+ };
34
+ }
35
+ // Check for required roles if specified
36
+ if (requiredRoles.length > 0) {
37
+ const hasAllRoles = requiredRoles.every(role => authService.userHasRole(role));
38
+ if (!hasAllRoles) {
39
+ return {
40
+ status: 'unauthorized',
41
+ redirect: AUTH_ROUTES.UNAUTHORIZED,
42
+ error: 'User does not have all required roles'
43
+ };
44
+ }
45
+ }
46
+ // Check for any required roles if specified
47
+ if (requiredAnyRoles.length > 0) {
48
+ const hasAnyRole = authService.userHasAnyRole(requiredAnyRoles);
49
+ if (!hasAnyRole) {
50
+ return {
51
+ status: 'unauthorized',
52
+ redirect: AUTH_ROUTES.UNAUTHORIZED,
53
+ error: 'User does not have any of the required roles'
54
+ };
55
+ }
56
+ }
57
+ // Access is granted
58
+ return {
59
+ status: 'authorized',
60
+ redirect: null,
61
+ error: null
62
+ };
63
+ }
64
+ /**
65
+ * Server-side compatible guard for SvelteKit load functions
66
+ *
67
+ * @param event SvelteKit load event with url and cookies
68
+ * @param options Guard options
69
+ * @returns A redirect object or null if authorized
70
+ */
71
+ export function guardRouteServer(event, options = {}) {
72
+ const { redirectTo = AUTH_ROUTES.SIGN_IN, includeReturnUrl = true, returnUrlParam = 'returnUrl' } = options;
73
+ // For server-side, check for auth cookie existence
74
+ // Note: Full validation should happen in the API middleware
75
+ const hasAuthCookie = event.cookies.get('svelte_boilerplate_auth_idToken') !== undefined;
76
+ if (!hasAuthCookie) {
77
+ // User is not authenticated - redirect to sign in
78
+ let redirectUrl = redirectTo;
79
+ // Add original URL as return parameter if requested
80
+ if (includeReturnUrl) {
81
+ redirectUrl += `?${returnUrlParam}=${encodeURIComponent(event.url.pathname)}`;
82
+ }
83
+ return {
84
+ status: 303,
85
+ redirect: redirectUrl
86
+ };
87
+ }
88
+ // For server-side, we can't fully check roles, but we return authorized
89
+ // The client-side will do a full check once hydrated
90
+ return null;
91
+ }
92
+ /**
93
+ * Redirects to unauthorized page when access is forbidden
94
+ */
95
+ export function redirectToUnauthorized() {
96
+ goto(AUTH_ROUTES.UNAUTHORIZED);
97
+ }
98
+ /**
99
+ * Redirects to sign in page
100
+ * @param returnUrl Optional URL to return to after sign in
101
+ */
102
+ export function redirectToSignIn(returnUrl) {
103
+ let redirectUrl = AUTH_ROUTES.SIGN_IN;
104
+ if (returnUrl) {
105
+ redirectUrl += `?returnUrl=${encodeURIComponent(returnUrl)}`;
106
+ }
107
+ goto(redirectUrl);
108
+ }
109
+ //# sourceMappingURL=auth-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-guard.js","sourceRoot":"","sources":["../../src/utils/auth-guard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * src/lib/utils/signout.ts
3
+ * Signout Utility
4
+ *
5
+ * A utility that handles user signout process, including:
6
+ * - Backend token revocation (when connected to a backend)
7
+ * - Firebase authentication signout
8
+ * - Clean state management during signout
9
+ *
10
+ * IMPORTANT: This utility is designed to be extended when connecting to a backend.
11
+ * The current implementation is for Firebase-only authentication. When connecting
12
+ * to a backend, modify the revokeTokenOnBackend() method to call your backend's
13
+ * token revocation endpoint.
14
+ */
15
+ import { AppError } from '@xbg.solutions/bpsk-core';
16
+ import type { ErrorOptions } from '@xbg.solutions/bpsk-core';
17
+ /**
18
+ * Options for the Signout error
19
+ */
20
+ export type SignoutErrorOptions = ErrorOptions & {
21
+ /** Signout error source */
22
+ source?: 'firebase' | 'backend' | 'token' | 'general';
23
+ /** Original error for context */
24
+ originalError?: Error;
25
+ };
26
+ /**
27
+ * Signout specific error class
28
+ */
29
+ export declare class SignoutError extends AppError {
30
+ /** Source of the signout error */
31
+ source?: string;
32
+ constructor(message: string, options?: SignoutErrorOptions);
33
+ }
34
+ /**
35
+ * Signout options
36
+ */
37
+ export interface SignoutOptions {
38
+ /** Skip backend token revocation */
39
+ skipBackendRevocation?: boolean;
40
+ /** Redirect URL after signout (defaults to sign in route) */
41
+ redirectUrl?: string;
42
+ /** Skip redirection after signout */
43
+ skipRedirect?: boolean;
44
+ /** Force complete signout even if backend revocation fails (defaults to false) */
45
+ forceCompleteSignout?: boolean;
46
+ }
47
+ /**
48
+ * Signs out the current user, optionally revoking their token on the backend first
49
+ *
50
+ * The signout process follows these steps:
51
+ * 1. Revoke the token on the backend (if a backend is connected)
52
+ * 2. Sign out from Firebase authentication
53
+ * 3. Clear local token state
54
+ * 4. Publish logout event
55
+ * 5. Redirect to the sign in page (if not skipped)
56
+ *
57
+ * @param options Signout options
58
+ * @returns Promise that resolves when signout is complete
59
+ * @throws SignoutError if signout fails
60
+ */
61
+ export declare function signout(options?: SignoutOptions): Promise<void>;
62
+ /**
63
+ * Safe version of signout with error handling
64
+ */
65
+ export declare const safeSignout: (options?: SignoutOptions | undefined) => Promise<{
66
+ success: boolean;
67
+ data?: void | undefined;
68
+ error?: AppError;
69
+ }>;
70
+ /**
71
+ * Default export for convenient imports
72
+ */
73
+ declare const _default: {
74
+ signout: typeof signout;
75
+ safeSignout: (options?: SignoutOptions | undefined) => Promise<{
76
+ success: boolean;
77
+ data?: void | undefined;
78
+ error?: AppError;
79
+ }>;
80
+ };
81
+ export default _default;
82
+ //# sourceMappingURL=signout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signout.d.ts","sourceRoot":"","sources":["../../src/utils/signout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAIL,QAAQ,EAMT,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAO7D;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,YAAY,GAAG;IAC/C,2BAA2B;IAC3B,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IACtD,iCAAiC;IACjC,aAAa,CAAC,EAAE,KAAK,CAAC;CACvB,CAAC;AAEF;;GAEG;AACH,qBAAa,YAAa,SAAQ,QAAQ;IACxC,kCAAkC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;gBAEX,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB;CAS/D;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,oCAAoC;IACpC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qCAAqC;IACrC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,kFAAkF;IAClF,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAuCD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmGzE;AAED;;GAEG;AACH,eAAO,MAAM,WAAW;;;;EAA6B,CAAC;AAEtD;;GAEG;;;;;;;;;AACH,wBAGE"}
@@ -0,0 +1,168 @@
1
+ /**
2
+ * src/lib/utils/signout.ts
3
+ * Signout Utility
4
+ *
5
+ * A utility that handles user signout process, including:
6
+ * - Backend token revocation (when connected to a backend)
7
+ * - Firebase authentication signout
8
+ * - Clean state management during signout
9
+ *
10
+ * IMPORTANT: This utility is designed to be extended when connecting to a backend.
11
+ * The current implementation is for Firebase-only authentication. When connecting
12
+ * to a backend, modify the revokeTokenOnBackend() method to call your backend's
13
+ * token revocation endpoint.
14
+ */
15
+ import { signOutUser, processFirebaseError, loggerService, AppError, normalizeError, withErrorHandling, publish, AUTH_EVENTS, AUTH_ROUTES_LEGACY as AUTH_ROUTES } from '@xbg.solutions/bpsk-core';
16
+ import { tokenService } from '../services/token/token.service';
17
+ // Create a logger instance for Signout utility
18
+ const signoutLogger = loggerService.withContext('SignoutUtility');
19
+ /**
20
+ * Signout specific error class
21
+ */
22
+ export class SignoutError extends AppError {
23
+ constructor(message, options = {}) {
24
+ super(message, {
25
+ category: 'auth',
26
+ statusCode: 401,
27
+ ...options
28
+ });
29
+ this.source = options.source;
30
+ }
31
+ }
32
+ /**
33
+ * Revokes the user's token on the backend
34
+ *
35
+ * IMPORTANT: This is a stub implementation that should be replaced when
36
+ * connecting to a real backend. The real implementation should:
37
+ * 1. Get the current authentication token
38
+ * 2. Make an API call to the backend's token revocation endpoint
39
+ * 3. Handle the response appropriately
40
+ *
41
+ * @returns Promise resolving to true if token was successfully revoked
42
+ */
43
+ async function revokeTokenOnBackend() {
44
+ signoutLogger.info('Backend token revocation requested');
45
+ // IMPORTANT: REPLACE THIS IMPLEMENTATION when connecting to a backend
46
+ // The following is a stub that simulates a successful token revocation
47
+ signoutLogger.info('⚠️ Using stub implementation of revokeTokenOnBackend. ' +
48
+ 'Replace this with actual backend call when connecting to a backend service.');
49
+ // Simulate successful token revocation
50
+ // When implementing a real backend connection:
51
+ // 1. Get the current ID token: const token = await tokenService.getToken();
52
+ // 2. Call your backend API: await fetch('/api/auth/revoke', {
53
+ // method: 'POST',
54
+ // headers: { Authorization: `Bearer ${token}` }
55
+ // });
56
+ // 3. Handle the response and return true if successful
57
+ // Artificial delay to simulate network request (remove in real implementation)
58
+ await new Promise(resolve => setTimeout(resolve, 100));
59
+ return true;
60
+ }
61
+ /**
62
+ * Signs out the current user, optionally revoking their token on the backend first
63
+ *
64
+ * The signout process follows these steps:
65
+ * 1. Revoke the token on the backend (if a backend is connected)
66
+ * 2. Sign out from Firebase authentication
67
+ * 3. Clear local token state
68
+ * 4. Publish logout event
69
+ * 5. Redirect to the sign in page (if not skipped)
70
+ *
71
+ * @param options Signout options
72
+ * @returns Promise that resolves when signout is complete
73
+ * @throws SignoutError if signout fails
74
+ */
75
+ export async function signout(options = {}) {
76
+ const startTime = Date.now();
77
+ signoutLogger.info('Starting signout process', { options });
78
+ try {
79
+ // Step 1: Revoke token on backend if not skipped
80
+ if (!options.skipBackendRevocation) {
81
+ try {
82
+ const revoked = await revokeTokenOnBackend();
83
+ if (!revoked && !options.forceCompleteSignout) {
84
+ throw new SignoutError('Failed to revoke token on backend', {
85
+ source: 'backend',
86
+ userMessage: 'Failed to securely sign you out. Please try again.'
87
+ });
88
+ }
89
+ }
90
+ catch (error) {
91
+ // Log the backend revocation error
92
+ signoutLogger.error('Backend token revocation failed', error instanceof Error ? error : new Error(String(error))); // Argument of type 'unknown' is not assignable to parameter of type 'Error | undefined'.
93
+ // If force complete is not enabled, throw to abort the signout
94
+ if (!options.forceCompleteSignout) {
95
+ throw new SignoutError('Backend token revocation failed', {
96
+ source: 'backend',
97
+ originalError: error instanceof Error ? error : undefined,
98
+ userMessage: 'Failed to securely sign you out. Please try again.'
99
+ });
100
+ }
101
+ // If force complete is enabled, log warning and continue
102
+ signoutLogger.warn('Continuing signout despite backend revocation failure (force complete enabled)');
103
+ }
104
+ }
105
+ // Step 2: Sign out from Firebase
106
+ try {
107
+ await signOutUser();
108
+ signoutLogger.info('Firebase signout successful');
109
+ }
110
+ catch (error) {
111
+ // Handle Firebase signout error
112
+ const firebaseError = processFirebaseError(error, 'Firebase signout failed', { action: 'auth/sign-out' });
113
+ signoutLogger.error('Firebase signout failed', firebaseError);
114
+ throw new SignoutError('Firebase signout failed', {
115
+ source: 'firebase',
116
+ originalError: firebaseError,
117
+ userMessage: firebaseError.userMessage || 'Failed to sign you out. Please try again.'
118
+ });
119
+ }
120
+ // Step 3: Clear local token state
121
+ try {
122
+ tokenService.clearTokenState();
123
+ signoutLogger.info('Token state cleared');
124
+ }
125
+ catch (error) {
126
+ // Log token clearing error but continue (non-fatal)
127
+ signoutLogger.warn('Failed to clear token state', error instanceof Error ? error : new Error(String(error))); // Argument of type 'unknown' is not assignable to parameter of type 'Error | undefined'.
128
+ }
129
+ // Step 4: Publish logout event
130
+ publish(AUTH_EVENTS.LOGOUT, {}, 'SignoutUtility');
131
+ // Step 5: Redirect to logged out page (if not skipped)
132
+ if (!options.skipRedirect) {
133
+ const redirectUrl = options.redirectUrl || AUTH_ROUTES.LOGGED_OUT;
134
+ signoutLogger.info('Redirecting after signout', { redirectUrl });
135
+ // Use direct navigation for reliability with replace to force a full page reload
136
+ // Add timestamp parameter to prevent caching and ensure clean state
137
+ const separator = redirectUrl.includes('?') ? '&' : '?';
138
+ window.location.replace(`${redirectUrl}${separator}logout=true&ts=${Date.now()}`);
139
+ }
140
+ const duration = Date.now() - startTime;
141
+ signoutLogger.info(`Signout completed successfully in ${duration}ms`);
142
+ }
143
+ catch (error) {
144
+ const duration = Date.now() - startTime;
145
+ const normalizedError = normalizeError(error, 'Signout failed', {
146
+ category: 'auth',
147
+ userMessage: 'Failed to sign you out completely. Please try again.',
148
+ context: {
149
+ durationMs: duration,
150
+ errorSource: error instanceof SignoutError ? error.source : 'general'
151
+ }
152
+ });
153
+ signoutLogger.error(`Signout failed after ${duration}ms`, normalizedError);
154
+ throw normalizedError;
155
+ }
156
+ }
157
+ /**
158
+ * Safe version of signout with error handling
159
+ */
160
+ export const safeSignout = withErrorHandling(signout);
161
+ /**
162
+ * Default export for convenient imports
163
+ */
164
+ export default {
165
+ signout,
166
+ safeSignout
167
+ };
168
+ //# sourceMappingURL=signout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signout.js","sourceRoot":"","sources":["../../src/utils/signout.ts"],"names":[],"mappings":"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"}