@sneat/auth-core 0.27.28 → 0.27.30
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/esm2022/lib/sneat-auth-guard.js +3 -3
- package/esm2022/lib/sneat-auth-guard.js.map +1 -1
- package/esm2022/lib/sneat-auth-state-service.js +12 -6
- package/esm2022/lib/sneat-auth-state-service.js.map +1 -1
- package/esm2022/lib/user/index.js +1 -0
- package/esm2022/lib/user/index.js.map +1 -1
- package/esm2022/lib/user/sneat-account-readiness.js +21 -0
- package/esm2022/lib/user/sneat-account-readiness.js.map +1 -0
- package/esm2022/lib/user/sneat-user.service.js +216 -23
- package/esm2022/lib/user/sneat-user.service.js.map +1 -1
- package/lib/sneat-auth-guard.d.ts +4 -4
- package/lib/user/index.d.ts +1 -0
- package/lib/user/sneat-account-readiness.d.ts +7 -0
- package/lib/user/sneat-user.service.d.ts +19 -0
- package/package.json +1 -1
- package/tsconfig.lib.prod.tsbuildinfo +1 -1
|
@@ -13,13 +13,13 @@ import * as i0 from "@angular/core";
|
|
|
13
13
|
* never read, and that injection is what coupled this file to `@angular/fire`.
|
|
14
14
|
*/
|
|
15
15
|
export class SneatAuthGuard {
|
|
16
|
-
canLoad(
|
|
16
|
+
canLoad() {
|
|
17
17
|
return true;
|
|
18
18
|
}
|
|
19
|
-
canActivate(
|
|
19
|
+
canActivate() {
|
|
20
20
|
return true;
|
|
21
21
|
}
|
|
22
|
-
canActivateChild(
|
|
22
|
+
canActivateChild() {
|
|
23
23
|
return true;
|
|
24
24
|
}
|
|
25
25
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: SneatAuthGuard, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sneat-auth-guard.js","sourceRoot":"","sources":["../../../../../../libs/auth/core/src/lib/sneat-auth-guard.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sneat-auth-guard.js","sourceRoot":"","sources":["../../../../../../libs/auth/core/src/lib/sneat-auth-guard.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;;AAE3C;;;;;;;;;;;GAWG;AAIH,MAAM,OAAO,cAAc;IAClB,OAAO;QAKZ,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,WAAW;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,gBAAgB;QACd,OAAO,IAAI,CAAC;IACd,CAAC;8GAfU,cAAc;kHAAd,cAAc,cAFb,MAAM;;2FAEP,cAAc;kBAH1B,UAAU;mBAAC;oBACV,UAAU,EAAE,MAAM;iBACnB;;AAmBD;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,WAAW,EAAE,CAAC,cAAc,CAAC;IAC7B,OAAO,EAAE,CAAC,cAAc,CAAC;CAC1B,CAAC","sourcesContent":["import {\n UrlTree,\n} from '@angular/router';\nimport { Observable } from 'rxjs';\nimport { Injectable } from '@angular/core';\n\n/**\n * Permissive class-based route guard: every hook returns `true`.\n *\n * @deprecated Prefer the functional `sneatAuthGuard`\n * (`./redirect-to-login.guard`), which actually blocks an unauthenticated\n * visitor and redirects them to `/login`. This guard admits everyone — it\n * never gated anything — and is kept only so existing route configs\n * referencing `SNEAT_AUTH_GUARDS` keep compiling.\n *\n * As of 0.27.0 it no longer injects Firebase `Auth`: the injected instance was\n * never read, and that injection is what coupled this file to `@angular/fire`.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class SneatAuthGuard {\n public canLoad():\n | Observable<boolean | UrlTree>\n | Promise<boolean | UrlTree>\n | boolean\n | UrlTree {\n return true;\n }\n\n public canActivate() {\n return true;\n }\n\n canActivateChild() {\n return true;\n }\n}\n\n/**\n * @deprecated Use `{ canActivate: [sneatAuthGuard] }` instead — see\n * `./redirect-to-login.guard`. Retained for route configs that still reference\n * it; both hooks resolve to the permissive `SneatAuthGuard` above.\n */\nexport const SNEAT_AUTH_GUARDS = {\n canActivate: [SneatAuthGuard],\n canLoad: [SneatAuthGuard],\n};\n"]}
|
|
@@ -58,14 +58,18 @@ export class SneatAuthStateService {
|
|
|
58
58
|
this.publishSignedOutState();
|
|
59
59
|
return;
|
|
60
60
|
}
|
|
61
|
+
const authUser = createSneatAuthUserFromFbUser(firebaseUser);
|
|
62
|
+
const current = this.authState$.value || {};
|
|
63
|
+
if (current.user?.uid !== authUser?.uid) {
|
|
64
|
+
this.analyticsService.identify(firebaseUser.uid);
|
|
65
|
+
}
|
|
61
66
|
this.authState$.next({
|
|
62
|
-
...
|
|
67
|
+
...current,
|
|
63
68
|
status: AuthStatuses.authenticating,
|
|
64
69
|
loadingPhase: 'getting-token',
|
|
70
|
+
token: current.user?.uid === authUser?.uid ? current.token : null,
|
|
71
|
+
user: authUser,
|
|
65
72
|
});
|
|
66
|
-
if (this.authState$.value?.user?.uid !== firebaseUser?.uid) {
|
|
67
|
-
this.analyticsService.identify(firebaseUser.uid);
|
|
68
|
-
}
|
|
69
73
|
firebaseUser
|
|
70
74
|
.getIdToken(false)
|
|
71
75
|
.then((token) => {
|
|
@@ -75,7 +79,9 @@ export class SneatAuthStateService {
|
|
|
75
79
|
}
|
|
76
80
|
this.tokenUserID = firebaseUser.uid;
|
|
77
81
|
const authUser = createSneatAuthUserFromFbUser(firebaseUser);
|
|
78
|
-
|
|
82
|
+
const previousAuthUser = this.authUser$.value;
|
|
83
|
+
if (previousAuthUser?.uid !== authUser?.uid ||
|
|
84
|
+
previousAuthUser?.isAnonymous !== authUser?.isAnonymous) {
|
|
79
85
|
this.authUser$.next(authUser);
|
|
80
86
|
}
|
|
81
87
|
const current = this.authState$.value || {};
|
|
@@ -232,7 +238,7 @@ export class SneatAuthStateService {
|
|
|
232
238
|
const auth = getAuth();
|
|
233
239
|
const userCredential = await signInWithCredential(auth, credential);
|
|
234
240
|
// Get a valid Firebase ID token that has a 'kid' header
|
|
235
|
-
|
|
241
|
+
await userCredential.user.getIdToken();
|
|
236
242
|
return Promise.resolve(userCredential);
|
|
237
243
|
}
|
|
238
244
|
async signInWithWebSDK(authProviderID) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sneat-auth-state-service.js","sourceRoot":"","sources":["../../../../../../libs/auth/core/src/lib/sneat-auth-state-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { SignInWithOAuthOptions } from '@capacitor-firebase/authentication/dist/esm/definitions';\nimport { Capacitor } from '@capacitor/core';\nimport {\n FirebaseAuthentication,\n SignInResult,\n} from '@capacitor-firebase/authentication';\nimport {\n AnalyticsService,\n clearCurrentSpace,\n EnumAsUnionOfKeys,\n EnvConfigToken,\n IAnalyticsService,\n SNEAT_FIREBASE_AUTH,\n SneatUrlOperationBlocker,\n} from '@sneat/core';\nimport { BehaviorSubject, from, Observable } from 'rxjs';\nimport { Injectable, inject } from '@angular/core';\nimport { ErrorLogger, IErrorLogger } from '@sneat/core';\nimport { distinctUntilChanged, shareReplay } from 'rxjs/operators';\nimport {\n AuthProvider,\n getAuth,\n signInWithCredential,\n User,\n UserCredential,\n UserInfo,\n GoogleAuthProvider,\n OAuthProvider,\n GithubAuthProvider,\n FacebookAuthProvider,\n signInWithEmailLink,\n signInWithCustomToken,\n signInWithPopup,\n signInWithRedirect,\n linkWithPopup,\n unlink,\n createUserWithEmailAndPassword,\n signInWithEmailAndPassword,\n} from 'firebase/auth';\n\n// TODO: fix & remove this eslint hint @nrwl/nx/enforce-module-boundaries\n\nimport { newRandomId } from '@sneat/random';\n\nexport enum AuthStatuses {\n authenticating = 'authenticating',\n authenticated = 'authenticated',\n notAuthenticated = 'notAuthenticated',\n}\n\nexport type AuthStatus = EnumAsUnionOfKeys<typeof AuthStatuses>;\n\n/**\n * A user-visible, evidence-based session progress phase. The UI maps these to\n * friendly copy (for example “Checking your sign-in”), never SDK terminology.\n */\nexport type SneatAuthLoadingPhase =\n | 'checking-session'\n | 'getting-token'\n | 'ready'\n | 'failed';\n\nexport interface ISneatAuthUser extends UserInfo {\n readonly isAnonymous: boolean;\n readonly emailVerified: boolean;\n readonly providerData: readonly UserInfo[];\n}\n\nexport interface ISneatAuthState {\n readonly status: AuthStatus;\n readonly loadingPhase?: SneatAuthLoadingPhase;\n readonly token?: string | null;\n readonly user?: ISneatAuthUser | null;\n readonly err?: unknown;\n}\n\nexport interface ISneatEmailAuthResult {\n readonly userID: string;\n readonly token: string;\n}\n\nconst initialAuthStatus = AuthStatuses.authenticating;\nexport const initialSneatAuthState = {\n status: initialAuthStatus,\n loadingPhase: 'checking-session' as const,\n};\n\n// The host must provide this from its authenticated route/session boundary.\n// Keeping it out of the root injector is what allows public shells to render\n// before Firebase Auth and Firestore are downloaded.\n@Injectable()\nexport class SneatAuthStateService {\n private readonly errorLogger = inject<IErrorLogger>(ErrorLogger);\n private readonly analyticsService =\n inject<IAnalyticsService>(AnalyticsService);\n readonly fbAuth = inject(SNEAT_FIREBASE_AUTH);\n private readonly operationBlocker = inject(SneatUrlOperationBlocker);\n\n // Web OAuth sign-in strategy from the app's environment config (default popup).\n private readonly signInMethod =\n inject(EnvConfigToken, { optional: true })?.signInMethod ?? 'popup';\n\n private readonly id = newRandomId({ len: 5 });\n\n private readonly authStatus$ = new BehaviorSubject<AuthStatus>(\n initialAuthStatus,\n );\n public readonly authStatus = this.authStatus$\n .asObservable()\n .pipe(distinctUntilChanged());\n\n private readonly authUser$ = new BehaviorSubject<\n ISneatAuthUser | null | undefined\n >(undefined);\n public readonly authUser = this.authUser$.asObservable();\n\n private readonly authState$ = new BehaviorSubject<ISneatAuthState>(\n initialSneatAuthState,\n );\n public readonly authState = this.authState$.asObservable().pipe(\n // tap(v => console.log('SneatAuthStateService => SneatAuthState:', v)),\n shareReplay(1),\n );\n\n private tokenGeneration = 0;\n private tokenUserID?: string;\n\n // private readonly fbAuth: Auth;\n\n constructor() {\n const errorLogger = this.errorLogger;\n this.fbAuth.onIdTokenChanged({\n next: (firebaseUser) => {\n if (this.operationBlocker.isBlocked('auth')) {\n return;\n }\n const tokenGeneration = ++this.tokenGeneration;\n const status: AuthStatus = firebaseUser\n ? AuthStatuses.authenticated\n : AuthStatuses.notAuthenticated;\n if (!firebaseUser) {\n this.publishSignedOutState();\n return;\n }\n this.authState$.next({\n ...this.authState$.value,\n status: AuthStatuses.authenticating,\n loadingPhase: 'getting-token',\n });\n if (\n this.authState$.value?.user?.uid !== firebaseUser?.uid\n ) {\n this.analyticsService.identify(firebaseUser.uid);\n }\n firebaseUser\n .getIdToken(false)\n .then((token) => {\n if (\n tokenGeneration !== this.tokenGeneration ||\n this.fbAuth.currentUser !== firebaseUser\n ) {\n return;\n }\n this.tokenUserID = firebaseUser.uid;\n const authUser = createSneatAuthUserFromFbUser(firebaseUser);\n if (this.authUser$.value?.uid !== authUser?.uid) {\n this.authUser$.next(authUser);\n }\n const current = this.authState$.value || {};\n this.authState$.next({\n ...current,\n status,\n loadingPhase: 'ready',\n token,\n user: authUser,\n });\n this.authStatus$.next(status); // Should be after authState$\n })\n .catch((err) => {\n if (\n tokenGeneration !== this.tokenGeneration ||\n this.fbAuth.currentUser !== firebaseUser\n ) {\n return;\n }\n const current = this.authState$.value || {};\n this.authState$.next({\n ...current,\n loadingPhase: 'failed',\n err: `fbUser.getIdToken() failed: ${err}`,\n });\n this.errorLogger.logError(err, 'Failed in fbUser.getIdToken()');\n });\n },\n error: (err) => {\n if (this.operationBlocker.isBlocked('auth')) {\n return;\n }\n const current = this.authState$.value || {};\n this.authState$.next({\n ...current,\n loadingPhase: 'failed',\n err: `fbAuth.onIdTokenChanged() failed: ${err}`,\n });\n errorLogger.logError(err, 'failed in fbAuth.onIdTokenChanged');\n },\n complete: () => void 0,\n });\n this.fbAuth.onAuthStateChanged({\n complete: () => void 0,\n next: (fbUser) => {\n if (this.operationBlocker.isBlocked('auth')) {\n return;\n }\n // console.log(\n // `SneatAuthStateService => authStatus: ${this.authStatus$.value}; fbUser`,\n // fbUser,\n // );\n const authUser = createSneatAuthUserFromFbUser(fbUser);\n if (!authUser) {\n ++this.tokenGeneration;\n this.publishSignedOutState();\n return;\n }\n const status = AuthStatuses.authenticated;\n this.authUser$.next(authUser);\n this.authState$.next({\n ...this.authState$.value,\n token:\n this.tokenUserID === authUser.uid\n ? this.authState$.value.token\n : null,\n user: authUser,\n status,\n loadingPhase: 'ready',\n });\n this.authStatus$.next(status);\n },\n error: (err) => {\n if (this.operationBlocker.isBlocked('auth')) {\n return;\n }\n this.errorLogger.logError(\n err,\n 'failed to retrieve Firebase auth user information',\n );\n const current = this.authState$.value || {};\n this.authState$.next({\n ...current,\n loadingPhase: 'failed',\n err: `fbAuth.onAuthStateChanged() failed: ${err}`,\n });\n },\n });\n }\n\n private publishSignedOutState(): void {\n clearCurrentSpace();\n this.tokenUserID = undefined;\n this.authUser$.next(null);\n this.authState$.next({\n ...this.authState$.value,\n status: AuthStatuses.notAuthenticated,\n loadingPhase: 'ready',\n token: null,\n user: null,\n });\n this.authStatus$.next(AuthStatuses.notAuthenticated);\n }\n\n public signOut(): Promise<void> {\n clearCurrentSpace();\n return this.fbAuth.signOut();\n }\n\n public signInWithToken(token: string): Promise<UserCredential> {\n return signInWithCustomToken(this.fbAuth, token);\n }\n\n public signInWithEmailLink(email: string): Observable<UserCredential> {\n return from(signInWithEmailLink(this.fbAuth, email));\n }\n\n public createUserWithEmailAndPassword(\n email: string,\n password: string,\n ): Promise<ISneatEmailAuthResult> {\n return this.toEmailAuthResult(\n createUserWithEmailAndPassword(this.fbAuth, email, password),\n );\n }\n\n public signInWithEmailAndPassword(\n email: string,\n password: string,\n ): Promise<ISneatEmailAuthResult> {\n return this.toEmailAuthResult(\n signInWithEmailAndPassword(this.fbAuth, email, password),\n );\n }\n\n private async toEmailAuthResult(\n credential: Promise<UserCredential>,\n ): Promise<ISneatEmailAuthResult> {\n const { user } = await credential;\n return {\n userID: user.uid,\n token: await user.getIdToken(),\n };\n }\n\n private isSigningInWith?: AuthProviderName;\n\n private async signInOnNativeLayer(\n authProviderID: AuthProviderID,\n ): Promise<UserCredential> {\n let signInResult: SignInResult | undefined;\n\n const o: SignInWithOAuthOptions = { skipNativeAuth: true };\n\n switch (authProviderID) {\n case 'google.com':\n signInResult = await FirebaseAuthentication.signInWithGoogle(o);\n break;\n case 'apple.com':\n signInResult = await FirebaseAuthentication.signInWithApple(o);\n break;\n case 'facebook.com':\n signInResult = await FirebaseAuthentication.signInWithFacebook(o);\n break;\n case 'microsoft.com':\n signInResult = await FirebaseAuthentication.signInWithMicrosoft(o);\n break;\n default:\n return Promise.reject('unsupported auth provider: ' + authProviderID);\n }\n // console.log(\n // `SneatAuthStateService.signInWith(${authProviderID}) => signed in on native layer, authenticating in webview...`,\n // signInResult,\n // );\n // we need to authenticate on webview layer using the id token and nonce from signInResult\n const userCredential = await this.authenticateOnWebviewLayer(\n authProviderID,\n signInResult,\n );\n\n return Promise.resolve(userCredential);\n }\n\n private async authenticateOnWebviewLayer(\n authProviderID: AuthProviderID,\n signInResult: SignInResult,\n ): Promise<UserCredential> {\n const oauthProvider = new OAuthProvider(authProviderID);\n const credential = oauthProvider.credential({\n idToken: signInResult.credential?.idToken,\n accessToken: signInResult.credential?.accessToken,\n rawNonce: signInResult.credential?.nonce,\n });\n const auth = getAuth();\n const userCredential = await signInWithCredential(auth, credential);\n\n // Get a valid Firebase ID token that has a 'kid' header\n const _firebaseIdToken = await userCredential.user.getIdToken();\n\n return Promise.resolve(userCredential);\n }\n\n private async signInWithWebSDK(\n authProviderID: AuthProviderID,\n ): Promise<UserCredential | undefined> {\n const authProvider = getAuthProvider(authProviderID);\n if (this.signInMethod === 'redirect') {\n // Full-page redirect; this navigates away and never resolves. The sign-in\n // is completed on return by BaseAppComponent's getRedirectResult() call.\n await signInWithRedirect(this.fbAuth, authProvider);\n return undefined;\n }\n const userCredential = await signInWithPopup(this.fbAuth, authProvider);\n return Promise.resolve(userCredential);\n }\n\n public async linkWith(\n authProviderID: AuthProviderID,\n ): Promise<UserCredential | undefined> {\n const authProvider = getAuthProvider(authProviderID);\n if (!this.fbAuth.currentUser) {\n return Promise.reject('no current user');\n }\n const userCredential = await linkWithPopup(\n this.fbAuth.currentUser,\n authProvider,\n );\n return Promise.resolve(userCredential);\n }\n\n public async unlinkAuthProvider(authProviderID: string): Promise<void> {\n const currentUser = this.fbAuth.currentUser;\n if (currentUser) {\n try {\n const updatedUser = await unlink(currentUser, authProviderID);\n const authUser = createSneatAuthUserFromFbUser(updatedUser);\n this.authUser$.next(authUser);\n return Promise.resolve();\n } catch (error) {\n return Promise.reject(\n `Failed to unlink ${authProviderID} account:` + error,\n );\n }\n } else {\n return Promise.reject('No user is currently signed in.');\n }\n }\n\n public async signInWith(\n authProviderID: AuthProviderID,\n ): Promise<UserCredential | undefined> {\n // console.log(\n // `SneatAuthStateService.signInWith(${authProviderID}), isSigningInWith=${this.isSigningInWith}, location.protocol=${location.protocol}`,\n // );\n this.analyticsService.logEvent('signingInWith', {\n provider: authProviderID,\n });\n try {\n if (this.isSigningInWith) {\n return Promise.reject(\n new Error(\n `a repeated call to SneatAuthStateService.signInWith(${authProviderID}) white previous sign in with ${this.isSigningInWith} is in progress`,\n ),\n );\n }\n\n let userCredential: UserCredential | undefined = undefined;\n\n if (Capacitor.isNativePlatform()) {\n userCredential = await this.signInOnNativeLayer(authProviderID);\n } else {\n userCredential = await this.signInWithWebSDK(authProviderID);\n }\n\n this.isSigningInWith = undefined;\n this.analyticsService.logEvent('signedInWith', {\n provider: authProviderID,\n });\n return Promise.resolve(userCredential);\n } catch (e) {\n this.isSigningInWith = undefined;\n return Promise.reject(e);\n }\n }\n}\n\nexport type AuthProviderID =\n | 'apple.com'\n | 'google.com'\n | 'microsoft.com'\n | 'facebook.com'\n | 'github.com'\n | 'phone';\n\nexport type AuthProviderName =\n | 'Google'\n | 'Apple'\n | 'Microsoft'\n | 'Facebook'\n | 'GitHub';\n\nfunction getAuthProvider(authProviderID: AuthProviderID): AuthProvider {\n switch (authProviderID) {\n case 'google.com':\n return new GoogleAuthProvider();\n case 'apple.com':\n return new OAuthProvider('apple.com');\n //\n // https://developer.apple.com/documentation/sign_in_with_apple/incorporating-sign-in-with-apple-into-other-platforms\n // (authProvider as OAuthProvider).setCustomParameters({\n // \t// \t// Localize the Apple authentication screen in current app locale.\n // \tlocale: 'en', // TODO: set locale\n // });\n case 'microsoft.com':\n return new OAuthProvider('microsoft.com');\n case 'facebook.com': {\n const facebookAuthProvider = new FacebookAuthProvider();\n facebookAuthProvider.addScope('email');\n return facebookAuthProvider;\n }\n case 'github.com': {\n const githubAuthProvider = new GithubAuthProvider();\n githubAuthProvider.addScope('read:user');\n githubAuthProvider.addScope('user:email');\n return githubAuthProvider;\n }\n default:\n throw new Error('unsupported auth provider: ' + authProviderID);\n }\n}\n\nfunction createSneatAuthUserFromFbUser(\n fbUser: User | null,\n): ISneatAuthUser | null {\n return (\n fbUser && {\n isAnonymous: fbUser.isAnonymous,\n emailVerified: fbUser.emailVerified,\n email: fbUser.email,\n uid: fbUser.uid,\n displayName: fbUser.displayName,\n phoneNumber: fbUser.phoneNumber,\n photoURL: fbUser.photoURL,\n providerId:\n fbUser.providerData?.length === 1 && fbUser.providerData[0]\n ? fbUser.providerData[0].providerId\n : fbUser.providerId,\n providerData: fbUser.providerData,\n }\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sneat-auth-state-service.js","sourceRoot":"","sources":["../../../../../../libs/auth/core/src/lib/sneat-auth-state-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { SignInWithOAuthOptions } from '@capacitor-firebase/authentication/dist/esm/definitions';\nimport { Capacitor } from '@capacitor/core';\nimport {\n FirebaseAuthentication,\n SignInResult,\n} from '@capacitor-firebase/authentication';\nimport {\n AnalyticsService,\n clearCurrentSpace,\n EnumAsUnionOfKeys,\n EnvConfigToken,\n IAnalyticsService,\n SNEAT_FIREBASE_AUTH,\n SneatUrlOperationBlocker,\n} from '@sneat/core';\nimport { BehaviorSubject, from, Observable } from 'rxjs';\nimport { Injectable, inject } from '@angular/core';\nimport { ErrorLogger, IErrorLogger } from '@sneat/core';\nimport { distinctUntilChanged, shareReplay } from 'rxjs/operators';\nimport {\n AuthProvider,\n getAuth,\n signInWithCredential,\n User,\n UserCredential,\n UserInfo,\n GoogleAuthProvider,\n OAuthProvider,\n GithubAuthProvider,\n FacebookAuthProvider,\n signInWithEmailLink,\n signInWithCustomToken,\n signInWithPopup,\n signInWithRedirect,\n linkWithPopup,\n unlink,\n createUserWithEmailAndPassword,\n signInWithEmailAndPassword,\n} from 'firebase/auth';\n\n// TODO: fix & remove this eslint hint @nrwl/nx/enforce-module-boundaries\n\nimport { newRandomId } from '@sneat/random';\n\nexport enum AuthStatuses {\n authenticating = 'authenticating',\n authenticated = 'authenticated',\n notAuthenticated = 'notAuthenticated',\n}\n\nexport type AuthStatus = EnumAsUnionOfKeys<typeof AuthStatuses>;\n\n/**\n * A user-visible, evidence-based session progress phase. The UI maps these to\n * friendly copy (for example “Checking your sign-in”), never SDK terminology.\n */\nexport type SneatAuthLoadingPhase =\n | 'checking-session'\n | 'getting-token'\n | 'ready'\n | 'failed';\n\nexport interface ISneatAuthUser extends UserInfo {\n readonly isAnonymous: boolean;\n readonly emailVerified: boolean;\n readonly providerData: readonly UserInfo[];\n}\n\nexport interface ISneatAuthState {\n readonly status: AuthStatus;\n readonly loadingPhase?: SneatAuthLoadingPhase;\n readonly token?: string | null;\n readonly user?: ISneatAuthUser | null;\n readonly err?: unknown;\n}\n\nexport interface ISneatEmailAuthResult {\n readonly userID: string;\n readonly token: string;\n}\n\nconst initialAuthStatus = AuthStatuses.authenticating;\nexport const initialSneatAuthState = {\n status: initialAuthStatus,\n loadingPhase: 'checking-session' as const,\n};\n\n// The host must provide this from its authenticated route/session boundary.\n// Keeping it out of the root injector is what allows public shells to render\n// before Firebase Auth and Firestore are downloaded.\n@Injectable()\nexport class SneatAuthStateService {\n private readonly errorLogger = inject<IErrorLogger>(ErrorLogger);\n private readonly analyticsService =\n inject<IAnalyticsService>(AnalyticsService);\n readonly fbAuth = inject(SNEAT_FIREBASE_AUTH);\n private readonly operationBlocker = inject(SneatUrlOperationBlocker);\n\n // Web OAuth sign-in strategy from the app's environment config (default popup).\n private readonly signInMethod =\n inject(EnvConfigToken, { optional: true })?.signInMethod ?? 'popup';\n\n private readonly id = newRandomId({ len: 5 });\n\n private readonly authStatus$ = new BehaviorSubject<AuthStatus>(\n initialAuthStatus,\n );\n public readonly authStatus = this.authStatus$\n .asObservable()\n .pipe(distinctUntilChanged());\n\n private readonly authUser$ = new BehaviorSubject<\n ISneatAuthUser | null | undefined\n >(undefined);\n public readonly authUser = this.authUser$.asObservable();\n\n private readonly authState$ = new BehaviorSubject<ISneatAuthState>(\n initialSneatAuthState,\n );\n public readonly authState = this.authState$.asObservable().pipe(\n // tap(v => console.log('SneatAuthStateService => SneatAuthState:', v)),\n shareReplay(1),\n );\n\n private tokenGeneration = 0;\n private tokenUserID?: string;\n\n // private readonly fbAuth: Auth;\n\n constructor() {\n const errorLogger = this.errorLogger;\n this.fbAuth.onIdTokenChanged({\n next: (firebaseUser) => {\n if (this.operationBlocker.isBlocked('auth')) {\n return;\n }\n const tokenGeneration = ++this.tokenGeneration;\n const status: AuthStatus = firebaseUser\n ? AuthStatuses.authenticated\n : AuthStatuses.notAuthenticated;\n if (!firebaseUser) {\n this.publishSignedOutState();\n return;\n }\n const authUser = createSneatAuthUserFromFbUser(firebaseUser);\n const current = this.authState$.value || {};\n if (current.user?.uid !== authUser?.uid) {\n this.analyticsService.identify(firebaseUser.uid);\n }\n this.authState$.next({\n ...current,\n status: AuthStatuses.authenticating,\n loadingPhase: 'getting-token',\n token: current.user?.uid === authUser?.uid ? current.token : null,\n user: authUser,\n });\n firebaseUser\n .getIdToken(false)\n .then((token) => {\n if (\n tokenGeneration !== this.tokenGeneration ||\n this.fbAuth.currentUser !== firebaseUser\n ) {\n return;\n }\n this.tokenUserID = firebaseUser.uid;\n const authUser = createSneatAuthUserFromFbUser(firebaseUser);\n const previousAuthUser = this.authUser$.value;\n if (\n previousAuthUser?.uid !== authUser?.uid ||\n previousAuthUser?.isAnonymous !== authUser?.isAnonymous\n ) {\n this.authUser$.next(authUser);\n }\n const current = this.authState$.value || {};\n this.authState$.next({\n ...current,\n status,\n loadingPhase: 'ready',\n token,\n user: authUser,\n });\n this.authStatus$.next(status); // Should be after authState$\n })\n .catch((err) => {\n if (\n tokenGeneration !== this.tokenGeneration ||\n this.fbAuth.currentUser !== firebaseUser\n ) {\n return;\n }\n const current = this.authState$.value || {};\n this.authState$.next({\n ...current,\n loadingPhase: 'failed',\n err: `fbUser.getIdToken() failed: ${err}`,\n });\n this.errorLogger.logError(err, 'Failed in fbUser.getIdToken()');\n });\n },\n error: (err) => {\n if (this.operationBlocker.isBlocked('auth')) {\n return;\n }\n const current = this.authState$.value || {};\n this.authState$.next({\n ...current,\n loadingPhase: 'failed',\n err: `fbAuth.onIdTokenChanged() failed: ${err}`,\n });\n errorLogger.logError(err, 'failed in fbAuth.onIdTokenChanged');\n },\n complete: () => void 0,\n });\n this.fbAuth.onAuthStateChanged({\n complete: () => void 0,\n next: (fbUser) => {\n if (this.operationBlocker.isBlocked('auth')) {\n return;\n }\n // console.log(\n // `SneatAuthStateService => authStatus: ${this.authStatus$.value}; fbUser`,\n // fbUser,\n // );\n const authUser = createSneatAuthUserFromFbUser(fbUser);\n if (!authUser) {\n ++this.tokenGeneration;\n this.publishSignedOutState();\n return;\n }\n const status = AuthStatuses.authenticated;\n this.authUser$.next(authUser);\n this.authState$.next({\n ...this.authState$.value,\n token:\n this.tokenUserID === authUser.uid\n ? this.authState$.value.token\n : null,\n user: authUser,\n status,\n loadingPhase: 'ready',\n });\n this.authStatus$.next(status);\n },\n error: (err) => {\n if (this.operationBlocker.isBlocked('auth')) {\n return;\n }\n this.errorLogger.logError(\n err,\n 'failed to retrieve Firebase auth user information',\n );\n const current = this.authState$.value || {};\n this.authState$.next({\n ...current,\n loadingPhase: 'failed',\n err: `fbAuth.onAuthStateChanged() failed: ${err}`,\n });\n },\n });\n }\n\n private publishSignedOutState(): void {\n clearCurrentSpace();\n this.tokenUserID = undefined;\n this.authUser$.next(null);\n this.authState$.next({\n ...this.authState$.value,\n status: AuthStatuses.notAuthenticated,\n loadingPhase: 'ready',\n token: null,\n user: null,\n });\n this.authStatus$.next(AuthStatuses.notAuthenticated);\n }\n\n public signOut(): Promise<void> {\n clearCurrentSpace();\n return this.fbAuth.signOut();\n }\n\n public signInWithToken(token: string): Promise<UserCredential> {\n return signInWithCustomToken(this.fbAuth, token);\n }\n\n public signInWithEmailLink(email: string): Observable<UserCredential> {\n return from(signInWithEmailLink(this.fbAuth, email));\n }\n\n public createUserWithEmailAndPassword(\n email: string,\n password: string,\n ): Promise<ISneatEmailAuthResult> {\n return this.toEmailAuthResult(\n createUserWithEmailAndPassword(this.fbAuth, email, password),\n );\n }\n\n public signInWithEmailAndPassword(\n email: string,\n password: string,\n ): Promise<ISneatEmailAuthResult> {\n return this.toEmailAuthResult(\n signInWithEmailAndPassword(this.fbAuth, email, password),\n );\n }\n\n private async toEmailAuthResult(\n credential: Promise<UserCredential>,\n ): Promise<ISneatEmailAuthResult> {\n const { user } = await credential;\n return {\n userID: user.uid,\n token: await user.getIdToken(),\n };\n }\n\n private isSigningInWith?: AuthProviderName;\n\n private async signInOnNativeLayer(\n authProviderID: AuthProviderID,\n ): Promise<UserCredential> {\n let signInResult: SignInResult | undefined;\n\n const o: SignInWithOAuthOptions = { skipNativeAuth: true };\n\n switch (authProviderID) {\n case 'google.com':\n signInResult = await FirebaseAuthentication.signInWithGoogle(o);\n break;\n case 'apple.com':\n signInResult = await FirebaseAuthentication.signInWithApple(o);\n break;\n case 'facebook.com':\n signInResult = await FirebaseAuthentication.signInWithFacebook(o);\n break;\n case 'microsoft.com':\n signInResult = await FirebaseAuthentication.signInWithMicrosoft(o);\n break;\n default:\n return Promise.reject('unsupported auth provider: ' + authProviderID);\n }\n // console.log(\n // `SneatAuthStateService.signInWith(${authProviderID}) => signed in on native layer, authenticating in webview...`,\n // signInResult,\n // );\n // we need to authenticate on webview layer using the id token and nonce from signInResult\n const userCredential = await this.authenticateOnWebviewLayer(\n authProviderID,\n signInResult,\n );\n\n return Promise.resolve(userCredential);\n }\n\n private async authenticateOnWebviewLayer(\n authProviderID: AuthProviderID,\n signInResult: SignInResult,\n ): Promise<UserCredential> {\n const oauthProvider = new OAuthProvider(authProviderID);\n const credential = oauthProvider.credential({\n idToken: signInResult.credential?.idToken,\n accessToken: signInResult.credential?.accessToken,\n rawNonce: signInResult.credential?.nonce,\n });\n const auth = getAuth();\n const userCredential = await signInWithCredential(auth, credential);\n\n // Get a valid Firebase ID token that has a 'kid' header\n await userCredential.user.getIdToken();\n\n return Promise.resolve(userCredential);\n }\n\n private async signInWithWebSDK(\n authProviderID: AuthProviderID,\n ): Promise<UserCredential | undefined> {\n const authProvider = getAuthProvider(authProviderID);\n if (this.signInMethod === 'redirect') {\n // Full-page redirect; this navigates away and never resolves. The sign-in\n // is completed on return by BaseAppComponent's getRedirectResult() call.\n await signInWithRedirect(this.fbAuth, authProvider);\n return undefined;\n }\n const userCredential = await signInWithPopup(this.fbAuth, authProvider);\n return Promise.resolve(userCredential);\n }\n\n public async linkWith(\n authProviderID: AuthProviderID,\n ): Promise<UserCredential | undefined> {\n const authProvider = getAuthProvider(authProviderID);\n if (!this.fbAuth.currentUser) {\n return Promise.reject('no current user');\n }\n const userCredential = await linkWithPopup(\n this.fbAuth.currentUser,\n authProvider,\n );\n return Promise.resolve(userCredential);\n }\n\n public async unlinkAuthProvider(authProviderID: string): Promise<void> {\n const currentUser = this.fbAuth.currentUser;\n if (currentUser) {\n try {\n const updatedUser = await unlink(currentUser, authProviderID);\n const authUser = createSneatAuthUserFromFbUser(updatedUser);\n this.authUser$.next(authUser);\n return Promise.resolve();\n } catch (error) {\n return Promise.reject(\n `Failed to unlink ${authProviderID} account:` + error,\n );\n }\n } else {\n return Promise.reject('No user is currently signed in.');\n }\n }\n\n public async signInWith(\n authProviderID: AuthProviderID,\n ): Promise<UserCredential | undefined> {\n // console.log(\n // `SneatAuthStateService.signInWith(${authProviderID}), isSigningInWith=${this.isSigningInWith}, location.protocol=${location.protocol}`,\n // );\n this.analyticsService.logEvent('signingInWith', {\n provider: authProviderID,\n });\n try {\n if (this.isSigningInWith) {\n return Promise.reject(\n new Error(\n `a repeated call to SneatAuthStateService.signInWith(${authProviderID}) white previous sign in with ${this.isSigningInWith} is in progress`,\n ),\n );\n }\n\n let userCredential: UserCredential | undefined = undefined;\n\n if (Capacitor.isNativePlatform()) {\n userCredential = await this.signInOnNativeLayer(authProviderID);\n } else {\n userCredential = await this.signInWithWebSDK(authProviderID);\n }\n\n this.isSigningInWith = undefined;\n this.analyticsService.logEvent('signedInWith', {\n provider: authProviderID,\n });\n return Promise.resolve(userCredential);\n } catch (e) {\n this.isSigningInWith = undefined;\n return Promise.reject(e);\n }\n }\n}\n\nexport type AuthProviderID =\n | 'apple.com'\n | 'google.com'\n | 'microsoft.com'\n | 'facebook.com'\n | 'github.com'\n | 'phone';\n\nexport type AuthProviderName =\n | 'Google'\n | 'Apple'\n | 'Microsoft'\n | 'Facebook'\n | 'GitHub';\n\nfunction getAuthProvider(authProviderID: AuthProviderID): AuthProvider {\n switch (authProviderID) {\n case 'google.com':\n return new GoogleAuthProvider();\n case 'apple.com':\n return new OAuthProvider('apple.com');\n //\n // https://developer.apple.com/documentation/sign_in_with_apple/incorporating-sign-in-with-apple-into-other-platforms\n // (authProvider as OAuthProvider).setCustomParameters({\n // \t// \t// Localize the Apple authentication screen in current app locale.\n // \tlocale: 'en', // TODO: set locale\n // });\n case 'microsoft.com':\n return new OAuthProvider('microsoft.com');\n case 'facebook.com': {\n const facebookAuthProvider = new FacebookAuthProvider();\n facebookAuthProvider.addScope('email');\n return facebookAuthProvider;\n }\n case 'github.com': {\n const githubAuthProvider = new GithubAuthProvider();\n githubAuthProvider.addScope('read:user');\n githubAuthProvider.addScope('user:email');\n return githubAuthProvider;\n }\n default:\n throw new Error('unsupported auth provider: ' + authProviderID);\n }\n}\n\nfunction createSneatAuthUserFromFbUser(\n fbUser: User | null,\n): ISneatAuthUser | null {\n return (\n fbUser && {\n isAnonymous: fbUser.isAnonymous,\n emailVerified: fbUser.emailVerified,\n email: fbUser.email,\n uid: fbUser.uid,\n displayName: fbUser.displayName,\n phoneNumber: fbUser.phoneNumber,\n photoURL: fbUser.photoURL,\n providerId:\n fbUser.providerData?.length === 1 && fbUser.providerData[0]\n ? fbUser.providerData[0].providerId\n : fbUser.providerId,\n providerData: fbUser.providerData,\n }\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../libs/auth/core/src/lib/user/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC","sourcesContent":["export * from './user-record.service';\nexport * from './sneat-user.service';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../libs/auth/core/src/lib/user/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC","sourcesContent":["export * from './user-record.service';\nexport * from './sneat-user.service';\nexport * from './sneat-account-readiness';\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns true only when the current permanent Firebase identity has a usable
|
|
3
|
+
* token and its matching persisted Sneat user record is ready.
|
|
4
|
+
*/
|
|
5
|
+
export function isSneatAccountReady(authState, userState) {
|
|
6
|
+
const authUser = authState?.user;
|
|
7
|
+
const user = userState?.user;
|
|
8
|
+
const uid = authUser?.uid;
|
|
9
|
+
return (authState?.status === 'authenticated' &&
|
|
10
|
+
authState.loadingPhase === 'ready' &&
|
|
11
|
+
typeof authState.token === 'string' &&
|
|
12
|
+
authState.token.trim().length > 0 &&
|
|
13
|
+
!!uid?.trim() &&
|
|
14
|
+
authUser?.isAnonymous === false &&
|
|
15
|
+
userState?.status === 'authenticated' &&
|
|
16
|
+
user?.uid === uid &&
|
|
17
|
+
user?.isAnonymous === false &&
|
|
18
|
+
userState.userRecordStatus === 'ready' &&
|
|
19
|
+
!!userState.record);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=sneat-account-readiness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sneat-account-readiness.js","sourceRoot":"","sources":["../../../../../../../libs/auth/core/src/lib/user/sneat-account-readiness.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,SAA6C,EAC7C,SAA6C;IAE7C,MAAM,QAAQ,GAAG,SAAS,EAAE,IAAI,CAAC;IACjC,MAAM,IAAI,GAAG,SAAS,EAAE,IAAI,CAAC;IAC7B,MAAM,GAAG,GAAG,QAAQ,EAAE,GAAG,CAAC;IAC1B,OAAO,CACL,SAAS,EAAE,MAAM,KAAK,eAAe;QACrC,SAAS,CAAC,YAAY,KAAK,OAAO;QAClC,OAAO,SAAS,CAAC,KAAK,KAAK,QAAQ;QACnC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;QACjC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE;QACb,QAAQ,EAAE,WAAW,KAAK,KAAK;QAC/B,SAAS,EAAE,MAAM,KAAK,eAAe;QACrC,IAAI,EAAE,GAAG,KAAK,GAAG;QACjB,IAAI,EAAE,WAAW,KAAK,KAAK;QAC3B,SAAS,CAAC,gBAAgB,KAAK,OAAO;QACtC,CAAC,CAAC,SAAS,CAAC,MAAM,CACnB,CAAC;AACJ,CAAC","sourcesContent":["import { ISneatAuthState } from '../sneat-auth-state-service';\nimport { ISneatUserState } from './sneat-user.service';\n\n/**\n * Returns true only when the current permanent Firebase identity has a usable\n * token and its matching persisted Sneat user record is ready.\n */\nexport function isSneatAccountReady(\n authState: ISneatAuthState | null | undefined,\n userState: ISneatUserState | null | undefined,\n): boolean {\n const authUser = authState?.user;\n const user = userState?.user;\n const uid = authUser?.uid;\n return (\n authState?.status === 'authenticated' &&\n authState.loadingPhase === 'ready' &&\n typeof authState.token === 'string' &&\n authState.token.trim().length > 0 &&\n !!uid?.trim() &&\n authUser?.isAnonymous === false &&\n userState?.status === 'authenticated' &&\n user?.uid === uid &&\n user?.isAnonymous === false &&\n userState.userRecordStatus === 'ready' &&\n !!userState.record\n );\n}\n"]}
|
|
@@ -4,17 +4,17 @@ import {
|
|
|
4
4
|
Firestore as AngularFirestore, collection, doc, onSnapshot, } from 'firebase/firestore';
|
|
5
5
|
import { SneatApiService } from '@sneat/api';
|
|
6
6
|
import { ErrorLogger, SneatUrlOperationBlocker, } from '@sneat/core';
|
|
7
|
-
import { initialSneatAuthState, SneatAuthStateService, } from '../sneat-auth-state-service';
|
|
7
|
+
import { initialSneatAuthState, AuthStatuses, SneatAuthStateService, } from '../sneat-auth-state-service';
|
|
8
8
|
import { BehaviorSubject, Observable, ReplaySubject } from 'rxjs';
|
|
9
9
|
import { UserRecordService, } from './user-record.service';
|
|
10
10
|
import * as i0 from "@angular/core";
|
|
11
11
|
const UsersCollection = 'users';
|
|
12
12
|
export class SneatUserService {
|
|
13
|
-
unsubscribeFromUserDoc(
|
|
13
|
+
unsubscribeFromUserDoc() {
|
|
14
|
+
clearTimeout(this.watchTimer);
|
|
15
|
+
this.watchTimer = undefined;
|
|
16
|
+
this.watchGeneration++;
|
|
14
17
|
if (this._unsubscribeFromUserDoc) {
|
|
15
|
-
// console.log(
|
|
16
|
-
// 'SneatUserService.unsubscribeFromUserDoc() called from ' + _from,
|
|
17
|
-
// );
|
|
18
18
|
this._unsubscribeFromUserDoc();
|
|
19
19
|
this._unsubscribeFromUserDoc = undefined;
|
|
20
20
|
}
|
|
@@ -27,6 +27,9 @@ export class SneatUserService {
|
|
|
27
27
|
// private userDocSubscription?: Subscription;
|
|
28
28
|
this.injector = inject(Injector);
|
|
29
29
|
this.userDocRef = (uid) => runInInjectionContext(this.injector, () => doc(this.userCollection, uid));
|
|
30
|
+
this.watchGeneration = 0;
|
|
31
|
+
this.accountGeneration = 0;
|
|
32
|
+
this.initOperationID = 0;
|
|
30
33
|
this.userChanged$ = new ReplaySubject(1);
|
|
31
34
|
this.userChanged = this.userChanged$.asObservable();
|
|
32
35
|
this.userState$ = new BehaviorSubject(initialSneatAuthState);
|
|
@@ -34,7 +37,12 @@ export class SneatUserService {
|
|
|
34
37
|
this.onAuthStateChanged = (authState) => {
|
|
35
38
|
// console.log('SneatUserService => authState changed:', authState);
|
|
36
39
|
if (authState.user) {
|
|
37
|
-
this.
|
|
40
|
+
if (this.isReadyForUserRecord(authState)) {
|
|
41
|
+
this.onUserSignedIn(authState);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
this.onAuthStatePending(authState);
|
|
45
|
+
}
|
|
38
46
|
}
|
|
39
47
|
else {
|
|
40
48
|
this.userState$.next(authState);
|
|
@@ -87,10 +95,28 @@ export class SneatUserService {
|
|
|
87
95
|
if (authUser?.email && authUser.emailVerified) {
|
|
88
96
|
this.$userTitle = authUser.email;
|
|
89
97
|
}
|
|
98
|
+
this.pendingUID = undefined;
|
|
90
99
|
if (this.uid === authUser?.uid) {
|
|
100
|
+
this.currentAuthState = authState;
|
|
101
|
+
this.pendingAuthState = undefined;
|
|
102
|
+
const current = this.userState$.value;
|
|
103
|
+
if (current.user?.isAnonymous !== authUser?.isAnonymous) {
|
|
104
|
+
this.userState$.next({
|
|
105
|
+
...authState,
|
|
106
|
+
record: current.record,
|
|
107
|
+
userRecordStatus: current.userRecordStatus,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
const deferredSnapshot = this.deferredMissingUserDocSnapshot;
|
|
111
|
+
this.deferredMissingUserDocSnapshot = undefined;
|
|
112
|
+
if (deferredSnapshot) {
|
|
113
|
+
this.userDocChanged(deferredSnapshot, authState, this.watchGeneration);
|
|
114
|
+
}
|
|
91
115
|
return;
|
|
92
116
|
}
|
|
93
|
-
this.
|
|
117
|
+
this.pendingAuthState = undefined;
|
|
118
|
+
this.deferredMissingUserDocSnapshot = undefined;
|
|
119
|
+
this.unsubscribeFromUserDoc();
|
|
94
120
|
if (!authUser) {
|
|
95
121
|
if (this.userState$.value?.record !== null) {
|
|
96
122
|
this.userState$.next({ ...this.userState$.value });
|
|
@@ -98,9 +124,13 @@ export class SneatUserService {
|
|
|
98
124
|
return;
|
|
99
125
|
}
|
|
100
126
|
const { uid } = authUser;
|
|
127
|
+
this.currentAuthState = authState;
|
|
128
|
+
this.accountGeneration++;
|
|
129
|
+
this.initAcknowledged = undefined;
|
|
101
130
|
this.uid = uid;
|
|
102
131
|
this.userState$.next({
|
|
103
132
|
...authState,
|
|
133
|
+
userRecordStatus: 'loading',
|
|
104
134
|
});
|
|
105
135
|
this.userChanged$.next(uid);
|
|
106
136
|
this.watchUserRecord(uid, authState);
|
|
@@ -109,38 +139,107 @@ export class SneatUserService {
|
|
|
109
139
|
// console.log(
|
|
110
140
|
// `SneatUserService.watchUserRecord(uid=${uid}): Loading user record...`,
|
|
111
141
|
// );
|
|
112
|
-
this.unsubscribeFromUserDoc(
|
|
142
|
+
this.unsubscribeFromUserDoc();
|
|
143
|
+
const generation = this.watchGeneration;
|
|
113
144
|
if (this.operationBlocker.isBlocked('server-requests')) {
|
|
145
|
+
this.setUserRecordStatus(uid, authState, 'failed');
|
|
114
146
|
return;
|
|
115
147
|
}
|
|
116
148
|
// TODO: Remove - setTimeout() not needed but trying to troubleshoot user record issue
|
|
117
|
-
setTimeout(() => {
|
|
149
|
+
this.watchTimer = setTimeout(() => {
|
|
150
|
+
this.watchTimer = undefined;
|
|
151
|
+
if (!this.isCurrentIdentity(uid, authState, generation))
|
|
152
|
+
return;
|
|
118
153
|
if (this.operationBlocker.isBlocked('server-requests')) {
|
|
154
|
+
this.setUserRecordStatus(uid, authState, 'failed');
|
|
119
155
|
return;
|
|
120
156
|
}
|
|
121
157
|
try {
|
|
122
158
|
const userDocRef = this.userDocRef(uid);
|
|
123
|
-
|
|
159
|
+
const unsubscribe = runInInjectionContext(this.injector, () => onSnapshot(userDocRef, {
|
|
124
160
|
next: (userDocSnapshot) => {
|
|
161
|
+
const currentAuthState = this.currentAuthState;
|
|
162
|
+
if (!currentAuthState ||
|
|
163
|
+
!this.isCurrentIdentity(uid, currentAuthState, generation))
|
|
164
|
+
return;
|
|
125
165
|
// console.log(
|
|
126
166
|
// `SneatUserService.watchUserRecord(uid=${uid}) => userDocSnapshot:`,
|
|
127
167
|
// userDocSnapshot,
|
|
128
168
|
// );
|
|
129
|
-
this.
|
|
130
|
-
this.userDocChanged(userDocSnapshot, authState);
|
|
169
|
+
this.userDocChanged(userDocSnapshot, currentAuthState, generation);
|
|
131
170
|
},
|
|
132
171
|
error: (err) => {
|
|
133
|
-
|
|
172
|
+
const currentAuthState = this.currentAuthState;
|
|
173
|
+
if (!currentAuthState ||
|
|
174
|
+
!this.isCurrentIdentity(uid, currentAuthState, generation))
|
|
175
|
+
return;
|
|
176
|
+
this.deferredMissingUserDocSnapshot = undefined;
|
|
177
|
+
this.setUserRecordStatus(uid, currentAuthState, 'failed');
|
|
178
|
+
this.unsubscribeFromUserDoc();
|
|
179
|
+
this.errorLogger.logError(err, 'Failed to read user record');
|
|
134
180
|
},
|
|
135
181
|
}));
|
|
182
|
+
if (this.watchGeneration === generation) {
|
|
183
|
+
this._unsubscribeFromUserDoc = unsubscribe;
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
unsubscribe();
|
|
187
|
+
}
|
|
136
188
|
}
|
|
137
189
|
catch (err) {
|
|
138
|
-
|
|
190
|
+
const currentAuthState = this.currentAuthState;
|
|
191
|
+
if (currentAuthState &&
|
|
192
|
+
this.isCurrentIdentity(uid, currentAuthState, generation)) {
|
|
193
|
+
this.deferredMissingUserDocSnapshot = undefined;
|
|
194
|
+
this.setUserRecordStatus(uid, currentAuthState, 'failed');
|
|
195
|
+
this.errorLogger.logError(err, 'Failed to watch user record');
|
|
196
|
+
}
|
|
139
197
|
return;
|
|
140
198
|
}
|
|
141
199
|
}, 100);
|
|
142
200
|
}
|
|
143
|
-
|
|
201
|
+
isReadyForUserRecord(authState) {
|
|
202
|
+
if (authState.status !== AuthStatuses.authenticated)
|
|
203
|
+
return false;
|
|
204
|
+
// Older callers that provide the original minimal auth-state shape remain
|
|
205
|
+
// supported. SneatAuthStateService always includes loadingPhase and token.
|
|
206
|
+
return authState.loadingPhase === undefined ||
|
|
207
|
+
(authState.loadingPhase === 'ready' && !!authState.token);
|
|
208
|
+
}
|
|
209
|
+
onAuthStatePending(authState) {
|
|
210
|
+
const uid = authState.user?.uid;
|
|
211
|
+
if (!uid)
|
|
212
|
+
return;
|
|
213
|
+
// A token refresh for the account already owning this watcher must not
|
|
214
|
+
// replace its stable authenticated identity with a transient auth state.
|
|
215
|
+
if (this.uid === uid && this.currentAuthState?.status === AuthStatuses.authenticated) {
|
|
216
|
+
this.pendingAuthState = authState;
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
// A different identity is visible before its token is ready. Retire the
|
|
220
|
+
// previous account immediately, but do not assign this UID or start a
|
|
221
|
+
// watcher until the auth service publishes the matching ready token.
|
|
222
|
+
if (this.pendingUID !== uid || this.uid) {
|
|
223
|
+
this.accountGeneration++;
|
|
224
|
+
this.initAcknowledged = undefined;
|
|
225
|
+
this.activeInit = undefined;
|
|
226
|
+
this.pendingAuthState = undefined;
|
|
227
|
+
this.deferredMissingUserDocSnapshot = undefined;
|
|
228
|
+
const hadCurrentUID = !!this.uid;
|
|
229
|
+
this.uid = undefined;
|
|
230
|
+
this.currentAuthState = undefined;
|
|
231
|
+
this.pendingUID = uid;
|
|
232
|
+
this.unsubscribeFromUserDoc();
|
|
233
|
+
if (hadCurrentUID)
|
|
234
|
+
this.userChanged$.next(undefined);
|
|
235
|
+
}
|
|
236
|
+
this.userState$.next({
|
|
237
|
+
...authState,
|
|
238
|
+
record: undefined,
|
|
239
|
+
userRecordStatus: 'loading',
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
userDocChanged(userDocSnapshot, authState, generation) {
|
|
144
243
|
// console.log(
|
|
145
244
|
// 'SneatUserService.userDocChanged() => userDocSnapshot.exists:',
|
|
146
245
|
// userDocSnapshot.exists(),
|
|
@@ -149,26 +248,64 @@ export class SneatUserService {
|
|
|
149
248
|
// 'userDocSnapshot:',
|
|
150
249
|
// userDocSnapshot,
|
|
151
250
|
// );
|
|
152
|
-
if (
|
|
251
|
+
if (!this.isCurrentIdentity(authState.user?.uid ?? '', authState, generation) ||
|
|
252
|
+
userDocSnapshot.ref.id !== this.uid) {
|
|
153
253
|
console.error('userDocSnapshot.ref.id !== this.uid - Should always be equal as we unsubscribe if uid changes');
|
|
154
254
|
return;
|
|
155
255
|
}
|
|
156
256
|
// console.log('SneatUserService => userDocSnapshot.exists:', userDocSnapshot.exists)
|
|
157
257
|
const authUser = authState.user;
|
|
158
|
-
|
|
159
|
-
|
|
258
|
+
const recordExists = userDocSnapshot.exists();
|
|
259
|
+
const initAcknowledged = this.initAcknowledged;
|
|
260
|
+
if (recordExists &&
|
|
261
|
+
authUser?.uid === initAcknowledged?.uid &&
|
|
262
|
+
this.accountGeneration === initAcknowledged?.accountGeneration) {
|
|
263
|
+
this.initAcknowledged = undefined;
|
|
160
264
|
}
|
|
161
|
-
const userRecord =
|
|
265
|
+
const userRecord = recordExists
|
|
162
266
|
? userDocSnapshot.data()
|
|
163
267
|
: authUser
|
|
164
268
|
? { title: authUser.displayName || authUser.email || authUser.uid }
|
|
165
269
|
: null;
|
|
270
|
+
if (recordExists) {
|
|
271
|
+
this.deferredMissingUserDocSnapshot = undefined;
|
|
272
|
+
}
|
|
273
|
+
else if (this.pendingAuthState?.user?.uid === authUser?.uid) {
|
|
274
|
+
this.deferredMissingUserDocSnapshot = userDocSnapshot;
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
this.deferredMissingUserDocSnapshot = undefined;
|
|
278
|
+
}
|
|
279
|
+
const current = this.userState$.value;
|
|
166
280
|
this.userState$.next({
|
|
167
281
|
...authState,
|
|
168
282
|
record: userRecord,
|
|
283
|
+
userRecordStatus: recordExists
|
|
284
|
+
? 'ready'
|
|
285
|
+
: current.userRecordStatus === 'failed'
|
|
286
|
+
? 'failed'
|
|
287
|
+
: 'loading',
|
|
169
288
|
});
|
|
289
|
+
if (authUser &&
|
|
290
|
+
!recordExists &&
|
|
291
|
+
current.userRecordStatus !== 'failed' &&
|
|
292
|
+
!this.pendingAuthState &&
|
|
293
|
+
!(this.initAcknowledged?.uid === authUser.uid &&
|
|
294
|
+
this.initAcknowledged.accountGeneration === this.accountGeneration)) {
|
|
295
|
+
this.initUserRecordFromAuthUser(authUser);
|
|
296
|
+
}
|
|
170
297
|
}
|
|
171
298
|
initUserRecordFromAuthUser(authUser) {
|
|
299
|
+
const uid = authUser.uid;
|
|
300
|
+
const accountGeneration = this.accountGeneration;
|
|
301
|
+
if (!uid || !this.isCurrentAuthIdentity(uid, authUser, accountGeneration))
|
|
302
|
+
return;
|
|
303
|
+
if (this.activeInit?.uid === uid &&
|
|
304
|
+
this.activeInit.accountGeneration === accountGeneration) {
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
const operation = { uid, accountGeneration, id: ++this.initOperationID };
|
|
308
|
+
this.activeInit = operation;
|
|
172
309
|
let request = {
|
|
173
310
|
email: authUser.email || undefined,
|
|
174
311
|
emailIsVerified: authUser.emailVerified,
|
|
@@ -178,15 +315,71 @@ export class SneatUserService {
|
|
|
178
315
|
request = { ...request, names: { fullName: authUser.displayName } };
|
|
179
316
|
}
|
|
180
317
|
this.userRecordService.initUserRecord(request).subscribe({
|
|
181
|
-
next: (
|
|
182
|
-
|
|
318
|
+
next: () => {
|
|
319
|
+
if (this.activeInit === operation)
|
|
320
|
+
this.activeInit = undefined;
|
|
321
|
+
if (!this.isCurrentAuthIdentity(uid, authUser, accountGeneration) ||
|
|
322
|
+
this.userState$.value.userRecordStatus === 'ready')
|
|
323
|
+
return;
|
|
324
|
+
this.initAcknowledged = { uid, accountGeneration };
|
|
325
|
+
// API acknowledgement is not readiness. Wait for the persisted snapshot.
|
|
326
|
+
},
|
|
327
|
+
error: (error) => {
|
|
328
|
+
if (this.activeInit === operation)
|
|
329
|
+
this.activeInit = undefined;
|
|
330
|
+
if (!this.isCurrentAuthIdentity(uid, authUser, accountGeneration) ||
|
|
331
|
+
this.userState$.value.userRecordStatus === 'ready')
|
|
332
|
+
return;
|
|
333
|
+
this.setUserRecordStatus(uid, { status: 'authenticated', user: authUser }, 'failed');
|
|
334
|
+
this.errorLogger.logError(error, 'Failed to initialize user record');
|
|
183
335
|
},
|
|
184
|
-
error: this.errorLogger.logErrorHandler('failed to create user record'),
|
|
185
336
|
});
|
|
186
337
|
}
|
|
338
|
+
/** Retry record watch and initialization after a failed first-load attempt. */
|
|
339
|
+
retryUserRecordInitialization() {
|
|
340
|
+
const current = this.userState$.value;
|
|
341
|
+
const uid = this.uid;
|
|
342
|
+
if (!uid ||
|
|
343
|
+
current.status !== 'authenticated' ||
|
|
344
|
+
current.user?.uid !== uid ||
|
|
345
|
+
current.userRecordStatus !== 'failed') {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
this.userState$.next({ ...current, userRecordStatus: 'loading' });
|
|
349
|
+
this.watchUserRecord(uid, current);
|
|
350
|
+
}
|
|
351
|
+
isCurrentIdentity(uid, authState, generation) {
|
|
352
|
+
return (!!uid &&
|
|
353
|
+
this.uid === uid &&
|
|
354
|
+
this.watchGeneration === generation &&
|
|
355
|
+
authState.status === 'authenticated' &&
|
|
356
|
+
authState.user?.uid === uid &&
|
|
357
|
+
this.userState$.value.user?.uid === uid);
|
|
358
|
+
}
|
|
359
|
+
isCurrentAuthIdentity(uid, authUser, accountGeneration) {
|
|
360
|
+
return (uid === this.uid &&
|
|
361
|
+
accountGeneration === this.accountGeneration &&
|
|
362
|
+
this.userState$.value.status === 'authenticated' &&
|
|
363
|
+
this.userState$.value.user?.uid === uid &&
|
|
364
|
+
authUser.uid === uid);
|
|
365
|
+
}
|
|
366
|
+
setUserRecordStatus(uid, authState, userRecordStatus) {
|
|
367
|
+
if (uid !== this.uid ||
|
|
368
|
+
authState.user?.uid !== uid ||
|
|
369
|
+
this.userState$.value.user?.uid !== uid) {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
this.userState$.next({ ...this.userState$.value, userRecordStatus });
|
|
373
|
+
}
|
|
187
374
|
onUserSignedOut() {
|
|
375
|
+
this.accountGeneration++;
|
|
376
|
+
this.initAcknowledged = undefined;
|
|
188
377
|
this.uid = undefined;
|
|
189
|
-
this.
|
|
378
|
+
this.pendingUID = undefined;
|
|
379
|
+
this.currentAuthState = undefined;
|
|
380
|
+
this.pendingAuthState = undefined;
|
|
381
|
+
this.deferredMissingUserDocSnapshot = undefined;
|
|
382
|
+
this.unsubscribeFromUserDoc();
|
|
190
383
|
}
|
|
191
384
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: SneatUserService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
192
385
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: SneatUserService, providedIn: 'root' }); }
|