mirror of
https://github.com/bitwarden/browser.git
synced 2025-04-13 19:58:00 +02:00
Refactor environment service to emit a single observable. This required significant changes to how the environment service behaves and tackles much of the tech debt planned for it.
141 lines
5.6 KiB
TypeScript
141 lines
5.6 KiB
TypeScript
import { Component, NgZone } from "@angular/core";
|
|
import { FormBuilder } from "@angular/forms";
|
|
import { ActivatedRoute, Router } from "@angular/router";
|
|
import { firstValueFrom } from "rxjs";
|
|
|
|
import { LoginComponent as BaseLoginComponent } from "@bitwarden/angular/auth/components/login.component";
|
|
import { FormValidationErrorsService } from "@bitwarden/angular/platform/abstractions/form-validation-errors.service";
|
|
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
|
import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction";
|
|
import { LoginService } from "@bitwarden/common/auth/abstractions/login.service";
|
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
|
import { WebAuthnLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login.service.abstraction";
|
|
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
|
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
|
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
|
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
|
import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password";
|
|
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
|
|
|
import { flagEnabled } from "../../platform/flags";
|
|
|
|
@Component({
|
|
selector: "app-login",
|
|
templateUrl: "login.component.html",
|
|
})
|
|
export class LoginComponent extends BaseLoginComponent {
|
|
showPasswordless = false;
|
|
constructor(
|
|
devicesApiService: DevicesApiServiceAbstraction,
|
|
appIdService: AppIdService,
|
|
loginStrategyService: LoginStrategyServiceAbstraction,
|
|
router: Router,
|
|
protected platformUtilsService: PlatformUtilsService,
|
|
protected i18nService: I18nService,
|
|
protected stateService: StateService,
|
|
protected environmentService: EnvironmentService,
|
|
protected passwordGenerationService: PasswordGenerationServiceAbstraction,
|
|
protected cryptoFunctionService: CryptoFunctionService,
|
|
syncService: SyncService,
|
|
logService: LogService,
|
|
ngZone: NgZone,
|
|
formBuilder: FormBuilder,
|
|
formValidationErrorService: FormValidationErrorsService,
|
|
route: ActivatedRoute,
|
|
loginService: LoginService,
|
|
ssoLoginService: SsoLoginServiceAbstraction,
|
|
webAuthnLoginService: WebAuthnLoginServiceAbstraction,
|
|
) {
|
|
super(
|
|
devicesApiService,
|
|
appIdService,
|
|
loginStrategyService,
|
|
router,
|
|
platformUtilsService,
|
|
i18nService,
|
|
stateService,
|
|
environmentService,
|
|
passwordGenerationService,
|
|
cryptoFunctionService,
|
|
logService,
|
|
ngZone,
|
|
formBuilder,
|
|
formValidationErrorService,
|
|
route,
|
|
loginService,
|
|
ssoLoginService,
|
|
webAuthnLoginService,
|
|
);
|
|
super.onSuccessfulLogin = async () => {
|
|
await syncService.fullSync(true);
|
|
};
|
|
super.successRoute = "/tabs/vault";
|
|
this.showPasswordless = flagEnabled("showPasswordless");
|
|
|
|
if (this.showPasswordless) {
|
|
this.formGroup.controls.email.setValue(this.loginService.getEmail());
|
|
this.formGroup.controls.rememberEmail.setValue(this.loginService.getRememberEmail());
|
|
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
this.validateEmail();
|
|
}
|
|
}
|
|
|
|
settings() {
|
|
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
this.router.navigate(["environment"]);
|
|
}
|
|
|
|
async launchSsoBrowser() {
|
|
// Save off email for SSO
|
|
await this.ssoLoginService.setSsoEmail(this.formGroup.value.email);
|
|
await this.loginService.saveEmailSettings();
|
|
// Generate necessary sso params
|
|
const passwordOptions: any = {
|
|
type: "password",
|
|
length: 64,
|
|
uppercase: true,
|
|
lowercase: true,
|
|
numbers: true,
|
|
special: false,
|
|
};
|
|
|
|
const state =
|
|
(await this.passwordGenerationService.generatePassword(passwordOptions)) +
|
|
":clientId=browser";
|
|
const codeVerifier = await this.passwordGenerationService.generatePassword(passwordOptions);
|
|
const codeVerifierHash = await this.cryptoFunctionService.hash(codeVerifier, "sha256");
|
|
const codeChallenge = Utils.fromBufferToUrlB64(codeVerifierHash);
|
|
|
|
await this.ssoLoginService.setCodeVerifier(codeVerifier);
|
|
await this.ssoLoginService.setSsoState(state);
|
|
|
|
const env = await firstValueFrom(this.environmentService.environment$);
|
|
let url = env.getWebVaultUrl();
|
|
if (url == null) {
|
|
url = "https://vault.bitwarden.com";
|
|
}
|
|
|
|
const redirectUri = url + "/sso-connector.html";
|
|
|
|
// Launch browser
|
|
this.platformUtilsService.launchUri(
|
|
url +
|
|
"/#/sso?clientId=browser" +
|
|
"&redirectUri=" +
|
|
encodeURIComponent(redirectUri) +
|
|
"&state=" +
|
|
state +
|
|
"&codeChallenge=" +
|
|
codeChallenge +
|
|
"&email=" +
|
|
encodeURIComponent(this.formGroup.controls.email.value),
|
|
);
|
|
}
|
|
}
|