keycloak-angular 19.0.2 → 20.1.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.
- package/README.md +39 -2
- package/fesm2022/keycloak-angular.mjs +101 -62
- package/fesm2022/keycloak-angular.mjs.map +1 -1
- package/index.d.ts +1534 -3
- package/package.json +5 -4
- package/lib/directives/has-roles.directive.d.ts +0 -95
- package/lib/features/keycloak.feature.d.ts +0 -43
- package/lib/features/with-refresh-token.feature.d.ts +0 -66
- package/lib/guards/auth.guard.d.ts +0 -75
- package/lib/interceptors/custom-bearer-token.interceptor.d.ts +0 -97
- package/lib/interceptors/include-bearer-token.interceptor.d.ts +0 -111
- package/lib/interceptors/keycloak.interceptor.d.ts +0 -71
- package/lib/legacy/core/core.module.d.ts +0 -12
- package/lib/legacy/core/interceptors/keycloak-bearer.interceptor.d.ts +0 -53
- package/lib/legacy/core/interfaces/keycloak-event.d.ts +0 -74
- package/lib/legacy/core/interfaces/keycloak-options.d.ts +0 -146
- package/lib/legacy/core/services/keycloak-auth-guard.d.ts +0 -50
- package/lib/legacy/core/services/keycloak.service.d.ts +0 -316
- package/lib/legacy/keycloak-angular.module.d.ts +0 -12
- package/lib/legacy/public_api.d.ts +0 -14
- package/lib/provide-keycloak.d.ts +0 -74
- package/lib/services/auto-refresh-token.service.d.ts +0 -47
- package/lib/services/user-activity.service.d.ts +0 -66
- package/lib/signals/keycloak-events-signal.d.ts +0 -118
- package/public_api.d.ts +0 -19
package/README.md
CHANGED
|
@@ -52,8 +52,9 @@ Note that `keycloak-js` is a peer dependency of `keycloak-angular`. This allows
|
|
|
52
52
|
|
|
53
53
|
| Angular | keycloak-js | keycloak-angular | Support |
|
|
54
54
|
| :-----: | :---------: | :--------------: | :-----------------: |
|
|
55
|
-
|
|
|
56
|
-
|
|
|
55
|
+
| 20.x | 18 - 26 | 20.x.x | New Features / Bugs |
|
|
56
|
+
| 19.x | 18 - 26 | 19.x.x | Bugs |
|
|
57
|
+
| 18.x | 18 - 26 | 16.x.x | - |
|
|
57
58
|
| 17.x | 18 - 25 | 15.x.x | - |
|
|
58
59
|
| 16.x | 18 - 25 | 14.x.x | - |
|
|
59
60
|
| 15.x | 18 - 21 | 13.x.x | - |
|
|
@@ -121,6 +122,41 @@ Create a file named `silent-check-sso.html` in the `public` or `assets` director
|
|
|
121
122
|
|
|
122
123
|
If you want to know more about these options and various other capabilities of the Keycloak client is recommended to read the [JavaScript Adapter documentation](https://www.keycloak.org/docs/latest/securing_apps/#_javascript_adapter).
|
|
123
124
|
|
|
125
|
+
## Load the keycloak configuration using an external file
|
|
126
|
+
|
|
127
|
+
To initialize the Keycloak application using a configuration file hosted externally, consider the following approach:
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
const initializeApp = async () => {
|
|
131
|
+
// Replace the URL with the actual path to your configuration file
|
|
132
|
+
const { config, initOptions } = await fetch('/config.json').then((res) => res?.json());
|
|
133
|
+
|
|
134
|
+
const appConfig: ApplicationConfig = {
|
|
135
|
+
providers: [
|
|
136
|
+
provideKeycloakAngular(config, {
|
|
137
|
+
...initOptions,
|
|
138
|
+
silentCheckSsoRedirectUri: window.location.origin + '/silent-check-sso.html',
|
|
139
|
+
redirectUri: window.location.origin + '/'
|
|
140
|
+
}),
|
|
141
|
+
provideZoneChangeDetection({ eventCoalescing: true }),
|
|
142
|
+
provideRouter(routes),
|
|
143
|
+
provideHttpClient(withInterceptors([includeBearerTokenInterceptor]))
|
|
144
|
+
]
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
await bootstrapApplication(AppComponent, appConfig);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
initializeApp().catch((error) => console.error(`Failed to initialize the application. ${error.message || error}`));
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Notes**:
|
|
154
|
+
|
|
155
|
+
- This approach uses fetch to load the Keycloak configuration (config.json) before bootstrapping the Angular application.
|
|
156
|
+
- Make sure that config.json is accessible at runtime and contains the correct structure for Keycloak configuration and initOptions.
|
|
157
|
+
|
|
158
|
+
For a working example, refer to the [Fetch Config Example Project](projects/examples/fetch_config/README.md).
|
|
159
|
+
|
|
124
160
|
> **Note About NgModules:**
|
|
125
161
|
> Since Keycloak-Angular v19, the KeycloakAngularModule, KeycloakService, KeycloakBearerInterceptor and KeycloakAuthGuard are deprecated.
|
|
126
162
|
> If your application relies on NgModules, the library still has support for it. See more information on how to configure a [NgModule the application](https://github.com/mauriciovigolo/keycloak-angular/docs/ngmodule.md).
|
|
@@ -243,6 +279,7 @@ import {
|
|
|
243
279
|
provideKeycloak,
|
|
244
280
|
createInterceptorCondition,
|
|
245
281
|
IncludeBearerTokenCondition,
|
|
282
|
+
includeBearerTokenInterceptor,
|
|
246
283
|
INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG
|
|
247
284
|
} from 'keycloak-angular';
|
|
248
285
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, NgModule, signal, InjectionToken,
|
|
2
|
+
import { Injectable, inject, NgModule, signal, InjectionToken, TemplateRef, ViewContainerRef, effect, Input, Directive, NgZone, computed, PLATFORM_ID, provideAppInitializer, EnvironmentInjector, runInInjectionContext, makeEnvironmentProviders } from '@angular/core';
|
|
3
3
|
import { HttpHeaders, HTTP_INTERCEPTORS } from '@angular/common/http';
|
|
4
4
|
import { Subject, from, combineLatest, of, fromEvent, mergeMap as mergeMap$1 } from 'rxjs';
|
|
5
5
|
import { map, mergeMap, debounceTime, takeUntil } from 'rxjs/operators';
|
|
@@ -21,7 +21,7 @@ import { CommonModule, isPlatformBrowser } from '@angular/common';
|
|
|
21
21
|
* will be removed in future versions.
|
|
22
22
|
* Use the new `KEYCLOAK_EVENT_SIGNAL` injection token to listen for the keycloak
|
|
23
23
|
* events.
|
|
24
|
-
* More info: https://github.com/mauriciovigolo/keycloak-angular/docs/migration-guides/v19.md
|
|
24
|
+
* More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md
|
|
25
25
|
*/
|
|
26
26
|
var KeycloakEventTypeLegacy;
|
|
27
27
|
(function (KeycloakEventTypeLegacy) {
|
|
@@ -77,7 +77,7 @@ var KeycloakEventTypeLegacy;
|
|
|
77
77
|
*
|
|
78
78
|
* @deprecated Class based guards are deprecated in Keycloak Angular and will be removed in future versions.
|
|
79
79
|
* Use the new `createAuthGuard` function to create a Guard for your application.
|
|
80
|
-
* More info: https://github.com/mauriciovigolo/keycloak-angular/docs/migration-guides/v19.md
|
|
80
|
+
* More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md
|
|
81
81
|
*/
|
|
82
82
|
class KeycloakAuthGuard {
|
|
83
83
|
constructor(router, keycloakAngular) {
|
|
@@ -119,7 +119,7 @@ class KeycloakAuthGuard {
|
|
|
119
119
|
*
|
|
120
120
|
* @deprecated This service is deprecated and will be removed in future versions.
|
|
121
121
|
* Use the new `provideKeycloak` function to load Keycloak in an Angular application.
|
|
122
|
-
* More info: https://github.com/mauriciovigolo/keycloak-angular/docs/migration-guides/v19.md
|
|
122
|
+
* More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md
|
|
123
123
|
*/
|
|
124
124
|
class KeycloakService {
|
|
125
125
|
constructor() {
|
|
@@ -538,10 +538,10 @@ class KeycloakService {
|
|
|
538
538
|
get keycloakEvents$() {
|
|
539
539
|
return this._keycloakEvents$;
|
|
540
540
|
}
|
|
541
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
542
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
541
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: KeycloakService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
542
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: KeycloakService }); }
|
|
543
543
|
}
|
|
544
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
544
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: KeycloakService, decorators: [{
|
|
545
545
|
type: Injectable
|
|
546
546
|
}] });
|
|
547
547
|
|
|
@@ -560,11 +560,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImpor
|
|
|
560
560
|
*
|
|
561
561
|
* @deprecated KeycloakBearerInterceptor is deprecated and will be removed in future versions.
|
|
562
562
|
* Use the new functional interceptor such as `includeBearerTokenInterceptor`.
|
|
563
|
-
* More info: https://github.com/mauriciovigolo/keycloak-angular/docs/migration-guides/v19.md
|
|
563
|
+
* More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md
|
|
564
564
|
*/
|
|
565
565
|
class KeycloakBearerInterceptor {
|
|
566
|
-
constructor(
|
|
567
|
-
this.keycloak =
|
|
566
|
+
constructor() {
|
|
567
|
+
this.keycloak = inject(KeycloakService);
|
|
568
568
|
}
|
|
569
569
|
/**
|
|
570
570
|
* Calls to update the keycloak token if the request should update the token.
|
|
@@ -623,12 +623,12 @@ class KeycloakBearerInterceptor {
|
|
|
623
623
|
return next.handle(kcReq);
|
|
624
624
|
}));
|
|
625
625
|
}
|
|
626
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
627
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
626
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: KeycloakBearerInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
627
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: KeycloakBearerInterceptor }); }
|
|
628
628
|
}
|
|
629
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
629
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: KeycloakBearerInterceptor, decorators: [{
|
|
630
630
|
type: Injectable
|
|
631
|
-
}]
|
|
631
|
+
}] });
|
|
632
632
|
|
|
633
633
|
/**
|
|
634
634
|
* @license
|
|
@@ -640,12 +640,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImpor
|
|
|
640
640
|
/**
|
|
641
641
|
* @deprecated NgModules are deprecated in Keycloak Angular and will be removed in future versions.
|
|
642
642
|
* Use the new `provideKeycloak` function to load Keycloak in an Angular application.
|
|
643
|
-
* More info: https://github.com/mauriciovigolo/keycloak-angular/docs/migration-guides/v19.md
|
|
643
|
+
* More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md
|
|
644
644
|
*/
|
|
645
645
|
class CoreModule {
|
|
646
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
647
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "
|
|
648
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "
|
|
646
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: CoreModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
647
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.3", ngImport: i0, type: CoreModule, imports: [CommonModule] }); }
|
|
648
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: CoreModule, providers: [
|
|
649
649
|
KeycloakService,
|
|
650
650
|
{
|
|
651
651
|
provide: HTTP_INTERCEPTORS,
|
|
@@ -654,7 +654,7 @@ class CoreModule {
|
|
|
654
654
|
}
|
|
655
655
|
], imports: [CommonModule] }); }
|
|
656
656
|
}
|
|
657
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
657
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: CoreModule, decorators: [{
|
|
658
658
|
type: NgModule,
|
|
659
659
|
args: [{
|
|
660
660
|
imports: [CommonModule],
|
|
@@ -679,14 +679,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImpor
|
|
|
679
679
|
/**
|
|
680
680
|
* @deprecated NgModules are deprecated in Keycloak Angular and will be removed in future versions.
|
|
681
681
|
* Use the new `provideKeycloak` function to load Keycloak in an Angular application.
|
|
682
|
-
* More info: https://github.com/mauriciovigolo/keycloak-angular/docs/migration-guides/v19.md
|
|
682
|
+
* More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md
|
|
683
683
|
*/
|
|
684
684
|
class KeycloakAngularModule {
|
|
685
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
686
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "
|
|
687
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "
|
|
685
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: KeycloakAngularModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
686
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.3", ngImport: i0, type: KeycloakAngularModule, imports: [CoreModule] }); }
|
|
687
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: KeycloakAngularModule, imports: [CoreModule] }); }
|
|
688
688
|
}
|
|
689
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
689
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: KeycloakAngularModule, decorators: [{
|
|
690
690
|
type: NgModule,
|
|
691
691
|
args: [{
|
|
692
692
|
imports: [CoreModule]
|
|
@@ -903,10 +903,10 @@ const KEYCLOAK_EVENT_SIGNAL = new InjectionToken('Keycloak Events Signal');
|
|
|
903
903
|
* ```
|
|
904
904
|
*/
|
|
905
905
|
class HasRolesDirective {
|
|
906
|
-
constructor(
|
|
907
|
-
this.templateRef =
|
|
908
|
-
this.viewContainer =
|
|
909
|
-
this.keycloak =
|
|
906
|
+
constructor() {
|
|
907
|
+
this.templateRef = inject(TemplateRef);
|
|
908
|
+
this.viewContainer = inject(ViewContainerRef);
|
|
909
|
+
this.keycloak = inject(Keycloak);
|
|
910
910
|
/**
|
|
911
911
|
* List of roles to validate against the resource or realm.
|
|
912
912
|
*/
|
|
@@ -917,25 +917,51 @@ class HasRolesDirective {
|
|
|
917
917
|
this.checkRealm = false;
|
|
918
918
|
this.viewContainer.clear();
|
|
919
919
|
const keycloakSignal = inject(KEYCLOAK_EVENT_SIGNAL);
|
|
920
|
+
/**
|
|
921
|
+
* This effect will reevaluate roles after authentication or token refresh.
|
|
922
|
+
* Or clear the view on logout.
|
|
923
|
+
*/
|
|
920
924
|
effect(() => {
|
|
921
925
|
const keycloakEvent = keycloakSignal();
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
926
|
+
switch (keycloakEvent.type) {
|
|
927
|
+
case KeycloakEventType.Ready: {
|
|
928
|
+
const authenticated = typeEventArgs(keycloakEvent.args);
|
|
929
|
+
if (authenticated) {
|
|
930
|
+
this.render();
|
|
931
|
+
}
|
|
932
|
+
else {
|
|
933
|
+
this.viewContainer.clear();
|
|
934
|
+
}
|
|
935
|
+
break;
|
|
936
|
+
}
|
|
937
|
+
case KeycloakEventType.AuthSuccess:
|
|
938
|
+
case KeycloakEventType.AuthRefreshSuccess:
|
|
939
|
+
case KeycloakEventType.TokenExpired:
|
|
940
|
+
this.render();
|
|
941
|
+
break;
|
|
942
|
+
case KeycloakEventType.AuthLogout:
|
|
943
|
+
this.viewContainer.clear();
|
|
944
|
+
break;
|
|
945
|
+
default:
|
|
946
|
+
break;
|
|
928
947
|
}
|
|
929
948
|
});
|
|
930
949
|
}
|
|
950
|
+
/**
|
|
951
|
+
* Here to reevaluate access when inputs change.
|
|
952
|
+
*/
|
|
953
|
+
ngOnChanges() {
|
|
954
|
+
this.render();
|
|
955
|
+
}
|
|
956
|
+
/**
|
|
957
|
+
* Clear the view and render it if user has access.
|
|
958
|
+
*/
|
|
931
959
|
render() {
|
|
932
960
|
const hasAccess = this.checkUserRoles();
|
|
961
|
+
this.viewContainer.clear();
|
|
933
962
|
if (hasAccess) {
|
|
934
963
|
this.viewContainer.createEmbeddedView(this.templateRef);
|
|
935
964
|
}
|
|
936
|
-
else {
|
|
937
|
-
this.viewContainer.clear();
|
|
938
|
-
}
|
|
939
965
|
}
|
|
940
966
|
/**
|
|
941
967
|
* Checks if the user has at least one of the specified roles in the resource or realm.
|
|
@@ -946,15 +972,15 @@ class HasRolesDirective {
|
|
|
946
972
|
const hasRealmRole = this.checkRealm ? this.roles.some((role) => this.keycloak.hasRealmRole(role)) : false;
|
|
947
973
|
return hasResourceRole || hasRealmRole;
|
|
948
974
|
}
|
|
949
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
950
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
975
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: HasRolesDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
976
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.3", type: HasRolesDirective, isStandalone: true, selector: "[kaHasRoles]", inputs: { roles: ["kaHasRoles", "roles"], resource: ["kaHasRolesResource", "resource"], checkRealm: ["kaHasRolesCheckRealm", "checkRealm"] }, usesOnChanges: true, ngImport: i0 }); }
|
|
951
977
|
}
|
|
952
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
978
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: HasRolesDirective, decorators: [{
|
|
953
979
|
type: Directive,
|
|
954
980
|
args: [{
|
|
955
981
|
selector: '[kaHasRoles]'
|
|
956
982
|
}]
|
|
957
|
-
}], ctorParameters: () => [
|
|
983
|
+
}], ctorParameters: () => [], propDecorators: { roles: [{
|
|
958
984
|
type: Input,
|
|
959
985
|
args: ['kaHasRoles']
|
|
960
986
|
}], resource: [{
|
|
@@ -990,8 +1016,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImpor
|
|
|
990
1016
|
* if it is a browser context.
|
|
991
1017
|
*/
|
|
992
1018
|
class UserActivityService {
|
|
993
|
-
constructor(
|
|
994
|
-
this.ngZone =
|
|
1019
|
+
constructor() {
|
|
1020
|
+
this.ngZone = inject(NgZone);
|
|
995
1021
|
/**
|
|
996
1022
|
* Signal to store the timestamp of the last user activity.
|
|
997
1023
|
* The timestamp is represented as the number of milliseconds since epoch.
|
|
@@ -1059,12 +1085,12 @@ class UserActivityService {
|
|
|
1059
1085
|
this.destroy$.next();
|
|
1060
1086
|
this.destroy$.complete();
|
|
1061
1087
|
}
|
|
1062
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1063
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1088
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: UserActivityService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1089
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: UserActivityService }); }
|
|
1064
1090
|
}
|
|
1065
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1091
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: UserActivityService, decorators: [{
|
|
1066
1092
|
type: Injectable
|
|
1067
|
-
}]
|
|
1093
|
+
}] });
|
|
1068
1094
|
|
|
1069
1095
|
/**
|
|
1070
1096
|
* @license
|
|
@@ -1085,9 +1111,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImpor
|
|
|
1085
1111
|
* session timeout and inactivity handling.
|
|
1086
1112
|
*/
|
|
1087
1113
|
class AutoRefreshTokenService {
|
|
1088
|
-
constructor(
|
|
1089
|
-
this.keycloak =
|
|
1090
|
-
this.userActivity =
|
|
1114
|
+
constructor() {
|
|
1115
|
+
this.keycloak = inject(Keycloak);
|
|
1116
|
+
this.userActivity = inject(UserActivityService);
|
|
1091
1117
|
this.options = this.defaultOptions;
|
|
1092
1118
|
this.initialized = false;
|
|
1093
1119
|
const keycloakSignal = inject(KEYCLOAK_EVENT_SIGNAL);
|
|
@@ -1101,16 +1127,22 @@ class AutoRefreshTokenService {
|
|
|
1101
1127
|
get defaultOptions() {
|
|
1102
1128
|
return {
|
|
1103
1129
|
sessionTimeout: 300000,
|
|
1104
|
-
onInactivityTimeout: 'logout'
|
|
1130
|
+
onInactivityTimeout: 'logout',
|
|
1131
|
+
logoutOptions: undefined,
|
|
1132
|
+
loginOptions: undefined
|
|
1105
1133
|
};
|
|
1106
1134
|
}
|
|
1107
1135
|
executeOnInactivityTimeout() {
|
|
1108
1136
|
switch (this.options.onInactivityTimeout) {
|
|
1109
1137
|
case 'login':
|
|
1110
|
-
this.keycloak
|
|
1138
|
+
this.keycloak
|
|
1139
|
+
.login(this.options.loginOptions)
|
|
1140
|
+
.catch((error) => console.error('Failed to execute the login call', error));
|
|
1111
1141
|
break;
|
|
1112
1142
|
case 'logout':
|
|
1113
|
-
this.keycloak
|
|
1143
|
+
this.keycloak
|
|
1144
|
+
.logout(this.options.logoutOptions)
|
|
1145
|
+
.catch((error) => console.error('Failed to execute the logout call', error));
|
|
1114
1146
|
break;
|
|
1115
1147
|
default:
|
|
1116
1148
|
break;
|
|
@@ -1132,12 +1164,12 @@ class AutoRefreshTokenService {
|
|
|
1132
1164
|
this.initialized = true;
|
|
1133
1165
|
this.userActivity.startMonitoring();
|
|
1134
1166
|
}
|
|
1135
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1136
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1167
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: AutoRefreshTokenService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1168
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: AutoRefreshTokenService }); }
|
|
1137
1169
|
}
|
|
1138
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1170
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImport: i0, type: AutoRefreshTokenService, decorators: [{
|
|
1139
1171
|
type: Injectable
|
|
1140
|
-
}], ctorParameters: () => [
|
|
1172
|
+
}], ctorParameters: () => [] });
|
|
1141
1173
|
|
|
1142
1174
|
/**
|
|
1143
1175
|
* @license
|
|
@@ -1173,6 +1205,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImpor
|
|
|
1173
1205
|
* - `'login'`: Execute `keycloak.login` function.
|
|
1174
1206
|
* - `'logout'`: Logs the user out by calling `keycloak.logout`.
|
|
1175
1207
|
* - `'none'`: No action is taken.
|
|
1208
|
+
* - `logoutOptions` (optional): Logout options to pass to keycloak.logout
|
|
1209
|
+
* when the user is getting logged out automatically after timout.
|
|
1210
|
+
* - `loginOptions` (optional): Login options to pass to keycloak.login
|
|
1211
|
+
* when the user is getting logged in automatically after timout.
|
|
1176
1212
|
*
|
|
1177
1213
|
* @returns A `KeycloakFeature` instance that configures and enables the
|
|
1178
1214
|
* auto-refresh token functionality.
|
|
@@ -1383,11 +1419,14 @@ const CUSTOM_BEARER_TOKEN_INTERCEPTOR_CONFIG = new InjectionToken('Include the b
|
|
|
1383
1419
|
const customBearerTokenInterceptor = (req, next) => {
|
|
1384
1420
|
const conditions = inject(CUSTOM_BEARER_TOKEN_INTERCEPTOR_CONFIG) ?? [];
|
|
1385
1421
|
const keycloak = inject(Keycloak);
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1422
|
+
return from(Promise.all(conditions.map(async (condition) => await condition.shouldAddToken(req, next, keycloak)))).pipe(mergeMap$1((evaluatedConditions) => {
|
|
1423
|
+
const matchingConditionIndex = evaluatedConditions.findIndex(Boolean);
|
|
1424
|
+
const matchingCondition = conditions[matchingConditionIndex];
|
|
1425
|
+
if (!matchingCondition) {
|
|
1426
|
+
return next(req);
|
|
1427
|
+
}
|
|
1428
|
+
return from(conditionallyUpdateToken(req, keycloak, matchingCondition)).pipe(mergeMap$1(() => keycloak.authenticated ? addAuthorizationHeader(req, next, keycloak, matchingCondition) : next(req)));
|
|
1429
|
+
}));
|
|
1391
1430
|
};
|
|
1392
1431
|
|
|
1393
1432
|
/**
|