@bravobit/bb-foundation 0.53.5 → 0.54.0

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,8 +6,9 @@ export declare class AuthSession {
6
6
  private readonly _storage;
7
7
  private readonly _accessTokenStorageKey;
8
8
  private readonly _refreshTokenStorageKey;
9
- private readonly _userStorageKey;
9
+ private readonly _authenticatedStorageKey;
10
10
  private readonly _strategy;
11
+ private _authenticated;
11
12
  private _accessTokenString;
12
13
  private _refreshTokenString;
13
14
  private _accessTokenPayload;
@@ -38,9 +39,12 @@ export declare class AuthSession {
38
39
  clear(): void;
39
40
  private restoreFromStorage;
40
41
  private persistTokensInStorage;
41
- private persistUserInStorage;
42
- private setAccessToken;
43
- private setRefreshToken;
42
+ private persistAuthenticatedInStorage;
43
+ private setAuthenticated;
44
+ private cacheAccessToken;
45
+ private cacheRefreshToken;
46
+ private cacheAuthenticated;
44
47
  private generateKey;
45
48
  private isTokenValid;
49
+ private getNextYearDate;
46
50
  }
@@ -16,7 +16,6 @@ export interface AuthConfig {
16
16
  };
17
17
  setRedirectOnFailedAuth?: boolean;
18
18
  interceptActing?: boolean;
19
- bootstrap?: boolean;
20
19
  providers?: string[];
21
20
  autoRefresh?: boolean;
22
21
  }
