@sneat/auth-core 0.26.6 → 0.27.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,15 +6,15 @@ import { AuthStatuses, SneatAuthStateService } from './sneat-auth-state-service'
6
6
  * Redirect target for an unauthenticated visitor: `/login`, or
7
7
  * `/login#<path>` for a non-root path so the login page can send them back
8
8
  * to it after signing in. Matches the URL shape the fleet's
9
- * `@angular/fire/auth-guard`-based `redirectToLoginIfNotSignedIn` pipe (see
10
- * `./sneat-auth-guard`) has always produced.
9
+ * `@angular/fire/auth-guard`-based `redirectToLoginIfNotSignedIn` pipe always
10
+ * produced — that pipe was removed in 0.27.0 together with `@angular/fire`.
11
11
  */
12
12
  export function loginRedirectPath(path) {
13
13
  return path && path !== '/' ? `/login#${path}` : '/login';
14
14
  }
15
15
  /**
16
16
  * Functional route guard — the `@angular/fire`-free replacement for the
17
- * fleet's one uniform pattern:
17
+ * fleet's one uniform pattern. Before 0.27.0 a protected route read:
18
18
  *
19
19
  * import { AuthGuard } from '@angular/fire/auth-guard';
20
20
  * import { redirectToLoginIfNotSignedIn } from '@sneat/auth-core';
@@ -23,7 +23,8 @@ export function loginRedirectPath(path) {
23
23
  * data: { authGuardPipe: () => redirectToLoginIfNotSignedIn },
24
24
  * }
25
25
  *
26
- * becomes simply:
26
+ * Since 0.27.0 — where both `AuthGuard` and `redirectToLoginIfNotSignedIn`
27
+ * are gone — it reads simply:
27
28
  *
28
29
  * import { sneatAuthGuard } from '@sneat/auth-core';
29
30
  * { canActivate: [sneatAuthGuard] }
@@ -32,9 +33,13 @@ export function loginRedirectPath(path) {
32
33
  * the attempted path as a hash fragment). Driven entirely by Sneat's own
33
34
  * `SneatAuthStateService` — no `@angular/fire` `Auth`/`AuthPipe` involved.
34
35
  *
36
+ * The attempted path comes from `RouterStateSnapshot.url`, which is already
37
+ * router-relative, so this needs none of the `<base href>` stripping the old
38
+ * `location.pathname`-based pipe did.
39
+ *
35
40
  * Waits out the initial `'authenticating'` status (Firebase hasn't resolved
36
- * the session yet) before deciding, exactly like the fleet's current
37
- * `user(auth).pipe(take(1), redirectToLoginIfNotSignedIn)` composition does.
41
+ * the session yet) before deciding, exactly like the old
42
+ * `user(auth).pipe(take(1), redirectToLoginIfNotSignedIn)` composition did.
38
43
  */
