@abp/ng.oauth 9.3.5 → 10.0.0-rc.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.
@@ -1,13 +1,12 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, Injectable, Inject, signal, provideAppInitializer, makeEnvironmentProviders, NgModule } from '@angular/core';
3
- import * as i2 from '@abp/ng.core';
4
- import { EnvironmentService, NAVIGATE_TO_MANAGE_PROFILE, AuthService, CORE_OPTIONS, IS_EXTERNAL_REQUEST, TENANT_KEY, AbpLocalStorageService, ConfigStateService, HttpErrorReporterService, SessionStateService, AbpWindowService, noop, AbstractAuthErrorFilter, AuthGuard, authGuard, ApiInterceptor, PIPE_TO_LOGIN_FN_KEY, CHECK_AUTHENTICATION_STATE_FN_KEY, AuthErrorFilterService } from '@abp/ng.core';
2
+ import { inject, Injectable, PLATFORM_ID, RESPONSE_INIT, REQUEST, Optional, Inject, DOCUMENT, Injector, signal, provideAppInitializer, makeEnvironmentProviders, NgModule } from '@angular/core';
3
+ import { EnvironmentService, NAVIGATE_TO_MANAGE_PROFILE, AuthService, CORE_OPTIONS, SessionStateService, HttpWaitService, TENANT_KEY, IS_EXTERNAL_REQUEST, APP_STARTED_WITH_SSR, AbpLocalStorageService, AbpCookieStorageService, ConfigStateService, HttpErrorReporterService, AbpWindowService, noop, AbstractAuthErrorFilter, AuthGuard, authGuard, asyncAuthGuard, ApiInterceptor, PIPE_TO_LOGIN_FN_KEY, CHECK_AUTHENTICATION_STATE_FN_KEY, AuthErrorFilterService } from '@abp/ng.core';
5
4
  import { HttpHeaders, HTTP_INTERCEPTORS } from '@angular/common/http';
6
- import * as i1 from 'angular-oauth2-oidc';
7
- import { OAuthService, OAuthErrorEvent, OAuthInfoEvent, OAuthModule, OAuthStorage } from 'angular-oauth2-oidc';
5
+ import { OAuthService, OAuthStorage, OAuthErrorEvent, OAuthInfoEvent, OAuthModule } from 'angular-oauth2-oidc';
6
+ import { firstValueFrom, timer, map, filter, take, timeout, catchError, of, pipe, tap as tap$1, from, lastValueFrom, EMPTY } from 'rxjs';
7
+ import { isPlatformServer, isPlatformBrowser } from '@angular/common';
8
8
  import compare from 'just-compare';
9
- import { map, filter, finalize, switchMap, tap, take } from 'rxjs/operators';
10
- import { pipe, of, filter as filter$1, tap as tap$1, take as take$1, from, lastValueFrom, EMPTY } from 'rxjs';
9
+ import { map as map$1, filter as filter$1, finalize, switchMap, tap, take as take$1 } from 'rxjs/operators';
11
10
  import { Router } from '@angular/router';
12
11
 