@@ -137,8 +137,10 @@ class AuthSession {
137
137
  _storage;
138
138
  _accessTokenStorageKey;
139
139
  _refreshTokenStorageKey;
140
- _userStorageKey;
140
+ _authenticatedStorageKey;
141
141
  _strategy;
142
+ // Authenticated.
143
+ _authenticated = false;
142
144
  // Token strings.
143
145
  _accessTokenString = null;
144
146
  _refreshTokenString = null;
@@ -154,7 +156,7 @@ class AuthSession {
154
156
  // Setting up the readonly storage keys.
155
157
  this._accessTokenStorageKey = this.generateKey(applicationId, 'au_act');
156
158
  this._refreshTokenStorageKey = this.generateKey(applicationId, 'au_rft');
157
- this._userStorageKey = this.generateKey(applicationId, 'au_usr');
159
+ this._authenticatedStorageKey = this.generateKey(applicationId, 'au_usr');
158
160
  // Setting up the storage.
159
161
  this._storage = options?.storage ?? null;
160
162
  this._strategy = options?.strategy ?? null;
@@ -188,17 +190,14 @@ class AuthSession {
188
190
  return this._refreshTokenPayload ?? null;
189
191
  }
190
192
  authenticated() {
191
- if (this._strategy === 'httpOnlyCookie') {
192
- return !!this.snapshot?.user;
193
- }
194
- return this.isTokenValid(this._accessTokenPayload) || this.isTokenValid(this._refreshTokenPayload);
193
+ return this._authenticated;
195
194
  }
196
195
  setTokens(accessToken, refreshToken, persist = true) {
197
196
  if (this._strategy === 'httpOnlyCookie') {
198
197
  return;
199
198
  }
200
- this.setAccessToken(accessToken);
201
- this.setRefreshToken(refreshToken);
199
+ this.cacheAccessToken(accessToken);
200
+ this.cacheRefreshToken(refreshToken);
202
201
  if (persist) {
203
202
  this.persistTokensInStorage();
204
203
  }
@@ -206,7 +205,7 @@ class AuthSession {
206
205
  setUser(user, persist = true) {
207
206
  this._user$.next(user ?? null);
208
207
  if (persist) {
209
- this.persistUserInStorage();
208
+ this.setAuthenticated(!!user);
210
209
  }
211
210
  }
212
211
  clear() {
@@ -217,18 +216,15 @@ class AuthSession {
217
216
  if (!this._storage) {
218
217
  return;
219
218
  }
219
+ const authenticated = this._storage.get(this._authenticatedStorageKey);
220
+ this.setAuthenticated(!!authenticated);
220
221
  if (this._strategy === 'browserStorage') {
221
222
  // Set the access token.
222
223
  const accessToken = this._storage.get(this._accessTokenStorageKey);
223
- this.setAccessToken(accessToken);
224
+ this.cacheAccessToken(accessToken);
224
225
  // Set the refresh token.
225
226
  const refreshToken = this._storage.get(this._refreshTokenStorageKey);
226
- this.setRefreshToken(refreshToken);
227
- }
228
- // Set the user if we have any correct token payloads.
229
- if ((this._accessTokenPayload || this._refreshTokenPayload) || this._strategy === 'httpOnlyCookie') {
230
- const user = this._storage.get(this._userStorageKey);
231
- this._user$.next(user ?? null); // Note: just settings here instead of setUser() because of syncing to the storage.
227
+ this.cacheRefreshToken(refreshToken);
232
228
  }
233
229
  }
234
230
  persistTokensInStorage() {
@@ -254,28 +250,37 @@ class AuthSession {
254
250
  this._storage.remove(this._refreshTokenStorageKey);
255
251
  }
256
252
  }
257
- persistUserInStorage() {
253
+ persistAuthenticatedInStorage() {
258
254
  if (!this._storage) {
259
255
  return;
260
256
  }
261
- const user = this._user$.getValue();
262
- if (!user) {
263
- return this._storage.remove(this._userStorageKey);
257
+ if (this._authenticated) {
258
+ const expires = this.refreshTokenPayload?.expiresAt
259
+ ?? this.accessTokenPayload?.expiresAt
260
+ ?? this.getNextYearDate();
261
+ this._storage.set(this._authenticatedStorageKey, this._authenticated, { expires });
262
+ }
263
+ else {
264
+ this._storage.remove(this._authenticatedStorageKey);
264
265
  }
265
- const date = new Date();
266
- date.setFullYear(date.getFullYear() + 1);
267
- this._storage.set(this._userStorageKey, user, {
268
- expires: new Date(date.getTime())
269
- });
270
266
  }
271
- setAccessToken(value) {
267
+ setAuthenticated(value, persist = true) {
268
+ this.cacheAuthenticated(value);
269
+ if (persist) {
270
+ this.persistAuthenticatedInStorage();
271
+ }
272
+ }
273
+ cacheAccessToken(value) {
272
274
  this._accessTokenString = value ?? null;
273
275
  this._accessTokenPayload = this._jwt.decode(this._accessTokenString);
274
276
  }
275
- setRefreshToken(value) {
277
+ cacheRefreshToken(value) {
276
278
  this._refreshTokenString = value ?? null;
277
279
  this._refreshTokenPayload = this._jwt.decode(this._refreshTokenString);
278
280
  }
281
+ cacheAuthenticated(value) {
282
+ this._authenticated = !!value;
283
+ }
279
284
  generateKey(applicationId, key) {
280
285
  return [applicationId, key].join('_');
281
286
  }
@@ -285,6 +290,11 @@ class AuthSession {
285
290
  }
286
291
  return token?.expiresAt?.getTime() > Date.now();
287
292
  }
293
+ getNextYearDate() {
294
+ const date = new Date();
295
+ date.setFullYear(date.getFullYear() + 1);
296
+ return date;
297
+ }
288
298
  }
289
299
 
290
300
  class Auth {
@@ -318,11 +328,6 @@ class Auth {
318
328
  this.user = this.session.user;
319
329
  }
320
330
  async initialize() {
321
- // Check if the app should bootstrap the authentication.
322
- const shouldBootstrap = this._config?.bootstrap ?? true;
323
- if (!shouldBootstrap) {
324
- return this.handleAutoRefreshing();
325
- }
326
331
  // Only retrieve from the server when we are actually authenticated.
327
332
  if (!this.session.authenticated()) {
328
333
  return;
@@ -529,10 +534,10 @@ class Auth {
529
534
  .filter(item => !!item)
530
535
  .join('/');
531
536
  }
532
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: Auth, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
533
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: Auth, providedIn: 'root' });
537
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: Auth, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
538
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: Auth, providedIn: 'root' });
534
539
  }
535
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: Auth, decorators: [{
540
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: Auth, decorators: [{
536
541
  type: Injectable,
537
542
  args: [{
538
543
  providedIn: 'root'
@@ -595,10 +600,10 @@ class BbAuthenticated {
595
600
  }
596
601
  }
597
602
  static ngAcceptInputType_bbAuthenticatedElse;
598
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: BbAuthenticated, deps: [], target: i0.ɵɵFactoryTarget.Directive });
599
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.1", type: BbAuthenticated, isStandalone: true, selector: "ng-template[bbAuthenticated]", inputs: { bbAuthenticatedElse: "bbAuthenticatedElse" }, ngImport: i0 });
603
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: BbAuthenticated, deps: [], target: i0.ɵɵFactoryTarget.Directive });
604
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.3", type: BbAuthenticated, isStandalone: true, selector: "ng-template[bbAuthenticated]", inputs: { bbAuthenticatedElse: "bbAuthenticatedElse" }, ngImport: i0 });
600
605
  }
601
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: BbAuthenticated, decorators: [{
606
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: BbAuthenticated, decorators: [{
602
607
  type: Directive,
603
608
  args: [{
604
609
  selector: 'ng-template[bbAuthenticated]'
@@ -663,10 +668,10 @@ class BbAnonymous {
663
668
  }
664
669
  }
665
670
  static ngAcceptInputType_bbAnonymousElse;
666
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: BbAnonymous, deps: [], target: i0.ɵɵFactoryTarget.Directive });
667
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.1", type: BbAnonymous, isStandalone: true, selector: "ng-template[bbAnonymous]", inputs: { bbAnonymousElse: "bbAnonymousElse" }, ngImport: i0 });
671
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: BbAnonymous, deps: [], target: i0.ɵɵFactoryTarget.Directive });
672
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.3", type: BbAnonymous, isStandalone: true, selector: "ng-template[bbAnonymous]", inputs: { bbAnonymousElse: "bbAnonymousElse" }, ngImport: i0 });
668
673
  }
669
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: BbAnonymous, decorators: [{
674
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: BbAnonymous, decorators: [{
670
675
  type: Directive,
671
676
  args: [{
672
677
  selector: 'ng-template[bbAnonymous]'
@@ -751,10 +756,10 @@ class Acting {
751
756
  const active$ = this._userId$.pipe(map(item => !!item), distinctUntilChanged());
752
757
  return combineLatestMap({ active: active$, user: this._auth.user });
753
758
  }
754
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: Acting, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
755
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: Acting, providedIn: 'root' });
759
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: Acting, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
760
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: Acting, providedIn: 'root' });
756
761
  }
757
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: Acting, decorators: [{
762
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: Acting, decorators: [{
758
763
  type: Injectable,
759
764
  args: [{
760
765
  providedIn: 'root'
@@ -776,10 +781,10 @@ class ActingInterceptor {
776
781
  });
777
782
  return next.handle(modified);
778
783
  }
779
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: ActingInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
780
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: ActingInterceptor });
784
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: ActingInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
785
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: ActingInterceptor });
781
786
  }
782
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: ActingInterceptor, decorators: [{
787
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: ActingInterceptor, decorators: [{
783
788
  type: Injectable
784
789
  }] });
785
790
 
@@ -862,10 +867,10 @@ class AuthInterceptor {
862
867
  // Return the default access token.
863
868
  return this._auth.session.accessToken;
864
869
  }
865
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: AuthInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
866
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: AuthInterceptor });
870
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: AuthInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
871
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: AuthInterceptor });
867
872
  }
