Skip to content

Commit de751a0

Browse files
Merge pull request #1193 from damienbod/fabiangosebrink/prompt-parameter-sent-multiple-times-with-silent-renew-(azure-integration)
Added fix overwriting param
2 parents 26bd4bb + 504be1f commit de751a0

File tree

4 files changed

+125
-10
lines changed

4 files changed

+125
-10
lines changed

projects/angular-auth-oidc-client/src/lib/check-auth.service.spec.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,72 @@ describe('CheckAuthService', () => {
436436
});
437437
})
438438
);
439+
440+
it(
441+
'should start check session and validation after forceRefreshSession has been called and is authenticated after forcing with silentrenew',
442+
waitForAsync(() => {
443+
spyOn(configurationProvider, 'hasAsLeastOneConfig').and.returnValue(true);
444+
spyOn(configurationProvider, 'getOpenIDConfiguration').and.returnValue({ authority: 'authority' });
445+
spyOn(callBackService, 'isCallback').and.returnValue(false);
446+
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(false);
447+
spyOn(callBackService, 'handleCallbackAndFireEvents').and.returnValue(of(null));
448+
spyOn(checkSessionService, 'isCheckSessionConfigured').and.returnValue(true);
449+
spyOn(silentRenewService, 'isSilentRenewConfigured').and.returnValue(true);
450+
451+
const checkSessionServiceStartSpy = spyOn(checkSessionService, 'start');
452+
const periodicallyTokenCheckServiceSpy = spyOn(periodicallyTokenCheckService, 'startTokenValidationPeriodically');
453+
const getOrCreateIframeSpy = spyOn(silentRenewService, 'getOrCreateIframe');
454+
455+
spyOn(refreshSessionService, 'forceRefreshSession').and.returnValue(
456+
of({
457+
idToken: 'idToken',
458+
accessToken: 'access_token',
459+
isAuthenticated: true,
460+
userData: null,
461+
configId: 'configId',
462+
})
463+
);
464+
465+
checkAuthService.checkAuthIncludingServer('configId').subscribe((result) => {
466+
expect(checkSessionServiceStartSpy).toHaveBeenCalledOnceWith('configId');
467+
expect(periodicallyTokenCheckServiceSpy).toHaveBeenCalledTimes(1);
468+
expect(getOrCreateIframeSpy).toHaveBeenCalledOnceWith('configId');
469+
});
470+
})
471+
);
472+
473+
it(
474+
'should start check session and validation after forceRefreshSession has been called and is authenticated after forcing without silentrenew',
475+
waitForAsync(() => {
476+
spyOn(configurationProvider, 'hasAsLeastOneConfig').and.returnValue(true);
477+
spyOn(configurationProvider, 'getOpenIDConfiguration').and.returnValue({ authority: 'authority' });
478+
spyOn(callBackService, 'isCallback').and.returnValue(false);
479+
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(false);
480+
spyOn(callBackService, 'handleCallbackAndFireEvents').and.returnValue(of(null));
481+
spyOn(checkSessionService, 'isCheckSessionConfigured').and.returnValue(true);
482+
spyOn(silentRenewService, 'isSilentRenewConfigured').and.returnValue(false);
483+
484+
const checkSessionServiceStartSpy = spyOn(checkSessionService, 'start');
485+
const periodicallyTokenCheckServiceSpy = spyOn(periodicallyTokenCheckService, 'startTokenValidationPeriodically');
486+
const getOrCreateIframeSpy = spyOn(silentRenewService, 'getOrCreateIframe');
487+
488+
spyOn(refreshSessionService, 'forceRefreshSession').and.returnValue(
489+
of({
490+
idToken: 'idToken',
491+
accessToken: 'access_token',
492+
isAuthenticated: true,
493+
userData: null,
494+
configId: 'configId',
495+
})
496+
);
497+
498+
checkAuthService.checkAuthIncludingServer('configId').subscribe((result) => {
499+
expect(checkSessionServiceStartSpy).toHaveBeenCalledOnceWith('configId');
500+
expect(periodicallyTokenCheckServiceSpy).toHaveBeenCalledTimes(1);
501+
expect(getOrCreateIframeSpy).not.toHaveBeenCalled();
502+
});
503+
})
504+
);
439505
});
440506