39
44
  export const sneatAuthGuard = async (_route, state) => {
40
45
  const authState = inject(SneatAuthStateService);
@@ -1 +1 @@
1
- {"version":3,"file":"redirect-to-login.guard.js","sourceRoot":"","sources":["../../../../../../libs/auth/core/src/lib/redirect-to-login.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAiB,MAAM,EAAuB,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEjF;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,IAAI,IAAI,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC5D,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,MAAM,cAAc,GAAkB,KAAK,EAChD,MAAM,EACN,KAA0B,EAC1B,EAAE;IACF,MAAM,SAAS,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9B,MAAM,MAAM,GAAG,MAAM,cAAc,CACjC,SAAS,CAAC,UAAU,CAAC,IAAI,CACvB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,YAAY,CAAC,cAAc,CAAC,CACjD,CACF,CAAC;IACF,IAAI,MAAM,KAAK,YAAY,CAAC,aAAa,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AACvD,CAAC,CAAC","sourcesContent":["import { inject } from '@angular/core';\nimport { CanActivateFn, Router, RouterStateSnapshot } from '@angular/router';\nimport { filter, firstValueFrom } from 'rxjs';\nimport { AuthStatuses, SneatAuthStateService } from './sneat-auth-state-service';\n\n/**\n * Redirect target for an unauthenticated visitor: `/login`, or\n * `/login#<path>` for a non-root path so the login page can send them back\n * to it after signing in. Matches the URL shape the fleet's\n * `@angular/fire/auth-guard`-based `redirectToLoginIfNotSignedIn` pipe (see\n * `./sneat-auth-guard`) has always produced.\n */\nexport function loginRedirectPath(path: string): string {\n return path && path !== '/' ? `/login#${path}` : '/login';\n}\n\n/**\n * Functional route guard — the `@angular/fire`-free replacement for the\n * fleet's one uniform pattern:\n *\n * import { AuthGuard } from '@angular/fire/auth-guard';\n * import { redirectToLoginIfNotSignedIn } from '@sneat/auth-core';\n * {\n * canActivate: [AuthGuard],\n * data: { authGuardPipe: () => redirectToLoginIfNotSignedIn },\n * }\n *\n * becomes simply:\n *\n * import { sneatAuthGuard } from '@sneat/auth-core';\n * { canActivate: [sneatAuthGuard] }\n *\n * Admits a signed-in visitor; redirects everyone else to `/login` (preserving\n * the attempted path as a hash fragment). Driven entirely by Sneat's own\n * `SneatAuthStateService` — no `@angular/fire` `Auth`/`AuthPipe` involved.\n *\n * Waits out the initial `'authenticating'` status (Firebase hasn't resolved\n * the session yet) before deciding, exactly like the fleet's current\n * `user(auth).pipe(take(1), redirectToLoginIfNotSignedIn)` composition does.\n */\nexport const sneatAuthGuard: CanActivateFn = async (\n _route,\n state: RouterStateSnapshot,\n) => {\n const authState = inject(SneatAuthStateService);\n const router = inject(Router);\n const status = await firstValueFrom(\n authState.authStatus.pipe(\n filter((s) => s !== AuthStatuses.authenticating),\n ),\n );\n if (status === AuthStatuses.authenticated) {\n return true;\n }\n return router.parseUrl(loginRedirectPath(state.url));\n};\n"]}
1
+ {"version":3,"file":"redirect-to-login.guard.js","sourceRoot":"","sources":["../../../../../../libs/auth/core/src/lib/redirect-to-login.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAiB,MAAM,EAAuB,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEjF;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,IAAI,IAAI,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC5D,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,CAAC,MAAM,cAAc,GAAkB,KAAK,EAChD,MAAM,EACN,KAA0B,EAC1B,EAAE;IACF,MAAM,SAAS,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9B,MAAM,MAAM,GAAG,MAAM,cAAc,CACjC,SAAS,CAAC,UAAU,CAAC,IAAI,CACvB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,YAAY,CAAC,cAAc,CAAC,CACjD,CACF,CAAC;IACF,IAAI,MAAM,KAAK,YAAY,CAAC,aAAa,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AACvD,CAAC,CAAC","sourcesContent":["import { inject } from '@angular/core';\nimport { CanActivateFn, Router, RouterStateSnapshot } from '@angular/router';\nimport { filter, firstValueFrom } from 'rxjs';\nimport { AuthStatuses, SneatAuthStateService } from './sneat-auth-state-service';\n\n/**\n * Redirect target for an unauthenticated visitor: `/login`, or\n * `/login#<path>` for a non-root path so the login page can send them back\n * to it after signing in. Matches the URL shape the fleet's\n * `@angular/fire/auth-guard`-based `redirectToLoginIfNotSignedIn` pipe always\n * produced — that pipe was removed in 0.27.0 together with `@angular/fire`.\n */\nexport function loginRedirectPath(path: string): string {\n return path && path !== '/' ? `/login#${path}` : '/login';\n}\n\n/**\n * Functional route guard — the `@angular/fire`-free replacement for the\n * fleet's one uniform pattern. Before 0.27.0 a protected route read:\n *\n * import { AuthGuard } from '@angular/fire/auth-guard';\n * import { redirectToLoginIfNotSignedIn } from '@sneat/auth-core';\n * {\n * canActivate: [AuthGuard],\n * data: { authGuardPipe: () => redirectToLoginIfNotSignedIn },\n * }\n *\n * Since 0.27.0 — where both `AuthGuard` and `redirectToLoginIfNotSignedIn`\n * are gone — it reads simply:\n *\n * import { sneatAuthGuard } from '@sneat/auth-core';\n * { canActivate: [sneatAuthGuard] }\n *\n * Admits a signed-in visitor; redirects everyone else to `/login` (preserving\n * the attempted path as a hash fragment). Driven entirely by Sneat's own\n * `SneatAuthStateService` — no `@angular/fire` `Auth`/`AuthPipe` involved.\n *\n * The attempted path comes from `RouterStateSnapshot.url`, which is already\n * router-relative, so this needs none of the `<base href>` stripping the old\n * `location.pathname`-based pipe did.\n *\n * Waits out the initial `'authenticating'` status (Firebase hasn't resolved\n * the session yet) before deciding, exactly like the old\n * `user(auth).pipe(take(1), redirectToLoginIfNotSignedIn)` composition did.\n */\nexport const sneatAuthGuard: CanActivateFn = async (\n _route,\n state: RouterStateSnapshot,\n) => {\n const authState = inject(SneatAuthStateService);\n const router = inject(Router);\n const status = await firstValueFrom(\n authState.authStatus.pipe(\n filter((s) => s !== AuthStatuses.authenticating),\n ),\n );\n if (status === AuthStatuses.authenticated) {\n return true;\n }\n return router.parseUrl(loginRedirectPath(state.url));\n};\n"]}
@@ -1,101 +1,41 @@
1
- import { Router, } from '@angular/router';
2
- import { Injectable, inject } from '@angular/core';
3
- import { Auth } from '@angular/fire/auth';
4
- import { map } from 'rxjs/operators';
1
+ import { Injectable } from '@angular/core';
5
2
  import * as i0 from "@angular/core";
6
3
  /**
7
- * Strip the document's `<base href>` prefix from a browser pathname, returning a
8
- * router-relative path.
4
+ * Permissive class-based route guard: every hook returns `true`.
9
5
  *
10
- * Apps mounted under a base href (e.g. `/app/` in the Sneat site-hosting
11
- * pattern) have a `location.pathname` of `/app/new-game`, but the Angular Router
12
- * matches routes relative to the base href (`new-game`). Feeding the un-stripped
13
- * pathname back into the router after login fails to match any route (NG04002).
6
+ * @deprecated Prefer the functional `sneatAuthGuard`
7
+ * (`./redirect-to-login.guard`), which actually blocks an unauthenticated
8
+ * visitor and redirects them to `/login`. This guard admits everyone — it
9
+ * never gated anything — and is kept only so existing route configs
10
+ * referencing `SNEAT_AUTH_GUARDS` keep compiling.
11
+ *
12
+ * As of 0.27.0 it no longer injects Firebase `Auth`: the injected instance was
13
+ * never read, and that injection is what coupled this file to `@angular/fire`.
14
14
  */
15
- function routerRelativePath(pathname) {
16
- const baseHref = document.querySelector('base')?.getAttribute('href') ?? '/';
17
- if (baseHref === '/' || baseHref === '') {
18
- return pathname;
19
- }
20
- const base = baseHref.replace(/\/$/, ''); // '/app/' -> '/app'
21
- if (pathname === base) {
22
- return '/';
23
- }
24
- if (pathname.startsWith(base + '/')) {
25
- return pathname.slice(base.length); // '/app/new-game' -> '/new-game'
26
- }
27
- return pathname;
28
- }
29
- export const redirectToLoginIfNotSignedIn = map((user) => {
30
- if (user) {
31
- return true;
32
- }
33
- const path = routerRelativePath(location.pathname);
34
- let url = '/login';
35
- if (path != '/') {
36
- url += '#' + path;
37
- }
38
- return url;
39
- });
40
- export class SneatAuthGuard /*implements CanLoad, CanActivate, CanActivateChild*/ {
41
- constructor() {
42
- this.router = inject(Router);
43
- this.auth = inject(Auth);
44
- }
15
+ export class SneatAuthGuard {
45
16
  canLoad(_route, _segments) {
46
- {
47
- // console.log('SneatAuthGuard.canLoad', route, segments);
48
- // const authPipeFactory =
49
- // (route.data && route.data['authCanLoadGuardPipe'] as AuthCanLoadPipeGenerator) ||
50
- // (() => redirectToLoginIfNotSignedIn);
51
- // const subj = new Subject<boolean>();
52
- // onAuthStateChanged(this.auth, {
53
- // next: (user) => {
54
- // console.log('onAuthStateChanged', user);
55
- // }
56
- // })
57
- // return this.auth.user.pipe(
58
- // map((user) => {
59
- // console.log('user', user);
60
- // return user;
61
- // }),
62
- // take(1),
63
- // authPipeFactory(route, segments),
64
- // map((can) => {
65
- // console.log('can', can);
66
- // if (typeof can === 'boolean') {
67
- // return can;
68
- // } else if (Array.isArray(can)) {
69
- // return this.router.createUrlTree(can);
70
- // } else {
71
- // return this.router.parseUrl(can);
72
- // }
73
- // }),
74
- // );
75
- return true;
76
- }
17
+ return true;
77
18
  }
78
19
  canActivate(_route, _state) {
79
- // console.log('SneatAuthGuard.canActivate', route, state);
80
20
  return true;
81
21
  }
82
22
  canActivateChild(_childRoute, _state) {
83
- // console.log('SneatAuthGuard.canActivateChild', childRoute, state);
84
23
  return true;
85
24
  }
86
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: SneatAuthGuard /*implements CanLoad, CanActivate, CanActivateChild*/, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
87
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: SneatAuthGuard /*implements CanLoad, CanActivate, CanActivateChild*/, providedIn: 'root' }); }
25
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: SneatAuthGuard, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
26
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: SneatAuthGuard, providedIn: 'root' }); }
88
27
  }
