build: update deps
Some checks failed
Build, Lint & Test Lib / Built, Lint and Test Library (push) Has been cancelled
Build, Lint & Test Lib / Angular latest (push) Has been cancelled
Build, Lint & Test Lib / Angular latest & Schematics Job (push) Has been cancelled
Build, Lint & Test Lib / Angular latest Standalone & Schematics Job (push) Has been cancelled
Build, Lint & Test Lib / Angular 16 & RxJs 6 (push) Has been cancelled
Build, Lint & Test Lib / Angular V16 (push) Has been cancelled
Docs / Build and Deploy Docs Job (push) Has been cancelled
Docs / Close Pull Request Job (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled

This commit is contained in:
2025-01-18 08:08:00 +08:00
parent 983254164b
commit da0d9855da
16 changed files with 1600 additions and 2431 deletions

View File

@@ -1,402 +0,0 @@
import { TestBed, waitForAsync } from '@angular/core/testing';
import {
ActivatedRouteSnapshot,
Router,
RouterStateSnapshot,
} from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { Observable, of } from 'rxjs';
import { mockProvider } from '../../test/auto-mock';
import { CheckAuthService } from '../auth-state/check-auth.service';
import { ConfigurationService } from '../config/config.service';
import { LoginResponse } from '../login/login-response';
import { LoginService } from '../login/login.service';
import { StoragePersistenceService } from '../storage/storage-persistence.service';
import { AutoLoginAllRoutesGuard } from './auto-login-all-routes.guard';
import { AutoLoginService } from './auto-login.service';
describe(`AutoLoginAllRoutesGuard`, () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
providers: [
AutoLoginService,
mockProvider(CheckAuthService),
mockProvider(LoginService),
mockProvider(StoragePersistenceService),
mockProvider(ConfigurationService),
],
});
});
describe('Class based', () => {
let guard: AutoLoginAllRoutesGuard;
let checkAuthService: CheckAuthService;
let loginService: LoginService;
let storagePersistenceService: StoragePersistenceService;
let configurationService: ConfigurationService;
let autoLoginService: AutoLoginService;
let router: Router;
beforeEach(() => {
checkAuthService = TestBed.inject(CheckAuthService);
loginService = TestBed.inject(LoginService);
storagePersistenceService = TestBed.inject(StoragePersistenceService);
configurationService = TestBed.inject(ConfigurationService);
spyOn(configurationService, 'getOpenIDConfiguration').and.returnValue(
of({ configId: 'configId1' })
);
guard = TestBed.inject(AutoLoginAllRoutesGuard);
autoLoginService = TestBed.inject(AutoLoginService);
router = TestBed.inject(Router);
});
afterEach(() => {
storagePersistenceService.clear({});
});
it('should create', () => {
expect(guard).toBeTruthy();
});
describe('canActivate', () => {
it('should save current route and call `login` if not authenticated already', waitForAsync(() => {
spyOn(checkAuthService, 'checkAuth').and.returnValue(
of({ isAuthenticated: false } as LoginResponse)
);
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
autoLoginService,
'checkSavedRedirectRouteAndNavigate'
);
const saveRedirectRouteSpy = spyOn(
autoLoginService,
'saveRedirectRoute'
);
const loginSpy = spyOn(loginService, 'login');
const canActivate$ = guard.canActivate(
{} as ActivatedRouteSnapshot,
{
url: 'some-url1',
} as RouterStateSnapshot
) as Observable<boolean>;
canActivate$.subscribe(() => {
expect(saveRedirectRouteSpy).toHaveBeenCalledOnceWith(
{ configId: 'configId1' },
'some-url1'
);
expect(loginSpy).toHaveBeenCalledOnceWith({ configId: 'configId1' });
expect(checkSavedRedirectRouteAndNavigateSpy).not.toHaveBeenCalled();
});
}));
it('should call `checkSavedRedirectRouteAndNavigate` if authenticated already', waitForAsync(() => {
spyOn(checkAuthService, 'checkAuth').and.returnValue(
of({ isAuthenticated: true } as LoginResponse)
);
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
autoLoginService,
'checkSavedRedirectRouteAndNavigate'
);
const saveRedirectRouteSpy = spyOn(
autoLoginService,
'saveRedirectRoute'
);
const loginSpy = spyOn(loginService, 'login');
const canActivate$ = guard.canActivate(
{} as ActivatedRouteSnapshot,
{
url: 'some-url1',
} as RouterStateSnapshot
) as Observable<boolean>;
canActivate$.subscribe(() => {
expect(saveRedirectRouteSpy).not.toHaveBeenCalled();
expect(loginSpy).not.toHaveBeenCalled();
expect(
checkSavedRedirectRouteAndNavigateSpy
).toHaveBeenCalledOnceWith({
configId: 'configId1',
});
});
}));
it('should call `checkSavedRedirectRouteAndNavigate` if authenticated already', waitForAsync(() => {
spyOn(checkAuthService, 'checkAuth').and.returnValue(
of({ isAuthenticated: true } as LoginResponse)
);
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
autoLoginService,
'checkSavedRedirectRouteAndNavigate'
);
const saveRedirectRouteSpy = spyOn(
autoLoginService,
'saveRedirectRoute'
);
const loginSpy = spyOn(loginService, 'login');
const canActivate$ = guard.canActivate(
{} as ActivatedRouteSnapshot,
{
url: 'some-url1',
} as RouterStateSnapshot
) as Observable<boolean>;
canActivate$.subscribe(() => {
expect(saveRedirectRouteSpy).not.toHaveBeenCalled();
expect(loginSpy).not.toHaveBeenCalled();
expect(
checkSavedRedirectRouteAndNavigateSpy
).toHaveBeenCalledOnceWith({ configId: 'configId1' });
});
}));
});
describe('canActivateChild', () => {
it('should save current route and call `login` if not authenticated already', waitForAsync(() => {
spyOn(checkAuthService, 'checkAuth').and.returnValue(
of({ isAuthenticated: false } as LoginResponse)
);
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
autoLoginService,
'checkSavedRedirectRouteAndNavigate'
);
const saveRedirectRouteSpy = spyOn(
autoLoginService,
'saveRedirectRoute'
);
const loginSpy = spyOn(loginService, 'login');
const canActivateChild$ = guard.canActivateChild(
{} as ActivatedRouteSnapshot,
{
url: 'some-url1',
} as RouterStateSnapshot
) as Observable<boolean>;
canActivateChild$.subscribe(() => {
expect(saveRedirectRouteSpy).toHaveBeenCalledOnceWith(
{ configId: 'configId1' },
'some-url1'
);
expect(loginSpy).toHaveBeenCalledOnceWith({ configId: 'configId1' });
expect(checkSavedRedirectRouteAndNavigateSpy).not.toHaveBeenCalled();
});
}));
it('should call `checkSavedRedirectRouteAndNavigate` if authenticated already', waitForAsync(() => {
spyOn(checkAuthService, 'checkAuth').and.returnValue(
of({ isAuthenticated: true } as LoginResponse)
);
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
autoLoginService,
'checkSavedRedirectRouteAndNavigate'
);
const saveRedirectRouteSpy = spyOn(
autoLoginService,
'saveRedirectRoute'
);
const loginSpy = spyOn(loginService, 'login');
const canActivateChild$ = guard.canActivateChild(
{} as ActivatedRouteSnapshot,
{
url: 'some-url1',
} as RouterStateSnapshot
) as Observable<boolean>;
canActivateChild$.subscribe(() => {
expect(saveRedirectRouteSpy).not.toHaveBeenCalled();
expect(loginSpy).not.toHaveBeenCalled();
expect(
checkSavedRedirectRouteAndNavigateSpy
).toHaveBeenCalledOnceWith({
configId: 'configId1',
});
});
}));
it('should call `checkSavedRedirectRouteAndNavigate` if authenticated already', waitForAsync(() => {
spyOn(checkAuthService, 'checkAuth').and.returnValue(
of({ isAuthenticated: true } as LoginResponse)
);
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
autoLoginService,
'checkSavedRedirectRouteAndNavigate'
);
const saveRedirectRouteSpy = spyOn(
autoLoginService,
'saveRedirectRoute'
);
const loginSpy = spyOn(loginService, 'login');
const canActivateChild$ = guard.canActivateChild(
{} as ActivatedRouteSnapshot,
{
url: 'some-url1',
} as RouterStateSnapshot
) as Observable<boolean>;
canActivateChild$.subscribe(() => {
expect(saveRedirectRouteSpy).not.toHaveBeenCalled();
expect(loginSpy).not.toHaveBeenCalled();
expect(
checkSavedRedirectRouteAndNavigateSpy
).toHaveBeenCalledOnceWith({ configId: 'configId1' });
});
}));
});
describe('canLoad', () => {
it('should save current route (empty) and call `login` if not authenticated already', waitForAsync(() => {
spyOn(checkAuthService, 'checkAuth').and.returnValue(
of({ isAuthenticated: false } as LoginResponse)
);
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
autoLoginService,
'checkSavedRedirectRouteAndNavigate'
);
const saveRedirectRouteSpy = spyOn(
autoLoginService,
'saveRedirectRoute'
);
const loginSpy = spyOn(loginService, 'login');
const canLoad$ = guard.canLoad();
canLoad$.subscribe(() => {
expect(saveRedirectRouteSpy).toHaveBeenCalledOnceWith(
{ configId: 'configId1' },
''
);
expect(loginSpy).toHaveBeenCalledOnceWith({ configId: 'configId1' });
expect(checkSavedRedirectRouteAndNavigateSpy).not.toHaveBeenCalled();
});
}));
it('should save current route (with router extractedUrl) and call `login` if not authenticated already', waitForAsync(() => {
spyOn(checkAuthService, 'checkAuth').and.returnValue(
of({ isAuthenticated: false } as LoginResponse)
);
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
autoLoginService,
'checkSavedRedirectRouteAndNavigate'
);
const saveRedirectRouteSpy = spyOn(
autoLoginService,
'saveRedirectRoute'
);
const loginSpy = spyOn(loginService, 'login');
const _routerSpy = spyOn(
router,
'getCurrentNavigation'
).and.returnValue({
extractedUrl: router.parseUrl(
'some-url12/with/some-param?queryParam=true'
),
extras: {},
id: 1,
initialUrl: router.parseUrl(''),
previousNavigation: null,
trigger: 'imperative',
});
const canLoad$ = guard.canLoad();
canLoad$.subscribe(() => {
expect(saveRedirectRouteSpy).toHaveBeenCalledOnceWith(
{ configId: 'configId1' },
'some-url12/with/some-param?queryParam=true'
);
expect(loginSpy).toHaveBeenCalledOnceWith({ configId: 'configId1' });
expect(checkSavedRedirectRouteAndNavigateSpy).not.toHaveBeenCalled();
});
}));
it('should call `checkSavedRedirectRouteAndNavigate` if authenticated already', waitForAsync(() => {
spyOn(checkAuthService, 'checkAuth').and.returnValue(
of({ isAuthenticated: true } as LoginResponse)
);
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
autoLoginService,
'checkSavedRedirectRouteAndNavigate'
);
const saveRedirectRouteSpy = spyOn(
autoLoginService,
'saveRedirectRoute'
);
const loginSpy = spyOn(loginService, 'login');
const canLoad$ = guard.canLoad() as Observable<boolean>;
canLoad$.subscribe(() => {
expect(saveRedirectRouteSpy).not.toHaveBeenCalled();
expect(loginSpy).not.toHaveBeenCalled();
expect(
checkSavedRedirectRouteAndNavigateSpy
).toHaveBeenCalledOnceWith({
configId: 'configId1',
});
});
}));
it('should save current route (with router extractedUrl) and call `login` if not authenticated already', waitForAsync(() => {
spyOn(checkAuthService, 'checkAuth').and.returnValue(
of({ isAuthenticated: false } as LoginResponse)
);
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
autoLoginService,
'checkSavedRedirectRouteAndNavigate'
);
const saveRedirectRouteSpy = spyOn(
autoLoginService,
'saveRedirectRoute'
);
const loginSpy = spyOn(loginService, 'login');
const _routerSpy = spyOn(
router,
'getCurrentNavigation'
).and.returnValue({
extractedUrl: router.parseUrl(
'some-url12/with/some-param?queryParam=true'
),
extras: {},
id: 1,
initialUrl: router.parseUrl(''),
previousNavigation: null,
trigger: 'imperative',
});
const canLoad$ = guard.canLoad();
canLoad$.subscribe(() => {
expect(saveRedirectRouteSpy).toHaveBeenCalledOnceWith(
{ configId: 'configId1' },
'some-url12/with/some-param?queryParam=true'
);
expect(loginSpy).toHaveBeenCalledOnceWith({ configId: 'configId1' });
expect(checkSavedRedirectRouteAndNavigateSpy).not.toHaveBeenCalled();
});
}));
it('should call `checkSavedRedirectRouteAndNavigate` if authenticated already', waitForAsync(() => {
spyOn(checkAuthService, 'checkAuth').and.returnValue(
of({ isAuthenticated: true } as LoginResponse)
);
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
autoLoginService,
'checkSavedRedirectRouteAndNavigate'
);
const saveRedirectRouteSpy = spyOn(
autoLoginService,
'saveRedirectRoute'
);
const loginSpy = spyOn(loginService, 'login');
const canLoad$ = guard.canLoad() as Observable<boolean>;
canLoad$.subscribe(() => {
expect(saveRedirectRouteSpy).not.toHaveBeenCalled();
expect(loginSpy).not.toHaveBeenCalled();
expect(
checkSavedRedirectRouteAndNavigateSpy
).toHaveBeenCalledOnceWith({ configId: 'configId1' });
});
}));
});
});
});