13
12
  const NavigateToManageProfileProvider = {
@@ -56,31 +55,84 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.7", ngImpor
56
55
  const abpOAuthGuard = (route, state) => {
57
56
  const oAuthService = inject(OAuthService);
58
57
  const authService = inject(AuthService);
58
+ const platformId = inject(PLATFORM_ID);
59
+ const resInit = inject(RESPONSE_INIT);
60
+ const environmentService = inject(EnvironmentService);
59
61
  const hasValidAccessToken = oAuthService.hasValidAccessToken();
60
62
  if (hasValidAccessToken) {
61
63
  return true;
62
64
  }
63
65
  const params = { returnUrl: state.url };
66
+ if (isPlatformServer(platformId) && resInit) {
67
+ const ssrAuthorizationUrl = environmentService.getEnvironment().oAuthConfig.ssrAuthorizationUrl;
68
+ const url = buildLoginUrl(ssrAuthorizationUrl, params);
69
+ const headers = new Headers(resInit.headers);
70
+ headers.set('Location', url);
71
+ resInit.status = 302;
72
+ resInit.statusText = 'Found';
73
+ resInit.headers = headers;
74
+ return;
75
+ }
64
76
  authService.navigateToLogin(params);
65
77
  return false;
66
78
  };
79
+ const buildLoginUrl = (path, params) => {
80
+ if (!params || Object.keys(params).length === 0)
81
+ return path;
82
+ const usp = new URLSearchParams();
83
+ for (const [k, v] of Object.entries(params)) {
84
+ if (v == null)
85
+ continue;
86
+ Array.isArray(v) ? v.forEach(x => usp.append(k, String(x))) : usp.set(k, String(v));
87
+ }
88
+ return `${path}?${usp.toString()}`;
89
+ };
90
+ const asyncAbpOAuthGuard = (route, state) => {
91
+ const oAuthService = inject(OAuthService);
92
+ const authService = inject(AuthService);
93
+ const environmentService = inject(EnvironmentService);
94
+ const platformId = inject(PLATFORM_ID);
95
+ const resInit = inject(RESPONSE_INIT);
96
+ const { oAuthConfig } = environmentService.getEnvironment();
97
+ if (oAuthConfig?.responseType === 'code') {
98
+ return firstValueFrom(timer(0, 100).pipe(map(() => oAuthService.hasValidAccessToken()), filter(Boolean), take(1), timeout(3000), catchError(() => {
99
+ if (isPlatformServer(platformId) && resInit) {
100
+ const ssrAuthorizationUrl = environmentService.getEnvironment().oAuthConfig.ssrAuthorizationUrl;
101
+ const url = buildLoginUrl(ssrAuthorizationUrl, { returnUrl: state.url });
102
+ const headers = new Headers(resInit.headers);
103
+ headers.set('Location', url);
104
+ resInit.status = 302;
105
+ resInit.statusText = 'Found';
106
+ resInit.headers = headers;
107
+ return;
108
+ }
109
+ authService.navigateToLogin({ returnUrl: state.url });
110
+ return of(false);
111
+ })));
112
+ }
113
+ if (oAuthService.hasValidAccessToken()) {
114
+ return true;
115
+ }
116
+ authService.navigateToLogin({ returnUrl: state.url });
117
+ return false;
118
+ };
67
119
 
68
120
  class OAuthConfigurationHandler {
69
- constructor(oAuthService, environmentService, options) {
70
- this.oAuthService = oAuthService;
71
- this.environmentService = environmentService;
72
- this.options = options;
121
+ constructor() {
122
+ this.oAuthService = inject(OAuthService);
123
+ this.environmentService = inject(EnvironmentService);
124
+ this.options = inject(CORE_OPTIONS);
73
125
  this.listenToSetEnvironment();
74
126
  }
75
127
  listenToSetEnvironment() {
76
128
  this.environmentService
77
129
  .createOnUpdateStream(state => state)
78
- .pipe(map(environment => environment.oAuthConfig), filter(config => !compare(config, this.options.environment.oAuthConfig)))
130
+ .pipe(map$1(environment => environment.oAuthConfig), filter$1(config => !compare(config, this.options.environment.oAuthConfig)))
79
131
  .subscribe((config) => {
80
132
  this.oAuthService.configure(config);
81
133
  });
82
134
  }
83
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: OAuthConfigurationHandler, deps: [{ token: i1.OAuthService }, { token: i2.EnvironmentService }, { token: CORE_OPTIONS }], target: i0.ɵɵFactoryTarget.Injectable }); }
135
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: OAuthConfigurationHandler, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
84
136
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: OAuthConfigurationHandler, providedIn: 'root' }); }
85
137
  }
86
138
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: OAuthConfigurationHandler, decorators: [{
@@ -88,17 +140,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.7", ngImpor
88
140
  args: [{
89
141
  providedIn: 'root',
90
142
  }]
91
- }], ctorParameters: () => [{ type: i1.OAuthService }, { type: i2.EnvironmentService }, { type: undefined, decorators: [{
92
- type: Inject,
93
- args: [CORE_OPTIONS]
94
- }] }] });
143
+ }], ctorParameters: () => [] });
95
144
 
