diff --git a/src/abstractions/api.service.ts b/src/abstractions/api.service.ts index f670c9ca00..a8faa65bb7 100644 --- a/src/abstractions/api.service.ts +++ b/src/abstractions/api.service.ts @@ -306,4 +306,6 @@ export abstract class ApiService { getActiveBearerToken: () => Promise; fetch: (request: Request) => Promise; nativeFetch: (request: Request) => Promise; + + preValidateSso: (identifier: string) => Promise; } diff --git a/src/angular/components/sso.component.ts b/src/angular/components/sso.component.ts index 563307ff75..1b6bdb22ae 100644 --- a/src/angular/components/sso.component.ts +++ b/src/angular/components/sso.component.ts @@ -23,6 +23,7 @@ export class SsoComponent { loggingIn = false; formPromise: Promise; + initiateSsoFormPromise: Promise; onSuccessfulLogin: () => Promise; onSuccessfulLoginNavigate: () => Promise; onSuccessfulLoginTwoFactorNavigate: () => Promise; @@ -67,8 +68,20 @@ export class SsoComponent { } async submit(returnUri?: string, includeUserIdentifier?: boolean) { - const authorizeUrl = await this.buildAuthorizeUrl(returnUri, includeUserIdentifier); - this.platformUtilsService.launchUri(authorizeUrl, { sameWindow: true }); + this.initiateSsoFormPromise = this.preValidate(); + if (await this.initiateSsoFormPromise) { + const authorizeUrl = await this.buildAuthorizeUrl(returnUri, includeUserIdentifier); + this.platformUtilsService.launchUri(authorizeUrl, { sameWindow: true }); + } + } + + async preValidate(): Promise { + if (this.identifier == null || this.identifier === '') { + this.platformUtilsService.showToast('error', this.i18nService.t('ssoValidationFailed'), + this.i18nService.t('ssoIdentifierRequired')); + return false; + } + return await this.apiService.preValidateSso(this.identifier); } protected async buildAuthorizeUrl(returnUri?: string, includeUserIdentifier?: boolean): Promise { diff --git a/src/services/api.service.ts b/src/services/api.service.ts index 22cb00f508..6be644dc03 100644 --- a/src/services/api.service.ts +++ b/src/services/api.service.ts @@ -1040,6 +1040,35 @@ export class ApiService implements ApiServiceAbstraction { return fetch(request); } + async preValidateSso(identifier: string): Promise { + + if (identifier == null || identifier === '') { + throw new Error('Organization Identifier was not provided.'); + } + const headers = new Headers({ + 'Accept': 'application/json', + 'Device-Type': this.deviceType, + }); + if (this.customUserAgent != null) { + headers.set('User-Agent', this.customUserAgent); + } + + const path = `/account/prevalidate?domainHint=${encodeURIComponent(identifier)}`; + const response = await this.fetch(new Request(this.identityBaseUrl + path, { + cache: 'no-store', + credentials: this.getCredentials(), + headers: headers, + method: 'GET', + })); + + if (response.status === 200) { + return true; + } else { + const error = await this.handleError(response, false); + return Promise.reject(error); + } + } + private async send(method: 'GET' | 'POST' | 'PUT' | 'DELETE', path: string, body: any, authed: boolean, hasResponse: boolean): Promise { const headers = new Headers({