@abp/ng.oauth 9.3.6 → 10.0.0-rc.2

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,27 +207,109 @@ 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) {
185
- const tokenBody = accessToken.split('.')[1].replace(/-/g, '+').replace(/_/g, '/');
309
+ let tokenBody = accessToken.split('.')[1].replace(/-/g, '+').replace(/_/g, '/');
310
+ while (tokenBody.length % 4 !== 0) {
311
+ tokenBody += '=';
312
+ }
186
313
  try {
187
314
  const parsedToken = JSON.parse(atob(tokenBody));
188
315
  return Boolean(parsedToken[this.#rememberMe]);
@@ -224,7 +351,7 @@ const checkAccessToken = function (injector) {
224
351
  const configState = injector.get(ConfigStateService);
225
352
  const oAuth = injector.get(OAuthService);
226
353
  if (oAuth.hasValidAccessToken() && !configState.getDeep('currentUser.id')) {
227
- clearOAuthStorage();
354
+ clearOAuthStorage(this.injector);
228
355
  }
229
356
  };
230
357
 
@@ -251,13 +378,13 @@ class AuthFlowStrategy {
251
378
  }
252
379
  async init() {
253
380
  if (this.oAuthConfig.clientId) {
254
- const shouldClear = shouldStorageClear(this.oAuthConfig.clientId, oAuthStorage);
381
+ const shouldClear = shouldStorageClear(this.oAuthConfig.clientId, this.injector);
255
382
  if (shouldClear)
256
- clearOAuthStorage(oAuthStorage);
383
+ clearOAuthStorage(this.injector);
257
384
  }
258
385
  this.oAuthService.configure(this.oAuthConfig);
259
386
  this.oAuthService.events
260
- .pipe(filter(event => event.type === 'token_refresh_error'))
387
+ .pipe(filter$1(event => event.type === 'token_refresh_error'))
261
388
  .subscribe(() => this.navigateToLogin());
262
389
  this.navigateToPreviousUrl();
263
390
  return this.oAuthService
@@ -275,31 +402,32 @@ class AuthFlowStrategy {
275
402
  const { responseType } = this.oAuthConfig;
276
403
  if (responseType === 'code') {
277
404
  this.oAuthService.events
278
- .pipe(filter(event => event.type === 'token_received' && !!this.oAuthService.state), take(1), map(() => {
405
+ .pipe(filter$1(event => event.type === 'token_received' && !!this.oAuthService.state), take$1(1), map$1(() => {
279
406
  const redirectUri = decodeURIComponent(this.oAuthService.state);
280
407
  if (redirectUri && redirectUri !== '/') {
281
408
  return redirectUri;
282
409
  }
283
410
  return '/';
284
- }), switchMap(redirectUri => this.configState.getOne$('currentUser').pipe(filter(user => !!user?.isAuthenticated), tap(() => this.router.navigateByUrl(redirectUri)))))
411
+ }), switchMap(redirectUri => this.configState.getOne$('currentUser').pipe(filter$1(user => !!user?.isAuthenticated), tap(() => this.router.navigateByUrl(redirectUri)))))
285
412
  .subscribe();
286
413
  }
287
414
  }
288
415
  refreshToken() {
289
- return this.oAuthService.refreshToken().catch(() => clearOAuthStorage());
416
+ return this.oAuthService.refreshToken().catch(() => clearOAuthStorage(this.injector));
290
417
  }
291
418
  listenToOauthErrors() {
292
419
  this.oAuthService.events
293
- .pipe(filter(event => event instanceof OAuthErrorEvent), tap((err) => {
420
+ .pipe(filter$1(event => event instanceof OAuthErrorEvent), tap((err) => {
294
421
  const shouldSkip = this.oAuthErrorFilterService.run(err);
295
422
  if (!shouldSkip) {
296
- clearOAuthStorage();
423
+ clearOAuthStorage(this.injector);
297
424
  }
298
425
  }), switchMap(() => this.configState.refreshAppState()))
299
426
  .subscribe();
300
427
  }
301
428
  }
302
- function shouldStorageClear(clientId, storage) {
429
+ function shouldStorageClear(clientId, injector) {
430
+ const storage = injector.get(OAuthStorage);
303
431
  const key = 'abpOAuthClientId';
304
432
  if (!storage.getItem(key)) {
305
433
  storage.setItem(key, clientId);
@@ -312,17 +440,25 @@ function shouldStorageClear(clientId, storage) {
312
440
  }
313
441
 
314
442
  class AuthCodeFlowStrategy extends AuthFlowStrategy {
315
- constructor() {
316
- super(...arguments);
443
+ constructor(injector) {
444
+ super(injector);
445
+ this.injector = injector;
317
446
  this.isInternalAuth = false;
447
+ this.platformId = injector.get(PLATFORM_ID);
448
+ this.appStartedWithSSR = injector.get(APP_STARTED_WITH_SSR);
449
+ this.document = injector.get(DOCUMENT);
318
450
  }
319
451
  async init() {
320
452
  this.checkRememberMeOption();
321
453
  this.listenToTokenReceived();
322
- return super
323
- .init()
324
- .then(() => this.oAuthService.tryLogin().catch(noop))
325
- .then(() => this.oAuthService.setupAutomaticSilentRefresh());
454
+ if (!this.appStartedWithSSR && isPlatformBrowser(this.platformId)) {
455
+ return super
456
+ .init()
457
+ .then(() => this.oAuthService.tryLogin().catch(noop))
458
+ .then(() => {
459
+ this.oAuthService.setupAutomaticSilentRefresh();
460
+ });
461
+ }
326
462
  }
327
463
  checkRememberMeOption() {
328
464
  const accessToken = this.oAuthService.getAccessToken();
@@ -344,51 +480,78 @@ class AuthCodeFlowStrategy extends AuthFlowStrategy {
344
480
  return { ...(lang && culture), ...queryParams };
345
481
  }
346
482
  setUICulture() {
347
- const urlParams = new URLSearchParams(window.location.search);
348
- this.configState.uiCultureFromAuthCodeFlow = urlParams.get('ui-culture');
483
+ if (isPlatformBrowser(this.platformId)) {
484
+ const urlParams = new URLSearchParams(window.location.search);
485
+ this.configState.uiCultureFromAuthCodeFlow = urlParams.get('ui-culture');
486
+ }
349
487
  }
350
488
  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);
489
+ if (isPlatformBrowser(this.platformId)) {
490
+ const location = this.windowService.window.location;
491
+ const history = this.windowService.window.history;
492
+ const query = location.search
493
+ .replace(/([?&])iss=[^&]*&?/, '$1')
494
+ .replace(/([?&])culture=[^&]*&?/, '$1')
495
+ .replace(/([?&])ui-culture=[^&]*&?/, '$1')
496
+ .replace(/[?&]+$/, '');
497
+ const href = location.origin + location.pathname + query + location.hash;
498
+ history.replaceState(null, '', href);
499
+ }
360
500
  }
361
501
  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();
502
+ if (isPlatformBrowser(this.platformId) && !this.appStartedWithSSR) {
503
+ this.oAuthService.events
504
+ .pipe(filter(event => event.type === 'token_received'), tap$1(() => {
505
+ //TODO: Investigate how to handle with ssr
506
+ this.setUICulture();
507
+ this.replaceURLParams();
508
+ }), take(1))
509
+ .subscribe();
510
+ }
368
511
  }
369
512
  navigateToLogin(queryParams) {
370
- let additionalState = '';
371
- if (queryParams?.returnUrl) {
372
- additionalState = queryParams.returnUrl;
513
+ if (isPlatformBrowser(this.platformId)) {
514
+ if (this.appStartedWithSSR) {
515
+ if (this.document.defaultView) {
516
+ this.document.defaultView.location.replace('/authorize');
517
+ }
518
+ }
519
+ else {
520
+ let additionalState = '';
521
+ if (queryParams?.returnUrl) {
522
+ additionalState = queryParams.returnUrl;
523
+ }
524
+ const cultureParams = this.getCultureParams(queryParams);
525
+ this.oAuthService.initCodeFlow(additionalState, cultureParams);
526
+ }
373
527
  }
374
- const cultureParams = this.getCultureParams(queryParams);
375
- this.oAuthService.initCodeFlow(additionalState, cultureParams);
376
528
  }
377
529
  checkIfInternalAuth(queryParams) {
378
- this.oAuthService.initCodeFlow('', this.getCultureParams(queryParams));
379
- return false;
530
+ if (isPlatformBrowser(this.platformId)) {
531
+ this.oAuthService.initCodeFlow('', this.getCultureParams(queryParams));
532
+ return false;
533
+ }
380
534
  }
381
535
  logout(queryParams) {
382
536
  this.rememberMeService.remove();
383
- if (queryParams?.noRedirectToLogoutUrl) {
384
- this.router.navigate(['/']);
385
- return from(this.oAuthService.revokeTokenAndLogout(true));
537
+ if (this.appStartedWithSSR) {
538
+ if (this.document.defaultView) {
539
+ this.document.defaultView.location.replace('/logout');
540
+ }
541
+ }
542
+ else {
543
+ if (queryParams?.noRedirectToLogoutUrl) {
544
+ this.router.navigate(['/']);
545
+ return from(this.oAuthService.revokeTokenAndLogout(true));
546
+ }
547
+ return from(this.oAuthService.revokeTokenAndLogout(this.getCultureParams(queryParams)));
386
548
  }
387
- return from(this.oAuthService.revokeTokenAndLogout(this.getCultureParams(queryParams)));
388
549
  }
389
550
  login(queryParams) {
390
- this.oAuthService.initCodeFlow('', this.getCultureParams(queryParams));
391
- return of(null);
551
+ if (isPlatformBrowser(this.platformId)) {
552
+ this.oAuthService.initCodeFlow('', this.getCultureParams(queryParams));
553
+ return of(null);
554
+ }
392
555
  }
393
556
  }
394
557
 
@@ -399,7 +562,7 @@ class AuthPasswordFlowStrategy extends AuthFlowStrategy {
399
562
  }
400
563
  listenToTokenExpiration() {
401
564
  this.oAuthService.events
402
- .pipe(filter(event => event instanceof OAuthInfoEvent &&
565
+ .pipe(filter$1(event => event instanceof OAuthInfoEvent &&
403
566
  event.type === 'token_expires' &&
404
567
  event.info === 'access_token'))
405
568
  .subscribe(() => {
@@ -447,7 +610,7 @@ class AuthPasswordFlowStrategy extends AuthFlowStrategy {
447
610
  }
448
611
  refreshToken() {
449
612
  return this.oAuthService.refreshToken().catch(() => {
450
- clearOAuthStorage();
613
+ clearOAuthStorage(this.injector);
451
614
  this.rememberMeService.remove();
452
615
  });
453
616
  }
@@ -472,18 +635,21 @@ class AbpOAuthService {
472
635
  get isInternalAuth() {
473
636
  return this.strategy.isInternalAuth;
474
637
  }
475
- constructor(injector) {
476
- this.injector = injector;
638
+ constructor() {
639
+ this.injector = inject(Injector);
640
+ this.appStartedWithSsr = this.injector.get(APP_STARTED_WITH_SSR);
641
+ this.platformId = this.injector.get(PLATFORM_ID);
642
+ this.document = this.injector.get(DOCUMENT);
477
643
  this.oAuthService = this.injector.get(OAuthService);
478
644
  }
479
645
  async init() {
480
646
  const environmentService = this.injector.get(EnvironmentService);
481
- const result$ = environmentService.getEnvironment$().pipe(map(env => env?.oAuthConfig), filter(Boolean), tap(oAuthConfig => {
647
+ const result$ = environmentService.getEnvironment$().pipe(map$1(env => env?.oAuthConfig), filter$1(Boolean), tap(oAuthConfig => {
482
648
  this.strategy =
483
649
  oAuthConfig.responseType === 'code'
484
650
  ? AUTH_FLOW_STRATEGY.Code(this.injector)
485
651
  : AUTH_FLOW_STRATEGY.Password(this.injector);
486
- }), switchMap(() => from(this.strategy.init())), take(1));
652
+ }), switchMap(() => from(this.strategy.init())), take$1(1));
487
653
  return await lastValueFrom(result$);
488
654
  }
489
655
  logout(queryParams) {
@@ -522,12 +688,16 @@ class AbpOAuthService {
522
688
  return this.oAuthService.getAccessToken();
523
689
  }
524
690
  refreshToken() {
691
+ if (isPlatformBrowser(this.platformId) && this.appStartedWithSsr) {
692
+ this.document.defaultView?.location.replace('/authorize');
693
+ return Promise.resolve();
694
+ }
525
695
  return this.oAuthService.refreshToken();
526
696
  }
527
697
  getAccessTokenExpiration() {
528
698
  return this.oAuthService.getAccessTokenExpiration();
529
699
  }
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 }); }
700
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: AbpOAuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
531
701
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: AbpOAuthService, providedIn: 'root' }); }
532
702
  }
533
703
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: AbpOAuthService, decorators: [{
@@ -535,7 +705,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.7", ngImpor
535
705
  args: [{
536
706
  providedIn: 'root',
537
707
  }]
538
- }], ctorParameters: () => [{ type: i0.Injector }] });
708
+ }], ctorParameters: () => [] });
539
709
 
540
710
  class OAuthErrorFilterService extends AbstractAuthErrorFilter {
541
711
  constructor() {
@@ -577,6 +747,43 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.7", ngImpor
577
747
  args: [{ providedIn: 'root' }]
578
748
  }] });
579
749
 
750
+ class BrowserTokenStorageService {
751
+ getItem(key) {
752
+ return this.readCookie(key);
753
+ }
754
+ removeItem(key) {
755
+ this.removeCookie(key);
756
+ }
757
+ setItem(key, data) {
758
+ this.writeCookie(key, data);
759
+ }
760
+ readCookie(name) {
761
+ if (typeof document === 'undefined')
762
+ return null;
763
+ const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
764
+ return match ? decodeURIComponent(match[2]) : null;
765
+ }
766
+ writeCookie(name, value, days = 7) {
767
+ if (typeof document === 'undefined')
768
+ return;
769
+ const expires = new Date(Date.now() + days * 86400000).toUTCString();
770
+ document.cookie = `${name}=${encodeURIComponent(value)}; expires=${expires}; path=/; Secure; SameSite=Lax`;
771
+ }
772
+ removeCookie(name) {
773
+ if (typeof document === 'undefined')
774
+ return;
775
+ document.cookie = `${name}=; Max-Age=0; path=/;`;
776
+ }
777
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: BrowserTokenStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
778
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: BrowserTokenStorageService, providedIn: 'root' }); }
779
+ }
780
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.7", ngImport: i0, type: BrowserTokenStorageService, decorators: [{
781
+ type: Injectable,
782
+ args: [{
783
+ providedIn: 'root',
784
+ }]
785
+ }] });
786
+
580
787
  function provideAbpOAuth() {
581
788
  const providers = [
582
789
  {
@@ -591,6 +798,10 @@ function provideAbpOAuth() {
591
798
  provide: authGuard,
592
799
  useValue: abpOAuthGuard,
593
800
  },
801
+ {
802
+ provide: asyncAuthGuard,
803
+ useValue: asyncAbpOAuthGuard,
804
+ },
594
805
  {
595
806
  provide: ApiInterceptor,
596
807
  useClass: OAuthApiInterceptor,
@@ -613,7 +824,12 @@ function provideAbpOAuth() {
613
824
  inject(OAuthConfigurationHandler);
614
825
  }),
615
826
  OAuthModule.forRoot().providers,
616
- { provide: OAuthStorage, useClass: AbpLocalStorageService },
827
+ ServerTokenStorageService,
828
+ BrowserTokenStorageService,
829
+ {
830
+ provide: OAuthStorage,
831
+ useFactory: oAuthStorageFactory,
832
+ },
617
833
  { provide: AuthErrorFilterService, useExisting: OAuthErrorFilterService },
618
834
  ];
619
835
  return makeEnvironmentProviders(providers);
@@ -641,5 +857,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.7", ngImpor
641
857
  * Generated bundle index. Do not edit.
642
858
  */
643
859
 
644
- export { AUTH_FLOW_STRATEGY, AbpOAuthGuard, AbpOAuthModule, AbpOAuthService, AuthCodeFlowStrategy, AuthFlowStrategy, AuthPasswordFlowStrategy, NavigateToManageProfileProvider, OAuthApiInterceptor, OAuthConfigurationHandler, OAuthErrorFilterService, RememberMeService, abpOAuthGuard, checkAccessToken, clearOAuthStorage, isTokenExpired, oAuthStorage, pipeToLogin, provideAbpOAuth, storageFactory };
860
+ 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
861
  //# sourceMappingURL=abp-ng.oauth.mjs.map