mirror of
https://github.com/bitwarden/browser.git
synced 2025-02-23 02:31:26 +01:00
CSA-2 SSO user interaction token (#780)
* Adding token processing for SSO redirect * Update preValidate return type * Remove unreachable code Co-authored-by: Carlos J. Muentes <cmuentes@bitwarden.com> Co-authored-by: Matt Gibson <mgibson@bitwarden.com>
This commit is contained in:
parent
0d658ba26d
commit
911cf794f4
@ -14,6 +14,7 @@ import { StateService } from "jslib-common/abstractions/state.service";
|
||||
import { Utils } from "jslib-common/misc/utils";
|
||||
import { AuthResult } from "jslib-common/models/domain/authResult";
|
||||
import { SsoLogInCredentials } from "jslib-common/models/domain/logInCredentials";
|
||||
import { SsoPreValidateResponse } from "jslib-common/models/response/ssoPreValidateResponse";
|
||||
|
||||
@Directive()
|
||||
export class SsoComponent {
|
||||
@ -21,7 +22,7 @@ export class SsoComponent {
|
||||
loggingIn = false;
|
||||
|
||||
formPromise: Promise<AuthResult>;
|
||||
initiateSsoFormPromise: Promise<any>;
|
||||
initiateSsoFormPromise: Promise<SsoPreValidateResponse>;
|
||||
onSuccessfulLogin: () => Promise<any>;
|
||||
onSuccessfulLoginNavigate: () => Promise<any>;
|
||||
onSuccessfulLoginTwoFactorNavigate: () => Promise<any>;
|
||||
@ -85,28 +86,30 @@ export class SsoComponent {
|
||||
}
|
||||
|
||||
async submit(returnUri?: string, includeUserIdentifier?: boolean) {
|
||||
this.initiateSsoFormPromise = this.preValidate();
|
||||
if (await this.initiateSsoFormPromise) {
|
||||
const authorizeUrl = await this.buildAuthorizeUrl(returnUri, includeUserIdentifier);
|
||||
this.platformUtilsService.launchUri(authorizeUrl, { sameWindow: true });
|
||||
}
|
||||
}
|
||||
|
||||
async preValidate(): Promise<boolean> {
|
||||
if (this.identifier == null || this.identifier === "") {
|
||||
this.platformUtilsService.showToast(
|
||||
"error",
|
||||
this.i18nService.t("ssoValidationFailed"),
|
||||
this.i18nService.t("ssoIdentifierRequired")
|
||||
);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
return await this.apiService.preValidateSso(this.identifier);
|
||||
|
||||
this.initiateSsoFormPromise = this.apiService.preValidateSso(this.identifier);
|
||||
const response = await this.initiateSsoFormPromise;
|
||||
|
||||
const authorizeUrl = await this.buildAuthorizeUrl(
|
||||
returnUri,
|
||||
includeUserIdentifier,
|
||||
response.token
|
||||
);
|
||||
this.platformUtilsService.launchUri(authorizeUrl, { sameWindow: true });
|
||||
}
|
||||
|
||||
protected async buildAuthorizeUrl(
|
||||
returnUri?: string,
|
||||
includeUserIdentifier?: boolean
|
||||
includeUserIdentifier?: boolean,
|
||||
token?: string
|
||||
): Promise<string> {
|
||||
let codeChallenge = this.codeChallenge;
|
||||
let state = this.state;
|
||||
@ -156,7 +159,9 @@ export class SsoComponent {
|
||||
"&" +
|
||||
"code_challenge_method=S256&response_mode=query&" +
|
||||
"domain_hint=" +
|
||||
encodeURIComponent(this.identifier);
|
||||
encodeURIComponent(this.identifier) +
|
||||
"&ssoToken=" +
|
||||
encodeURIComponent(token);
|
||||
|
||||
if (includeUserIdentifier) {
|
||||
const userIdentifier = await this.apiService.getSsoUserIdentifier();
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
OrganizationConnectionConfigApis,
|
||||
OrganizationConnectionResponse,
|
||||
} from "jslib-common/models/response/organizationConnectionResponse";
|
||||
import { SsoPreValidateResponse } from "jslib-common/models/response/ssoPreValidateResponse";
|
||||
|
||||
import { PolicyType } from "../enums/policyType";
|
||||
import { SetKeyConnectorKeyRequest } from "../models/request/account/setKeyConnectorKeyRequest";
|
||||
@ -688,7 +689,7 @@ export abstract class ApiService {
|
||||
fetch: (request: Request) => Promise<Response>;
|
||||
nativeFetch: (request: Request) => Promise<Response>;
|
||||
|
||||
preValidateSso: (identifier: string) => Promise<boolean>;
|
||||
preValidateSso: (identifier: string) => Promise<SsoPreValidateResponse>;
|
||||
|
||||
postCreateSponsorship: (
|
||||
sponsorshipOrgId: string,
|
||||
|
10
common/src/models/response/ssoPreValidateResponse.ts
Normal file
10
common/src/models/response/ssoPreValidateResponse.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { BaseResponse } from "./baseResponse";
|
||||
|
||||
export class SsoPreValidateResponse extends BaseResponse {
|
||||
token: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.token = this.getResponseProperty("Token");
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ import {
|
||||
OrganizationConnectionConfigApis,
|
||||
OrganizationConnectionResponse,
|
||||
} from "jslib-common/models/response/organizationConnectionResponse";
|
||||
import { SsoPreValidateResponse } from "jslib-common/models/response/ssoPreValidateResponse";
|
||||
|
||||
import { ApiService as ApiServiceAbstraction } from "../abstractions/api.service";
|
||||
import { EnvironmentService } from "../abstractions/environment.service";
|
||||
@ -2295,7 +2296,7 @@ export class ApiService implements ApiServiceAbstraction {
|
||||
return fetch(request);
|
||||
}
|
||||
|
||||
async preValidateSso(identifier: string): Promise<boolean> {
|
||||
async preValidateSso(identifier: string): Promise<SsoPreValidateResponse> {
|
||||
if (identifier == null || identifier === "") {
|
||||
throw new Error("Organization Identifier was not provided.");
|
||||
}
|
||||
@ -2318,7 +2319,8 @@ export class ApiService implements ApiServiceAbstraction {
|
||||
);
|
||||
|
||||
if (response.status === 200) {
|
||||
return true;
|
||||
const body = await response.json();
|
||||
return new SsoPreValidateResponse(body);
|
||||
} else {
|
||||
const error = await this.handleError(response, false, true);
|
||||
return Promise.reject(error);
|
||||
|
Loading…
Reference in New Issue
Block a user