96
145
  class OAuthApiInterceptor {
97
- constructor(oAuthService, sessionState, httpWaitService, tenantKey) {
98
- this.oAuthService = oAuthService;
99
- this.sessionState = sessionState;
100
- this.httpWaitService = httpWaitService;
101
- this.tenantKey = tenantKey;
146
+ constructor() {
147
+ this.oAuthService = inject(OAuthService);
148
+ this.sessionState = inject(SessionStateService);
149
+ this.httpWaitService = inject(HttpWaitService);
150
+ this.tenantKey = inject(TENANT_KEY);
102
151
  }
103
152
  intercept(request, next) {
104
153
  this.httpWaitService.addRequest(request);
@@ -129,7 +178,7 @@ class OAuthApiInterceptor {
129
178
  headers['X-Requested-With'] = 'XMLHttpRequest';
130
179
  return headers;
131
180
  }
132
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: OAuthApiInterceptor, deps: [{ token: i1.OAuthService }, { token: i2.SessionStateService }, { token: i2.HttpWaitService }, { token: TENANT_KEY }], target: i0.ɵɵFactoryTarget.Injectable }); }
181
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: OAuthApiInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
133
182
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: OAuthApiInterceptor, providedIn: 'root' }); }
134
183
  }
135
184
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: OAuthApiInterceptor, decorators: [{
@@ -137,14 +186,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.7", ngImpor
137
186
  args: [{
138
187
  providedIn: 'root',
139
188
  }]
140
- }], ctorParameters: () => [{ type: i1.OAuthService }, { type: i2.SessionStateService }, { type: i2.HttpWaitService }, { type: undefined, decorators: [{
141
- type: Inject,
142
- args: [TENANT_KEY]
143
- }] }] });
144
-
145
- const oAuthStorage = localStorage;
189
+ }] });
146
190
 
