+ selector: 'app-root',
+ template: `
Welcome
@@ -41,16 +41,16 @@ import { AuthService } from './core/auth.service';
`,
- standalone: false
+ standalone: false
})
export class AppComponent {
+ private authService = inject(AuthService);
+
isAuthenticated$: Observable
;
isDoneLoading$: Observable;
canActivateProtectedRoutes$: Observable;
- constructor(
- private authService: AuthService,
- ) {
+ constructor() {
this.isAuthenticated$ = this.authService.isAuthenticated$;
this.isDoneLoading$ = this.authService.isDoneLoading$;
this.canActivateProtectedRoutes$ = this.authService.canActivateProtectedRoutes$;
diff --git a/src/app/core/auth-config.ts b/src/app/core/auth-config.ts
index c34d9fc..f3c0c74 100644
--- a/src/app/core/auth-config.ts
+++ b/src/app/core/auth-config.ts
@@ -10,7 +10,7 @@ export const authConfig: AuthConfig = {
useSilentRefresh: true, // Needed for Code Flow to suggest using iframe-based refreshes
silentRefreshTimeout: 5000, // For faster testing
timeoutFactor: 0.25, // For faster testing
- sessionChecksEnabled: true,
+ sessionChecksEnabled: false, // Can turn this to true but it may cause CSP issues
showDebugInformation: true, // Also requires enabling "Verbose" level in devtools
clearHashAfterLogin: false, // https://github.com/manfredsteyer/angular-oauth2-oidc/issues/457#issuecomment-431807040,
nonceStateSeparator : 'semicolon' // Real semicolon gets mangled by Duende ID Server's URI encoding
diff --git a/src/app/core/auth-guard-with-forced-login.service.ts b/src/app/core/auth-guard-with-forced-login.service.ts
index 4f45a50..aec5844 100644
--- a/src/app/core/auth-guard-with-forced-login.service.ts
+++ b/src/app/core/auth-guard-with-forced-login.service.ts
@@ -1,4 +1,4 @@
-import { Injectable } from '@angular/core';
+import { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { filter, switchMap, tap } from 'rxjs/operators';
@@ -7,11 +7,8 @@ import { AuthService } from './auth.service';
@Injectable()
export class AuthGuardWithForcedLogin {
+ private authService = inject(AuthService);
- constructor(
- private authService: AuthService,
- ) {
- }
canActivate(
route: ActivatedRouteSnapshot,
diff --git a/src/app/core/auth-guard.service.ts b/src/app/core/auth-guard.service.ts
index c2b5686..f25d891 100644
--- a/src/app/core/auth-guard.service.ts
+++ b/src/app/core/auth-guard.service.ts
@@ -1,4 +1,4 @@
-import { Injectable } from '@angular/core';
+import { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
@@ -7,9 +7,7 @@ import { AuthService } from './auth.service';
@Injectable()
export class AuthGuard {
- constructor(
- private authService: AuthService,
- ) { }
+ private authService = inject(AuthService);
canActivate(
route: ActivatedRouteSnapshot,
diff --git a/src/app/core/auth.service.ts b/src/app/core/auth.service.ts
index 6a5a7f5..1f60b29 100644
--- a/src/app/core/auth.service.ts
+++ b/src/app/core/auth.service.ts
@@ -1,6 +1,6 @@
/* eslint-disable brace-style */
-import { Injectable } from '@angular/core';
+import { Injectable, inject } from '@angular/core';
import { Router } from '@angular/router';
import { OAuthErrorEvent, OAuthService } from 'angular-oauth2-oidc';
import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
@@ -8,6 +8,9 @@ import { filter, map } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class AuthService {
+ private oauthService = inject(OAuthService);
+ private router = inject(Router);
+
private isAuthenticatedSubject$ = new BehaviorSubject(false);
public isAuthenticated$ = this.isAuthenticatedSubject$.asObservable();
@@ -35,10 +38,7 @@ export class AuthService {
this.router.navigateByUrl('/should-login');
}
- constructor(
- private oauthService: OAuthService,
- private router: Router,
- ) {
+ constructor() {
// Useful for debugging:
this.oauthService.events.subscribe(event => {
if (event instanceof OAuthErrorEvent) {
diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts
index 9f5ddb4..9d0765e 100644
--- a/src/app/core/core.module.ts
+++ b/src/app/core/core.module.ts
@@ -1,5 +1,5 @@
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
-import { ModuleWithProviders, NgModule, Optional, SkipSelf, inject, provideAppInitializer } from '@angular/core';
+import { ModuleWithProviders, NgModule, inject, provideAppInitializer } from '@angular/core';
import { AuthConfig, OAuthModule, OAuthModuleConfig, OAuthStorage } from 'angular-oauth2-oidc';
import { authAppInitializerFactory } from './auth-app-initializer.factory';
import { authConfig } from './auth-config';
@@ -37,7 +37,9 @@ export class CoreModule {
};
}
- constructor(@Optional() @SkipSelf() parentModule: CoreModule) {
+ constructor() {
+ const parentModule = inject(CoreModule, { optional: true, skipSelf: true });
+
if (parentModule) {
throw new Error('CoreModule is already loaded. Import it in the AppModule only');
}
diff --git a/src/app/feature-basics/admin1.component.ts b/src/app/feature-basics/admin1.component.ts
index 0392257..ee97aa9 100644
--- a/src/app/feature-basics/admin1.component.ts
+++ b/src/app/feature-basics/admin1.component.ts
@@ -1,21 +1,21 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit, inject } from '@angular/core';
import { Observable } from 'rxjs';
import { ApiService } from '../shared/api.service';
@Component({
- selector: 'app-admin',
- template: `
+ selector: 'app-admin',
+ template: `
This is the ⚙ ADMIN component.
It will not redirect you to the login server.
- {{ apiResponse | async }}
`,
- standalone: false
+ standalone: false
})
export class Admin1Component implements OnInit {
- apiResponse!: Observable;
+ private apiService = inject(ApiService);
- constructor(private apiService: ApiService) { }
+ apiResponse!: Observable;
ngOnInit() {
this.apiResponse = this.apiService.getProtectedApiResponse();
diff --git a/src/app/feature-basics/home.component.ts b/src/app/feature-basics/home.component.ts
index 2d975be..d5ca16b 100644
--- a/src/app/feature-basics/home.component.ts
+++ b/src/app/feature-basics/home.component.ts
@@ -1,20 +1,20 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit, inject } from '@angular/core';
import { Observable } from 'rxjs';
import { ApiService } from '../shared/api.service';
@Component({
- selector: 'app-home',
- template: `
+ selector: 'app-home',
+ template: `
This is the 🏠 HOME component.
- {{ apiResponse | async }}
`,
- standalone: false
+ standalone: false
})
export class HomeComponent implements OnInit {
- apiResponse!: Observable;
+ private apiService = inject(ApiService);
- constructor(private apiService: ApiService) { }
+ apiResponse!: Observable;
ngOnInit() {
this.apiResponse = this.apiService.getProtectedApiResponse();
diff --git a/src/app/feature-extras/admin2.component.ts b/src/app/feature-extras/admin2.component.ts
index abe789e..ef769ff 100644
--- a/src/app/feature-extras/admin2.component.ts
+++ b/src/app/feature-extras/admin2.component.ts
@@ -1,21 +1,21 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit, inject } from '@angular/core';
import { Observable } from 'rxjs';
import { ApiService } from '../shared/api.service';
@Component({
- selector: 'app-admin',
- template: `
+ selector: 'app-admin',
+ template: `
This is the 🔧 ADMIN 2 component.
It will redirect you to login if needed.
- {{ apiResponse | async }}
`,
- standalone: false
+ standalone: false
})
export class Admin2Component implements OnInit {
- apiResponse!: Observable;
+ private apiService = inject(ApiService);
- constructor(private apiService: ApiService) { }
+ apiResponse!: Observable;
ngOnInit() {
this.apiResponse = this.apiService.getProtectedApiResponse();
diff --git a/src/app/shared/api.service.ts b/src/app/shared/api.service.ts
index 165804d..fb1497c 100644
--- a/src/app/shared/api.service.ts
+++ b/src/app/shared/api.service.ts
@@ -1,11 +1,11 @@
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
-import { Injectable } from '@angular/core';
+import { Injectable, inject } from '@angular/core';
import { Observable, of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
@Injectable()
export class ApiService {
- constructor(private http: HttpClient) { }
+ private http = inject(HttpClient);
getProtectedApiResponse(): Observable {
return this.http.get('https://demo.duendesoftware.com/api/test')
diff --git a/src/app/should-login.component.ts b/src/app/should-login.component.ts
index d292f7f..5796d4d 100644
--- a/src/app/should-login.component.ts
+++ b/src/app/should-login.component.ts
@@ -1,14 +1,14 @@
-import { Component } from '@angular/core';
+import { Component, inject } from '@angular/core';
import { OAuthService } from 'angular-oauth2-oidc';
@Component({
- selector: 'app-should-login',
- template: `You need to be logged in to view requested page.
+ selector: 'app-should-login',
+ template: `You need to be logged in to view requested page.
Please log in before continuing.
`,
- standalone: false
+ standalone: false
})
export class ShouldLoginComponent {
- constructor(private authService: OAuthService) { }
+ private authService = inject(OAuthService);
public login($event: any) {
$event.preventDefault();
diff --git a/src/main.ts b/src/main.ts
index 91ec6da..03bd0e3 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,4 +1,4 @@
-import { enableProdMode } from '@angular/core';
+import { enableProdMode, provideZoneChangeDetection } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
@@ -8,5 +8,5 @@ if (environment.production) {
enableProdMode();
}
-platformBrowserDynamic().bootstrapModule(AppModule)
+platformBrowserDynamic().bootstrapModule(AppModule, { applicationProviders: [provideZoneChangeDetection()], })
.catch(err => console.log(err));
diff --git a/tsconfig.json b/tsconfig.json
index 4e7a933..50c76f1 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -11,14 +11,10 @@
"sourceMap": true,
"declaration": false,
"experimentalDecorators": true,
- "moduleResolution": "node",
+ "moduleResolution": "bundler",
"importHelpers": true,
"target": "ES2022",
"module": "es2020",
- "lib": [
- "es2018",
- "dom"
- ],
"useDefineForClassFields": false
},
"angularCompilerOptions": {