868
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: AuthInterceptor, decorators: [{
873
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: AuthInterceptor, decorators: [{
869
874
  type: Injectable
870
875
  }] });
871
876
 
@@ -875,9 +880,6 @@ function provideAuthConfig(config) {
875
880
  { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
876
881
  provideAppInitializer(() => inject(Auth).initialize())
877
882
  ];
878
- if (config?.strategy === 'httpOnlyCookie' && !config?.bootstrap) {
879
- throw new Error('the "bootstrap" option must be enabled when using strategy=httpOnlyCookie');
880
- }
881
883
  if (config?.interceptActing) {
882
884
  providers.push({ provide: HTTP_INTERCEPTORS, useClass: ActingInterceptor, multi: true });
883
885
  }
@@ -893,11 +895,11 @@ class AuthModule {
893
895
  ]
894
896
  };
895
897
  }
896
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: AuthModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
897
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.1", ngImport: i0, type: AuthModule, imports: [BbAuthenticated], exports: [BbAuthenticated] });
898
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: AuthModule });
898
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: AuthModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
899
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.3", ngImport: i0, type: AuthModule, imports: [BbAuthenticated], exports: [BbAuthenticated] });
900
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: AuthModule });
899
901
  }
900
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: AuthModule, decorators: [{
902
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: AuthModule, decorators: [{
901
903
  type: NgModule,
902
904
  args: [{
903
905
  imports: [BbAuthenticated],