1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-18 09:13:33 +00:00

[PM-17751] Store SSO email in state on web client (#13295)

* Moved saving of SSO email outside of browser/desktop code

* Clarified comments.

* Tests

* Refactored login component services to manage state

* Fixed input on login component

* Fixed tests

* Linting

* Moved web setting in state into web override

* updated tests

* Fixed typing.

* Fixed type safety issues.

* Added comments and renamed for clarity.

* Removed method parameters that weren't used

* Added clarifying comments

* Added more comments.

* Removed test that is not necessary on base

* Test cleanup

* More comments.

* Linting

* Fixed test.

* Fixed base URL

* Fixed typechecking.

* Type checking

* Moved setting of email state to default service

* Added comments.

* Consolidated SSO URL formatting

* Updated comment

* Fixed reference.

* Fixed missing parameter.

* Initialized service.

* Added comments

* Added initialization of new service

* Made email optional due to CLI.

* Fixed comment on handleSsoClick.

* Added SSO email persistence to v1 component.

---------

Co-authored-by: Bernd Schoolmann <mail@quexten.com>
This commit is contained in:
Todd Martin
2025-02-21 17:09:50 -05:00
committed by GitHub
parent 9dd2033081
commit 077e0f89cc
26 changed files with 534 additions and 245 deletions

View File

@@ -1,6 +1,7 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { Injectable } from "@angular/core";
import { Router } from "@angular/router";
import { firstValueFrom } from "rxjs";
import {
@@ -37,6 +38,7 @@ export class WebLoginComponentService
passwordGenerationService: PasswordGenerationServiceAbstraction,
platformUtilsService: PlatformUtilsService,
ssoLoginService: SsoLoginServiceAbstraction,
private router: Router,
) {
super(
cryptoFunctionService,
@@ -45,7 +47,20 @@ export class WebLoginComponentService
platformUtilsService,
ssoLoginService,
);
this.clientType = this.platformUtilsService.getClientType();
}
/**
* For the web client, redirecting to the SSO component is done via the router.
* We do not need to provide email, state, or code challenge since those are set in state
* or generated on the SSO component.
*/
protected override async redirectToSso(
email: string,
state: string,
codeChallenge: string,
): Promise<void> {
await this.router.navigate(["/sso"]);
return;
}
async getOrgPoliciesFromOrgInvite(): Promise<PasswordPolicies | null> {

View File

@@ -295,6 +295,7 @@ const safeProviders: SafeProvider[] = [
PasswordGenerationServiceAbstraction,
PlatformUtilsService,
SsoLoginServiceAbstraction,
Router,
],
}),
safeProvider({

View File

@@ -16,17 +16,21 @@ window.addEventListener("load", () => {
} else if (state != null && state.includes(":clientId=browser")) {
initiateBrowserSso(code, state, false);
} else {
window.location.href = window.location.origin + "/#/sso?code=" + code + "&state=" + state;
// Match any characters between "_returnUri='" and the next "'"
const returnUri = extractFromRegex(state, "(?<=_returnUri=')(.*)(?=')");
if (returnUri) {
window.location.href = window.location.origin + `/#${returnUri}`;
} else {
window.location.href = window.location.origin + "/#/sso?code=" + code + "&state=" + state;
}
initiateWebAppSso(code, state);
}
});
function initiateWebAppSso(code: string, state: string) {
// If we've initiated SSO from somewhere other than the SSO component on the web app, the SSO component will add
// a _returnUri to the state variable. Here we're extracting that URI and sending the user there instead of to the SSO component.
const returnUri = extractFromRegex(state, "(?<=_returnUri=')(.*)(?=')");
if (returnUri) {
window.location.href = window.location.origin + `/#${returnUri}`;
} else {
window.location.href = window.location.origin + "/#/sso?code=" + code + "&state=" + state;
}
}
function initiateBrowserSso(code: string, state: string, lastpass: boolean) {
window.postMessage({ command: "authResult", code: code, state: state, lastpass: lastpass }, "*");
const handOffMessage = ("; " + document.cookie)