@rdlabo/ionic-angular-kit 0.0.15 → 0.0.16
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 +65 -1
- package/fesm2022/rdlabo-ionic-angular-kit-auth-firebase-social.mjs +218 -0
- package/fesm2022/rdlabo-ionic-angular-kit-auth-firebase-social.mjs.map +1 -0
- package/fesm2022/rdlabo-ionic-angular-kit-auth-firebase.mjs +340 -0
- package/fesm2022/rdlabo-ionic-angular-kit-auth-firebase.mjs.map +1 -0
- package/fesm2022/rdlabo-ionic-angular-kit.mjs.map +1 -1
- package/package.json +25 -1
- package/types/rdlabo-ionic-angular-kit-auth-firebase-social.d.ts +104 -0
- package/types/rdlabo-ionic-angular-kit-auth-firebase.d.ts +266 -0
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import { InjectionToken, makeEnvironmentProviders } from '@angular/core';
|
|
2
|
+
import { Capacitor } from '@capacitor/core';
|
|
3
|
+
import { provideFirebaseApp, initializeApp, getApp } from '@angular/fire/app';
|
|
4
|
+
import { Auth, provideAuth, initializeAuth, indexedDBLocalPersistence, getAuth } from '@angular/fire/auth';
|
|
5
|
+
import { provideAnalytics, getAnalytics } from '@angular/fire/analytics';
|
|
6
|
+
import { signInWithEmailAndPassword, createUserWithEmailAndPassword, sendEmailVerification, signOut, sendPasswordResetEmail, unlink, onAuthStateChanged, reauthenticateWithCredential, EmailAuthProvider } from 'firebase/auth';
|
|
7
|
+
import { Observable } from 'rxjs';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* DI token for the Firebase `Auth` instance.
|
|
11
|
+
*
|
|
12
|
+
* @remarks
|
|
13
|
+
* Inject this (`inject(KIT_FIREBASE_AUTH)`) instead of `@angular/fire`'s `Auth`, so the
|
|
14
|
+
* `@angular/fire` dependency stays isolated inside the kit. This is the seam that makes the planned
|
|
15
|
+
* `@angular/fire` → `firebase/auth` migration a kit-internal change: only {@link provideKitFirebase}
|
|
16
|
+
* (which binds this token) has to change; every consumer keeps injecting `KIT_FIREBASE_AUTH`.
|
|
17
|
+
*
|
|
18
|
+
* The value is a `firebase/auth` `Auth` (the SDK type is exposed directly, not re-abstracted —
|
|
19
|
+
* Firebase Auth itself is not being dropped, only the `@angular/fire` wrapper).
|
|
20
|
+
*/
|
|
21
|
+
const KIT_FIREBASE_AUTH = new InjectionToken('@rdlabo/ionic-angular-kit:firebase-auth');
|
|
22
|
+
/**
|
|
23
|
+
* Wire Firebase App + Auth into the application and bind {@link KIT_FIREBASE_AUTH}.
|
|
24
|
+
*
|
|
25
|
+
* @remarks
|
|
26
|
+
* Replaces each app's hand-rolled `provideFirebaseApp(...)` + `provideAuth(...)` (with its
|
|
27
|
+
* native/web persistence branch) with one call, and — crucially — keeps `@angular/fire` out of the
|
|
28
|
+
* application: apps inject {@link KIT_FIREBASE_AUTH} and import auth operations/types straight from
|
|
29
|
+
* `firebase/auth`. On a native platform the persistence uses `indexedDBLocalPersistence`; on the web
|
|
30
|
+
* it uses the default (`getAuth`).
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* bootstrapApplication(AppComponent, {
|
|
35
|
+
* providers: [provideKitFirebase({ firebaseConfig: environment.firebase })],
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
const provideKitFirebase = (config) => makeEnvironmentProviders([
|
|
40
|
+
provideFirebaseApp(() => initializeApp(config.firebaseConfig)),
|
|
41
|
+
provideAuth(() => Capacitor.isNativePlatform()
|
|
42
|
+
? initializeAuth(getApp(), { persistence: indexedDBLocalPersistence })
|
|
43
|
+
: getAuth()),
|
|
44
|
+
// Expose @angular/fire's Auth instance under the kit token; phase 3 rebinds this to a
|
|
45
|
+
// firebase/auth instance without touching any consumer.
|
|
46
|
+
{ provide: KIT_FIREBASE_AUTH, useExisting: Auth },
|
|
47
|
+
]);
|
|
48
|
+
/**
|
|
49
|
+
* Wire Firebase Analytics into the application (optional; only the apps that use it call this).
|
|
50
|
+
*/
|
|
51
|
+
const provideKitFirebaseAnalytics = () => makeEnvironmentProviders([provideAnalytics(() => getAnalytics())]);
|
|
52
|
+
|
|
53
|
+
/** The fleet's canonical Japanese error dictionary (see {@link KitAuthText}). */
|
|
54
|
+
const KIT_DEFAULT_AUTH_TEXT = {
|
|
55
|
+
errors: {
|
|
56
|
+
'auth/invalid-email': { header: 'メールアドレスが間違っています', message: 'メールアドレスのフォーマットが間違っています。ご確認ください。' },
|
|
57
|
+
'auth/user-not-found': {
|
|
58
|
+
header: 'ユーザが見つかりません',
|
|
59
|
+
message: '入力いただいたユーザは存在しません。登録されていないメールアドレスか、すでに退会しています。',
|
|
60
|
+
},
|
|
61
|
+
'auth/wrong-password': {
|
|
62
|
+
header: 'パスワードが間違っています',
|
|
63
|
+
message: '入力いただいたパスワードが間違っているか、このユーザはFacebookログインを利用しており、パスワードログインを有効にしていません。',
|
|
64
|
+
},
|
|
65
|
+
'auth/weak-password': {
|
|
66
|
+
header: '脆弱性があります',
|
|
67
|
+
message: 'パスワードは最低でも6文字以上のものをご利用ください。大文字小文字数字が混在しているとセキュリティを高めることにつながります。',
|
|
68
|
+
},
|
|
69
|
+
'auth/email-already-in-use': {
|
|
70
|
+
header: 'ユーザが存在しています',
|
|
71
|
+
message: 'このメールアドレスを利用してすでにユーザが作成されています。ログイン画面に戻って、ログインください。',
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
fallbackError: { header: 'エラー', message: '処理に失敗しました' },
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/** Run a value-returning op through the {@link KitAuthHooks} lifecycle; resolve `null` on failure. */
|
|
78
|
+
const runAuthFlow = async (op, hooks) => {
|
|
79
|
+
await hooks?.before?.();
|
|
80
|
+
try {
|
|
81
|
+
const result = await op();
|
|
82
|
+
await hooks?.success?.();
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
catch (e) {
|
|
86
|
+
await hooks?.error?.(e);
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
await hooks?.finally?.();
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
/** Run a void op through the lifecycle; resolve `true` on success, `false` on a (hooked) failure. */
|
|
94
|
+
const runAuthFlowVoid = async (op, hooks) => {
|
|
95
|
+
const result = await runAuthFlow(async () => {
|
|
96
|
+
await op();
|
|
97
|
+
return true;
|
|
98
|
+
}, hooks);
|
|
99
|
+
return result === true;
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Sign in with email and password.
|
|
103
|
+
*
|
|
104
|
+
* @remarks
|
|
105
|
+
* Bundles the Firebase op so the app never imports `signInWithEmailAndPassword` directly (the SDK
|
|
106
|
+
* stays isolated in the kit). Resolves the credential, or `null` on failure (handed to the `error`
|
|
107
|
+
* hook).
|
|
108
|
+
*/
|
|
109
|
+
const kitSignIn = (auth, email, password, hooks) => runAuthFlow(() => signInWithEmailAndPassword(auth, email, password), hooks);
|
|
110
|
+
/**
|
|
111
|
+
* Create an account and send the verification email.
|
|
112
|
+
*
|
|
113
|
+
* @remarks
|
|
114
|
+
* Bundles the two-step "create → send verification" sequence. Resolves the credential, or `null` on
|
|
115
|
+
* failure. Any success toast is the caller's, via the `success` hook.
|
|
116
|
+
*/
|
|
117
|
+
const kitSignUp = (auth, email, password, hooks) => runAuthFlow(async () => {
|
|
118
|
+
const credential = await createUserWithEmailAndPassword(auth, email, password);
|
|
119
|
+
await sendEmailVerification(credential.user);
|
|
120
|
+
return credential;
|
|
121
|
+
}, hooks);
|
|
122
|
+
/**
|
|
123
|
+
* Sign out.
|
|
124
|
+
*
|
|
125
|
+
* @remarks
|
|
126
|
+
* App-specific cleanup (clearing stores, toasts, navigation, third-party logout) is the caller's,
|
|
127
|
+
* done via the hooks — the kit only owns the Firebase op. `true` on success, `false` on failure.
|
|
128
|
+
*/
|
|
129
|
+
const kitSignOut = (auth, hooks) => runAuthFlowVoid(() => signOut(auth), hooks);
|
|
130
|
+
/** Send a password-reset email. `true` on success, `false` on failure. */
|
|
131
|
+
const kitSendPasswordReset = (auth, email, hooks) => runAuthFlowVoid(() => sendPasswordResetEmail(auth, email), hooks);
|
|
132
|
+
/**
|
|
133
|
+
* Unlink a linked auth provider (e.g. `'facebook.com'`, `'apple.com'`) from the current user.
|
|
134
|
+
*
|
|
135
|
+
* @remarks
|
|
136
|
+
* Exposed from the core (not `/social`) so an app can unlink without importing `unlink` from
|
|
137
|
+
* `firebase/auth` directly — keeping the invariant that the SDK is only imported inside the kit. Any
|
|
138
|
+
* app-specific step around it (e.g. a backend DELETE before unlinking) goes in the `before` hook.
|
|
139
|
+
* Resolves the updated `User`, or `null` on failure (including when there is no signed-in user).
|
|
140
|
+
*/
|
|
141
|
+
const kitUnlinkProvider = (auth, providerId, hooks) => runAuthFlow(() => {
|
|
142
|
+
const user = auth.currentUser;
|
|
143
|
+
if (!user) {
|
|
144
|
+
throw new Error('kitUnlinkProvider: no signed-in user');
|
|
145
|
+
}
|
|
146
|
+
return unlink(user, providerId);
|
|
147
|
+
}, hooks);
|
|
148
|
+
/**
|
|
149
|
+
* (Re-)send the verification email to the signed-in user (a no-op when signed out).
|
|
150
|
+
*
|
|
151
|
+
* @remarks
|
|
152
|
+
* `true` on success (including the signed-out no-op), `false` on failure.
|
|
153
|
+
*/
|
|
154
|
+
const kitSendEmailVerification = (auth, hooks) => runAuthFlowVoid(async () => {
|
|
155
|
+
const user = auth.currentUser;
|
|
156
|
+
if (user) {
|
|
157
|
+
await sendEmailVerification(user);
|
|
158
|
+
}
|
|
159
|
+
}, hooks);
|
|
160
|
+
// This module talks to `firebase/auth` directly (not @angular/fire); only the DI provider
|
|
161
|
+
// (kit-firebase-provider.ts) touches @angular/fire, so the planned SDK swap is provider-local.
|
|
162
|
+
/**
|
|
163
|
+
* The current Firebase user as an Observable (emits on every auth-state change; `null` when signed out).
|
|
164
|
+
*
|
|
165
|
+
* @remarks
|
|
166
|
+
* Wraps `onAuthStateChanged` so consumers get an rxjs stream without pulling in `@angular/fire`'s
|
|
167
|
+
* `authState` (or `rxfire`). Emits the current value on subscribe and completes its listener on
|
|
168
|
+
* teardown.
|
|
169
|
+
*
|
|
170
|
+
* @param auth - the Firebase `Auth` instance (inject `KIT_FIREBASE_AUTH`)
|
|
171
|
+
*/
|
|
172
|
+
const kitAuthState = (auth) => new Observable((subscriber) => onAuthStateChanged(auth, (user) => subscriber.next(user), (err) => subscriber.error(err)));
|
|
173
|
+
/**
|
|
174
|
+
* The current user's ID token, or `null` when signed out.
|
|
175
|
+
*
|
|
176
|
+
* @remarks
|
|
177
|
+
* For building `Authorization` / bearer headers in interceptors and services. Failure to fetch a
|
|
178
|
+
* token is **thrown, not swallowed** — the caller decides the fallback (e.g. an empty header) as its
|
|
179
|
+
* own side effect, so the kit never silently hides an auth failure.
|
|
180
|
+
*
|
|
181
|
+
* @param auth - the Firebase `Auth` instance (inject `KIT_FIREBASE_AUTH`)
|
|
182
|
+
* @param forceRefresh - force a token refresh (default `false`)
|
|
183
|
+
* @returns the ID token, or `null` if there is no signed-in user
|
|
184
|
+
* @throws if the token fetch fails for a signed-in user
|
|
185
|
+
*/
|
|
186
|
+
const kitGetIdToken = (auth, forceRefresh = false) => {
|
|
187
|
+
const user = auth.currentUser;
|
|
188
|
+
return user ? user.getIdToken(forceRefresh) : Promise.resolve(null);
|
|
189
|
+
};
|
|
190
|
+
/**
|
|
191
|
+
* Thrown by {@link kitReauthenticateThenMutate} when re-authentication fails.
|
|
192
|
+
*
|
|
193
|
+
* @remarks
|
|
194
|
+
* Carries the underlying Firebase error as {@link cause}. A re-auth failure is not always a wrong
|
|
195
|
+
* password (it can be a lockout, an offline network, or an expired session) — use
|
|
196
|
+
* {@link kitIsWrongPasswordError} to tell them apart.
|
|
197
|
+
*/
|
|
198
|
+
class KitReauthError extends Error {
|
|
199
|
+
constructor(cause) {
|
|
200
|
+
super('re-authentication failed');
|
|
201
|
+
this.name = 'KitReauthError';
|
|
202
|
+
this.cause = cause;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Firebase error codes that mean "the current password was wrong".
|
|
207
|
+
*
|
|
208
|
+
* @remarks
|
|
209
|
+
* Any other re-auth failure (lockout, offline, expired session) must NOT be treated as a wrong
|
|
210
|
+
* password. With email enumeration protection (Firebase v10+) a wrong password is reported as
|
|
211
|
+
* `auth/invalid-credential` rather than `auth/wrong-password`, so both are listed.
|
|
212
|
+
*/
|
|
213
|
+
const KIT_WRONG_PASSWORD_CODES = new Set([
|
|
214
|
+
'auth/wrong-password',
|
|
215
|
+
'auth/invalid-credential',
|
|
216
|
+
'auth/invalid-login-credentials',
|
|
217
|
+
'auth/missing-password',
|
|
218
|
+
]);
|
|
219
|
+
/**
|
|
220
|
+
* Whether an error (typically a {@link KitReauthError}) represents a wrong current password.
|
|
221
|
+
*
|
|
222
|
+
* @param e - the caught error
|
|
223
|
+
*/
|
|
224
|
+
const kitIsWrongPasswordError = (e) => {
|
|
225
|
+
const cause = e instanceof KitReauthError ? e.cause : e;
|
|
226
|
+
const code = cause?.code;
|
|
227
|
+
return code !== undefined && KIT_WRONG_PASSWORD_CODES.has(code);
|
|
228
|
+
};
|
|
229
|
+
/**
|
|
230
|
+
* Re-authenticate the current user with their email/password, then run a sensitive mutation.
|
|
231
|
+
*
|
|
232
|
+
* @remarks
|
|
233
|
+
* The one non-trivial mechanic every app cloned before changing email/password: build the
|
|
234
|
+
* `EmailAuthProvider` credential, `reauthenticateWithCredential`, and only on success run `mutate`.
|
|
235
|
+
* Pure — no DI, no UI. A re-auth failure throws {@link KitReauthError}; `mutate`'s own error
|
|
236
|
+
* propagates unwrapped.
|
|
237
|
+
*
|
|
238
|
+
* @param auth - the Firebase `Auth` instance
|
|
239
|
+
* @param currentEmail - the current email (for the re-auth credential)
|
|
240
|
+
* @param currentPassword - the current password (for the re-auth credential)
|
|
241
|
+
* @param mutate - the change to run once re-authenticated, receiving the current `User`
|
|
242
|
+
* @throws {@link KitReauthError} if there is no signed-in user or re-authentication fails
|
|
243
|
+
*/
|
|
244
|
+
const kitReauthenticateThenMutate = async (auth, currentEmail, currentPassword, mutate) => {
|
|
245
|
+
const user = auth.currentUser;
|
|
246
|
+
if (!user) {
|
|
247
|
+
throw new KitReauthError('no current user');
|
|
248
|
+
}
|
|
249
|
+
try {
|
|
250
|
+
await reauthenticateWithCredential(user, EmailAuthProvider.credential(currentEmail, currentPassword));
|
|
251
|
+
}
|
|
252
|
+
catch (e) {
|
|
253
|
+
throw new KitReauthError(e);
|
|
254
|
+
}
|
|
255
|
+
await mutate(user);
|
|
256
|
+
};
|
|
257
|
+
/**
|
|
258
|
+
* Run the fleet's canonical "confirm current password → change" flow, re-prompting in place on a
|
|
259
|
+
* wrong password.
|
|
260
|
+
*
|
|
261
|
+
* @remarks
|
|
262
|
+
* Owns the drift-prone *control flow* (the retry loop, the wrong-password classification every app
|
|
263
|
+
* once got wrong, and when to show loading) while generating **no UI** — the prompt and the loading
|
|
264
|
+
* overlay are {@link KitReauthWithRetryOptions | side-effect callbacks} the app supplies. On a wrong
|
|
265
|
+
* password the loop re-prompts instead of dropping the user out of the flow. Any non-wrong-password
|
|
266
|
+
* re-auth failure (lockout, offline, expired session) and any error from `mutate` are re-thrown —
|
|
267
|
+
* re-auth failures unwrapped to the underlying Firebase error so the caller's error dictionary can
|
|
268
|
+
* read its `code`.
|
|
269
|
+
*
|
|
270
|
+
* @param auth - the Firebase `Auth` instance
|
|
271
|
+
* @param currentEmail - the current email (for the re-auth credential)
|
|
272
|
+
* @param options - the pure mutation plus the app's prompt / loading side effects
|
|
273
|
+
* @returns `true` if the mutation completed, `false` if the user cancelled
|
|
274
|
+
* @throws the underlying Firebase error on a non-wrong-password failure, or `mutate`'s own error
|
|
275
|
+
*/
|
|
276
|
+
const kitReauthWithRetry = async (auth, currentEmail, options) => {
|
|
277
|
+
const run = options.withLoading ?? ((fn) => fn());
|
|
278
|
+
let wrongPasswordRetry = false;
|
|
279
|
+
for (;;) {
|
|
280
|
+
const password = await options.prompt(wrongPasswordRetry);
|
|
281
|
+
if (password === null) {
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
try {
|
|
285
|
+
await run(() => kitReauthenticateThenMutate(auth, currentEmail, password, options.mutate));
|
|
286
|
+
return true;
|
|
287
|
+
}
|
|
288
|
+
catch (e) {
|
|
289
|
+
if (kitIsWrongPasswordError(e)) {
|
|
290
|
+
wrongPasswordRetry = true;
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
throw e instanceof KitReauthError && e.cause instanceof Error ? e.cause : e;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
/**
|
|
298
|
+
* Classify a Firebase user into the fleet's 3-state auth status.
|
|
299
|
+
*
|
|
300
|
+
* @remarks
|
|
301
|
+
* `null` (signed out) → `'required'`. A signed-in user is `'user'` when their email is verified, OR
|
|
302
|
+
* they signed in with one of `verifiedProviders`, OR `allowWhen` returns true; otherwise `'confirm'`
|
|
303
|
+
* (signed in but unverified). This is only the shared classification — app-specific side effects
|
|
304
|
+
* around it (reloading the user to refresh `emailVerified`, caching a token) stay in the app.
|
|
305
|
+
*
|
|
306
|
+
* @example
|
|
307
|
+
* ```ts
|
|
308
|
+
* kitResolveAuthStatus(user, {
|
|
309
|
+
* verifiedProviders: ['facebook.com', 'apple.com'],
|
|
310
|
+
* allowWhen: () => environment.e2e,
|
|
311
|
+
* });
|
|
312
|
+
* ```
|
|
313
|
+
*/
|
|
314
|
+
const kitResolveAuthStatus = (user, options) => {
|
|
315
|
+
if (user === null) {
|
|
316
|
+
return 'required';
|
|
317
|
+
}
|
|
318
|
+
const verifiedByProvider = options?.verifiedProviders?.some((id) => user.providerData.some((p) => p.providerId === id)) ?? false;
|
|
319
|
+
const verified = user.emailVerified || verifiedByProvider || (options?.allowWhen?.(user) ?? false);
|
|
320
|
+
return verified ? 'user' : 'confirm';
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
// Firebase auth: the flow library for the fleet. `@angular/fire` is used in *one* place only — the
|
|
324
|
+
// DI provider (kit-firebase-provider.ts) — so the planned `@angular/fire` → `firebase/auth` swap is
|
|
325
|
+
// provider-local. Apps inject `KIT_FIREBASE_AUTH` and call these pure flow functions, never importing
|
|
326
|
+
// the SDK for the covered operations.
|
|
327
|
+
//
|
|
328
|
+
// The public surface is intentionally curated: dependency wiring plus pure flow functions (each
|
|
329
|
+
// pairing a Firebase operation with the uniform `{ before, success, error, finally }` hooks and the
|
|
330
|
+
// no-throw null/false contract). The re-auth mechanics (kitReauthenticateThenMutate / KitReauthError
|
|
331
|
+
// / KIT_WRONG_PASSWORD_CODES / kitIsWrongPasswordError) are internal details of `kitReauthWithRetry`
|
|
332
|
+
// and are not exported.
|
|
333
|
+
// Dependency isolation (DI wiring + the Auth token + analytics).
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Generated bundle index. Do not edit.
|
|
337
|
+
*/
|
|
338
|
+
|
|
339
|
+
export { KIT_DEFAULT_AUTH_TEXT, KIT_FIREBASE_AUTH, kitAuthState, kitGetIdToken, kitReauthWithRetry, kitResolveAuthStatus, kitSendEmailVerification, kitSendPasswordReset, kitSignIn, kitSignOut, kitSignUp, kitUnlinkProvider, provideKitFirebase, provideKitFirebaseAnalytics };
|
|
340
|
+
//# sourceMappingURL=rdlabo-ionic-angular-kit-auth-firebase.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rdlabo-ionic-angular-kit-auth-firebase.mjs","sources":["../../../projects/kit/auth-firebase/src/kit-firebase-provider.ts","../../../projects/kit/auth-firebase/src/kit-firebase-auth-config.ts","../../../projects/kit/auth-firebase/src/kit-firebase-auth.ts","../../../projects/kit/auth-firebase/src/public-api.ts","../../../projects/kit/auth-firebase/src/rdlabo-ionic-angular-kit-auth-firebase.ts"],"sourcesContent":["import type { EnvironmentProviders } from '@angular/core';\nimport { InjectionToken, makeEnvironmentProviders } from '@angular/core';\nimport { Capacitor } from '@capacitor/core';\nimport type { FirebaseOptions } from '@angular/fire/app';\nimport { getApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';\nimport { Auth, getAuth, indexedDBLocalPersistence, initializeAuth, provideAuth } from '@angular/fire/auth';\nimport { getAnalytics, provideAnalytics } from '@angular/fire/analytics';\nimport type { Auth as FirebaseAuth } from 'firebase/auth';\n\n/**\n * DI token for the Firebase `Auth` instance.\n *\n * @remarks\n * Inject this (`inject(KIT_FIREBASE_AUTH)`) instead of `@angular/fire`'s `Auth`, so the\n * `@angular/fire` dependency stays isolated inside the kit. This is the seam that makes the planned\n * `@angular/fire` → `firebase/auth` migration a kit-internal change: only {@link provideKitFirebase}\n * (which binds this token) has to change; every consumer keeps injecting `KIT_FIREBASE_AUTH`.\n *\n * The value is a `firebase/auth` `Auth` (the SDK type is exposed directly, not re-abstracted —\n * Firebase Auth itself is not being dropped, only the `@angular/fire` wrapper).\n */\nexport const KIT_FIREBASE_AUTH = new InjectionToken<FirebaseAuth>('@rdlabo/ionic-angular-kit:firebase-auth');\n\n/** Configuration for {@link provideKitFirebase}. */\nexport interface KitFirebaseConfig {\n /** The Firebase project options (`apiKey`, `authDomain`, `projectId`, …). */\n readonly firebaseConfig: FirebaseOptions;\n}\n\n/**\n * Wire Firebase App + Auth into the application and bind {@link KIT_FIREBASE_AUTH}.\n *\n * @remarks\n * Replaces each app's hand-rolled `provideFirebaseApp(...)` + `provideAuth(...)` (with its\n * native/web persistence branch) with one call, and — crucially — keeps `@angular/fire` out of the\n * application: apps inject {@link KIT_FIREBASE_AUTH} and import auth operations/types straight from\n * `firebase/auth`. On a native platform the persistence uses `indexedDBLocalPersistence`; on the web\n * it uses the default (`getAuth`).\n *\n * @example\n * ```ts\n * bootstrapApplication(AppComponent, {\n * providers: [provideKitFirebase({ firebaseConfig: environment.firebase })],\n * });\n * ```\n */\nexport const provideKitFirebase = (config: KitFirebaseConfig): EnvironmentProviders =>\n makeEnvironmentProviders([\n provideFirebaseApp(() => initializeApp(config.firebaseConfig)),\n provideAuth(() =>\n Capacitor.isNativePlatform()\n ? initializeAuth(getApp(), { persistence: indexedDBLocalPersistence })\n : getAuth(),\n ),\n // Expose @angular/fire's Auth instance under the kit token; phase 3 rebinds this to a\n // firebase/auth instance without touching any consumer.\n { provide: KIT_FIREBASE_AUTH, useExisting: Auth },\n ]);\n\n/**\n * Wire Firebase Analytics into the application (optional; only the apps that use it call this).\n */\nexport const provideKitFirebaseAnalytics = (): EnvironmentProviders =>\n makeEnvironmentProviders([provideAnalytics(() => getAnalytics())]);\n","/** A user-facing message (alert header + body). */\nexport interface KitAuthMessage {\n readonly header: string;\n readonly message: string;\n}\n\n/**\n * The fleet's canonical Firebase auth error dictionary: error `code` → message, plus a fallback for\n * unmapped codes.\n *\n * @remarks\n * The kit does *not* present errors itself (that's an app side effect). This is offered as an\n * importable constant so an app can render its error alert from a shared, canonical source instead of\n * re-declaring the same five messages. Apps that need `$localize` (i18n) keep their own dictionary;\n * JA-only apps can import {@link KIT_DEFAULT_AUTH_TEXT} and spread it, overriding the odd code.\n *\n * @example\n * ```ts\n * import { KIT_DEFAULT_AUTH_TEXT } from '@rdlabo/ionic-angular-kit/auth-firebase';\n *\n * const AUTH_ERRORS = { ...KIT_DEFAULT_AUTH_TEXT.errors, 'auth/wrong-password': { header: '…', message: '…' } };\n * presentError(code: string) {\n * const msg = AUTH_ERRORS[code] ?? KIT_DEFAULT_AUTH_TEXT.fallbackError;\n * return this.overlay.alertClose(msg);\n * }\n * ```\n */\nexport interface KitAuthText {\n /** Firebase error `code` → message. */\n readonly errors: Readonly<Record<string, KitAuthMessage>>;\n /** Shown when an error has no matching `code`. */\n readonly fallbackError: KitAuthMessage;\n}\n\n/** The fleet's canonical Japanese error dictionary (see {@link KitAuthText}). */\nexport const KIT_DEFAULT_AUTH_TEXT: KitAuthText = {\n errors: {\n 'auth/invalid-email': { header: 'メールアドレスが間違っています', message: 'メールアドレスのフォーマットが間違っています。ご確認ください。' },\n 'auth/user-not-found': {\n header: 'ユーザが見つかりません',\n message: '入力いただいたユーザは存在しません。登録されていないメールアドレスか、すでに退会しています。',\n },\n 'auth/wrong-password': {\n header: 'パスワードが間違っています',\n message: '入力いただいたパスワードが間違っているか、このユーザはFacebookログインを利用しており、パスワードログインを有効にしていません。',\n },\n 'auth/weak-password': {\n header: '脆弱性があります',\n message: 'パスワードは最低でも6文字以上のものをご利用ください。大文字小文字数字が混在しているとセキュリティを高めることにつながります。',\n },\n 'auth/email-already-in-use': {\n header: 'ユーザが存在しています',\n message: 'このメールアドレスを利用してすでにユーザが作成されています。ログイン画面に戻って、ログインください。',\n },\n },\n fallbackError: { header: 'エラー', message: '処理に失敗しました' },\n};\n","import type { Auth, User, UserCredential } from 'firebase/auth';\nimport {\n createUserWithEmailAndPassword,\n EmailAuthProvider,\n onAuthStateChanged,\n reauthenticateWithCredential,\n sendEmailVerification,\n sendPasswordResetEmail,\n signInWithEmailAndPassword,\n signOut,\n unlink,\n} from 'firebase/auth';\nimport { Observable } from 'rxjs';\n\n/**\n * Uniform lifecycle hooks for the bundled email/password auth flows — where the app hangs its own\n * side effects on a flow.\n *\n * @remarks\n * The kit performs the Firebase operation and renders nothing itself. `before` runs before the op,\n * `success` on success, `error` on failure (with the raw error — the app presents it, from its own\n * dictionary), and `finally` always. Failures are *not* thrown: value flows resolve to `null` and\n * boolean flows to `false`. Return values are awaited and ignored.\n *\n * @example\n * ```ts\n * kitSignIn(auth, email, password, {\n * error: (e) => this.presentAuthError(e), // app's own error dictionary\n * success: () => this.nav.navigateRoot('/'),\n * });\n * ```\n */\nexport interface KitAuthHooks {\n before?: () => void | Promise<unknown>;\n success?: () => void | Promise<unknown>;\n error?: (error: unknown) => void | Promise<unknown>;\n finally?: () => void | Promise<unknown>;\n}\n\n/** Run a value-returning op through the {@link KitAuthHooks} lifecycle; resolve `null` on failure. */\nconst runAuthFlow = async <T>(op: () => Promise<T>, hooks?: KitAuthHooks): Promise<T | null> => {\n await hooks?.before?.();\n try {\n const result = await op();\n await hooks?.success?.();\n return result;\n } catch (e) {\n await hooks?.error?.(e);\n return null;\n } finally {\n await hooks?.finally?.();\n }\n};\n\n/** Run a void op through the lifecycle; resolve `true` on success, `false` on a (hooked) failure. */\nconst runAuthFlowVoid = async (op: () => Promise<void>, hooks?: KitAuthHooks): Promise<boolean> => {\n const result = await runAuthFlow(async () => {\n await op();\n return true as const;\n }, hooks);\n return result === true;\n};\n\n/**\n * Sign in with email and password.\n *\n * @remarks\n * Bundles the Firebase op so the app never imports `signInWithEmailAndPassword` directly (the SDK\n * stays isolated in the kit). Resolves the credential, or `null` on failure (handed to the `error`\n * hook).\n */\nexport const kitSignIn = (\n auth: Auth,\n email: string,\n password: string,\n hooks?: KitAuthHooks,\n): Promise<UserCredential | null> => runAuthFlow(() => signInWithEmailAndPassword(auth, email, password), hooks);\n\n/**\n * Create an account and send the verification email.\n *\n * @remarks\n * Bundles the two-step \"create → send verification\" sequence. Resolves the credential, or `null` on\n * failure. Any success toast is the caller's, via the `success` hook.\n */\nexport const kitSignUp = (\n auth: Auth,\n email: string,\n password: string,\n hooks?: KitAuthHooks,\n): Promise<UserCredential | null> =>\n runAuthFlow(async () => {\n const credential = await createUserWithEmailAndPassword(auth, email, password);\n await sendEmailVerification(credential.user);\n return credential;\n }, hooks);\n\n/**\n * Sign out.\n *\n * @remarks\n * App-specific cleanup (clearing stores, toasts, navigation, third-party logout) is the caller's,\n * done via the hooks — the kit only owns the Firebase op. `true` on success, `false` on failure.\n */\nexport const kitSignOut = (auth: Auth, hooks?: KitAuthHooks): Promise<boolean> =>\n runAuthFlowVoid(() => signOut(auth), hooks);\n\n/** Send a password-reset email. `true` on success, `false` on failure. */\nexport const kitSendPasswordReset = (auth: Auth, email: string, hooks?: KitAuthHooks): Promise<boolean> =>\n runAuthFlowVoid(() => sendPasswordResetEmail(auth, email), hooks);\n\n/**\n * Unlink a linked auth provider (e.g. `'facebook.com'`, `'apple.com'`) from the current user.\n *\n * @remarks\n * Exposed from the core (not `/social`) so an app can unlink without importing `unlink` from\n * `firebase/auth` directly — keeping the invariant that the SDK is only imported inside the kit. Any\n * app-specific step around it (e.g. a backend DELETE before unlinking) goes in the `before` hook.\n * Resolves the updated `User`, or `null` on failure (including when there is no signed-in user).\n */\nexport const kitUnlinkProvider = (auth: Auth, providerId: string, hooks?: KitAuthHooks): Promise<User | null> =>\n runAuthFlow(() => {\n const user = auth.currentUser;\n if (!user) {\n throw new Error('kitUnlinkProvider: no signed-in user');\n }\n return unlink(user, providerId);\n }, hooks);\n\n/**\n * (Re-)send the verification email to the signed-in user (a no-op when signed out).\n *\n * @remarks\n * `true` on success (including the signed-out no-op), `false` on failure.\n */\nexport const kitSendEmailVerification = (auth: Auth, hooks?: KitAuthHooks): Promise<boolean> =>\n runAuthFlowVoid(async () => {\n const user = auth.currentUser;\n if (user) {\n await sendEmailVerification(user);\n }\n }, hooks);\n\n// This module talks to `firebase/auth` directly (not @angular/fire); only the DI provider\n// (kit-firebase-provider.ts) touches @angular/fire, so the planned SDK swap is provider-local.\n\n/**\n * The current Firebase user as an Observable (emits on every auth-state change; `null` when signed out).\n *\n * @remarks\n * Wraps `onAuthStateChanged` so consumers get an rxjs stream without pulling in `@angular/fire`'s\n * `authState` (or `rxfire`). Emits the current value on subscribe and completes its listener on\n * teardown.\n *\n * @param auth - the Firebase `Auth` instance (inject `KIT_FIREBASE_AUTH`)\n */\nexport const kitAuthState = (auth: Auth): Observable<User | null> =>\n new Observable<User | null>((subscriber) =>\n onAuthStateChanged(\n auth,\n (user) => subscriber.next(user),\n (err) => subscriber.error(err),\n ),\n );\n\n/**\n * The current user's ID token, or `null` when signed out.\n *\n * @remarks\n * For building `Authorization` / bearer headers in interceptors and services. Failure to fetch a\n * token is **thrown, not swallowed** — the caller decides the fallback (e.g. an empty header) as its\n * own side effect, so the kit never silently hides an auth failure.\n *\n * @param auth - the Firebase `Auth` instance (inject `KIT_FIREBASE_AUTH`)\n * @param forceRefresh - force a token refresh (default `false`)\n * @returns the ID token, or `null` if there is no signed-in user\n * @throws if the token fetch fails for a signed-in user\n */\nexport const kitGetIdToken = (auth: Auth, forceRefresh = false): Promise<string | null> => {\n const user = auth.currentUser;\n return user ? user.getIdToken(forceRefresh) : Promise.resolve(null);\n};\n\n/**\n * Thrown by {@link kitReauthenticateThenMutate} when re-authentication fails.\n *\n * @remarks\n * Carries the underlying Firebase error as {@link cause}. A re-auth failure is not always a wrong\n * password (it can be a lockout, an offline network, or an expired session) — use\n * {@link kitIsWrongPasswordError} to tell them apart.\n */\nexport class KitReauthError extends Error {\n constructor(cause?: unknown) {\n super('re-authentication failed');\n this.name = 'KitReauthError';\n this.cause = cause;\n }\n}\n\n/**\n * Firebase error codes that mean \"the current password was wrong\".\n *\n * @remarks\n * Any other re-auth failure (lockout, offline, expired session) must NOT be treated as a wrong\n * password. With email enumeration protection (Firebase v10+) a wrong password is reported as\n * `auth/invalid-credential` rather than `auth/wrong-password`, so both are listed.\n */\nexport const KIT_WRONG_PASSWORD_CODES: ReadonlySet<string> = new Set([\n 'auth/wrong-password',\n 'auth/invalid-credential',\n 'auth/invalid-login-credentials',\n 'auth/missing-password',\n]);\n\n/**\n * Whether an error (typically a {@link KitReauthError}) represents a wrong current password.\n *\n * @param e - the caught error\n */\nexport const kitIsWrongPasswordError = (e: unknown): boolean => {\n const cause = e instanceof KitReauthError ? e.cause : e;\n const code = (cause as { code?: string } | undefined)?.code;\n return code !== undefined && KIT_WRONG_PASSWORD_CODES.has(code);\n};\n\n/**\n * Re-authenticate the current user with their email/password, then run a sensitive mutation.\n *\n * @remarks\n * The one non-trivial mechanic every app cloned before changing email/password: build the\n * `EmailAuthProvider` credential, `reauthenticateWithCredential`, and only on success run `mutate`.\n * Pure — no DI, no UI. A re-auth failure throws {@link KitReauthError}; `mutate`'s own error\n * propagates unwrapped.\n *\n * @param auth - the Firebase `Auth` instance\n * @param currentEmail - the current email (for the re-auth credential)\n * @param currentPassword - the current password (for the re-auth credential)\n * @param mutate - the change to run once re-authenticated, receiving the current `User`\n * @throws {@link KitReauthError} if there is no signed-in user or re-authentication fails\n */\nexport const kitReauthenticateThenMutate = async (\n auth: Auth,\n currentEmail: string,\n currentPassword: string,\n mutate: (user: User) => Promise<void>,\n): Promise<void> => {\n const user = auth.currentUser;\n if (!user) {\n throw new KitReauthError('no current user');\n }\n try {\n await reauthenticateWithCredential(user, EmailAuthProvider.credential(currentEmail, currentPassword));\n } catch (e) {\n throw new KitReauthError(e);\n }\n await mutate(user);\n};\n\n/**\n * The app-supplied side effects for {@link kitReauthWithRetry}.\n *\n * @remarks\n * The kit owns the *control flow* but generates no UI; every user-facing effect (the prompt, the\n * loading overlay) is a callback the app implements, rendering from its own dictionary.\n */\nexport interface KitReauthWithRetryOptions {\n /**\n * Present the current-password prompt.\n *\n * @remarks\n * A side effect — the app presents whatever it likes (e.g. an `ion-alert` with a masked input and\n * dictionary text). Receives `true` when re-prompting after a wrong password.\n *\n * @returns the entered password, or `null` if the user cancels/dismisses\n */\n prompt: (wrongPasswordRetry: boolean) => Promise<string | null>;\n /**\n * The sensitive change to run once re-authenticated.\n *\n * @remarks\n * Keep this pure — just the Firebase op(s) (e.g. `updatePassword(user, next)`). Loading and other\n * UI are side effects handled by {@link withLoading}, not here.\n */\n mutate: (user: User) => Promise<void>;\n /**\n * Wrap the re-authentication + mutation with a loading indicator (a side effect).\n *\n * @remarks\n * Optional. Runs only after a password is entered, around each attempt — so no loading flashes on a\n * cancelled prompt, and it re-shows on a wrong-password retry. The app implements it (e.g.\n * present/dismiss an `ion-loading`).\n */\n withLoading?: (run: () => Promise<void>) => Promise<void>;\n}\n\n/**\n * Run the fleet's canonical \"confirm current password → change\" flow, re-prompting in place on a\n * wrong password.\n *\n * @remarks\n * Owns the drift-prone *control flow* (the retry loop, the wrong-password classification every app\n * once got wrong, and when to show loading) while generating **no UI** — the prompt and the loading\n * overlay are {@link KitReauthWithRetryOptions | side-effect callbacks} the app supplies. On a wrong\n * password the loop re-prompts instead of dropping the user out of the flow. Any non-wrong-password\n * re-auth failure (lockout, offline, expired session) and any error from `mutate` are re-thrown —\n * re-auth failures unwrapped to the underlying Firebase error so the caller's error dictionary can\n * read its `code`.\n *\n * @param auth - the Firebase `Auth` instance\n * @param currentEmail - the current email (for the re-auth credential)\n * @param options - the pure mutation plus the app's prompt / loading side effects\n * @returns `true` if the mutation completed, `false` if the user cancelled\n * @throws the underlying Firebase error on a non-wrong-password failure, or `mutate`'s own error\n */\nexport const kitReauthWithRetry = async (\n auth: Auth,\n currentEmail: string,\n options: KitReauthWithRetryOptions,\n): Promise<boolean> => {\n const run = options.withLoading ?? ((fn) => fn());\n let wrongPasswordRetry = false;\n for (;;) {\n const password = await options.prompt(wrongPasswordRetry);\n if (password === null) {\n return false;\n }\n try {\n await run(() => kitReauthenticateThenMutate(auth, currentEmail, password, options.mutate));\n return true;\n } catch (e) {\n if (kitIsWrongPasswordError(e)) {\n wrongPasswordRetry = true;\n continue;\n }\n throw e instanceof KitReauthError && e.cause instanceof Error ? e.cause : e;\n }\n }\n};\n\n/** The fleet's 3-state auth status derived from the Firebase user. */\nexport type KitAuthStatus = 'user' | 'confirm' | 'required';\n\n/** Options for {@link kitResolveAuthStatus}. */\nexport interface KitResolveAuthStatusOptions {\n /**\n * Provider IDs that count as verified even without `emailVerified` — a social login (e.g.\n * `'facebook.com'`, `'apple.com'`) has no email-verification step but is a real, trusted account.\n */\n readonly verifiedProviders?: readonly string[];\n /**\n * Extra predicate to treat a signed-in user as fully authed regardless of verification — for an\n * e2e bypass or an anonymous-allowed app. Receives the current user.\n */\n readonly allowWhen?: (user: User) => boolean;\n}\n\n/**\n * Classify a Firebase user into the fleet's 3-state auth status.\n *\n * @remarks\n * `null` (signed out) → `'required'`. A signed-in user is `'user'` when their email is verified, OR\n * they signed in with one of `verifiedProviders`, OR `allowWhen` returns true; otherwise `'confirm'`\n * (signed in but unverified). This is only the shared classification — app-specific side effects\n * around it (reloading the user to refresh `emailVerified`, caching a token) stay in the app.\n *\n * @example\n * ```ts\n * kitResolveAuthStatus(user, {\n * verifiedProviders: ['facebook.com', 'apple.com'],\n * allowWhen: () => environment.e2e,\n * });\n * ```\n */\nexport const kitResolveAuthStatus = (user: User | null, options?: KitResolveAuthStatusOptions): KitAuthStatus => {\n if (user === null) {\n return 'required';\n }\n const verifiedByProvider =\n options?.verifiedProviders?.some((id) => user.providerData.some((p) => p.providerId === id)) ?? false;\n const verified = user.emailVerified || verifiedByProvider || (options?.allowWhen?.(user) ?? false);\n return verified ? 'user' : 'confirm';\n};\n","// Firebase auth: the flow library for the fleet. `@angular/fire` is used in *one* place only — the\n// DI provider (kit-firebase-provider.ts) — so the planned `@angular/fire` → `firebase/auth` swap is\n// provider-local. Apps inject `KIT_FIREBASE_AUTH` and call these pure flow functions, never importing\n// the SDK for the covered operations.\n//\n// The public surface is intentionally curated: dependency wiring plus pure flow functions (each\n// pairing a Firebase operation with the uniform `{ before, success, error, finally }` hooks and the\n// no-throw null/false contract). The re-auth mechanics (kitReauthenticateThenMutate / KitReauthError\n// / KIT_WRONG_PASSWORD_CODES / kitIsWrongPasswordError) are internal details of `kitReauthWithRetry`\n// and are not exported.\n\n// Dependency isolation (DI wiring + the Auth token + analytics).\nexport * from './kit-firebase-provider';\n\n// The canonical error dictionary — an importable constant for apps to render their own error alert.\nexport { KIT_DEFAULT_AUTH_TEXT } from './kit-firebase-auth-config';\nexport type { KitAuthText, KitAuthMessage } from './kit-firebase-auth-config';\n\n// Adapters + pure flow functions.\nexport {\n kitAuthState,\n kitGetIdToken,\n kitResolveAuthStatus,\n kitSignIn,\n kitSignUp,\n kitSignOut,\n kitSendPasswordReset,\n kitSendEmailVerification,\n kitUnlinkProvider,\n kitReauthWithRetry,\n} from './kit-firebase-auth';\nexport type {\n KitAuthHooks,\n KitAuthStatus,\n KitResolveAuthStatusOptions,\n KitReauthWithRetryOptions,\n} from './kit-firebase-auth';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|