@sudobility/auth_lib 0.0.1
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/dist/config/firebase-init.d.ts +40 -0
- package/dist/config/firebase-init.d.ts.map +1 -0
- package/dist/config/firebase-init.js +75 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +4 -0
- package/dist/config/types.d.ts +41 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +4 -0
- package/dist/hooks/index.d.ts +5 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +4 -0
- package/dist/hooks/useFirebaseAuthNetworkClient.d.ts +16 -0
- package/dist/hooks/useFirebaseAuthNetworkClient.d.ts.map +1 -0
- package/dist/hooks/useFirebaseAuthNetworkClient.js +162 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/utils/firebase-errors.d.ts +32 -0
- package/dist/utils/firebase-errors.d.ts.map +1 -0
- package/dist/utils/firebase-errors.js +59 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/package.json +56 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Configurable Firebase initialization
|
|
3
|
+
*/
|
|
4
|
+
import { type FirebaseApp } from 'firebase/app';
|
|
5
|
+
import { type Auth } from 'firebase/auth';
|
|
6
|
+
import type { FirebaseConfig, FirebaseInitOptions, FirebaseInitResult } from './types';
|
|
7
|
+
/**
|
|
8
|
+
* Check if Firebase is configured with the required fields
|
|
9
|
+
*/
|
|
10
|
+
export declare function isFirebaseConfigured(): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Initialize Firebase Auth with the provided configuration.
|
|
13
|
+
* This should be called once at app startup (e.g., in main.tsx).
|
|
14
|
+
*
|
|
15
|
+
* @param options - Firebase initialization options
|
|
16
|
+
* @returns Firebase app and auth instances
|
|
17
|
+
* @throws Error if Firebase is already initialized with different config
|
|
18
|
+
*/
|
|
19
|
+
export declare function initializeFirebaseAuth(options: FirebaseInitOptions): FirebaseInitResult;
|
|
20
|
+
/**
|
|
21
|
+
* Get the Firebase app instance.
|
|
22
|
+
* Must call initializeFirebaseAuth() first.
|
|
23
|
+
*
|
|
24
|
+
* @returns Firebase app instance or null if not initialized
|
|
25
|
+
*/
|
|
26
|
+
export declare function getFirebaseApp(): FirebaseApp | null;
|
|
27
|
+
/**
|
|
28
|
+
* Get the Firebase auth instance.
|
|
29
|
+
* Must call initializeFirebaseAuth() first.
|
|
30
|
+
*
|
|
31
|
+
* @returns Firebase auth instance or null if not initialized
|
|
32
|
+
*/
|
|
33
|
+
export declare function getFirebaseAuth(): Auth | null;
|
|
34
|
+
/**
|
|
35
|
+
* Get the current Firebase configuration.
|
|
36
|
+
*
|
|
37
|
+
* @returns Firebase config or null if not initialized
|
|
38
|
+
*/
|
|
39
|
+
export declare function getFirebaseConfig(): FirebaseConfig | null;
|
|
40
|
+
//# sourceMappingURL=firebase-init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"firebase-init.d.ts","sourceRoot":"","sources":["../../src/config/firebase-init.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,WAAW,EAAkC,MAAM,cAAc,CAAC;AAChF,OAAO,EAAE,KAAK,IAAI,EAAW,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EACV,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAOjB;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAS9C;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,mBAAmB,GAC3B,kBAAkB,CAyBpB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,WAAW,GAAG,IAAI,CAEnD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,IAAI,GAAG,IAAI,CAE7C;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,IAAI,CAEzD"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Configurable Firebase initialization
|
|
3
|
+
*/
|
|
4
|
+
import { getApp, getApps, initializeApp } from 'firebase/app';
|
|
5
|
+
import { getAuth } from 'firebase/auth';
|
|
6
|
+
// Singleton state
|
|
7
|
+
let firebaseApp = null;
|
|
8
|
+
let firebaseAuth = null;
|
|
9
|
+
let firebaseConfig = null;
|
|
10
|
+
/**
|
|
11
|
+
* Check if Firebase is configured with the required fields
|
|
12
|
+
*/
|
|
13
|
+
export function isFirebaseConfigured() {
|
|
14
|
+
if (!firebaseConfig)
|
|
15
|
+
return false;
|
|
16
|
+
const requiredFields = [
|
|
17
|
+
'apiKey',
|
|
18
|
+
'authDomain',
|
|
19
|
+
'projectId',
|
|
20
|
+
'appId',
|
|
21
|
+
];
|
|
22
|
+
return requiredFields.every(field => !!firebaseConfig?.[field]);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Initialize Firebase Auth with the provided configuration.
|
|
26
|
+
* This should be called once at app startup (e.g., in main.tsx).
|
|
27
|
+
*
|
|
28
|
+
* @param options - Firebase initialization options
|
|
29
|
+
* @returns Firebase app and auth instances
|
|
30
|
+
* @throws Error if Firebase is already initialized with different config
|
|
31
|
+
*/
|
|
32
|
+
export function initializeFirebaseAuth(options) {
|
|
33
|
+
const { config } = options;
|
|
34
|
+
// Store the config
|
|
35
|
+
firebaseConfig = config;
|
|
36
|
+
// Check if already initialized
|
|
37
|
+
if (firebaseApp && firebaseAuth) {
|
|
38
|
+
return { app: firebaseApp, auth: firebaseAuth };
|
|
39
|
+
}
|
|
40
|
+
// Validate configuration
|
|
41
|
+
if (!isFirebaseConfigured()) {
|
|
42
|
+
throw new Error('[auth_lib] Firebase configuration is incomplete. Required fields: apiKey, authDomain, projectId, appId');
|
|
43
|
+
}
|
|
44
|
+
// Initialize Firebase app (avoid duplicate initialization)
|
|
45
|
+
firebaseApp = getApps().length === 0 ? initializeApp(config) : getApp();
|
|
46
|
+
// Initialize Firebase Auth
|
|
47
|
+
firebaseAuth = getAuth(firebaseApp);
|
|
48
|
+
return { app: firebaseApp, auth: firebaseAuth };
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get the Firebase app instance.
|
|
52
|
+
* Must call initializeFirebaseAuth() first.
|
|
53
|
+
*
|
|
54
|
+
* @returns Firebase app instance or null if not initialized
|
|
55
|
+
*/
|
|
56
|
+
export function getFirebaseApp() {
|
|
57
|
+
return firebaseApp;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get the Firebase auth instance.
|
|
61
|
+
* Must call initializeFirebaseAuth() first.
|
|
62
|
+
*
|
|
63
|
+
* @returns Firebase auth instance or null if not initialized
|
|
64
|
+
*/
|
|
65
|
+
export function getFirebaseAuth() {
|
|
66
|
+
return firebaseAuth;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get the current Firebase configuration.
|
|
70
|
+
*
|
|
71
|
+
* @returns Firebase config or null if not initialized
|
|
72
|
+
*/
|
|
73
|
+
export function getFirebaseConfig() {
|
|
74
|
+
return firebaseConfig;
|
|
75
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Config exports
|
|
3
|
+
*/
|
|
4
|
+
export { initializeFirebaseAuth, getFirebaseApp, getFirebaseAuth, getFirebaseConfig, isFirebaseConfigured, } from './firebase-init';
|
|
5
|
+
export type { FirebaseConfig, FirebaseInitOptions, FirebaseInitResult, FirebaseAuthNetworkClientOptions, } from './types';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EACV,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,gCAAgC,GACjC,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Type definitions for auth_lib
|
|
3
|
+
*/
|
|
4
|
+
import type { Auth } from 'firebase/auth';
|
|
5
|
+
import type { FirebaseApp } from 'firebase/app';
|
|
6
|
+
/**
|
|
7
|
+
* Firebase configuration object
|
|
8
|
+
*/
|
|
9
|
+
export interface FirebaseConfig {
|
|
10
|
+
apiKey: string;
|
|
11
|
+
authDomain: string;
|
|
12
|
+
projectId: string;
|
|
13
|
+
storageBucket?: string;
|
|
14
|
+
messagingSenderId?: string;
|
|
15
|
+
appId: string;
|
|
16
|
+
measurementId?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Options for initializing Firebase Auth
|
|
20
|
+
*/
|
|
21
|
+
export interface FirebaseInitOptions {
|
|
22
|
+
/** Firebase configuration */
|
|
23
|
+
config: FirebaseConfig;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Result of Firebase initialization
|
|
27
|
+
*/
|
|
28
|
+
export interface FirebaseInitResult {
|
|
29
|
+
app: FirebaseApp;
|
|
30
|
+
auth: Auth;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Options for the Firebase Auth network client hook
|
|
34
|
+
*/
|
|
35
|
+
export interface FirebaseAuthNetworkClientOptions {
|
|
36
|
+
/** Callback when user is logged out due to 403 */
|
|
37
|
+
onLogout?: () => void;
|
|
38
|
+
/** Callback when token refresh fails */
|
|
39
|
+
onTokenRefreshFailed?: (error: unknown) => void;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,6BAA6B;IAC7B,MAAM,EAAE,cAAc,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,WAAW,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,gCAAgC;IAC/C,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,wCAAwC;IACxC,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACjD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Hook to provide a resilient network client with automatic token refresh and logout handling.
|
|
3
|
+
*
|
|
4
|
+
* - On 401 (Unauthorized): Force refresh Firebase token and retry once
|
|
5
|
+
* - On 403 (Forbidden): Log the user out
|
|
6
|
+
*/
|
|
7
|
+
import type { NetworkClient } from '@sudobility/types';
|
|
8
|
+
import type { FirebaseAuthNetworkClientOptions } from '../config/types';
|
|
9
|
+
/**
|
|
10
|
+
* Hook to get a Firebase Auth network client with automatic 401 retry and 403 logout.
|
|
11
|
+
*
|
|
12
|
+
* @param options - Optional callbacks for logout and token refresh failure
|
|
13
|
+
* @returns NetworkClient instance
|
|
14
|
+
*/
|
|
15
|
+
export declare function useFirebaseAuthNetworkClient(options?: FirebaseAuthNetworkClientOptions): NetworkClient;
|
|
16
|
+
//# sourceMappingURL=useFirebaseAuthNetworkClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFirebaseAuthNetworkClient.d.ts","sourceRoot":"","sources":["../../src/hooks/useFirebaseAuthNetworkClient.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EACV,aAAa,EAId,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,iBAAiB,CAAC;AAyLxE;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,CAAC,EAAE,gCAAgC,GACzC,aAAa,CAEf"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Hook to provide a resilient network client with automatic token refresh and logout handling.
|
|
3
|
+
*
|
|
4
|
+
* - On 401 (Unauthorized): Force refresh Firebase token and retry once
|
|
5
|
+
* - On 403 (Forbidden): Log the user out
|
|
6
|
+
*/
|
|
7
|
+
import { useMemo } from 'react';
|
|
8
|
+
import { getNetworkService } from '@sudobility/di';
|
|
9
|
+
import { signOut } from 'firebase/auth';
|
|
10
|
+
import { getFirebaseAuth } from '../config/firebase-init';
|
|
11
|
+
/**
|
|
12
|
+
* Get a fresh Firebase ID token with force refresh.
|
|
13
|
+
* Returns empty string if not authenticated.
|
|
14
|
+
*/
|
|
15
|
+
async function getAuthToken(forceRefresh = false) {
|
|
16
|
+
const auth = getFirebaseAuth();
|
|
17
|
+
const user = auth?.currentUser;
|
|
18
|
+
if (!user)
|
|
19
|
+
return '';
|
|
20
|
+
try {
|
|
21
|
+
return await user.getIdToken(forceRefresh);
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
console.error('[useFirebaseAuthNetworkClient] Failed to get ID token:', err);
|
|
25
|
+
return '';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Log the user out via Firebase.
|
|
30
|
+
*/
|
|
31
|
+
async function logoutUser(onLogout) {
|
|
32
|
+
const auth = getFirebaseAuth();
|
|
33
|
+
if (!auth)
|
|
34
|
+
return;
|
|
35
|
+
try {
|
|
36
|
+
await signOut(auth);
|
|
37
|
+
onLogout?.();
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
console.error('[useFirebaseAuthNetworkClient] Failed to sign out:', err);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Create a network client adapter that wraps the platform network client
|
|
45
|
+
* with 401 retry and 403 logout handling.
|
|
46
|
+
*/
|
|
47
|
+
function createFirebaseAuthNetworkClient(options) {
|
|
48
|
+
const platformNetwork = getNetworkService();
|
|
49
|
+
const parseResponse = async (response) => {
|
|
50
|
+
let data;
|
|
51
|
+
const contentType = response.headers.get('content-type');
|
|
52
|
+
if (contentType?.includes('application/json')) {
|
|
53
|
+
try {
|
|
54
|
+
data = (await response.json());
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// JSON parse failed, leave data undefined
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const headers = {};
|
|
61
|
+
response.headers.forEach((value, key) => {
|
|
62
|
+
headers[key] = value;
|
|
63
|
+
});
|
|
64
|
+
return {
|
|
65
|
+
ok: response.ok,
|
|
66
|
+
status: response.status,
|
|
67
|
+
statusText: response.statusText,
|
|
68
|
+
headers,
|
|
69
|
+
data,
|
|
70
|
+
success: response.ok,
|
|
71
|
+
timestamp: new Date().toISOString(),
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Execute request with retry logic:
|
|
76
|
+
* - On 401: Force refresh token and retry once
|
|
77
|
+
* - On 403: Log user out (no retry)
|
|
78
|
+
*/
|
|
79
|
+
const executeWithRetry = async (url, requestInit) => {
|
|
80
|
+
const response = await platformNetwork.request(url, requestInit);
|
|
81
|
+
// On 401, get fresh token and retry once
|
|
82
|
+
if (response.status === 401) {
|
|
83
|
+
const freshToken = await getAuthToken(true);
|
|
84
|
+
if (freshToken) {
|
|
85
|
+
const retryHeaders = {
|
|
86
|
+
...requestInit.headers,
|
|
87
|
+
Authorization: `Bearer ${freshToken}`,
|
|
88
|
+
};
|
|
89
|
+
const retryResponse = await platformNetwork.request(url, {
|
|
90
|
+
...requestInit,
|
|
91
|
+
headers: retryHeaders,
|
|
92
|
+
});
|
|
93
|
+
return parseResponse(retryResponse);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
// Token refresh failed
|
|
97
|
+
options?.onTokenRefreshFailed?.(new Error('Failed to refresh token'));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// On 403, log the user out
|
|
101
|
+
if (response.status === 403) {
|
|
102
|
+
console.warn('[useFirebaseAuthNetworkClient] 403 Forbidden - logging user out');
|
|
103
|
+
await logoutUser(options?.onLogout);
|
|
104
|
+
// Return the original response so the UI can handle it
|
|
105
|
+
}
|
|
106
|
+
return parseResponse(response);
|
|
107
|
+
};
|
|
108
|
+
return {
|
|
109
|
+
async request(url, reqOptions) {
|
|
110
|
+
const requestInit = {
|
|
111
|
+
method: reqOptions?.method ?? 'GET',
|
|
112
|
+
headers: reqOptions?.headers ?? undefined,
|
|
113
|
+
body: reqOptions?.body ?? undefined,
|
|
114
|
+
signal: reqOptions?.signal ?? undefined,
|
|
115
|
+
};
|
|
116
|
+
return executeWithRetry(url, requestInit);
|
|
117
|
+
},
|
|
118
|
+
async get(url, reqOptions) {
|
|
119
|
+
const requestInit = {
|
|
120
|
+
method: 'GET',
|
|
121
|
+
headers: reqOptions?.headers ?? undefined,
|
|
122
|
+
signal: reqOptions?.signal ?? undefined,
|
|
123
|
+
};
|
|
124
|
+
return executeWithRetry(url, requestInit);
|
|
125
|
+
},
|
|
126
|
+
async post(url, body, reqOptions) {
|
|
127
|
+
const requestInit = {
|
|
128
|
+
method: 'POST',
|
|
129
|
+
headers: reqOptions?.headers ?? undefined,
|
|
130
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
131
|
+
signal: reqOptions?.signal ?? undefined,
|
|
132
|
+
};
|
|
133
|
+
return executeWithRetry(url, requestInit);
|
|
134
|
+
},
|
|
135
|
+
async put(url, body, reqOptions) {
|
|
136
|
+
const requestInit = {
|
|
137
|
+
method: 'PUT',
|
|
138
|
+
headers: reqOptions?.headers ?? undefined,
|
|
139
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
140
|
+
signal: reqOptions?.signal ?? undefined,
|
|
141
|
+
};
|
|
142
|
+
return executeWithRetry(url, requestInit);
|
|
143
|
+
},
|
|
144
|
+
async delete(url, reqOptions) {
|
|
145
|
+
const requestInit = {
|
|
146
|
+
method: 'DELETE',
|
|
147
|
+
headers: reqOptions?.headers ?? undefined,
|
|
148
|
+
signal: reqOptions?.signal ?? undefined,
|
|
149
|
+
};
|
|
150
|
+
return executeWithRetry(url, requestInit);
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Hook to get a Firebase Auth network client with automatic 401 retry and 403 logout.
|
|
156
|
+
*
|
|
157
|
+
* @param options - Optional callbacks for logout and token refresh failure
|
|
158
|
+
* @returns NetworkClient instance
|
|
159
|
+
*/
|
|
160
|
+
export function useFirebaseAuthNetworkClient(options) {
|
|
161
|
+
return useMemo(() => createFirebaseAuthNetworkClient(options), [options]);
|
|
162
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview @sudobility/auth_lib - Firebase authentication utilities
|
|
3
|
+
*
|
|
4
|
+
* This library provides:
|
|
5
|
+
* - Configurable Firebase Auth initialization
|
|
6
|
+
* - Network client with automatic 401 token refresh and 403 logout handling
|
|
7
|
+
* - Firebase error message utilities
|
|
8
|
+
*/
|
|
9
|
+
export { initializeFirebaseAuth, getFirebaseApp, getFirebaseAuth, getFirebaseConfig, isFirebaseConfigured, } from './config';
|
|
10
|
+
export type { FirebaseConfig, FirebaseInitOptions, FirebaseInitResult, FirebaseAuthNetworkClientOptions, } from './config';
|
|
11
|
+
export { useFirebaseAuthNetworkClient } from './hooks';
|
|
12
|
+
export { getFirebaseErrorMessage, getFirebaseErrorCode, formatFirebaseError, isFirebaseAuthError, } from './utils';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,UAAU,CAAC;AAElB,YAAY,EACV,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,gCAAgC,GACjC,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAC;AAGvD,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview @sudobility/auth_lib - Firebase authentication utilities
|
|
3
|
+
*
|
|
4
|
+
* This library provides:
|
|
5
|
+
* - Configurable Firebase Auth initialization
|
|
6
|
+
* - Network client with automatic 401 token refresh and 403 logout handling
|
|
7
|
+
* - Firebase error message utilities
|
|
8
|
+
*/
|
|
9
|
+
// Config
|
|
10
|
+
export { initializeFirebaseAuth, getFirebaseApp, getFirebaseAuth, getFirebaseConfig, isFirebaseConfigured, } from './config';
|
|
11
|
+
// Hooks
|
|
12
|
+
export { useFirebaseAuthNetworkClient } from './hooks';
|
|
13
|
+
// Utils
|
|
14
|
+
export { getFirebaseErrorMessage, getFirebaseErrorCode, formatFirebaseError, isFirebaseAuthError, } from './utils';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Firebase authentication error utilities
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Get user-friendly error message from Firebase error code
|
|
6
|
+
*
|
|
7
|
+
* @param code - Firebase error code (e.g., 'auth/user-not-found')
|
|
8
|
+
* @returns User-friendly error message
|
|
9
|
+
*/
|
|
10
|
+
export declare function getFirebaseErrorMessage(code: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Extract error code from Firebase error
|
|
13
|
+
*
|
|
14
|
+
* @param error - Error object from Firebase
|
|
15
|
+
* @returns Error code string or empty string if not found
|
|
16
|
+
*/
|
|
17
|
+
export declare function getFirebaseErrorCode(error: unknown): string;
|
|
18
|
+
/**
|
|
19
|
+
* Get user-friendly message from Firebase error object
|
|
20
|
+
*
|
|
21
|
+
* @param error - Error object from Firebase
|
|
22
|
+
* @returns User-friendly error message
|
|
23
|
+
*/
|
|
24
|
+
export declare function formatFirebaseError(error: unknown): string;
|
|
25
|
+
/**
|
|
26
|
+
* Check if an error is a Firebase auth error
|
|
27
|
+
*
|
|
28
|
+
* @param error - Error object to check
|
|
29
|
+
* @returns True if the error is a Firebase auth error
|
|
30
|
+
*/
|
|
31
|
+
export declare function isFirebaseAuthError(error: unknown): boolean;
|
|
32
|
+
//# sourceMappingURL=firebase-errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"firebase-errors.d.ts","sourceRoot":"","sources":["../../src/utils/firebase-errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmBH;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI5D;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAK3D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAG1D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAG3D"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Firebase authentication error utilities
|
|
3
|
+
*/
|
|
4
|
+
/** Map of Firebase auth error codes to user-friendly messages */
|
|
5
|
+
const FIREBASE_ERROR_MESSAGES = {
|
|
6
|
+
'auth/user-not-found': 'No account found with this email',
|
|
7
|
+
'auth/wrong-password': 'Incorrect password',
|
|
8
|
+
'auth/invalid-email': 'Invalid email address',
|
|
9
|
+
'auth/invalid-credential': 'Invalid email or password',
|
|
10
|
+
'auth/email-already-in-use': 'An account with this email already exists',
|
|
11
|
+
'auth/weak-password': 'Password must be at least 6 characters',
|
|
12
|
+
'auth/too-many-requests': 'Too many attempts. Please try again later.',
|
|
13
|
+
'auth/network-request-failed': 'Network error. Please check your connection.',
|
|
14
|
+
'auth/popup-closed-by-user': 'Sign in cancelled',
|
|
15
|
+
'auth/popup-blocked': 'Popup blocked. Please allow popups for this site.',
|
|
16
|
+
'auth/account-exists-with-different-credential': 'An account already exists with this email using a different sign-in method.',
|
|
17
|
+
'auth/operation-not-allowed': 'This sign-in method is not enabled.',
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Get user-friendly error message from Firebase error code
|
|
21
|
+
*
|
|
22
|
+
* @param code - Firebase error code (e.g., 'auth/user-not-found')
|
|
23
|
+
* @returns User-friendly error message
|
|
24
|
+
*/
|
|
25
|
+
export function getFirebaseErrorMessage(code) {
|
|
26
|
+
return (FIREBASE_ERROR_MESSAGES[code] ?? 'Something went wrong. Please try again.');
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Extract error code from Firebase error
|
|
30
|
+
*
|
|
31
|
+
* @param error - Error object from Firebase
|
|
32
|
+
* @returns Error code string or empty string if not found
|
|
33
|
+
*/
|
|
34
|
+
export function getFirebaseErrorCode(error) {
|
|
35
|
+
if (error && typeof error === 'object' && 'code' in error) {
|
|
36
|
+
return error.code;
|
|
37
|
+
}
|
|
38
|
+
return '';
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get user-friendly message from Firebase error object
|
|
42
|
+
*
|
|
43
|
+
* @param error - Error object from Firebase
|
|
44
|
+
* @returns User-friendly error message
|
|
45
|
+
*/
|
|
46
|
+
export function formatFirebaseError(error) {
|
|
47
|
+
const code = getFirebaseErrorCode(error);
|
|
48
|
+
return getFirebaseErrorMessage(code);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Check if an error is a Firebase auth error
|
|
52
|
+
*
|
|
53
|
+
* @param error - Error object to check
|
|
54
|
+
* @returns True if the error is a Firebase auth error
|
|
55
|
+
*/
|
|
56
|
+
export function isFirebaseAuthError(error) {
|
|
57
|
+
const code = getFirebaseErrorCode(error);
|
|
58
|
+
return code.startsWith('auth/');
|
|
59
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sudobility/auth_lib",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Firebase authentication utilities with token refresh handling",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"dev": "tsc --watch",
|
|
22
|
+
"clean": "rm -rf dist",
|
|
23
|
+
"typecheck": "bunx tsc --noEmit",
|
|
24
|
+
"lint": "bunx eslint src",
|
|
25
|
+
"lint:fix": "bunx eslint src --fix",
|
|
26
|
+
"format": "bunx prettier --write \"src/**/*.{ts,tsx,js,jsx,json}\"",
|
|
27
|
+
"test": "bun test",
|
|
28
|
+
"prepublishOnly": "bun run build"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
32
|
+
"firebase": "^12.0.0",
|
|
33
|
+
"@sudobility/di": "^1.5.8",
|
|
34
|
+
"@sudobility/types": "^1.9.40"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@eslint/js": "^9.0.0",
|
|
38
|
+
"@types/bun": "^1.2.8",
|
|
39
|
+
"@types/react": "^19.2.5",
|
|
40
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
41
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
42
|
+
"eslint": "^9.0.0",
|
|
43
|
+
"eslint-config-prettier": "^10.0.0",
|
|
44
|
+
"eslint-plugin-prettier": "^5.0.0",
|
|
45
|
+
"prettier": "^3.0.0",
|
|
46
|
+
"typescript": "~5.9.3"
|
|
47
|
+
},
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
},
|
|
51
|
+
"repository": {
|
|
52
|
+
"type": "git",
|
|
53
|
+
"url": "https://github.com/sudobility/auth_lib.git"
|
|
54
|
+
},
|
|
55
|
+
"license": "MIT"
|
|
56
|
+
}
|