fix: fix all biome
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { TestBed } from '@/testing';
|
||||
import { vi } from 'vitest';
|
||||
import { lastValueFrom } from 'rxjs';
|
||||
import { CryptoService } from '../utils/crypto/crypto.service';
|
||||
import { JwtWindowCryptoService } from './jwt-window-crypto.service';
|
||||
|
||||
@@ -11,9 +11,6 @@ describe('JwtWindowCryptoService', () => {
|
||||
imports: [],
|
||||
providers: [JwtWindowCryptoService, CryptoService],
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
service = TestBed.inject(JwtWindowCryptoService);
|
||||
});
|
||||
|
||||
@@ -29,7 +26,7 @@ describe('JwtWindowCryptoService', () => {
|
||||
);
|
||||
|
||||
const value = await lastValueFrom(observable);
|
||||
expect(value).toBe(outcome);
|
||||
expect(value).toBe(outcome);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { inject, Injectable } from 'injection-js';
|
||||
import { from, Observable } from 'rxjs';
|
||||
import { from, type Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { CryptoService } from '../utils/crypto/crypto.service';
|
||||
|
||||
|
||||
@@ -2,12 +2,22 @@ import { ValidationResult } from './validation-result';
|
||||
|
||||
export class StateValidationResult {
|
||||
constructor(
|
||||
// biome-ignore lint/style/noParameterProperties: <explanation>
|
||||
// biome-ignore lint/nursery/useConsistentMemberAccessibility: <explanation>
|
||||
public accessToken = '',
|
||||
// biome-ignore lint/style/noParameterProperties: <explanation>
|
||||
// biome-ignore lint/nursery/useConsistentMemberAccessibility: <explanation>
|
||||
public idToken = '',
|
||||
// biome-ignore lint/style/noParameterProperties: <explanation>
|
||||
// biome-ignore lint/nursery/useConsistentMemberAccessibility: <explanation>
|
||||
public authResponseIsValid = false,
|
||||
// biome-ignore lint/style/noParameterProperties: <explanation>
|
||||
// biome-ignore lint/nursery/useConsistentMemberAccessibility: <explanation>
|
||||
public decodedIdToken: any = {
|
||||
at_hash: '',
|
||||
},
|
||||
// biome-ignore lint/style/noParameterProperties: <explanation>
|
||||
// biome-ignore lint/nursery/useConsistentMemberAccessibility: <explanation>
|
||||
public state: ValidationResult = ValidationResult.NotSet
|
||||
) {}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { TestBed } from '@/testing';
|
||||
import { of } from 'rxjs';
|
||||
import { lastValueFrom, of } from 'rxjs';
|
||||
import { vi } from 'vitest';
|
||||
import type { AuthWellKnownEndpoints } from '../config/auth-well-known/auth-well-known-endpoints';
|
||||
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||
@@ -36,18 +36,12 @@ describe('State Validation Service', () => {
|
||||
FlowHelper,
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
stateValidationService = TestBed.inject(StateValidationService);
|
||||
tokenValidationService = TestBed.inject(TokenValidationService);
|
||||
tokenHelperService = TestBed.inject(TokenHelperService);
|
||||
loggerService = TestBed.inject(LoggerService);
|
||||
storagePersistenceService = TestBed.inject(StoragePersistenceService);
|
||||
flowHelper = TestBed.inject(FlowHelper);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
config = {
|
||||
authority: 'https://localhost:44363',
|
||||
redirectUrl: 'https://localhost:44363',
|
||||
@@ -694,7 +688,7 @@ describe('State Validation Service', () => {
|
||||
);
|
||||
|
||||
const isValid = await lastValueFrom(isValidObs$);
|
||||
expect(isValid.authResponseIsValid).toBe(false);
|
||||
expect(isValid.authResponseIsValid).toBe(false);
|
||||
});
|
||||
|
||||
it('should return invalid context error', async () => {
|
||||
@@ -730,7 +724,7 @@ expect(isValid.authResponseIsValid).toBe(false);
|
||||
);
|
||||
|
||||
const isValid = await lastValueFrom(isValidObs$);
|
||||
expect(isValid.authResponseIsValid).toBe(false);
|
||||
expect(isValid.authResponseIsValid).toBe(false);
|
||||
});
|
||||
|
||||
it('should return invalid result if validateIdTokenExpNotExpired is false', async () => {
|
||||
@@ -825,14 +819,14 @@ expect(isValid.authResponseIsValid).toBe(false);
|
||||
);
|
||||
|
||||
const state = await lastValueFrom(stateObs$);
|
||||
expect(logWarningSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
config,
|
||||
'authCallback id token expired'
|
||||
);;
|
||||
expect(state.accessToken).toBe('access_tokenTEST');;
|
||||
expect(state.idToken).toBe('id_tokenTEST');;
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');;
|
||||
expect(state.authResponseIsValid).toBe(false);
|
||||
expect(logWarningSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
config,
|
||||
'authCallback id token expired'
|
||||
);
|
||||
expect(state.accessToken).toBe('access_tokenTEST');
|
||||
expect(state.idToken).toBe('id_tokenTEST');
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');
|
||||
expect(state.authResponseIsValid).toBe(false);
|
||||
});
|
||||
|
||||
it('should return invalid result if validateStateFromHashCallback is false', async () => {
|
||||
@@ -877,14 +871,14 @@ expect(state.authResponseIsValid).toBe(false);
|
||||
).toHaveBeenCalled();
|
||||
|
||||
const state = await lastValueFrom(stateObs$);
|
||||
expect(logWarningSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
config,
|
||||
'authCallback incorrect state'
|
||||
);;
|
||||
expect(state.accessToken).toBe('');;
|
||||
expect(state.authResponseIsValid).toBe(false);;
|
||||
expect(state.decodedIdToken).toBeDefined();;
|
||||
expect(state.idToken).toBe('');
|
||||
expect(logWarningSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
config,
|
||||
'authCallback incorrect state'
|
||||
);
|
||||
expect(state.accessToken).toBe('');
|
||||
expect(state.authResponseIsValid).toBe(false);
|
||||
expect(state.decodedIdToken).toBeDefined();
|
||||
expect(state.idToken).toBe('');
|
||||
});
|
||||
|
||||
it('access_token should equal result.access_token and is valid if response_type is "id_token token"', async () => {
|
||||
@@ -974,10 +968,10 @@ expect(state.idToken).toBe('');
|
||||
);
|
||||
|
||||
const state = await lastValueFrom(stateObs$);
|
||||
expect(state.accessToken).toBe('access_tokenTEST');;
|
||||
expect(state.idToken).toBe('id_tokenTEST');;
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');;
|
||||
expect(state.authResponseIsValid).toBe(true);
|
||||
expect(state.accessToken).toBe('access_tokenTEST');
|
||||
expect(state.idToken).toBe('id_tokenTEST');
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');
|
||||
expect(state.authResponseIsValid).toBe(true);
|
||||
});
|
||||
|
||||
it('should return invalid result if validateSignatureIdToken is false', async () => {
|
||||
@@ -1027,14 +1021,14 @@ expect(state.authResponseIsValid).toBe(true);
|
||||
);
|
||||
|
||||
const state = await lastValueFrom(stateObs$);
|
||||
expect(logDebugSpy).toBeCalledWith([
|
||||
[config, 'authCallback Signature validation failed id_token'],
|
||||
[config, 'authCallback token(s) invalid'],
|
||||
]);;
|
||||
expect(state.accessToken).toBe('access_tokenTEST');;
|
||||
expect(state.idToken).toBe('id_tokenTEST');;
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');;
|
||||
expect(state.authResponseIsValid).toBe(false);
|
||||
expect(logDebugSpy).toBeCalledWith([
|
||||
[config, 'authCallback Signature validation failed id_token'],
|
||||
[config, 'authCallback token(s) invalid'],
|
||||
]);
|
||||
expect(state.accessToken).toBe('access_tokenTEST');
|
||||
expect(state.idToken).toBe('id_tokenTEST');
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');
|
||||
expect(state.authResponseIsValid).toBe(false);
|
||||
});
|
||||
|
||||
it('should return invalid result if validateIdTokenNonce is false', async () => {
|
||||
@@ -1087,14 +1081,14 @@ expect(state.authResponseIsValid).toBe(false);
|
||||
);
|
||||
|
||||
const state = await lastValueFrom(stateObs$);
|
||||
expect(logWarningSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
config,
|
||||
'authCallback incorrect nonce, did you call the checkAuth() method multiple times?'
|
||||
);;
|
||||
expect(state.accessToken).toBe('access_tokenTEST');;
|
||||
expect(state.idToken).toBe('id_tokenTEST');;
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');;
|
||||
expect(state.authResponseIsValid).toBe(false);
|
||||
expect(logWarningSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
config,
|
||||
'authCallback incorrect nonce, did you call the checkAuth() method multiple times?'
|
||||
);
|
||||
expect(state.accessToken).toBe('access_tokenTEST');
|
||||
expect(state.idToken).toBe('id_tokenTEST');
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');
|
||||
expect(state.authResponseIsValid).toBe(false);
|
||||
});
|
||||
|
||||
it('should return invalid result if validateRequiredIdToken is false', async () => {
|
||||
@@ -1155,18 +1149,18 @@ expect(state.authResponseIsValid).toBe(false);
|
||||
);
|
||||
|
||||
const state = await lastValueFrom(stateObs$);
|
||||
expect(logDebugSpy).toHaveBeenCalledWith(
|
||||
config,
|
||||
'authCallback Validation, one of the REQUIRED properties missing from id_token'
|
||||
);;
|
||||
expect(logDebugSpy).toHaveBeenCalledWith(
|
||||
config,
|
||||
'authCallback token(s) invalid'
|
||||
);;
|
||||
expect(state.accessToken).toBe('access_tokenTEST');;
|
||||
expect(state.idToken).toBe('id_tokenTEST');;
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');;
|
||||
expect(state.authResponseIsValid).toBe(false);
|
||||
expect(logDebugSpy).toHaveBeenCalledWith(
|
||||
config,
|
||||
'authCallback Validation, one of the REQUIRED properties missing from id_token'
|
||||
);
|
||||
expect(logDebugSpy).toHaveBeenCalledWith(
|
||||
config,
|
||||
'authCallback token(s) invalid'
|
||||
);
|
||||
expect(state.accessToken).toBe('access_tokenTEST');
|
||||
expect(state.idToken).toBe('id_tokenTEST');
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');
|
||||
expect(state.authResponseIsValid).toBe(false);
|
||||
});
|
||||
|
||||
it('should return invalid result if validateIdTokenIatMaxOffset is false', async () => {
|
||||
@@ -1230,14 +1224,14 @@ expect(state.authResponseIsValid).toBe(false);
|
||||
);
|
||||
|
||||
const state = await lastValueFrom(stateObs$);
|
||||
expect(logWarningSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
config,
|
||||
'authCallback Validation, iat rejected id_token was issued too far away from the current time'
|
||||
);;
|
||||
expect(state.accessToken).toBe('access_tokenTEST');;
|
||||
expect(state.idToken).toBe('id_tokenTEST');;
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');;
|
||||
expect(state.authResponseIsValid).toBe(false);
|
||||
expect(logWarningSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
config,
|
||||
'authCallback Validation, iat rejected id_token was issued too far away from the current time'
|
||||
);
|
||||
expect(state.accessToken).toBe('access_tokenTEST');
|
||||
expect(state.idToken).toBe('id_tokenTEST');
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');
|
||||
expect(state.authResponseIsValid).toBe(false);
|
||||
});
|
||||
|
||||
it('should return invalid result if validateIdTokenIss is false and has authWellKnownEndPoints', async () => {
|
||||
@@ -1308,14 +1302,14 @@ expect(state.authResponseIsValid).toBe(false);
|
||||
);
|
||||
|
||||
const state = await lastValueFrom(stateObs$);
|
||||
expect(logWarningSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
config,
|
||||
'authCallback incorrect iss does not match authWellKnownEndpoints issuer'
|
||||
);;
|
||||
expect(state.accessToken).toBe('access_tokenTEST');;
|
||||
expect(state.idToken).toBe('id_tokenTEST');;
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');;
|
||||
expect(state.authResponseIsValid).toBe(false);
|
||||
expect(logWarningSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
config,
|
||||
'authCallback incorrect iss does not match authWellKnownEndpoints issuer'
|
||||
);
|
||||
expect(state.accessToken).toBe('access_tokenTEST');
|
||||
expect(state.idToken).toBe('id_tokenTEST');
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');
|
||||
expect(state.authResponseIsValid).toBe(false);
|
||||
});
|
||||
|
||||
it('should return invalid result if validateIdTokenIss is false and has no authWellKnownEndPoints', async () => {
|
||||
@@ -1374,15 +1368,15 @@ expect(state.authResponseIsValid).toBe(false);
|
||||
);
|
||||
|
||||
const state = await lastValueFrom(stateObs$);
|
||||
expect(logWarningSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
config,
|
||||
'authWellKnownEndpoints is undefined'
|
||||
);;
|
||||
expect(state.accessToken).toBe('access_tokenTEST');;
|
||||
expect(state.idToken).toBe('id_tokenTEST');;
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');;
|
||||
expect(state.authResponseIsValid).toBe(false);;
|
||||
expect(state.state).toBe(ValidationResult.NoAuthWellKnownEndPoints);
|
||||
expect(logWarningSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
config,
|
||||
'authWellKnownEndpoints is undefined'
|
||||
);
|
||||
expect(state.accessToken).toBe('access_tokenTEST');
|
||||
expect(state.idToken).toBe('id_tokenTEST');
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');
|
||||
expect(state.authResponseIsValid).toBe(false);
|
||||
expect(state.state).toBe(ValidationResult.NoAuthWellKnownEndPoints);
|
||||
});
|
||||
|
||||
it('should return invalid result if validateIdTokenAud is false', async () => {
|
||||
@@ -1451,14 +1445,14 @@ expect(state.state).toBe(ValidationResult.NoAuthWellKnownEndPoints);
|
||||
);
|
||||
|
||||
const state = await lastValueFrom(stateObs$);
|
||||
expect(logWarningSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
config,
|
||||
'authCallback incorrect aud'
|
||||
);;
|
||||
expect(state.accessToken).toBe('access_tokenTEST');;
|
||||
expect(state.idToken).toBe('id_tokenTEST');;
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');;
|
||||
expect(state.authResponseIsValid).toBe(false);
|
||||
expect(logWarningSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
config,
|
||||
'authCallback incorrect aud'
|
||||
);
|
||||
expect(state.accessToken).toBe('access_tokenTEST');
|
||||
expect(state.idToken).toBe('id_tokenTEST');
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');
|
||||
expect(state.authResponseIsValid).toBe(false);
|
||||
});
|
||||
|
||||
it('should return invalid result if validateIdTokenAzpExistsIfMoreThanOneAud is false', async () => {
|
||||
@@ -1531,15 +1525,15 @@ expect(state.authResponseIsValid).toBe(false);
|
||||
);
|
||||
|
||||
const state = await lastValueFrom(stateObs$);
|
||||
expect(logWarningSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
config,
|
||||
'authCallback missing azp'
|
||||
);;
|
||||
expect(state.accessToken).toBe('access_tokenTEST');;
|
||||
expect(state.idToken).toBe('id_tokenTEST');;
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');;
|
||||
expect(state.authResponseIsValid).toBe(false);;
|
||||
expect(state.state).toBe(ValidationResult.IncorrectAzp);
|
||||
expect(logWarningSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
config,
|
||||
'authCallback missing azp'
|
||||
);
|
||||
expect(state.accessToken).toBe('access_tokenTEST');
|
||||
expect(state.idToken).toBe('id_tokenTEST');
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');
|
||||
expect(state.authResponseIsValid).toBe(false);
|
||||
expect(state.state).toBe(ValidationResult.IncorrectAzp);
|
||||
});
|
||||
|
||||
it('should return invalid result if validateIdTokenAzpValid is false', async () => {
|
||||
@@ -1616,15 +1610,15 @@ expect(state.state).toBe(ValidationResult.IncorrectAzp);
|
||||
);
|
||||
|
||||
const state = await lastValueFrom(stateObs$);
|
||||
expect(logWarningSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
config,
|
||||
'authCallback incorrect azp'
|
||||
);;
|
||||
expect(state.accessToken).toBe('access_tokenTEST');;
|
||||
expect(state.idToken).toBe('id_tokenTEST');;
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');;
|
||||
expect(state.authResponseIsValid).toBe(false);;
|
||||
expect(state.state).toBe(ValidationResult.IncorrectAzp);
|
||||
expect(logWarningSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
config,
|
||||
'authCallback incorrect azp'
|
||||
);
|
||||
expect(state.accessToken).toBe('access_tokenTEST');
|
||||
expect(state.idToken).toBe('id_tokenTEST');
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');
|
||||
expect(state.authResponseIsValid).toBe(false);
|
||||
expect(state.state).toBe(ValidationResult.IncorrectAzp);
|
||||
});
|
||||
|
||||
it('should return invalid result if isIdTokenAfterRefreshTokenRequestValid is false', async () => {
|
||||
@@ -1705,17 +1699,17 @@ expect(state.state).toBe(ValidationResult.IncorrectAzp);
|
||||
);
|
||||
|
||||
const state = await lastValueFrom(stateObs$);
|
||||
expect(logWarningSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
config,
|
||||
'authCallback pre, post id_token claims do not match in refresh'
|
||||
);;
|
||||
expect(state.accessToken).toBe('access_tokenTEST');;
|
||||
expect(state.idToken).toBe('id_tokenTEST');;
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');;
|
||||
expect(state.authResponseIsValid).toBe(false);;
|
||||
expect(state.state).toBe(
|
||||
ValidationResult.IncorrectIdTokenClaimsAfterRefresh
|
||||
);
|
||||
expect(logWarningSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
config,
|
||||
'authCallback pre, post id_token claims do not match in refresh'
|
||||
);
|
||||
expect(state.accessToken).toBe('access_tokenTEST');
|
||||
expect(state.idToken).toBe('id_tokenTEST');
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');
|
||||
expect(state.authResponseIsValid).toBe(false);
|
||||
expect(state.state).toBe(
|
||||
ValidationResult.IncorrectIdTokenClaimsAfterRefresh
|
||||
);
|
||||
});
|
||||
|
||||
it('Reponse is valid if authConfiguration.response_type does not equal "id_token token"', async () => {
|
||||
@@ -1808,18 +1802,18 @@ expect(state.state).toBe(
|
||||
);
|
||||
|
||||
const state = await lastValueFrom(stateObs$);
|
||||
expect(logDebugSpy).toHaveBeenCalledWith(
|
||||
config,
|
||||
'authCallback token(s) validated, continue'
|
||||
);;
|
||||
expect(logDebugSpy).toHaveBeenCalledWith(
|
||||
config,
|
||||
'authCallback token(s) invalid'
|
||||
);;
|
||||
expect(state.accessToken).toBe('');;
|
||||
expect(state.idToken).toBe('id_tokenTEST');;
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');;
|
||||
expect(state.authResponseIsValid).toBe(true);
|
||||
expect(logDebugSpy).toHaveBeenCalledWith(
|
||||
config,
|
||||
'authCallback token(s) validated, continue'
|
||||
);
|
||||
expect(logDebugSpy).toHaveBeenCalledWith(
|
||||
config,
|
||||
'authCallback token(s) invalid'
|
||||
);
|
||||
expect(state.accessToken).toBe('');
|
||||
expect(state.idToken).toBe('id_tokenTEST');
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');
|
||||
expect(state.authResponseIsValid).toBe(true);
|
||||
});
|
||||
|
||||
it('Response is invalid if validateIdTokenAtHash is false', async () => {
|
||||
@@ -1913,14 +1907,14 @@ expect(state.authResponseIsValid).toBe(true);
|
||||
);
|
||||
|
||||
const state = await lastValueFrom(stateObs$);
|
||||
expect(logWarningSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
config,
|
||||
'authCallback incorrect at_hash'
|
||||
);;
|
||||
expect(state.accessToken).toBe('access_tokenTEST');;
|
||||
expect(state.idToken).toBe('id_tokenTEST');;
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');;
|
||||
expect(state.authResponseIsValid).toBe(false);
|
||||
expect(logWarningSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
config,
|
||||
'authCallback incorrect at_hash'
|
||||
);
|
||||
expect(state.accessToken).toBe('access_tokenTEST');
|
||||
expect(state.idToken).toBe('id_tokenTEST');
|
||||
expect(state.decodedIdToken).toBe('decoded_id_token');
|
||||
expect(state.authResponseIsValid).toBe(false);
|
||||
});
|
||||
|
||||
it('should return valid result if validateIdTokenIss is false and iss_validation_off is true', async () => {
|
||||
@@ -2010,15 +2004,15 @@ expect(state.authResponseIsValid).toBe(false);
|
||||
);
|
||||
|
||||
const state = await lastValueFrom(stateObs$);
|
||||
expect(logDebugSpy).toBeCalledWith([
|
||||
[config, 'iss validation is turned off, this is not recommended!'],
|
||||
[config, 'authCallback token(s) validated, continue'],
|
||||
]);;
|
||||
expect(state.state).toBe(ValidationResult.Ok);;
|
||||
expect(state.accessToken).toBe('access_tokenTEST');;
|
||||
expect(state.authResponseIsValid).toBe(true);;
|
||||
expect(state.decodedIdToken).toBeDefined();;
|
||||
expect(state.idToken).toBe('id_tokenTEST');
|
||||
expect(logDebugSpy).toBeCalledWith([
|
||||
[config, 'iss validation is turned off, this is not recommended!'],
|
||||
[config, 'authCallback token(s) validated, continue'],
|
||||
]);
|
||||
expect(state.state).toBe(ValidationResult.Ok);
|
||||
expect(state.accessToken).toBe('access_tokenTEST');
|
||||
expect(state.authResponseIsValid).toBe(true);
|
||||
expect(state.decodedIdToken).toBeDefined();
|
||||
expect(state.idToken).toBe('id_tokenTEST');
|
||||
});
|
||||
|
||||
it('should return valid if there is no id_token', async () => {
|
||||
@@ -2095,10 +2089,10 @@ expect(state.idToken).toBe('id_tokenTEST');
|
||||
);
|
||||
|
||||
const state = await lastValueFrom(stateObs$);
|
||||
expect(state.accessToken).toBe('access_tokenTEST');;
|
||||
expect(state.idToken).toBe('');;
|
||||
expect(state.decodedIdToken).toBeDefined();;
|
||||
expect(state.authResponseIsValid).toBe(true);
|
||||
expect(state.accessToken).toBe('access_tokenTEST');
|
||||
expect(state.idToken).toBe('');
|
||||
expect(state.decodedIdToken).toBeDefined();
|
||||
expect(state.authResponseIsValid).toBe(true);
|
||||
});
|
||||
|
||||
it('should return OK if disableIdTokenValidation is true', async () => {
|
||||
@@ -2134,8 +2128,8 @@ expect(state.authResponseIsValid).toBe(true);
|
||||
);
|
||||
|
||||
const isValid = await lastValueFrom(isValidObs$);
|
||||
expect(isValid.state).toBe(ValidationResult.Ok);;
|
||||
expect(isValid.authResponseIsValid).toBe(true);
|
||||
expect(isValid.state).toBe(ValidationResult.Ok);
|
||||
expect(isValid.authResponseIsValid).toBe(true);
|
||||
});
|
||||
|
||||
it('should return OK if disableIdTokenValidation is true', async () => {
|
||||
@@ -2171,8 +2165,8 @@ expect(isValid.authResponseIsValid).toBe(true);
|
||||
);
|
||||
|
||||
const isValid = await lastValueFrom(isValidObs$);
|
||||
expect(isValid.state).toBe(ValidationResult.Ok);;
|
||||
expect(isValid.authResponseIsValid).toBe(true);
|
||||
expect(isValid.state).toBe(ValidationResult.Ok);
|
||||
expect(isValid.authResponseIsValid).toBe(true);
|
||||
});
|
||||
|
||||
it('should return OK if disableIdTokenValidation is false but inrefreshtokenflow and no id token is returned', async () => {
|
||||
@@ -2208,8 +2202,8 @@ expect(isValid.authResponseIsValid).toBe(true);
|
||||
);
|
||||
|
||||
const isValid = await lastValueFrom(isValidObs$);
|
||||
expect(isValid.state).toBe(ValidationResult.Ok);;
|
||||
expect(isValid.authResponseIsValid).toBe(true);
|
||||
expect(isValid.state).toBe(ValidationResult.Ok);
|
||||
expect(isValid.authResponseIsValid).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { inject, Injectable } from 'injection-js';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { Injectable, inject } from 'injection-js';
|
||||
import { type Observable, of } from 'rxjs';
|
||||
import { map, mergeMap } from 'rxjs/operators';
|
||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
||||
import { CallbackContext } from '../flows/callback-context';
|
||||
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||
import type { CallbackContext } from '../flows/callback-context';
|
||||
import { LoggerService } from '../logging/logger.service';
|
||||
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
||||
import { EqualityService } from '../utils/equality/equality.service';
|
||||
@@ -122,6 +122,7 @@ export class StateValidationService {
|
||||
configuration
|
||||
)
|
||||
.pipe(
|
||||
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: <explanation>
|
||||
mergeMap((isSignatureIdTokenValid: boolean) => {
|
||||
if (!isSignatureIdTokenValid) {
|
||||
this.loggerService.logDebug(
|
||||
@@ -324,12 +325,11 @@ export class StateValidationService {
|
||||
);
|
||||
})
|
||||
);
|
||||
} else {
|
||||
this.loggerService.logDebug(
|
||||
configuration,
|
||||
'No id_token found, skipping id_token validation'
|
||||
);
|
||||
}
|
||||
this.loggerService.logDebug(
|
||||
configuration,
|
||||
'No id_token found, skipping id_token validation'
|
||||
);
|
||||
|
||||
return this.validateDefault(
|
||||
isCurrentFlowImplicitFlowWithAccessToken,
|
||||
@@ -391,14 +391,13 @@ export class StateValidationService {
|
||||
toReturn.state = ValidationResult.IncorrectAtHash;
|
||||
this.handleUnsuccessfulValidation(configuration);
|
||||
|
||||
return toReturn;
|
||||
} else {
|
||||
toReturn.authResponseIsValid = true;
|
||||
toReturn.state = ValidationResult.Ok;
|
||||
this.handleSuccessfulValidation(configuration);
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
toReturn.authResponseIsValid = true;
|
||||
toReturn.state = ValidationResult.Ok;
|
||||
this.handleSuccessfulValidation(configuration);
|
||||
|
||||
return toReturn;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,20 +7,21 @@ export function getVerifyAlg(
|
||||
name: 'RSASSA-PKCS1-v1_5',
|
||||
hash: 'SHA-256',
|
||||
};
|
||||
case 'E':
|
||||
case 'E': {
|
||||
if (alg.includes('256')) {
|
||||
return {
|
||||
name: 'ECDSA',
|
||||
hash: 'SHA-256',
|
||||
};
|
||||
} else if (alg.includes('384')) {
|
||||
}
|
||||
if (alg.includes('384')) {
|
||||
return {
|
||||
name: 'ECDSA',
|
||||
hash: 'SHA-384',
|
||||
};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -35,7 +36,7 @@ export function alg2kty(alg: string): string {
|
||||
return 'EC';
|
||||
|
||||
default:
|
||||
throw new Error('Cannot infer kty from alg: ' + alg);
|
||||
throw new Error(`Cannot infer kty from alg: ${alg}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,39 +44,42 @@ export function getImportAlg(
|
||||
alg: string
|
||||
): RsaHashedImportParams | EcKeyImportParams | null {
|
||||
switch (alg.charAt(0)) {
|
||||
case 'R':
|
||||
case 'R': {
|
||||
if (alg.includes('256')) {
|
||||
return {
|
||||
name: 'RSASSA-PKCS1-v1_5',
|
||||
hash: 'SHA-256',
|
||||
};
|
||||
} else if (alg.includes('384')) {
|
||||
}
|
||||
if (alg.includes('384')) {
|
||||
return {
|
||||
name: 'RSASSA-PKCS1-v1_5',
|
||||
hash: 'SHA-384',
|
||||
};
|
||||
} else if (alg.includes('512')) {
|
||||
}
|
||||
if (alg.includes('512')) {
|
||||
return {
|
||||
name: 'RSASSA-PKCS1-v1_5',
|
||||
hash: 'SHA-512',
|
||||
};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
case 'E':
|
||||
return null;
|
||||
}
|
||||
case 'E': {
|
||||
if (alg.includes('256')) {
|
||||
return {
|
||||
name: 'ECDSA',
|
||||
namedCurve: 'P-256',
|
||||
};
|
||||
} else if (alg.includes('384')) {
|
||||
}
|
||||
if (alg.includes('384')) {
|
||||
return {
|
||||
name: 'ECDSA',
|
||||
namedCurve: 'P-384',
|
||||
};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { inject, Injectable } from 'injection-js';
|
||||
import { Injectable, inject } from 'injection-js';
|
||||
import { base64url } from 'rfc4648';
|
||||
import { from, Observable, of } from 'rxjs';
|
||||
import { type Observable, from, of } from 'rxjs';
|
||||
import { map, mergeMap, tap } from 'rxjs/operators';
|
||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
||||
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||
import { JwkExtractor } from '../extractors/jwk.extractor';
|
||||
import { LoggerService } from '../logging/logger.service';
|
||||
import { TokenHelperService } from '../utils/tokenHelper/token-helper.service';
|
||||
@@ -257,6 +257,7 @@ export class TokenValidationService {
|
||||
const dateTimeIatIdToken = new Date(0); // The 0 here is the key, which sets the date to the epoch
|
||||
|
||||
dateTimeIatIdToken.setUTCSeconds(dataIdToken.iat);
|
||||
|
||||
maxOffsetAllowedInSeconds = maxOffsetAllowedInSeconds || 0;
|
||||
|
||||
const nowInUtc = new Date(new Date().toUTCString());
|
||||
@@ -295,10 +296,7 @@ export class TokenValidationService {
|
||||
if (!isFromRefreshToken && dataIdToken.nonce !== localNonce) {
|
||||
this.loggerService.logDebug(
|
||||
configuration,
|
||||
'Validate_id_token_nonce failed, dataIdToken.nonce: ' +
|
||||
dataIdToken.nonce +
|
||||
' local_nonce:' +
|
||||
localNonce
|
||||
`Validate_id_token_nonce failed, dataIdToken.nonce: ${dataIdToken.nonce} local_nonce:${localNonce}`
|
||||
);
|
||||
|
||||
return false;
|
||||
@@ -319,10 +317,7 @@ export class TokenValidationService {
|
||||
) {
|
||||
this.loggerService.logDebug(
|
||||
configuration,
|
||||
'Validate_id_token_iss failed, dataIdToken.iss: ' +
|
||||
dataIdToken.iss +
|
||||
' authWellKnownEndpoints issuer:' +
|
||||
authWellKnownEndpointsIssuer
|
||||
`Validate_id_token_iss failed, dataIdToken.iss: ${dataIdToken.iss} authWellKnownEndpoints issuer:${authWellKnownEndpointsIssuer}`
|
||||
);
|
||||
|
||||
return false;
|
||||
@@ -346,23 +341,18 @@ export class TokenValidationService {
|
||||
if (!result) {
|
||||
this.loggerService.logDebug(
|
||||
configuration,
|
||||
'Validate_id_token_aud array failed, dataIdToken.aud: ' +
|
||||
dataIdToken.aud +
|
||||
' client_id:' +
|
||||
aud
|
||||
`Validate_id_token_aud array failed, dataIdToken.aud: ${dataIdToken.aud} client_id:${aud}`
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (dataIdToken.aud !== aud) {
|
||||
}
|
||||
if (dataIdToken.aud !== aud) {
|
||||
this.loggerService.logDebug(
|
||||
configuration,
|
||||
'Validate_id_token_aud failed, dataIdToken.aud: ' +
|
||||
dataIdToken.aud +
|
||||
' client_id:' +
|
||||
aud
|
||||
`Validate_id_token_aud failed, dataIdToken.aud: ${dataIdToken.aud} client_id:${aud}`
|
||||
);
|
||||
|
||||
return false;
|
||||
@@ -403,10 +393,7 @@ export class TokenValidationService {
|
||||
if ((state as string) !== (localState as string)) {
|
||||
this.loggerService.logDebug(
|
||||
configuration,
|
||||
'ValidateStateFromHashCallback failed, state: ' +
|
||||
state +
|
||||
' local_state:' +
|
||||
localState
|
||||
`ValidateStateFromHashCallback failed, state: ${state} local_state:${localState}`
|
||||
);
|
||||
|
||||
return false;
|
||||
@@ -555,7 +542,7 @@ export class TokenValidationService {
|
||||
): Observable<boolean> {
|
||||
this.loggerService.logDebug(
|
||||
configuration,
|
||||
'at_hash from the server:' + atHash
|
||||
`at_hash from the server:${atHash}`
|
||||
);
|
||||
|
||||
// 'sha256' 'sha384' 'sha512'
|
||||
@@ -568,29 +555,28 @@ export class TokenValidationService {
|
||||
}
|
||||
|
||||
return this.jwtWindowCryptoService
|
||||
.generateAtHash('' + accessToken, sha)
|
||||
.generateAtHash(`${accessToken}`, sha)
|
||||
.pipe(
|
||||
mergeMap((hash: string) => {
|
||||
this.loggerService.logDebug(
|
||||
configuration,
|
||||
'at_hash client validation not decoded:' + hash
|
||||
`at_hash client validation not decoded:${hash}`
|
||||
);
|
||||
if (hash === atHash) {
|
||||
return of(true); // isValid;
|
||||
} else {
|
||||
return this.jwtWindowCryptoService
|
||||
.generateAtHash('' + decodeURIComponent(accessToken), sha)
|
||||
.pipe(
|
||||
map((newHash: string) => {
|
||||
this.loggerService.logDebug(
|
||||
configuration,
|
||||
'-gen access--' + hash
|
||||
);
|
||||
|
||||
return newHash === atHash;
|
||||
})
|
||||
);
|
||||
}
|
||||
return this.jwtWindowCryptoService
|
||||
.generateAtHash(`${decodeURIComponent(accessToken)}`, sha)
|
||||
.pipe(
|
||||
map((newHash: string) => {
|
||||
this.loggerService.logDebug(
|
||||
configuration,
|
||||
`-gen access--${hash}`
|
||||
);
|
||||
|
||||
return newHash === atHash;
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -599,7 +585,7 @@ export class TokenValidationService {
|
||||
const minutes = Math.floor(millis / 60000);
|
||||
const seconds = ((millis % 60000) / 1000).toFixed(0);
|
||||
|
||||
return minutes + ':' + (+seconds < 10 ? '0' : '') + seconds;
|
||||
return `${minutes}:${+seconds < 10 ? '0' : ''}${seconds}`;
|
||||
}
|
||||
|
||||
private calculateNowWithOffset(offsetSeconds: number): number {
|
||||
|
||||
Reference in New Issue
Block a user