441507
describe('checkAuthMultiple', () => {

projects/angular-auth-oidc-client/src/lib/flows/callback-handling/code-flow-callback-handler.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export class CodeFlowCallbackHandlerService {
2727
codeFlowCallback(urlToCheck: string, configId: string): Observable<CallbackContext> {
2828
const code = this.urlService.getUrlParameter(urlToCheck, 'code');
2929
const state = this.urlService.getUrlParameter(urlToCheck, 'state');
30-
const sessionState = this.urlService.getUrlParameter(urlToCheck, 'session_state') || null;
30+
const sessionState = this.urlService.getUrlParameter(urlToCheck, 'session_state');
3131

3232
if (!state) {
3333
this.loggerService.logDebug(configId, 'no state in url');

projects/angular-auth-oidc-client/src/lib/utils/url/url.service.spec.ts

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,8 @@ describe('UrlService Tests', () => {
323323
'&scope=openid%20email%20profile' +
324324
'&nonce=nonce' +
325325
'&state=state' +
326-
'&prompt=myprompt' +
327-
'&to=add&as=well';
326+
'&to=add&as=well' +
327+
'&prompt=myprompt';
328328

329329
expect(value).toEqual(expectValue);
330330
});
@@ -623,6 +623,47 @@ describe('UrlService Tests', () => {
623623
expect(value).toEqual(expectValue);
624624
});
625625

626+
it('should add the prompt only once even if it is configured AND passed with `none` in silent renew case, taking the passed one', () => {
627+
const config = { authority: 'https://localhost:5001' } as OpenIdConfiguration;
628+
config.clientId = '188968487735-b1hh7k87nkkh6vv84548sinju2kpr7gn.apps.googleusercontent.com';
629+
config.responseType = 'code';
630+
config.scope = 'openid email profile';
631+
config.redirectUrl = 'https://localhost:44386';
632+
633+
config.customParamsAuthRequest = {
634+
prompt: 'select_account',
635+
};
636+
637+
configurationProvider.setConfig(config);
638+
spyOn(storagePersistenceService, 'read')
639+
.withArgs('authWellKnownEndPoints', 'configId')
640+
.and.returnValue({ authorizationEndpoint: 'http://example' });
641+
642+
const value = (service as any).createAuthorizeUrl(
643+
'', // Implicit Flow
644+
config.redirectUrl,
645+
'nonce',
646+
'state',
647+
'configId',
648+
'somePrompt'
649+
);
650+
651+
const expectValue =
652+
'http://example?client_id=188968487735-b1hh7k87nkkh6vv84548sinju2kpr7gn.apps.googleusercontent.com' +
653+
'&redirect_uri=https%3A%2F%2Flocalhost%3A44386' +
654+
'&response_type=code' +
655+
'&scope=openid%20email%20profile' +
656+
'&nonce=nonce' +
657+
'&state=state' +
658+
'&code_challenge=' +
659+
'&code_challenge_method=S256' +
660+
'&prompt=somePrompt';
661+
662+
expect(value).toEqual(expectValue);
663+
});
664+
});
665+
666+
describe('createRevocationEndpointBodyAccessToken', () => {
626667
it('createRevocationBody access_token default', () => {
627668
const config = { authority: 'https://localhost:5001' } as OpenIdConfiguration;
628669
config.redirectUrl = 'https://localhost:44386';
@@ -653,7 +694,9 @@ describe('UrlService Tests', () => {
653694

654695
expect(value).toBeNull();
655696
});
697+
});
656698

699+
describe('createRevocationEndpointBodyRefreshToken', () => {
657700
it('createRevocationBody refresh_token default', () => {
658701
const config = { authority: 'https://localhost:5001' } as OpenIdConfiguration;
659702
config.redirectUrl = 'https://localhost:44386';
@@ -684,7 +727,9 @@ describe('UrlService Tests', () => {
684727

685728
expect(value).toBeNull();
686729
});
730+
});
687731

732+
describe('getRevocationEndpointUrl', () => {
688733
it('getRevocationEndpointUrl with params', () => {
689734
const config = { authority: 'https://localhost:5001' } as OpenIdConfiguration;
690735
config.redirectUrl = 'https://localhost:44386';

projects/angular-auth-oidc-client/src/lib/utils/url/url.service.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -328,20 +328,20 @@ export class UrlService {
328328
params = params.append('code_challenge_method', 'S256');
329329
}
330330

331+
const mergedParams = { ...customParamsAuthRequest, ...customRequestParams };
332+
333+
if (Object.keys(mergedParams).length > 0) {
334+
params = this.appendCustomParams({ ...mergedParams }, params);
335+
}
336+
331337
if (prompt) {
332-
params = params.append('prompt', prompt);
338+
params = this.overWriteParam(params, 'prompt', prompt);
333339
}
334340

335341
if (hdParam) {
336342
params = params.append('hd', hdParam);
337343
}
338344

339-
const mergedParams = { ...customParamsAuthRequest, ...customRequestParams };
340-
341-
if (Object.keys(mergedParams).length > 0) {
342-
params = this.appendCustomParams({ ...mergedParams }, params);
343-
}
344-
345345
return `${authorizationUrl}?${params}`;
346346
}
347347

@@ -495,6 +495,10 @@ export class UrlService {
495495
return params;
496496
}
497497

498+
private overWriteParam(params: HttpParams, key: string, value: string | number | boolean): HttpParams {
499+
return params.set(key, value);
500+
}
501+
498502
private createHttpParams(existingParams?: string): HttpParams {
499503
existingParams = existingParams ?? '';
500504

0 commit comments

Comments
 (0)