147
- function clearOAuthStorage(storage = oAuthStorage) {
191
+ function clearOAuthStorage(injector) {
192
+ const storage = injector.get(OAuthStorage);
148
193
  const keys = [
149
194
  'access_token',
150
195
  'id_token',
@@ -162,23 +207,102 @@ function clearOAuthStorage(storage = oAuthStorage) {
162
207
  keys.forEach(key => storage.removeItem(key));
163
208
  }
164
209
 
165
- function storageFactory() {
166
- return oAuthStorage;
210
+ class ServerTokenStorageService {
211
+ constructor(req) {
212
+ this.req = req;
213
+ this.cookies = new Map();
214
+ const cookieHeader = this.req?.headers.get('cookie') ?? '';
215
+ for (const part of cookieHeader.split(';')) {
216
+ const i = part.indexOf('=');
217
+ if (i > -1) {
218
+ const k = part.slice(0, i).trim();
219
+ const v = decodeURIComponent(part.slice(i + 1).trim());
220
+ this.cookies.set(k, v);
221
+ }
222
+ }
223
+ }
224
+ getItem(key) {
225
+ const fromCookie = this.cookies.get(key);
226
+ if (fromCookie) {
227
+ return fromCookie;
228
+ }
229
+ return '';
230
+ }
231
+ setItem(_k, _v) { }
232
+ removeItem(_k) { }
233
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: ServerTokenStorageService, deps: [{ token: REQUEST, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
234
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: ServerTokenStorageService, providedIn: null }); }
235
+ }
236
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: ServerTokenStorageService, decorators: [{
237
+ type: Injectable,
238
+ args: [{ providedIn: null }]
239
+ }], ctorParameters: () => [{ type: Request, decorators: [{
240
+ type: Optional
241
+ }, {
242
+ type: Inject,
243
+ args: [REQUEST]
244
+ }] }] });
245
+
246
+ class MockStorage {
247
+ constructor() {
248
+ this.data = new Map();
249
+ }
250
+ get length() {
251
+ return this.data.size;
252
+ }
253
+ clear() {
254
+ this.data.clear();
255
+ }
256
+ getItem(key) {
257
+ return this.data.get(key) || null;
258
+ }
259
+ key(index) {
260
+ return Array.from(this.data.keys())[index] || null;
261
+ }
262
+ removeItem(key) {
263
+ this.data.delete(key);
264
+ }
265
+ setItem(key, value) {
266
+ this.data.set(key, value);
267
+ }
268
+ }
269
+ function oAuthStorageFactory() {
270
+ const platformId = inject(PLATFORM_ID);
271
+ const appStartedWithSSR = inject(APP_STARTED_WITH_SSR);
272
+ if (appStartedWithSSR) {
273
+ return isPlatformBrowser(platformId)
274
+ ? inject(BrowserTokenStorageService)
275
+ : inject(ServerTokenStorageService);
276
+ }
277
+ return inject(AbpLocalStorageService);
167
278
  }
168
279
 
169
280
  class RememberMeService {
170
281
  constructor() {
171
282
  this.#rememberMe = 'remember_me';
172
283
  this.localStorageService = inject(AbpLocalStorageService);
284
+ this.cookieStorageService = inject(AbpCookieStorageService);
285
+ this.appStartedWithSsr = inject(APP_STARTED_WITH_SSR, { optional: true });
173
286
  }
174
287
  #rememberMe;
175
288
  set(remember) {
289
+ if (this.appStartedWithSsr) {
290
+ this.cookieStorageService.setItem(this.#rememberMe, JSON.stringify(remember));
291
+ return;
292
+ }
176
293
  this.localStorageService.setItem(this.#rememberMe, JSON.stringify(remember));
177
294
  }
178
295
  remove() {
296
+ if (this.appStartedWithSsr) {
297
+ this.cookieStorageService.removeItem(this.#rememberMe);
298
+ return;
299
+ }
179
300
  this.localStorageService.removeItem(this.#rememberMe);
180
301
  }
181
302
  get() {
303
+ if (this.appStartedWithSsr) {
304
+ return Boolean(JSON.parse(this.cookieStorageService.getItem(this.#rememberMe) || 'false'));
305
+ }
182
306
  return Boolean(JSON.parse(this.localStorageService.getItem(this.#rememberMe) || 'false'));
183
307
  }
184
308
  getFromToken(accessToken) {
@@ -224,7 +348,7 @@ const checkAccessToken = function (injector) {
224
348
  const configState = injector.get(ConfigStateService);
225
349
  const oAuth = injector.get(OAuthService);
226
350
  if (oAuth.hasValidAccessToken() && !configState.getDeep('currentUser.id')) {
227
- clearOAuthStorage();
351
+ clearOAuthStorage(this.injector);
228
352
  }
229
353
  };
230
354
 
@@ -251,13 +375,13 @@ class AuthFlowStrategy {
251
375
  }
252
376
  async init() {
253
377
  if (this.oAuthConfig.clientId) {
254
- const shouldClear = shouldStorageClear(this.oAuthConfig.clientId, oAuthStorage);
378
+ const shouldClear = shouldStorageClear(this.oAuthConfig.clientId, this.injector);
255
379
  if (shouldClear)
256
- clearOAuthStorage(oAuthStorage);
380
+ clearOAuthStorage(this.injector);
257
381
  }
258
382
  this.oAuthService.configure(this.oAuthConfig);
259
383
  this.oAuthService.events
260
- .pipe(filter(event => event.type === 'token_refresh_error'))
384
+ .pipe(filter$1(event => event.type === 'token_refresh_error'))
261
385
  .subscribe(() => this.navigateToLogin());
262
386
  this.navigateToPreviousUrl();
263
387
  return this.oAuthService
@@ -275,31 +399,32 @@ class AuthFlowStrategy {
275
399
  const { responseType } = this.oAuthConfig;
276
400
  if (responseType === 'code') {
277
401
  this.oAuthService.events
278
- .pipe(filter(event => event.type === 'token_received' && !!this.oAuthService.state), take(1), map(() => {
402
+ .pipe(filter$1(event => event.type === 'token_received' && !!this.oAuthService.state), take$1(1), map$1(() => {
279
403
  const redirectUri = decodeURIComponent(this.oAuthService.state);
280
404
  if (redirectUri && redirectUri !== '/') {
281
405
  return redirectUri;
282
406
  }
283
407
  return '/';
284
- }), switchMap(redirectUri => this.configState.getOne$('currentUser').pipe(filter(user => !!user?.isAuthenticated), tap(() => this.router.navigateByUrl(redirectUri)))))
408
+ }), switchMap(redirectUri => this.configState.getOne$('currentUser').pipe(filter$1(user => !!user?.isAuthenticated), tap(() => this.router.navigateByUrl(redirectUri)))))
285
409
  .subscribe();
286
410
  }
287
411
  }
288
412
  refreshToken() {
289
- return this.oAuthService.refreshToken().catch(() => clearOAuthStorage());
413
+ return this.oAuthService.refreshToken().catch(() => clearOAuthStorage(this.injector));
290
414
  }
291
415
  listenToOauthErrors() {
292
416
  this.oAuthService.events
293
- .pipe(filter(event => event instanceof OAuthErrorEvent), tap((err) => {
417
+ .pipe(filter$1(event => event instanceof OAuthErrorEvent), tap((err) => {
294
418
  const shouldSkip = this.oAuthErrorFilterService.run(err);
295
419
  if (!shouldSkip) {
296
- clearOAuthStorage();
420
+ clearOAuthStorage(this.injector);
297
421
  }
298
422
  }), switchMap(() => this.configState.refreshAppState()))
299
423
  .subscribe();
300
424
  }
301
425
  }
302
- function shouldStorageClear(clientId, storage) {
426
+ function shouldStorageClear(clientId, injector) {
427
+ const storage = injector.get(OAuthStorage);
303
428
  const key = 'abpOAuthClientId';
304
429
  if (!storage.getItem(key)) {
305
430
  storage.setItem(key, clientId);
@@ -312,17 +437,25 @@ function shouldStorageClear(clientId, storage) {
312
437
  }
313
438
 
314
439
  class AuthCodeFlowStrategy extends AuthFlowStrategy {
315
- constructor() {
316
- super(...arguments);
440
+ constructor(injector) {
441
+ super(injector);
442
+ this.injector = injector;
317
443
  this.isInternalAuth = false;
444
+ this.platformId = injector.get(PLATFORM_ID);
445
+ this.appStartedWithSSR = injector.get(APP_STARTED_WITH_SSR);
446
+ this.document = injector.get(DOCUMENT);
318
447
  }
319
448
  async init() {
320
449
  this.checkRememberMeOption();
321
450
  this.listenToTokenReceived();
322
- return super
323
- .init()
324
- .then(() => this.oAuthService.tryLogin().catch(noop))
325
- .then(() => this.oAuthService.setupAutomaticSilentRefresh());
451
+ if (!this.appStartedWithSSR && isPlatformBrowser(this.platformId)) {
452
+ return super
453
+ .init()
454
+ .then(() => this.oAuthService.tryLogin().catch(noop))
455
+ .then(() => {
456
+ this.oAuthService.setupAutomaticSilentRefresh();
457
+ });
458
+ }
326
459
  }
327
460
  checkRememberMeOption() {
328
461
  const accessToken = this.oAuthService.getAccessToken();
@@ -344,51 +477,78 @@ class AuthCodeFlowStrategy extends AuthFlowStrategy {
344
477
  return { ...(lang && culture), ...queryParams };
345
478
  }
346
479
  setUICulture() {
347
- const urlParams = new URLSearchParams(window.location.search);
348
- this.configState.uiCultureFromAuthCodeFlow = urlParams.get('ui-culture');
480
+ if (isPlatformBrowser(this.platformId)) {
481
+ const urlParams = new URLSearchParams(window.location.search);
482
+ this.configState.uiCultureFromAuthCodeFlow = urlParams.get('ui-culture');
483
+ }
349
484
  }
350
485
  replaceURLParams() {
351
- const location = this.windowService.window.location;
352
- const history = this.windowService.window.history;
353
- const query = location.search
354
- .replace(/([?&])iss=[^&]*&?/, '$1')
355
- .replace(/([?&])culture=[^&]*&?/, '$1')
356
- .replace(/([?&])ui-culture=[^&]*&?/, '$1')
357
- .replace(/[?&]+$/, '');
358
- const href = location.origin + location.pathname + query + location.hash;
359
- history.replaceState(null, '', href);
486
+ if (isPlatformBrowser(this.platformId)) {
487
+ const location = this.windowService.window.location;
488
+ const history = this.windowService.window.history;
489
+ const query = location.search
490
+ .replace(/([?&])iss=[^&]*&?/, '$1')
491
+ .replace(/([?&])culture=[^&]*&?/, '$1')
492
+ .replace(/([?&])ui-culture=[^&]*&?/, '$1')
493
+ .replace(/[?&]+$/, '');
494
+ const href = location.origin + location.pathname + query + location.hash;
495
+ history.replaceState(null, '', href);
496
+ }
360
497
  }
361
498
  listenToTokenReceived() {
362
- this.oAuthService.events
363
- .pipe(filter$1(event => event.type === 'token_received'), tap$1(() => {
364
- this.setUICulture();
365
- this.replaceURLParams();
366
- }), take$1(1))
367
- .subscribe();
499
+ if (isPlatformBrowser(this.platformId) && !this.appStartedWithSSR) {
500
+ this.oAuthService.events
501
+ .pipe(filter(event => event.type === 'token_received'), tap$1(() => {
502
+ //TODO: Investigate how to handle with ssr
503
+ this.setUICulture();
504
+ this.replaceURLParams();
505
+ }), take(1))
506
+ .subscribe();
507
+ }
368
508
  }
369
509
  navigateToLogin(queryParams) {
370
- let additionalState = '';
371
- if (queryParams?.returnUrl) {
372
- additionalState = queryParams.returnUrl;
510
+ if (isPlatformBrowser(this.platformId)) {
511
+ if (this.appStartedWithSSR) {
512
+ if (this.document.defaultView) {
513
+ this.document.defaultView.location.replace('/authorize');
514
+ }
515
+ }
516
+ else {
517
+ let additionalState = '';
518
+ if (queryParams?.returnUrl) {
519
+ additionalState = queryParams.returnUrl;
520
+ }
521
+ const cultureParams = this.getCultureParams(queryParams);
522
+ this.oAuthService.initCodeFlow(additionalState, cultureParams);
523
+ }
373
524
  }
374
- const cultureParams = this.getCultureParams(queryParams);
375
- this.oAuthService.initCodeFlow(additionalState, cultureParams);
376
525
  }
377
526
  checkIfInternalAuth(queryParams) {
378
- this.oAuthService.initCodeFlow('', this.getCultureParams(queryParams));
379
- return false;
527
+ if (isPlatformBrowser(this.platformId)) {
528
+ this.oAuthService.initCodeFlow('', this.getCultureParams(queryParams));
529
+ return false;
530
+ }
380
531
  }
381
532
  logout(queryParams) {
382
533
  this.rememberMeService.remove();
383
- if (queryParams?.noRedirectToLogoutUrl) {
384
- this.router.navigate(['/']);
385
- return from(this.oAuthService.revokeTokenAndLogout(true));
534
+ if (this.appStartedWithSSR) {
535
+ if (this.document.defaultView) {
536
+ this.document.defaultView.location.replace('/logout');
537
+ }
538
+ }
539
+ else {
540
+ if (queryParams?.noRedirectToLogoutUrl) {
541
+ this.router.navigate(['/']);
542
+ return from(this.oAuthService.revokeTokenAndLogout(true));
543
+ }
544
+ return from(this.oAuthService.revokeTokenAndLogout(this.getCultureParams(queryParams)));
386
545
  }
387
- return from(this.oAuthService.revokeTokenAndLogout(this.getCultureParams(queryParams)));
388
546
  }
389
547
  login(queryParams) {
390
- this.oAuthService.initCodeFlow('', this.getCultureParams(queryParams));
391
- return of(null);
548
+ if (isPlatformBrowser(this.platformId)) {
549
+ this.oAuthService.initCodeFlow('', this.getCultureParams(queryParams));
550
+ return of(null);
551
+ }
392
552
  }
393
553
  }
394
554
 
@@ -399,7 +559,7 @@ class AuthPasswordFlowStrategy extends AuthFlowStrategy {
399
559
  }
400
560
  listenToTokenExpiration() {
401
561
  this.oAuthService.events
402
- .pipe(filter(event => event instanceof OAuthInfoEvent &&
562
+ .pipe(filter$1(event => event instanceof OAuthInfoEvent &&
403
563
  event.type === 'token_expires' &&
404
564
  event.info === 'access_token'))
405
565
  .subscribe(() => {
@@ -447,7 +607,7 @@ class AuthPasswordFlowStrategy extends AuthFlowStrategy {
447
607
  }
448
608
  refreshToken() {
449
609
  return this.oAuthService.refreshToken().catch(() => {
450
- clearOAuthStorage();
610
+ clearOAuthStorage(this.injector);
451
611
  this.rememberMeService.remove();
452
612
  });
453
613
  }
@@ -472,18 +632,21 @@ class AbpOAuthService {
472
632
  get isInternalAuth() {
473
633
  return this.strategy.isInternalAuth;
474
634
  }
475
- constructor(injector) {
476
- this.injector = injector;
635
+ constructor() {
636
+ this.injector = inject(Injector);
637
+ this.appStartedWithSsr = this.injector.get(APP_STARTED_WITH_SSR);
638
+ this.platformId = this.injector.get(PLATFORM_ID);
639
+ this.document = this.injector.get(DOCUMENT);
477
640
  this.oAuthService = this.injector.get(OAuthService);
478
641
  }
479
642
  async init() {
480
643
  const environmentService = this.injector.get(EnvironmentService);
481
- const result$ = environmentService.getEnvironment$().pipe(map(env => env?.oAuthConfig), filter(Boolean), tap(oAuthConfig => {
644
+ const result$ = environmentService.getEnvironment$().pipe(map$1(env => env?.oAuthConfig), filter$1(Boolean), tap(oAuthConfig => {
482
645
  this.strategy =
483
646
  oAuthConfig.responseType === 'code'
484
647
  ? AUTH_FLOW_STRATEGY.Code(this.injector)
485
648
  : AUTH_FLOW_STRATEGY.Password(this.injector);
486
- }), switchMap(() => from(this.strategy.init())), take(1));
649
+ }), switchMap(() => from(this.strategy.init())), take$1(1));
487
650
  return await lastValueFrom(result$);
488
651
  }
489
652
  logout(queryParams) {
@@ -522,12 +685,16 @@ class AbpOAuthService {
522
685
  return this.oAuthService.getAccessToken();
523
686
  }
524
687
  refreshToken() {
688
+ if (isPlatformBrowser(this.platformId) && this.appStartedWithSsr) {
689
+ this.document.defaultView?.location.replace('/authorize');
690
+ return Promise.resolve();
691
+ }
525
692
  return this.oAuthService.refreshToken();
526
693
  }
527
694
  getAccessTokenExpiration() {
528
695
  return this.oAuthService.getAccessTokenExpiration();
529
696
  }
530
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: AbpOAuthService, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
697
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: AbpOAuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
531
698
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: AbpOAuthService, providedIn: 'root' }); }
532
699
  }
533
700
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: AbpOAuthService, decorators: [{
@@ -535,7 +702,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.7", ngImpor
535
702
  args: [{
536
703
  providedIn: 'root',
537
704
  }]
538
- }], ctorParameters: () => [{ type: i0.Injector }] });
705
+ }], ctorParameters: () => [] });
539
706
 
540
707
  class OAuthErrorFilterService extends AbstractAuthErrorFilter {
541
708
  constructor() {
@@ -577,6 +744,43 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.7", ngImpor
577
744
  args: [{ providedIn: 'root' }]
578
745
  }] });
579
746
 
747
+ class BrowserTokenStorageService {
748
+ getItem(key) {
749
+ return this.readCookie(key);
750
+ }
751
+ removeItem(key) {
752
+ this.removeCookie(key);
753
+ }
754
+ setItem(key, data) {
755
+ this.writeCookie(key, data);
756
+ }
757
+ readCookie(name) {
758
+ if (typeof document === 'undefined')
759
+ return null;
760
+ const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
761
+ return match ? decodeURIComponent(match[2]) : null;
762
+ }
763
+ writeCookie(name, value, days = 7) {
764
+ if (typeof document === 'undefined')
765
+ return;
766
+ const expires = new Date(Date.now() + days * 86400000).toUTCString();
767
+ document.cookie = `${name}=${encodeURIComponent(value)}; expires=${expires}; path=/; Secure; SameSite=Lax`;
768
+ }
769
+ removeCookie(name) {
770
+ if (typeof document === 'undefined')
771
+ return;
772
+ document.cookie = `${name}=; Max-Age=0; path=/;`;
773
+ }
774
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: BrowserTokenStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
775
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: BrowserTokenStorageService, providedIn: 'root' }); }
776
+ }
777
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: BrowserTokenStorageService, decorators: [{
778
+ type: Injectable,
779
+ args: [{
780
+ providedIn: 'root',
781
+ }]
782
+ }] });
783
+
580
784
  function provideAbpOAuth() {
581
785
  const providers = [
582
786
  {
@@ -591,6 +795,10 @@ function provideAbpOAuth() {
591
795
  provide: authGuard,
592
796
  useValue: abpOAuthGuard,
593
797
  },
798
+ {
799
+ provide: asyncAuthGuard,
800
+ useValue: asyncAbpOAuthGuard,
801
+ },
594
802
  {
595
803
  provide: ApiInterceptor,
596
804
  useClass: OAuthApiInterceptor,
@@ -613,7 +821,12 @@ function provideAbpOAuth() {
613
821
  inject(OAuthConfigurationHandler);
614
822
  }),
615
823
  OAuthModule.forRoot().providers,
616
- { provide: OAuthStorage, useClass: AbpLocalStorageService },
824
+ ServerTokenStorageService,
825
+ BrowserTokenStorageService,
826
+ {
827
+ provide: OAuthStorage,
828
+ useFactory: oAuthStorageFactory,
829
+ },
617
830
  { provide: AuthErrorFilterService, useExisting: OAuthErrorFilterService },
618
831
  ];
619
832
  return makeEnvironmentProviders(providers);
@@ -641,5 +854,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.7", ngImpor
641
854
  * Generated bundle index. Do not edit.
642
855
  */
643
856
 
644
- export { AUTH_FLOW_STRATEGY, AbpOAuthGuard, AbpOAuthModule, AbpOAuthService, AuthCodeFlowStrategy, AuthFlowStrategy, AuthPasswordFlowStrategy, NavigateToManageProfileProvider, OAuthApiInterceptor, OAuthConfigurationHandler, OAuthErrorFilterService, RememberMeService, abpOAuthGuard, checkAccessToken, clearOAuthStorage, isTokenExpired, oAuthStorage, pipeToLogin, provideAbpOAuth, storageFactory };
857
+ export { AUTH_FLOW_STRATEGY, AbpOAuthGuard, AbpOAuthModule, AbpOAuthService, AuthCodeFlowStrategy, AuthFlowStrategy, AuthPasswordFlowStrategy, BrowserTokenStorageService, MockStorage, NavigateToManageProfileProvider, OAuthApiInterceptor, OAuthConfigurationHandler, OAuthErrorFilterService, RememberMeService, ServerTokenStorageService, abpOAuthGuard, asyncAbpOAuthGuard, buildLoginUrl, checkAccessToken, clearOAuthStorage, isTokenExpired, oAuthStorageFactory, pipeToLogin, provideAbpOAuth };
645
858
  //# sourceMappingURL=abp-ng.oauth.mjs.map