89
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: SneatAuthGuard /*implements CanLoad, CanActivate, CanActivateChild*/, decorators: [{
28
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: SneatAuthGuard, decorators: [{
90
29
  type: Injectable,
91
30
  args: [{
92
31
  providedIn: 'root',
93
32
  }]
94
33
  }] });
95
- export const canLoad = (pipe) => ({
96
- canLoad: [SneatAuthGuard],
97
- data: { authCanLoadGuardPipe: pipe },
98
- });
34
+ /**
35
+ * @deprecated Use `{ canActivate: [sneatAuthGuard] }` instead — see
36
+ * `./redirect-to-login.guard`. Retained for route configs that still reference
37
+ * it; both hooks resolve to the permissive `SneatAuthGuard` above.
38
+ */
99
39
  export const SNEAT_AUTH_GUARDS = {
100
40
  canActivate: [SneatAuthGuard],
101
41
  canLoad: [SneatAuthGuard],
@@ -1 +1 @@
1
- {"version":3,"file":"sneat-auth-guard.js","sourceRoot":"","sources":["../../../../../../libs/auth/core/src/lib/sneat-auth-guard.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ActivatedRouteSnapshot,\n // CanActivate,\n // CanActivateChild,\n // CanLoad,\n Route,\n Router,\n RouterStateSnapshot,\n UrlSegment,\n UrlTree,\n} from '@angular/router';\nimport { Observable } from 'rxjs';\nimport { Injectable, inject } from '@angular/core';\nimport { Auth } from '@angular/fire/auth';\nimport { map } from 'rxjs/operators';\nimport { AuthPipe } from '@angular/fire/auth-guard';\n\ntype AuthCanLoadPipeGenerator = (\n route: Route,\n segments: UrlSegment[],\n) => AuthPipe;\n\n/**\n * Strip the document's `<base href>` prefix from a browser pathname, returning a\n * router-relative path.\n *\n * Apps mounted under a base href (e.g. `/app/` in the Sneat site-hosting\n * pattern) have a `location.pathname` of `/app/new-game`, but the Angular Router\n * matches routes relative to the base href (`new-game`). Feeding the un-stripped\n * pathname back into the router after login fails to match any route (NG04002).\n */\nfunction routerRelativePath(pathname: string): string {\n const baseHref = document.querySelector('base')?.getAttribute('href') ?? '/';\n if (baseHref === '/' || baseHref === '') {\n return pathname;\n }\n const base = baseHref.replace(/\\/$/, ''); // '/app/' -> '/app'\n if (pathname === base) {\n return '/';\n }\n if (pathname.startsWith(base + '/')) {\n return pathname.slice(base.length); // '/app/new-game' -> '/new-game'\n }\n return pathname;\n}\n\nexport const redirectToLoginIfNotSignedIn: AuthPipe = map((user) => {\n if (user) {\n return true;\n }\n const path = routerRelativePath(location.pathname);\n let url = '/login';\n if (path != '/') {\n url += '#' + path;\n }\n return url;\n});\n\n@Injectable({\n providedIn: 'root',\n})\nexport class SneatAuthGuard /*implements CanLoad, CanActivate, CanActivateChild*/ {\n private readonly router = inject(Router);\n private readonly auth = inject(Auth);\n\n public canLoad(\n _route: Route,\n _segments: UrlSegment[],\n ):\n | Observable<boolean | UrlTree>\n | Promise<boolean | UrlTree>\n | boolean\n | UrlTree {\n {\n // console.log('SneatAuthGuard.canLoad', route, segments);\n // const authPipeFactory =\n // \t(route.data && route.data['authCanLoadGuardPipe'] as AuthCanLoadPipeGenerator) ||\n // \t(() => redirectToLoginIfNotSignedIn);\n // const subj = new Subject<boolean>();\n // onAuthStateChanged(this.auth, {\n // \tnext: (user) => {\n // \t\tconsole.log('onAuthStateChanged', user);\n // \t}\n // })\n // return this.auth.user.pipe(\n // \tmap((user) => {\n // \t\tconsole.log('user', user);\n // \t\treturn user;\n // \t}),\n // \ttake(1),\n // \tauthPipeFactory(route, segments),\n // \tmap((can) => {\n // \t\tconsole.log('can', can);\n // \t\tif (typeof can === 'boolean') {\n // \t\t\treturn can;\n // \t\t} else if (Array.isArray(can)) {\n // \t\t\treturn this.router.createUrlTree(can);\n // \t\t} else {\n // \t\t\treturn this.router.parseUrl(can);\n // \t\t}\n // \t}),\n // );\n return true;\n }\n }\n\n public canActivate(\n _route: ActivatedRouteSnapshot,\n _state: RouterStateSnapshot, //: Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree\n ) {\n // console.log('SneatAuthGuard.canActivate', route, state);\n return true;\n }\n\n canActivateChild(\n _childRoute: ActivatedRouteSnapshot,\n _state: RouterStateSnapshot, // : Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree\n ) {\n // console.log('SneatAuthGuard.canActivateChild', childRoute, state);\n return true;\n }\n}\n\nexport const canLoad = (pipe?: AuthCanLoadPipeGenerator) => ({\n canLoad: [SneatAuthGuard],\n data: { authCanLoadGuardPipe: pipe },\n});\n\nexport const SNEAT_AUTH_GUARDS = {\n canActivate: [SneatAuthGuard],\n canLoad: [SneatAuthGuard],\n};\n"]}
1
+ {"version":3,"file":"sneat-auth-guard.js","sourceRoot":"","sources":["../../../../../../libs/auth/core/src/lib/sneat-auth-guard.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;;AAE3C;;;;;;;;;;;GAWG;AAIH,MAAM,OAAO,cAAc;IAClB,OAAO,CACZ,MAAa,EACb,SAAuB;QAMvB,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,WAAW,CAChB,MAA8B,EAC9B,MAA2B;QAE3B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,gBAAgB,CACd,WAAmC,EACnC,MAA2B;QAE3B,OAAO,IAAI,CAAC;IACd,CAAC;8GAxBU,cAAc;kHAAd,cAAc,cAFb,MAAM;;2FAEP,cAAc;kBAH1B,UAAU;mBAAC;oBACV,UAAU,EAAE,MAAM;iBACnB;;AA4BD;;;;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 ActivatedRouteSnapshot,\n Route,\n RouterStateSnapshot,\n UrlSegment,\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 _route: Route,\n _segments: UrlSegment[],\n ):\n | Observable<boolean | UrlTree>\n | Promise<boolean | UrlTree>\n | boolean\n | UrlTree {\n return true;\n }\n\n public canActivate(\n _route: ActivatedRouteSnapshot,\n _state: RouterStateSnapshot,\n ) {\n return true;\n }\n\n canActivateChild(\n _childRoute: ActivatedRouteSnapshot,\n _state: RouterStateSnapshot,\n ) {\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"]}
@@ -1,12 +1,11 @@
1
1
  import { Capacitor } from '@capacitor/core';
2
2
  import { FirebaseAuthentication, } from '@capacitor-firebase/authentication';
3
- import { AnalyticsService, EnvConfigToken, } from '@sneat/core';
3
+ import { AnalyticsService, EnvConfigToken, SNEAT_FIREBASE_AUTH, } from '@sneat/core';
4
4
  import { BehaviorSubject, from } from 'rxjs';
5
5
  import { Injectable, inject } from '@angular/core';
6
6
  import { ErrorLogger } from '@sneat/core';
7
7
  import { distinctUntilChanged, shareReplay } from 'rxjs/operators';
8
- import { Auth, getAuth, signInWithCredential, } from '@angular/fire/auth';
9
- import { GoogleAuthProvider, OAuthProvider, GithubAuthProvider, FacebookAuthProvider, signInWithEmailLink, signInWithCustomToken, signInWithPopup, signInWithRedirect, linkWithPopup, unlink, } from 'firebase/auth';
8
+ import { getAuth, signInWithCredential, GoogleAuthProvider, OAuthProvider, GithubAuthProvider, FacebookAuthProvider, signInWithEmailLink, signInWithCustomToken, signInWithPopup, signInWithRedirect, linkWithPopup, unlink, } from 'firebase/auth';
10
9
  // TODO: fix & remove this eslint hint @nrwl/nx/enforce-module-boundaries
11
10
  import { newRandomId } from '@sneat/random';
12
11
  import * as i0 from "@angular/core";
@@ -23,7 +22,7 @@ export class SneatAuthStateService {
23
22
  constructor() {
24
23
  this.errorLogger = inject(ErrorLogger);
25
24
  this.analyticsService = inject(AnalyticsService);
26
- this.fbAuth = inject(Auth);
25
+ this.fbAuth = inject(SNEAT_FIREBASE_AUTH);
27
26
  // Web OAuth sign-in strategy from the app's environment config (default popup).
28
27
  this.signInMethod = inject(EnvConfigToken, { optional: true })?.signInMethod ?? 'popup';
29
28
  this.id = newRandomId({ len: 5 });
@@ -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 EnumAsUnionOfKeys,\n EnvConfigToken,\n IAnalyticsService,\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 Auth,\n AuthProvider,\n getAuth,\n signInWithCredential,\n User,\n UserCredential,\n UserInfo,\n} from '@angular/fire/auth';\n\nimport {\n GoogleAuthProvider,\n OAuthProvider,\n GithubAuthProvider,\n FacebookAuthProvider,\n signInWithEmailLink,\n signInWithCustomToken,\n signInWithPopup,\n signInWithRedirect,\n linkWithPopup,\n unlink,\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\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 token?: string | null;\n readonly user?: ISneatAuthUser | null;\n readonly err?: unknown;\n}\n\nconst initialAuthStatus = AuthStatuses.authenticating;\nexport const initialSneatAuthState = { status: initialAuthStatus };\n\n@Injectable({ providedIn: 'root' })\nexport class SneatAuthStateService {\n private readonly errorLogger = inject<IErrorLogger>(ErrorLogger);\n private readonly analyticsService =\n inject<IAnalyticsService>(AnalyticsService);\n readonly fbAuth = inject(Auth);\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 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 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 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 err: `fbUser.getIdToken() failed: ${err}`,\n });\n this.errorLogger.logError(err, 'Failed in fbUser.getIdToken()');\n });\n },\n error: (err) => {\n const current = this.authState$.value || {};\n this.authState$.next({\n ...current,\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 // 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 });\n this.authStatus$.next(status);\n },\n error: (err) => {\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 err: `fbAuth.onAuthStateChanged() failed: ${err}`,\n });\n },\n });\n }\n\n private publishSignedOutState(): void {\n this.tokenUserID = undefined;\n this.authUser$.next(null);\n this.authState$.next({\n ...this.authState$.value,\n status: AuthStatuses.notAuthenticated,\n token: null,\n user: null,\n });\n this.authStatus$.next(AuthStatuses.notAuthenticated);\n }\n\n public signOut(): Promise<void> {\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 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 EnumAsUnionOfKeys,\n EnvConfigToken,\n IAnalyticsService,\n SNEAT_FIREBASE_AUTH,\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} 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\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 token?: string | null;\n readonly user?: ISneatAuthUser | null;\n readonly err?: unknown;\n}\n\nconst initialAuthStatus = AuthStatuses.authenticating;\nexport const initialSneatAuthState = { status: initialAuthStatus };\n\n@Injectable({ providedIn: 'root' })\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\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 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 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 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 err: `fbUser.getIdToken() failed: ${err}`,\n });\n this.errorLogger.logError(err, 'Failed in fbUser.getIdToken()');\n });\n },\n error: (err) => {\n const current = this.authState$.value || {};\n this.authState$.next({\n ...current,\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 // 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 });\n this.authStatus$.next(status);\n },\n error: (err) => {\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 err: `fbAuth.onAuthStateChanged() failed: ${err}`,\n });\n },\n });\n }\n\n private publishSignedOutState(): void {\n this.tokenUserID = undefined;\n this.authUser$.next(null);\n this.authState$.next({\n ...this.authState$.value,\n status: AuthStatuses.notAuthenticated,\n token: null,\n user: null,\n });\n this.authStatus$.next(AuthStatuses.notAuthenticated);\n }\n\n public signOut(): Promise<void> {\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 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,7 +1,7 @@
1
1
  import { Injectable, inject, Injector, runInInjectionContext, } from '@angular/core';
2
2
  import {
3
3
  // Action,
4
- Firestore as AngularFirestore, collection, doc, onSnapshot, } from '@angular/fire/firestore';
4
+ Firestore as AngularFirestore, collection, doc, onSnapshot, } from 'firebase/firestore';
5
5
  import { SneatApiService } from '@sneat/api';
6
6
  import { ErrorLogger } from '@sneat/core';
7
7
  import { initialSneatAuthState, SneatAuthStateService, } from '../sneat-auth-state-service';
@@ -1 +1 @@
1
- {"version":3,"file":"sneat-user.service.js","sourceRoot":"","sources":["../../../../../../../libs/auth/core/src/lib/user/sneat-user.service.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Injectable,\n inject,\n Injector,\n runInInjectionContext,\n} from '@angular/core';\nimport {\n // Action,\n Firestore as AngularFirestore,\n CollectionReference,\n DocumentSnapshot,\n collection,\n doc,\n onSnapshot,\n Unsubscribe,\n} from '@angular/fire/firestore';\nimport { SneatApiService } from '@sneat/api';\nimport { IUserRecord } from '@sneat/auth-models';\nimport { ErrorLogger, IErrorLogger } from '@sneat/core';\nimport {\n initialSneatAuthState,\n ISneatAuthState,\n ISneatAuthUser,\n SneatAuthStateService,\n} from '../sneat-auth-state-service';\nimport { BehaviorSubject, Observable, ReplaySubject } from 'rxjs';\nimport {\n IInitUserRecordRequest,\n UserRecordService,\n} from './user-record.service';\n\nexport interface ISneatUserState extends ISneatAuthState {\n record?: IUserRecord | null; // undefined => not loaded yet, null = does not exists\n}\n\nconst UsersCollection = 'users';\n\n@Injectable({ providedIn: 'root' }) // TODO: lazy loading\nexport class SneatUserService {\n private readonly errorLogger = inject<IErrorLogger>(ErrorLogger);\n private readonly sneatApiService = inject(SneatApiService);\n private readonly userRecordService = inject(UserRecordService);\n\n // private userDocSubscription?: Subscription;\n private readonly injector = inject(Injector);\n private readonly userCollection: CollectionReference<IUserRecord>;\n private readonly userDocRef = (uid: string) =>\n runInInjectionContext(this.injector, () => doc(this.userCollection, uid));\n\n private uid?: string;\n private $userTitle?: string;\n\n private readonly userChanged$ = new ReplaySubject<string | undefined>(1);\n public readonly userChanged = this.userChanged$.asObservable();\n\n private readonly userState$ = new BehaviorSubject<ISneatUserState>(\n initialSneatAuthState,\n );\n\n public readonly userState = this.userState$.asObservable();\n\n private _unsubscribeFromUserDoc?: Unsubscribe;\n\n private unsubscribeFromUserDoc(_from: string) {\n if (this._unsubscribeFromUserDoc) {\n // console.log(\n // 'SneatUserService.unsubscribeFromUserDoc() called from ' + _from,\n // );\n this._unsubscribeFromUserDoc();\n this._unsubscribeFromUserDoc = undefined;\n }\n }\n\n constructor() {\n const afs = inject(AngularFirestore);\n const sneatAuthStateService = inject(SneatAuthStateService);\n this.userCollection = collection(\n afs,\n UsersCollection,\n ) as CollectionReference<IUserRecord>;\n sneatAuthStateService.authState.subscribe({\n next: this.onAuthStateChanged,\n error: this.errorLogger.logErrorHandler('failed to get sneat auth state'),\n });\n }\n\n public get currentUserID(): string | undefined {\n return this.uid;\n }\n\n // public get userTitle(): string | undefined {\n // \treturn this.$userTitle;\n // }\n\n public setUserCountry(countryID: string): Observable<void> {\n return this.sneatApiService.post('users/set_user_country', { countryID });\n }\n\n public onUserSignedIn(authState: ISneatAuthState): void {\n const authUser = authState.user;\n // afUser.getIdToken().then(idToken => {\n // \tconsole.log('Firebase idToken:', idToken);\n // }).catch(err => this.errorLoggerService.logError(err, 'Failed to get Firebase ID token'));\n if (authUser?.email && authUser.emailVerified) {\n this.$userTitle = authUser.email;\n }\n if (this.uid === authUser?.uid) {\n return;\n }\n this.unsubscribeFromUserDoc('onUserSignedIn()');\n if (!authUser) {\n if (this.userState$.value?.record !== null) {\n this.userState$.next({ ...this.userState$.value });\n }\n return;\n }\n const { uid } = authUser;\n this.uid = uid;\n this.userState$.next({\n ...authState,\n });\n this.userChanged$.next(uid);\n this.watchUserRecord(uid, authState);\n }\n\n private watchUserRecord(uid: string, authState: ISneatAuthState): void {\n // console.log(\n // `SneatUserService.watchUserRecord(uid=${uid}): Loading user record...`,\n // );\n this.unsubscribeFromUserDoc('whatUserRecord()');\n\n // TODO: Remove - setTimeout() not needed but trying to troubleshoot user record issue\n setTimeout(() => {\n try {\n const userDocRef = this.userDocRef(uid);\n this._unsubscribeFromUserDoc = runInInjectionContext(\n this.injector,\n () =>\n onSnapshot(userDocRef, {\n next: (userDocSnapshot) => {\n // console.log(\n // `SneatUserService.watchUserRecord(uid=${uid}) => userDocSnapshot:`,\n // userDocSnapshot,\n // );\n this.onAuthStateChanged(authState);\n this.userDocChanged(userDocSnapshot, authState);\n },\n error: (err) => {\n console.error(\n `SneatUserService.watchUserRecord(uid=${uid}) => failed:`,\n err,\n );\n },\n }),\n );\n } catch (err) {\n console.error(\n `SneatUserService.watchUserRecord(uid=${uid}) => Failed to setup watcher for user record::`,\n err,\n );\n return;\n }\n }, 100);\n }\n\n private onAuthStateChanged = (authState: ISneatAuthState): void => {\n // console.log('SneatUserService => authState changed:', authState);\n if (authState.user) {\n this.onUserSignedIn(authState);\n } else {\n this.userState$.next(authState);\n this.userChanged$.next(undefined);\n this.onUserSignedOut();\n }\n };\n\n private userDocChanged(\n userDocSnapshot: DocumentSnapshot<IUserRecord>,\n authState: ISneatAuthState,\n ): void {\n // console.log(\n // 'SneatUserService.userDocChanged() => userDocSnapshot.exists:',\n // userDocSnapshot.exists(),\n // 'authState:',\n // authState,\n // 'userDocSnapshot:',\n // userDocSnapshot,\n // );\n if (userDocSnapshot.ref.id !== this.uid) {\n console.error(\n 'userDocSnapshot.ref.id !== this.uid - Should always be equal as we unsubscribe if uid changes',\n );\n return;\n }\n // console.log('SneatUserService => userDocSnapshot.exists:', userDocSnapshot.exists)\n const authUser = authState.user;\n if (authUser && !userDocSnapshot.exists()) {\n this.initUserRecordFromAuthUser(authUser);\n }\n const userRecord: IUserRecord | null = userDocSnapshot.exists()\n ? (userDocSnapshot.data() as IUserRecord)\n : authUser\n ? { title: authUser.displayName || authUser.email || authUser.uid }\n : null;\n\n this.userState$.next({\n ...authState,\n record: userRecord,\n });\n }\n\n private initUserRecordFromAuthUser(authUser: ISneatAuthUser): void {\n let request: IInitUserRecordRequest = {\n email: authUser.email || undefined,\n emailIsVerified: authUser.emailVerified,\n authProvider: authUser?.providerId,\n };\n if (authUser?.displayName) {\n request = { ...request, names: { fullName: authUser.displayName } };\n }\n this.userRecordService.initUserRecord(request).subscribe({\n next: (_userDto) => {\n // User record created successfully - no additional action needed\n },\n error: this.errorLogger.logErrorHandler('failed to create user record'),\n });\n }\n\n private onUserSignedOut(): void {\n this.uid = undefined;\n this.unsubscribeFromUserDoc('onUserSignedOut()');\n }\n\n // private createUserRecord(userDocRef: DocumentReference, authUser: ISneatAuthUser): void {\n // \tif (this.userState$.value) {\n // \t\treturn;\n // \t}\n // \tthis.db.firestore.runTransaction(async tx => {\n // \t\tif (this.userState$.value) {\n // \t\t\treturn undefined;\n // \t\t}\n // \t\tconst u = await tx.get(userDocRef);\n // \t\tif (!u.exists) {\n // \t\t\tconst title = authUser.displayName || authUser.email || authUser.uid;\n // \t\t\tconst user: IUserRecord = authUser.email\n // \t\t\t\t? {title, email: authUser.email, emailVerified: authUser.emailVerified}\n // \t\t\t\t: {title};\n // \t\t\tawait tx.set(userDocRef, user);\n // \t\t\treturn user;\n // \t\t}\n // \t\treturn undefined;\n // \t}).then(user => {\n // \t\tif (user) {\n // \t\t\tconsole.log('user record created:', user);\n // \t\t}\n // \t\tif (!this.userState$.value) {\n // \t\t\tconst userState: ISneatUserState = {\n // \t\t\t\tstatus: AuthStatuses.authenticated,\n // \t\t\t\trecord: user,\n // \t\t\t\tuser: authUser,\n // \t\t\t};\n // \t\t\tthis.userState$.next(userState);\n // \t\t}\n // \t}).catch(this.errorLogger.logErrorHandler('failed to create user record'));\n // }\n}\n"]}
1
+ {"version":3,"file":"sneat-user.service.js","sourceRoot":"","sources":["../../../../../../../libs/auth/core/src/lib/user/sneat-user.service.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Injectable,\n inject,\n Injector,\n runInInjectionContext,\n} from '@angular/core';\nimport {\n // Action,\n Firestore as AngularFirestore,\n CollectionReference,\n DocumentSnapshot,\n collection,\n doc,\n onSnapshot,\n Unsubscribe,\n} from 'firebase/firestore';\nimport { SneatApiService } from '@sneat/api';\nimport { IUserRecord } from '@sneat/auth-models';\nimport { ErrorLogger, IErrorLogger } from '@sneat/core';\nimport {\n initialSneatAuthState,\n ISneatAuthState,\n ISneatAuthUser,\n SneatAuthStateService,\n} from '../sneat-auth-state-service';\nimport { BehaviorSubject, Observable, ReplaySubject } from 'rxjs';\nimport {\n IInitUserRecordRequest,\n UserRecordService,\n} from './user-record.service';\n\nexport interface ISneatUserState extends ISneatAuthState {\n record?: IUserRecord | null; // undefined => not loaded yet, null = does not exists\n}\n\nconst UsersCollection = 'users';\n\n@Injectable({ providedIn: 'root' }) // TODO: lazy loading\nexport class SneatUserService {\n private readonly errorLogger = inject<IErrorLogger>(ErrorLogger);\n private readonly sneatApiService = inject(SneatApiService);\n private readonly userRecordService = inject(UserRecordService);\n\n // private userDocSubscription?: Subscription;\n private readonly injector = inject(Injector);\n private readonly userCollection: CollectionReference<IUserRecord>;\n private readonly userDocRef = (uid: string) =>\n runInInjectionContext(this.injector, () => doc(this.userCollection, uid));\n\n private uid?: string;\n private $userTitle?: string;\n\n private readonly userChanged$ = new ReplaySubject<string | undefined>(1);\n public readonly userChanged = this.userChanged$.asObservable();\n\n private readonly userState$ = new BehaviorSubject<ISneatUserState>(\n initialSneatAuthState,\n );\n\n public readonly userState = this.userState$.asObservable();\n\n private _unsubscribeFromUserDoc?: Unsubscribe;\n\n private unsubscribeFromUserDoc(_from: string) {\n if (this._unsubscribeFromUserDoc) {\n // console.log(\n // 'SneatUserService.unsubscribeFromUserDoc() called from ' + _from,\n // );\n this._unsubscribeFromUserDoc();\n this._unsubscribeFromUserDoc = undefined;\n }\n }\n\n constructor() {\n const afs = inject(AngularFirestore);\n const sneatAuthStateService = inject(SneatAuthStateService);\n this.userCollection = collection(\n afs,\n UsersCollection,\n ) as CollectionReference<IUserRecord>;\n sneatAuthStateService.authState.subscribe({\n next: this.onAuthStateChanged,\n error: this.errorLogger.logErrorHandler('failed to get sneat auth state'),\n });\n }\n\n public get currentUserID(): string | undefined {\n return this.uid;\n }\n\n // public get userTitle(): string | undefined {\n // \treturn this.$userTitle;\n // }\n\n public setUserCountry(countryID: string): Observable<void> {\n return this.sneatApiService.post('users/set_user_country', { countryID });\n }\n\n public onUserSignedIn(authState: ISneatAuthState): void {\n const authUser = authState.user;\n // afUser.getIdToken().then(idToken => {\n // \tconsole.log('Firebase idToken:', idToken);\n // }).catch(err => this.errorLoggerService.logError(err, 'Failed to get Firebase ID token'));\n if (authUser?.email && authUser.emailVerified) {\n this.$userTitle = authUser.email;\n }\n if (this.uid === authUser?.uid) {\n return;\n }\n this.unsubscribeFromUserDoc('onUserSignedIn()');\n if (!authUser) {\n if (this.userState$.value?.record !== null) {\n this.userState$.next({ ...this.userState$.value });\n }\n return;\n }\n const { uid } = authUser;\n this.uid = uid;\n this.userState$.next({\n ...authState,\n });\n this.userChanged$.next(uid);\n this.watchUserRecord(uid, authState);\n }\n\n private watchUserRecord(uid: string, authState: ISneatAuthState): void {\n // console.log(\n // `SneatUserService.watchUserRecord(uid=${uid}): Loading user record...`,\n // );\n this.unsubscribeFromUserDoc('whatUserRecord()');\n\n // TODO: Remove - setTimeout() not needed but trying to troubleshoot user record issue\n setTimeout(() => {\n try {\n const userDocRef = this.userDocRef(uid);\n this._unsubscribeFromUserDoc = runInInjectionContext(\n this.injector,\n () =>\n onSnapshot(userDocRef, {\n next: (userDocSnapshot) => {\n // console.log(\n // `SneatUserService.watchUserRecord(uid=${uid}) => userDocSnapshot:`,\n // userDocSnapshot,\n // );\n this.onAuthStateChanged(authState);\n this.userDocChanged(userDocSnapshot, authState);\n },\n error: (err) => {\n console.error(\n `SneatUserService.watchUserRecord(uid=${uid}) => failed:`,\n err,\n );\n },\n }),\n );\n } catch (err) {\n console.error(\n `SneatUserService.watchUserRecord(uid=${uid}) => Failed to setup watcher for user record::`,\n err,\n );\n return;\n }\n }, 100);\n }\n\n private onAuthStateChanged = (authState: ISneatAuthState): void => {\n // console.log('SneatUserService => authState changed:', authState);\n if (authState.user) {\n this.onUserSignedIn(authState);\n } else {\n this.userState$.next(authState);\n this.userChanged$.next(undefined);\n this.onUserSignedOut();\n }\n };\n\n private userDocChanged(\n userDocSnapshot: DocumentSnapshot<IUserRecord>,\n authState: ISneatAuthState,\n ): void {\n // console.log(\n // 'SneatUserService.userDocChanged() => userDocSnapshot.exists:',\n // userDocSnapshot.exists(),\n // 'authState:',\n // authState,\n // 'userDocSnapshot:',\n // userDocSnapshot,\n // );\n if (userDocSnapshot.ref.id !== this.uid) {\n console.error(\n 'userDocSnapshot.ref.id !== this.uid - Should always be equal as we unsubscribe if uid changes',\n );\n return;\n }\n // console.log('SneatUserService => userDocSnapshot.exists:', userDocSnapshot.exists)\n const authUser = authState.user;\n if (authUser && !userDocSnapshot.exists()) {\n this.initUserRecordFromAuthUser(authUser);\n }\n const userRecord: IUserRecord | null = userDocSnapshot.exists()\n ? (userDocSnapshot.data() as IUserRecord)\n : authUser\n ? { title: authUser.displayName || authUser.email || authUser.uid }\n : null;\n\n this.userState$.next({\n ...authState,\n record: userRecord,\n });\n }\n\n private initUserRecordFromAuthUser(authUser: ISneatAuthUser): void {\n let request: IInitUserRecordRequest = {\n email: authUser.email || undefined,\n emailIsVerified: authUser.emailVerified,\n authProvider: authUser?.providerId,\n };\n if (authUser?.displayName) {\n request = { ...request, names: { fullName: authUser.displayName } };\n }\n this.userRecordService.initUserRecord(request).subscribe({\n next: (_userDto) => {\n // User record created successfully - no additional action needed\n },\n error: this.errorLogger.logErrorHandler('failed to create user record'),\n });\n }\n\n private onUserSignedOut(): void {\n this.uid = undefined;\n this.unsubscribeFromUserDoc('onUserSignedOut()');\n }\n\n // private createUserRecord(userDocRef: DocumentReference, authUser: ISneatAuthUser): void {\n // \tif (this.userState$.value) {\n // \t\treturn;\n // \t}\n // \tthis.db.firestore.runTransaction(async tx => {\n // \t\tif (this.userState$.value) {\n // \t\t\treturn undefined;\n // \t\t}\n // \t\tconst u = await tx.get(userDocRef);\n // \t\tif (!u.exists) {\n // \t\t\tconst title = authUser.displayName || authUser.email || authUser.uid;\n // \t\t\tconst user: IUserRecord = authUser.email\n // \t\t\t\t? {title, email: authUser.email, emailVerified: authUser.emailVerified}\n // \t\t\t\t: {title};\n // \t\t\tawait tx.set(userDocRef, user);\n // \t\t\treturn user;\n // \t\t}\n // \t\treturn undefined;\n // \t}).then(user => {\n // \t\tif (user) {\n // \t\t\tconsole.log('user record created:', user);\n // \t\t}\n // \t\tif (!this.userState$.value) {\n // \t\t\tconst userState: ISneatUserState = {\n // \t\t\t\tstatus: AuthStatuses.authenticated,\n // \t\t\t\trecord: user,\n // \t\t\t\tuser: authUser,\n // \t\t\t};\n // \t\t\tthis.userState$.next(userState);\n // \t\t}\n // \t}).catch(this.errorLogger.logErrorHandler('failed to create user record'));\n // }\n}\n"]}
@@ -3,13 +3,13 @@ import { CanActivateFn } from '@angular/router';
3
3
  * Redirect target for an unauthenticated visitor: `/login`, or
4
4
  * `/login#<path>` for a non-root path so the login page can send them back
5
5
  * to it after signing in. Matches the URL shape the fleet's
6
- * `@angular/fire/auth-guard`-based `redirectToLoginIfNotSignedIn` pipe (see
7
- * `./sneat-auth-guard`) has always produced.
6
+ * `@angular/fire/auth-guard`-based `redirectToLoginIfNotSignedIn` pipe always
7
+ * produced — that pipe was removed in 0.27.0 together with `@angular/fire`.
8
8
  */
9
9
  export declare function loginRedirectPath(path: string): string;
10
10
  /**
11
11
  * Functional route guard — the `@angular/fire`-free replacement for the
12
- * fleet's one uniform pattern:
12
+ * fleet's one uniform pattern. Before 0.27.0 a protected route read:
13
13
  *
14
14
  * import { AuthGuard } from '@angular/fire/auth-guard';
15
15
  * import { redirectToLoginIfNotSignedIn } from '@sneat/auth-core';
@@ -18,7 +18,8 @@ export declare function loginRedirectPath(path: string): string;
18
18
  * data: { authGuardPipe: () => redirectToLoginIfNotSignedIn },
19
19
  * }
20
20
  *
21
- * becomes simply:
21
+ * Since 0.27.0 — where both `AuthGuard` and `redirectToLoginIfNotSignedIn`
22
+ * are gone — it reads simply:
22
23
  *
23
24
  * import { sneatAuthGuard } from '@sneat/auth-core';
24
25
  * { canActivate: [sneatAuthGuard] }
@@ -27,8 +28,12 @@ export declare function loginRedirectPath(path: string): string;
27
28
  * the attempted path as a hash fragment). Driven entirely by Sneat's own
28
29
  * `SneatAuthStateService` — no `@angular/fire` `Auth`/`AuthPipe` involved.
29
30
  *
31
+ * The attempted path comes from `RouterStateSnapshot.url`, which is already
32
+ * router-relative, so this needs none of the `<base href>` stripping the old
33
+ * `location.pathname`-based pipe did.
34
+ *
30
35
  * Waits out the initial `'authenticating'` status (Firebase hasn't resolved
31
- * the session yet) before deciding, exactly like the fleet's current
32
- * `user(auth).pipe(take(1), redirectToLoginIfNotSignedIn)` composition does.
36
+ * the session yet) before deciding, exactly like the old
37
+ * `user(auth).pipe(take(1), redirectToLoginIfNotSignedIn)` composition did.
33
38
  */
34
39
  export declare const sneatAuthGuard: CanActivateFn;
@@ -1,26 +1,31 @@
1
1
  import { ActivatedRouteSnapshot, Route, RouterStateSnapshot, UrlSegment, UrlTree } from '@angular/router';
2
2
  import { Observable } from 'rxjs';
3
- import { AuthPipe } from '@angular/fire/auth-guard';
4
3
  import * as i0 from "@angular/core";
5
- type AuthCanLoadPipeGenerator = (route: Route, segments: UrlSegment[]) => AuthPipe;
6
- export declare const redirectToLoginIfNotSignedIn: AuthPipe;
4
+ /**
5
+ * Permissive class-based route guard: every hook returns `true`.
6
+ *
7
+ * @deprecated Prefer the functional `sneatAuthGuard`
8
+ * (`./redirect-to-login.guard`), which actually blocks an unauthenticated
9
+ * visitor and redirects them to `/login`. This guard admits everyone — it
10
+ * never gated anything — and is kept only so existing route configs
11
+ * referencing `SNEAT_AUTH_GUARDS` keep compiling.
12
+ *
13
+ * As of 0.27.0 it no longer injects Firebase `Auth`: the injected instance was
14
+ * never read, and that injection is what coupled this file to `@angular/fire`.
15
+ */
7
16
  export declare class SneatAuthGuard {
8
- private readonly router;
9
- private readonly auth;
10
17
  canLoad(_route: Route, _segments: UrlSegment[]): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree;
11
18
  canActivate(_route: ActivatedRouteSnapshot, _state: RouterStateSnapshot): boolean;
12
19
  canActivateChild(_childRoute: ActivatedRouteSnapshot, _state: RouterStateSnapshot): boolean;
13
20
  static ɵfac: i0.ɵɵFactoryDeclaration<SneatAuthGuard, never>;
14
21
  static ɵprov: i0.ɵɵInjectableDeclaration<SneatAuthGuard>;
15
22
  }
16
- export declare const canLoad: (pipe?: AuthCanLoadPipeGenerator) => {
17
- canLoad: (typeof SneatAuthGuard)[];
18
- data: {
19
- authCanLoadGuardPipe: AuthCanLoadPipeGenerator | undefined;
20
- };
21
- };
23
+ /**
24
+ * @deprecated Use `{ canActivate: [sneatAuthGuard] }` instead — see
25
+ * `./redirect-to-login.guard`. Retained for route configs that still reference
26
+ * it; both hooks resolve to the permissive `SneatAuthGuard` above.
27
+ */
22
28
  export declare const SNEAT_AUTH_GUARDS: {
23
29
  canActivate: (typeof SneatAuthGuard)[];
24
30
  canLoad: (typeof SneatAuthGuard)[];
25
31
  };
26
- export {};
@@ -1,6 +1,6 @@
1
1
  import { EnumAsUnionOfKeys } from '@sneat/core';
2
2
  import { Observable } from 'rxjs';
3
- import { Auth, UserCredential, UserInfo } from '@angular/fire/auth';
3
+ import { UserCredential, UserInfo } from 'firebase/auth';
4
4
  import * as i0 from "@angular/core";
5
5
  export declare enum AuthStatuses {
6
6
  authenticating = "authenticating",
@@ -25,7 +25,7 @@ export declare const initialSneatAuthState: {
25
25
  export declare class SneatAuthStateService {
26
26
  private readonly errorLogger;
27
27
  private readonly analyticsService;
28
- readonly fbAuth: Auth;
28
+ readonly fbAuth: import("firebase/auth").Auth;
29
29
  private readonly signInMethod;
30
30
  private readonly id;
31
31
  private readonly authStatus$;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sneat/auth-core",
3
- "version": "0.26.6",
3
+ "version": "0.27.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -8,13 +8,12 @@
8
8
  "@angular/common": ">=22.0.0 <23.0.0",
9
9
  "@angular/core": ">=22.0.0 <23.0.0",
10
10
  "@angular/router": ">=22.0.0 <23.0.0",
11
- "@angular/fire": ">=20",
12
11
  "@capacitor-firebase/authentication": ">=8.0.0 <9.0.0",
13
12
  "@capacitor/core": ">=8.0.0 <9.0.0",
14
- "@sneat/api": "^0.26.0",
15
- "@sneat/auth-models": "^0.26.0",
16
- "@sneat/core": "^0.26.0",
17
- "@sneat/dto": "^0.26.0",
13
+ "@sneat/api": "^0.27.0",
14
+ "@sneat/auth-models": "^0.27.0",
15
+ "@sneat/core": "^0.27.0",
16
+ "@sneat/dto": "^0.27.0",
18
17
  "@sneat/random": "*",
19
18
  "firebase": "*",
20
19
  "rxjs": ">=7.8.0"