View File

@@ -1,101 +0,0 @@
import { inject, Injectable } from 'injection-js';
import {
ActivatedRouteSnapshot,
Router,
RouterStateSnapshot,
UrlTree,
} from '@angular/router';
import { Observable } from 'rxjs';
import { map, switchMap, take } from 'rxjs/operators';
import { CheckAuthService } from '../auth-state/check-auth.service';
import { ConfigurationService } from '../config/config.service';
import { LoginService } from '../login/login.service';
import { AutoLoginService } from './auto-login.service';
/**
* @deprecated Please do not use the `AutoLoginAllRoutesGuard` anymore as it is not recommended anymore, deprecated and will be removed in future versions of this library. More information [Why is AutoLoginAllRoutesGuard not recommended?](https://github.com/damienbod/angular-auth-oidc-client/issues/1549)
*/
@Injectable()
export class AutoLoginAllRoutesGuard {
private readonly autoLoginService = inject(AutoLoginService);
private readonly checkAuthService = inject(CheckAuthService);
private readonly loginService = inject(LoginService);
private readonly configurationService = inject(ConfigurationService);
private readonly router = inject(Router);
canLoad(): Observable<boolean> {
const url =
this.router
.getCurrentNavigation()
?.extractedUrl.toString()
.substring(1) ?? '';
return checkAuth(
url,
this.configurationService,
this.checkAuthService,
this.autoLoginService,
this.loginService
);
}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean | UrlTree> {
return checkAuth(
state.url,
this.configurationService,
this.checkAuthService,
this.autoLoginService,
this.loginService
);
}
canActivateChild(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean | UrlTree> {
return checkAuth(
state.url,
this.configurationService,
this.checkAuthService,
this.autoLoginService,
this.loginService
);
}
}
function checkAuth(
url: string,
configurationService: ConfigurationService,
checkAuthService: CheckAuthService,
autoLoginService: AutoLoginService,
loginService: LoginService
): Observable<boolean> {
return configurationService.getOpenIDConfiguration().pipe(
switchMap((config) => {
const allConfigs = configurationService.getAllConfigurations();
return checkAuthService.checkAuth(config, allConfigs).pipe(
take(1),
map(({ isAuthenticated }) => {
if (isAuthenticated) {
autoLoginService.checkSavedRedirectRouteAndNavigate(config);
}
if (!isAuthenticated) {
autoLoginService.saveRedirectRoute(config, url);
loginService.login(config);
}
return isAuthenticated;
})
);
})
);
}

View File

@@ -124,7 +124,7 @@ describe('Configuration Service', () => {
configService.getOpenIDConfiguration('configId1').subscribe((config) => {
expect(config).toBeNull();
expect(consoleSpy).toHaveBeenCalledOnceWith(`[angular-auth-oidc-client] No configuration found for config id 'configId1'.`)
expect(consoleSpy).toHaveBeenCalledOnceWith(`[oidc-client-rx] No configuration found for config id 'configId1'.`)
});
}));

View File

@@ -88,7 +88,7 @@ export class ConfigurationService {
const config = this.configsInternal[configId!];
if(!config && isDevMode()) {
console.warn(`[angular-auth-oidc-client] No configuration found for config id '${configId}'.`);
console.warn(`[oidc-client-rx] No configuration found for config id '${configId}'.`);
}
return config || null;

View File

@@ -1,5 +1,5 @@
/*
* Public API Surface of angular-auth-oidc-client
* Public API Surface of oidc-client-rx
*/
export * from '.';