mirror of
https://github.com/bitwarden/browser
synced 2026-02-11 22:13:32 +00:00
refactor(email-verification-feature-flag): [PM-7882] Email Verification
Lots of fixes and removal of the register route for signup in a lot of places.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<app-header [noTheme]="true"> </app-header>
|
||||
<app-header [noTheme]="true"></app-header>
|
||||
<div class="center-content">
|
||||
<div class="content login-page">
|
||||
<div class="logo-image"></div>
|
||||
@@ -30,9 +30,9 @@
|
||||
</form>
|
||||
<p class="createAccountLink">
|
||||
{{ "newAroundHere" | i18n }}
|
||||
<a [routerLink]="registerRoute$ | async" (click)="setLoginEmailValues()">{{
|
||||
"createAccount" | i18n
|
||||
}}</a>
|
||||
<a routerLink="/signup" (click)="setLoginEmailValues()">{{
|
||||
"createAccount" | i18n
|
||||
}}</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { Component, OnDestroy, OnInit, ViewChild } from "@angular/core";
|
||||
import { FormBuilder, Validators } from "@angular/forms";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
import { Subject, firstValueFrom, switchMap, takeUntil, tap } from "rxjs";
|
||||
|
||||
import { EnvironmentSelectorComponent } from "@bitwarden/angular/auth/components/environment-selector.component";
|
||||
import { LoginEmailServiceAbstraction, RegisterRouteService } from "@bitwarden/auth/common";
|
||||
import { LoginEmailServiceAbstraction } from "@bitwarden/auth/common";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { ToastService } from "@bitwarden/components";
|
||||
|
||||
import { AccountSwitcherService } from "./account-switching/services/account-switcher.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
|
||||
@Component({
|
||||
selector: "app-home",
|
||||
@@ -30,9 +28,6 @@ export class HomeComponent implements OnInit, OnDestroy {
|
||||
rememberEmail: [false],
|
||||
});
|
||||
|
||||
// TODO: remove when email verification flag is removed
|
||||
registerRoute$ = this.registerRouteService.registerRoute$();
|
||||
|
||||
constructor(
|
||||
protected platformUtilsService: PlatformUtilsService,
|
||||
private formBuilder: FormBuilder,
|
||||
@@ -40,10 +35,10 @@ export class HomeComponent implements OnInit, OnDestroy {
|
||||
private i18nService: I18nService,
|
||||
private loginEmailService: LoginEmailServiceAbstraction,
|
||||
private accountSwitcherService: AccountSwitcherService,
|
||||
private registerRouteService: RegisterRouteService,
|
||||
private toastService: ToastService,
|
||||
private configService: ConfigService,
|
||||
private route: ActivatedRoute,
|
||||
private logService: LogService,
|
||||
) {}
|
||||
|
||||
async ngOnInit(): Promise<void> {
|
||||
@@ -122,6 +117,15 @@ export class HomeComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
async setLoginEmailValues() {
|
||||
if (!this.formGroup.value.rememberEmail || !this.formGroup.value.email) {
|
||||
this.logService.warning(
|
||||
`Failed to setLoginEmailValues due to null value for either:
|
||||
\n\tformGroup.value.rememberEmail: ${this.formGroup.value.rememberEmail}
|
||||
\n\tformGroup.value.email: ${this.formGroup.value.email}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Note: Browser saves email settings here instead of the login component
|
||||
this.loginEmailService.setRememberEmail(this.formGroup.value.rememberEmail);
|
||||
await this.loginEmailService.setLoginEmail(this.formGroup.value.email);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<form #form (ngSubmit)="submit()" [appApiAction]="formPromise" [formGroup]="formGroup">
|
||||
<form #form (ngSubmit)="submitLogin()" [appApiAction]="formPromise" [formGroup]="formGroup">
|
||||
<header>
|
||||
<h1 class="login-center">
|
||||
<span class="title">{{ "logIn" | i18n }}</span>
|
||||
@@ -60,7 +60,7 @@
|
||||
<div class="content login-buttons">
|
||||
<button type="submit" class="btn primary block" [disabled]="form.loading">
|
||||
<span [hidden]="form.loading"
|
||||
><b>{{ "logInWithMasterPassword" | i18n }}</b></span
|
||||
><b>{{ "logInWithMasterPassword" | i18n }}</b></span
|
||||
>
|
||||
<i class="bwi bwi-spinner bwi-lg bwi-spin" [hidden]="!form.loading" aria-hidden="true"></i>
|
||||
</button>
|
||||
|
||||
@@ -10,7 +10,6 @@ import { FormValidationErrorsService } from "@bitwarden/angular/platform/abstrac
|
||||
import {
|
||||
LoginStrategyServiceAbstraction,
|
||||
LoginEmailServiceAbstraction,
|
||||
RegisterRouteService,
|
||||
} from "@bitwarden/auth/common";
|
||||
import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction";
|
||||
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||
@@ -52,7 +51,6 @@ export class LoginComponentV1 extends BaseLoginComponent implements OnInit {
|
||||
loginEmailService: LoginEmailServiceAbstraction,
|
||||
ssoLoginService: SsoLoginServiceAbstraction,
|
||||
webAuthnLoginService: WebAuthnLoginServiceAbstraction,
|
||||
registerRouteService: RegisterRouteService,
|
||||
toastService: ToastService,
|
||||
) {
|
||||
super(
|
||||
@@ -74,7 +72,6 @@ export class LoginComponentV1 extends BaseLoginComponent implements OnInit {
|
||||
loginEmailService,
|
||||
ssoLoginService,
|
||||
webAuthnLoginService,
|
||||
registerRouteService,
|
||||
toastService,
|
||||
);
|
||||
this.onSuccessfulLogin = async () => {
|
||||
|
||||
@@ -607,7 +607,7 @@ const routes: Routes = [
|
||||
children: [
|
||||
{
|
||||
path: "signup",
|
||||
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
||||
canActivate: [unauthGuardFn()],
|
||||
data: {
|
||||
elevation: 1,
|
||||
pageIcon: RegistrationUserAddIcon,
|
||||
@@ -633,7 +633,7 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: "finish-signup",
|
||||
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
||||
canActivate: [unauthGuardFn()],
|
||||
data: {
|
||||
pageIcon: RegistrationLockAltIcon,
|
||||
elevation: 1,
|
||||
@@ -679,7 +679,6 @@ const routes: Routes = [
|
||||
children: [
|
||||
{
|
||||
path: "set-password-jit",
|
||||
canActivate: [canAccessFeature(FeatureFlag.EmailVerification)],
|
||||
component: SetPasswordJitComponent,
|
||||
data: {
|
||||
pageTitle: {
|
||||
|
||||
@@ -304,7 +304,7 @@ const routes: Routes = [
|
||||
children: [
|
||||
{
|
||||
path: "signup",
|
||||
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
||||
canActivate: [unauthGuardFn()],
|
||||
data: {
|
||||
pageIcon: RegistrationUserAddIcon,
|
||||
pageTitle: {
|
||||
@@ -328,7 +328,7 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: "finish-signup",
|
||||
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
||||
canActivate: [unauthGuardFn()],
|
||||
data: {
|
||||
pageIcon: RegistrationLockAltIcon,
|
||||
} satisfies AnonLayoutWrapperData,
|
||||
@@ -358,7 +358,6 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: "set-password-jit",
|
||||
canActivate: [canAccessFeature(FeatureFlag.EmailVerification)],
|
||||
component: SetPasswordJitComponent,
|
||||
data: {
|
||||
pageTitle: {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<form
|
||||
id="login-page"
|
||||
#form
|
||||
(ngSubmit)="submit()"
|
||||
(ngSubmit)="submitLogin()"
|
||||
[appApiAction]="formPromise"
|
||||
[formGroup]="formGroup"
|
||||
attr.aria-hidden="{{ showingModal }}"
|
||||
@@ -50,7 +50,7 @@
|
||||
</div>
|
||||
<div class="sub-options">
|
||||
<p class="no-margin">{{ "newAroundHere" | i18n }}</p>
|
||||
<button type="button" class="text text-primary" [routerLink]="registerRoute$ | async">
|
||||
<button type="button" class="text text-primary" routerLink="/signup">
|
||||
{{ "createAccount" | i18n }}
|
||||
</button>
|
||||
</div>
|
||||
@@ -113,7 +113,7 @@
|
||||
<div class="buttons-row">
|
||||
<button type="submit" class="btn primary block" [disabled]="form.loading">
|
||||
<b [hidden]="form.loading"
|
||||
><i class="bwi bwi-sign-in" aria-hidden="true"></i>
|
||||
><i class="bwi bwi-sign-in" aria-hidden="true"></i>
|
||||
{{ "loginWithMasterPassword" | i18n }}</b
|
||||
>
|
||||
<i class="bwi bwi-spinner bwi-spin" [hidden]="!form.loading" aria-hidden="true"></i>
|
||||
|
||||
@@ -11,7 +11,6 @@ import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||
import {
|
||||
LoginStrategyServiceAbstraction,
|
||||
LoginEmailServiceAbstraction,
|
||||
RegisterRouteService,
|
||||
} from "@bitwarden/auth/common";
|
||||
import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction";
|
||||
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||
@@ -78,7 +77,6 @@ export class LoginComponentV1 extends BaseLoginComponent implements OnInit, OnDe
|
||||
loginEmailService: LoginEmailServiceAbstraction,
|
||||
ssoLoginService: SsoLoginServiceAbstraction,
|
||||
webAuthnLoginService: WebAuthnLoginServiceAbstraction,
|
||||
registerRouteService: RegisterRouteService,
|
||||
toastService: ToastService,
|
||||
private configService: ConfigService,
|
||||
) {
|
||||
@@ -101,7 +99,6 @@ export class LoginComponentV1 extends BaseLoginComponent implements OnInit, OnDe
|
||||
loginEmailService,
|
||||
ssoLoginService,
|
||||
webAuthnLoginService,
|
||||
registerRouteService,
|
||||
toastService,
|
||||
);
|
||||
this.onSuccessfulLogin = () => {
|
||||
@@ -210,7 +207,7 @@ export class LoginComponentV1 extends BaseLoginComponent implements OnInit, OnDe
|
||||
return;
|
||||
}
|
||||
|
||||
await super.submit();
|
||||
await super.submitLogin();
|
||||
if (this.captchaSiteKey) {
|
||||
const content = document.getElementById("content") as HTMLDivElement;
|
||||
content.setAttribute("style", "width:335px");
|
||||
@@ -228,7 +225,7 @@ export class LoginComponentV1 extends BaseLoginComponent implements OnInit, OnDe
|
||||
}
|
||||
|
||||
// Save off email for SSO
|
||||
await this.ssoLoginService.setSsoEmail(this.formGroup.value.email);
|
||||
await this.ssoLoginService.setSsoEmail(this.loggedEmail);
|
||||
|
||||
// Generate necessary sso params
|
||||
const passwordOptions: any = {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { Component, OnDestroy, OnInit, ViewChild } from "@angular/core";
|
||||
import { FormBuilder, Validators } from "@angular/forms";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
@@ -14,7 +12,6 @@ import { OrganizationSponsorshipRedeemRequest } from "@bitwarden/common/admin-co
|
||||
import { PreValidateSponsorshipResponse } from "@bitwarden/common/admin-console/models/response/pre-validate-sponsorship.response";
|
||||
import { PlanSponsorshipType, PlanType, ProductTierType } from "@bitwarden/common/billing/enums";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service";
|
||||
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
||||
import { DialogService, ToastService } from "@bitwarden/components";
|
||||
@@ -48,22 +45,20 @@ export class FamiliesForEnterpriseSetupComponent implements OnInit, OnDestroy {
|
||||
loading = true;
|
||||
badToken = false;
|
||||
|
||||
token: string;
|
||||
existingFamilyOrganizations: Organization[];
|
||||
existingFamilyOrganizations$: Observable<Organization[]>;
|
||||
token!: string;
|
||||
existingFamilyOrganizations$!: Observable<Organization[]>;
|
||||
|
||||
showNewOrganization = false;
|
||||
_organizationPlansComponent: OrganizationPlansComponent;
|
||||
preValidateSponsorshipResponse: PreValidateSponsorshipResponse;
|
||||
preValidateSponsorshipResponse!: PreValidateSponsorshipResponse;
|
||||
_selectedFamilyOrganizationId = "";
|
||||
|
||||
private _destroy = new Subject<void>();
|
||||
formGroup = this.formBuilder.group({
|
||||
selectedFamilyOrganizationId: ["", Validators.required],
|
||||
});
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
private i18nService: I18nService,
|
||||
private route: ActivatedRoute,
|
||||
private apiService: ApiService,
|
||||
@@ -85,7 +80,6 @@ export class FamiliesForEnterpriseSetupComponent implements OnInit, OnDestroy {
|
||||
variant: "error",
|
||||
title: null,
|
||||
message: this.i18nService.t("sponsoredFamiliesAcceptFailed"),
|
||||
timeout: 10000,
|
||||
});
|
||||
// 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
|
||||
@@ -131,7 +125,7 @@ export class FamiliesForEnterpriseSetupComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
});
|
||||
this.formGroup.valueChanges.pipe(takeUntil(this._destroy)).subscribe((val) => {
|
||||
this.selectedFamilyOrganizationId = val.selectedFamilyOrganizationId;
|
||||
this.selectedFamilyOrganizationId = val.selectedFamilyOrganizationId ?? "";
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { Component } from "@angular/core";
|
||||
import { ActivatedRoute, Params, Router } from "@angular/router";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { RegisterRouteService } from "@bitwarden/auth/common";
|
||||
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
@@ -20,9 +16,9 @@ import { EmergencyAccessService } from "../services/emergency-access.service";
|
||||
templateUrl: "accept-emergency.component.html",
|
||||
})
|
||||
export class AcceptEmergencyComponent extends BaseAcceptComponent {
|
||||
name: string;
|
||||
emergencyAccessId: string;
|
||||
acceptEmergencyAccessInviteToken: string;
|
||||
name!: string;
|
||||
emergencyAccessId!: string;
|
||||
acceptEmergencyAccessInviteToken!: string;
|
||||
|
||||
protected requiredParameters: string[] = ["id", "name", "email", "token"];
|
||||
protected failedShortMessage = "emergencyInviteAcceptFailedShort";
|
||||
@@ -34,10 +30,9 @@ export class AcceptEmergencyComponent extends BaseAcceptComponent {
|
||||
i18nService: I18nService,
|
||||
route: ActivatedRoute,
|
||||
authService: AuthService,
|
||||
registerRouteService: RegisterRouteService,
|
||||
private emergencyAccessService: EmergencyAccessService,
|
||||
) {
|
||||
super(router, platformUtilsService, i18nService, route, authService, registerRouteService);
|
||||
super(router, platformUtilsService, i18nService, route, authService);
|
||||
}
|
||||
|
||||
async authedHandler(qParams: Params): Promise<void> {
|
||||
@@ -71,25 +66,12 @@ export class AcceptEmergencyComponent extends BaseAcceptComponent {
|
||||
}
|
||||
|
||||
async register() {
|
||||
let queryParams: Params;
|
||||
let registerRoute = await firstValueFrom(this.registerRoute$);
|
||||
if (registerRoute === "/register") {
|
||||
queryParams = {
|
||||
email: this.email,
|
||||
};
|
||||
} else if (registerRoute === "/signup") {
|
||||
// We have to override the base component route as we don't need users to
|
||||
// complete email verification if they are coming directly an emailed invite.
|
||||
registerRoute = "/finish-signup";
|
||||
queryParams = {
|
||||
await this.router.navigate(["/signup"], {
|
||||
queryParams: {
|
||||
email: this.email,
|
||||
acceptEmergencyAccessInviteToken: this.acceptEmergencyAccessInviteToken,
|
||||
emergencyAccessId: this.emergencyAccessId,
|
||||
};
|
||||
}
|
||||
|
||||
await this.router.navigate([registerRoute], {
|
||||
queryParams: queryParams,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { Component, NgZone, OnInit } from "@angular/core";
|
||||
import { FormBuilder } from "@angular/forms";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
import { firstValueFrom, takeUntil } from "rxjs";
|
||||
import { takeUntil } from "rxjs";
|
||||
import { first } from "rxjs/operators";
|
||||
|
||||
import { LoginComponentV1 as BaseLoginComponent } from "@bitwarden/angular/auth/components/login-v1.component";
|
||||
@@ -11,7 +11,6 @@ import { FormValidationErrorsService } from "@bitwarden/angular/platform/abstrac
|
||||
import {
|
||||
LoginStrategyServiceAbstraction,
|
||||
LoginEmailServiceAbstraction,
|
||||
RegisterRouteService,
|
||||
} from "@bitwarden/auth/common";
|
||||
import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction";
|
||||
import { InternalPolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
@@ -72,7 +71,6 @@ export class LoginComponentV1 extends BaseLoginComponent implements OnInit {
|
||||
loginEmailService: LoginEmailServiceAbstraction,
|
||||
ssoLoginService: SsoLoginServiceAbstraction,
|
||||
webAuthnLoginService: WebAuthnLoginServiceAbstraction,
|
||||
registerRouteService: RegisterRouteService,
|
||||
toastService: ToastService,
|
||||
) {
|
||||
super(
|
||||
@@ -94,7 +92,6 @@ export class LoginComponentV1 extends BaseLoginComponent implements OnInit {
|
||||
loginEmailService,
|
||||
ssoLoginService,
|
||||
webAuthnLoginService,
|
||||
registerRouteService,
|
||||
toastService,
|
||||
);
|
||||
this.onSuccessfulLoginNavigate = this.goAfterLogIn;
|
||||
@@ -105,7 +102,7 @@ export class LoginComponentV1 extends BaseLoginComponent implements OnInit {
|
||||
};
|
||||
|
||||
private async submitFormHelper(showToast: boolean) {
|
||||
await super.submit(showToast);
|
||||
await super.submitLogin(showToast);
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
@@ -178,17 +175,14 @@ export class LoginComponentV1 extends BaseLoginComponent implements OnInit {
|
||||
}
|
||||
|
||||
async goToRegister() {
|
||||
// TODO: remove when email verification flag is removed
|
||||
const registerRoute = await firstValueFrom(this.registerRoute$);
|
||||
|
||||
if (this.emailFormControl.valid) {
|
||||
await this.router.navigate([registerRoute], {
|
||||
await this.router.navigate(["/signup"], {
|
||||
queryParams: { email: this.emailFormControl.value },
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await this.router.navigate([registerRoute]);
|
||||
await this.router.navigate(["/signup"]);
|
||||
}
|
||||
|
||||
protected override async handleMigrateEncryptionKey(result: AuthResult): Promise<boolean> {
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { Component } from "@angular/core";
|
||||
import { ActivatedRoute, Params, Router } from "@angular/router";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { RegisterRouteService } from "@bitwarden/auth/common";
|
||||
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
@@ -13,6 +9,7 @@ import { BaseAcceptComponent } from "../../common/base.accept.component";
|
||||
|
||||
import { AcceptOrganizationInviteService } from "./accept-organization.service";
|
||||
import { OrganizationInvite } from "./organization-invite";
|
||||
import { ToastService } from "@bitwarden/components";
|
||||
|
||||
@Component({
|
||||
templateUrl: "accept-organization.component.html",
|
||||
@@ -27,10 +24,10 @@ export class AcceptOrganizationComponent extends BaseAcceptComponent {
|
||||
i18nService: I18nService,
|
||||
route: ActivatedRoute,
|
||||
authService: AuthService,
|
||||
registerRouteService: RegisterRouteService,
|
||||
private toastService: ToastService,
|
||||
private acceptOrganizationInviteService: AcceptOrganizationInviteService,
|
||||
) {
|
||||
super(router, platformUtilsService, i18nService, route, authService, registerRouteService);
|
||||
super(router, platformUtilsService, i18nService, route, authService);
|
||||
}
|
||||
|
||||
async authedHandler(qParams: Params): Promise<void> {
|
||||
@@ -41,20 +38,20 @@ export class AcceptOrganizationComponent extends BaseAcceptComponent {
|
||||
return;
|
||||
}
|
||||
|
||||
this.platformUtilService.showToast(
|
||||
"success",
|
||||
this.i18nService.t("inviteAccepted"),
|
||||
invite.initOrganization
|
||||
this.toastService.showToast({
|
||||
variant: "success",
|
||||
title: this.i18nService.t("inviteAccepted"),
|
||||
message: invite.initOrganization
|
||||
? this.i18nService.t("inviteInitAcceptedDesc")
|
||||
: this.i18nService.t("inviteAcceptedDesc"),
|
||||
{ timeout: 10000 },
|
||||
);
|
||||
});
|
||||
|
||||
await this.router.navigate(["/vault"]);
|
||||
}
|
||||
|
||||
async unauthedHandler(qParams: Params): Promise<void> {
|
||||
const invite = OrganizationInvite.fromParams(qParams);
|
||||
|
||||
await this.acceptOrganizationInviteService.setOrganizationInvitation(invite);
|
||||
await this.accelerateInviteAcceptIfPossible(invite);
|
||||
}
|
||||
@@ -92,25 +89,10 @@ export class AcceptOrganizationComponent extends BaseAcceptComponent {
|
||||
// if SSO is disabled OR if sso is enabled but the SSO login required policy is not enabled
|
||||
// then send user to create account
|
||||
|
||||
// TODO: update logic when email verification flag is removed
|
||||
let queryParams: Params;
|
||||
let registerRoute = await firstValueFrom(this.registerRoute$);
|
||||
if (registerRoute === "/register") {
|
||||
queryParams = {
|
||||
fromOrgInvite: "true",
|
||||
await this.router.navigate(["/signup"], {
|
||||
queryParams: {
|
||||
email: invite.email,
|
||||
};
|
||||
} else if (registerRoute === "/signup") {
|
||||
// We have to override the base component route as we don't need users to complete email verification
|
||||
// if they are coming directly from an emailed org invite.
|
||||
registerRoute = "/finish-signup";
|
||||
queryParams = {
|
||||
email: invite.email,
|
||||
};
|
||||
}
|
||||
|
||||
await this.router.navigate([registerRoute], {
|
||||
queryParams: queryParams,
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,10 @@ export class OrganizationInvite {
|
||||
return Object.assign(new OrganizationInvite(), json);
|
||||
}
|
||||
|
||||
static fromParams(params: Params): OrganizationInvite | null {
|
||||
static fromParams(params: Params | null): OrganizationInvite {
|
||||
// Conversation topic:
|
||||
// What if the query parameters we passed in are null? How do we outwardly communicate
|
||||
// that this happened?
|
||||
if (params == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -100,7 +100,6 @@ export class AdjustStorageDialogComponent {
|
||||
variant: "warning",
|
||||
title: null,
|
||||
message: this.i18nService.t("couldNotChargeCardPayInvoice"),
|
||||
timeout: 10000,
|
||||
});
|
||||
// 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
|
||||
|
||||
@@ -1,30 +1,25 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { Directive, OnInit } from "@angular/core";
|
||||
import { ActivatedRoute, Params, Router } from "@angular/router";
|
||||
import { Subject, firstValueFrom } from "rxjs";
|
||||
import { first, switchMap, takeUntil } from "rxjs/operators";
|
||||
|
||||
import { RegisterRouteService } from "@bitwarden/auth/common";
|
||||
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { ToastService } from "@bitwarden/components";
|
||||
|
||||
@Directive()
|
||||
export abstract class BaseAcceptComponent implements OnInit {
|
||||
loading = true;
|
||||
authed = false;
|
||||
email: string;
|
||||
actionPromise: Promise<any>;
|
||||
email!: string;
|
||||
actionPromise!: Promise<any>;
|
||||
|
||||
protected requiredParameters: string[] = [];
|
||||
protected failedShortMessage = "inviteAcceptFailedShort";
|
||||
protected failedMessage = "inviteAcceptFailed";
|
||||
|
||||
// TODO: remove when email verification flag is removed
|
||||
registerRoute$ = this.registerRouteService.registerRoute$();
|
||||
|
||||
private destroy$ = new Subject<void>();
|
||||
|
||||
constructor(
|
||||
@@ -33,10 +28,11 @@ export abstract class BaseAcceptComponent implements OnInit {
|
||||
protected i18nService: I18nService,
|
||||
protected route: ActivatedRoute,
|
||||
protected authService: AuthService,
|
||||
protected registerRouteService: RegisterRouteService,
|
||||
protected toastService: ToastService,
|
||||
) {}
|
||||
|
||||
abstract authedHandler(qParams: Params): Promise<void>;
|
||||
|
||||
abstract unauthedHandler(qParams: Params): Promise<void>;
|
||||
|
||||
async ngOnInit() {
|
||||
@@ -47,7 +43,7 @@ export abstract class BaseAcceptComponent implements OnInit {
|
||||
let error = this.requiredParameters.some(
|
||||
(e) => qParams?.[e] == null || qParams[e] === "",
|
||||
);
|
||||
let errorMessage: string = null;
|
||||
let errorMessage: string | null = null;
|
||||
if (!error) {
|
||||
this.email = qParams.email;
|
||||
|
||||
@@ -55,7 +51,7 @@ export abstract class BaseAcceptComponent implements OnInit {
|
||||
if (status !== AuthenticationStatus.LoggedOut) {
|
||||
try {
|
||||
await this.authedHandler(qParams);
|
||||
} catch (e) {
|
||||
} catch (e: { message: string } | any) {
|
||||
error = true;
|
||||
errorMessage = e.message;
|
||||
}
|
||||
@@ -69,7 +65,13 @@ export abstract class BaseAcceptComponent implements OnInit {
|
||||
errorMessage != null
|
||||
? this.i18nService.t(this.failedShortMessage, errorMessage)
|
||||
: this.i18nService.t(this.failedMessage);
|
||||
this.platformUtilService.showToast("error", null, message, { timeout: 10000 });
|
||||
|
||||
this.toastService.showToast({
|
||||
variant: "error",
|
||||
title: null,
|
||||
message,
|
||||
});
|
||||
|
||||
// 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(["/"]);
|
||||
|
||||
@@ -111,10 +111,7 @@ const routes: Routes = [
|
||||
{
|
||||
path: "register",
|
||||
component: TrialInitiationComponent,
|
||||
canActivate: [
|
||||
canAccessFeature(FeatureFlag.EmailVerification, false, "/signup", false),
|
||||
unauthGuardFn(),
|
||||
],
|
||||
canActivate: [unauthGuardFn()],
|
||||
data: { titleId: "createAccount" } satisfies RouteDataProperties,
|
||||
},
|
||||
{
|
||||
@@ -343,7 +340,7 @@ const routes: Routes = [
|
||||
children: [
|
||||
{
|
||||
path: "signup",
|
||||
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
||||
canActivate: [unauthGuardFn()],
|
||||
data: {
|
||||
pageIcon: RegistrationUserAddIcon,
|
||||
pageTitle: {
|
||||
@@ -368,7 +365,7 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: "finish-signup",
|
||||
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
||||
canActivate: [unauthGuardFn()],
|
||||
data: {
|
||||
pageIcon: RegistrationLockAltIcon,
|
||||
titleId: "setAStrongPassword",
|
||||
@@ -402,7 +399,6 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: "set-password-jit",
|
||||
canActivate: [canAccessFeature(FeatureFlag.EmailVerification)],
|
||||
component: SetPasswordJitComponent,
|
||||
data: {
|
||||
pageTitle: {
|
||||
@@ -415,7 +411,7 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: "signup-link-expired",
|
||||
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
||||
canActivate: [unauthGuardFn()],
|
||||
data: {
|
||||
pageIcon: RegistrationExpiredLinkIcon,
|
||||
pageTitle: {
|
||||
@@ -673,7 +669,7 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: "trial-initiation",
|
||||
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
||||
canActivate: [unauthGuardFn()],
|
||||
component: CompleteTrialInitiationComponent,
|
||||
resolve: {
|
||||
pageTitle: freeTrialTextResolver,
|
||||
@@ -684,7 +680,7 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: "secrets-manager-trial-initiation",
|
||||
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
||||
canActivate: [unauthGuardFn()],
|
||||
component: CompleteTrialInitiationComponent,
|
||||
resolve: {
|
||||
pageTitle: freeTrialTextResolver,
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { FormBuilder } from "@angular/forms";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
|
||||
import { AnonLayoutWrapperDataService } from "@bitwarden/auth/angular";
|
||||
import { RegisterRouteService } from "@bitwarden/auth/common";
|
||||
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
@@ -43,26 +39,23 @@ import { SendAccessTextComponent } from "./send-access-text.component";
|
||||
})
|
||||
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
|
||||
export class AccessComponent implements OnInit {
|
||||
protected send: SendAccessView;
|
||||
protected send!: SendAccessView;
|
||||
protected sendType = SendType;
|
||||
protected loading = true;
|
||||
protected passwordRequired = false;
|
||||
protected formPromise: Promise<SendAccessResponse>;
|
||||
protected password: string;
|
||||
protected formPromise!: Promise<SendAccessResponse>;
|
||||
protected password!: string;
|
||||
protected unavailable = false;
|
||||
protected error = false;
|
||||
protected hideEmail = false;
|
||||
protected decKey: SymmetricCryptoKey;
|
||||
protected accessRequest: SendAccessRequest;
|
||||
protected decKey!: SymmetricCryptoKey;
|
||||
protected accessRequest!: SendAccessRequest;
|
||||
protected expiredSendIcon = ExpiredSendIcon;
|
||||
|
||||
protected formGroup = this.formBuilder.group({});
|
||||
|
||||
// TODO: remove when email verification flag is removed
|
||||
registerRoute$ = this.registerRouteService.registerRoute$();
|
||||
|
||||
private id: string;
|
||||
private key: string;
|
||||
private id!: string;
|
||||
private key!: string;
|
||||
|
||||
constructor(
|
||||
private cryptoFunctionService: CryptoFunctionService,
|
||||
@@ -71,8 +64,6 @@ export class AccessComponent implements OnInit {
|
||||
private sendApiService: SendApiService,
|
||||
private toastService: ToastService,
|
||||
private i18nService: I18nService,
|
||||
private configService: ConfigService,
|
||||
private registerRouteService: RegisterRouteService,
|
||||
private layoutWrapperDataService: AnonLayoutWrapperDataService,
|
||||
protected formBuilder: FormBuilder,
|
||||
) {}
|
||||
@@ -119,7 +110,7 @@ export class AccessComponent implements OnInit {
|
||||
);
|
||||
this.accessRequest.password = Utils.fromBufferToB64(passwordHash);
|
||||
}
|
||||
let sendResponse: SendAccessResponse = null;
|
||||
let sendResponse: SendAccessResponse;
|
||||
if (this.loading) {
|
||||
sendResponse = await this.sendApiService.postSendAccess(this.id, this.accessRequest);
|
||||
} else {
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
href="https://www.bitwarden.com/products/send?source=web-vault"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>Bitwarden Send</a
|
||||
>Bitwarden Send</a
|
||||
>
|
||||
{{ "sendAccessTaglineOr" | i18n }}
|
||||
<a bitLink [routerLink]="registerRoute$ | async" target="_blank" rel="noreferrer">{{
|
||||
"sendAccessTaglineSignUp" | i18n
|
||||
}}</a>
|
||||
<a bitLink routerLink="/signup" target="_blank" rel="noreferrer">{{
|
||||
"sendAccessTaglineSignUp" | i18n
|
||||
}}</a>
|
||||
{{ "sendAccessTaglineTryToday" | i18n }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { Component } from "@angular/core";
|
||||
|
||||
import { RegisterRouteService } from "@bitwarden/auth/common";
|
||||
|
||||
import { SharedModule } from "../../shared";
|
||||
|
||||
@Component({
|
||||
@@ -11,7 +9,5 @@ import { SharedModule } from "../../shared";
|
||||
imports: [SharedModule],
|
||||
})
|
||||
export class SendAccessExplainerComponent {
|
||||
// TODO: remove when email verification flag is removed
|
||||
registerRoute$ = this.registerRouteService.registerRoute$();
|
||||
constructor(private registerRouteService: RegisterRouteService) {}
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,23 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { Component } from "@angular/core";
|
||||
import { ActivatedRoute, Params, Router } from "@angular/router";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { RegisterRouteService } from "@bitwarden/auth/common";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { ProviderUserAcceptRequest } from "@bitwarden/common/admin-console/models/request/provider/provider-user-accept.request";
|
||||
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { BaseAcceptComponent } from "@bitwarden/web-vault/app/common/base.accept.component";
|
||||
import { ToastService } from "@bitwarden/components";
|
||||
|
||||
@Component({
|
||||
selector: "app-accept-provider",
|
||||
templateUrl: "accept-provider.component.html",
|
||||
})
|
||||
export class AcceptProviderComponent extends BaseAcceptComponent {
|
||||
providerName: string;
|
||||
providerId: string;
|
||||
providerUserId: string;
|
||||
providerInviteToken: string;
|
||||
providerName!: string;
|
||||
providerId!: string;
|
||||
providerUserId!: string;
|
||||
providerInviteToken!: string;
|
||||
|
||||
failedMessage = "providerInviteAcceptFailed";
|
||||
|
||||
@@ -32,10 +29,10 @@ export class AcceptProviderComponent extends BaseAcceptComponent {
|
||||
route: ActivatedRoute,
|
||||
authService: AuthService,
|
||||
private apiService: ApiService,
|
||||
private toastService: ToastService,
|
||||
platformUtilService: PlatformUtilsService,
|
||||
registerRouteService: RegisterRouteService,
|
||||
) {
|
||||
super(router, platformUtilService, i18nService, route, authService, registerRouteService);
|
||||
super(router, platformUtilService, i18nService, route, authService);
|
||||
}
|
||||
|
||||
async authedHandler(qParams: Params) {
|
||||
@@ -47,12 +44,13 @@ export class AcceptProviderComponent extends BaseAcceptComponent {
|
||||
qParams.providerUserId,
|
||||
request,
|
||||
);
|
||||
this.platformUtilService.showToast(
|
||||
"success",
|
||||
this.i18nService.t("inviteAccepted"),
|
||||
this.i18nService.t("providerInviteAcceptedDesc"),
|
||||
{ timeout: 10000 },
|
||||
);
|
||||
|
||||
this.toastService.showToast({
|
||||
variant: "success",
|
||||
title: this.i18nService.t("inviteAccepted"),
|
||||
message: this.i18nService.t("providerInviteAcceptedDesc"),
|
||||
});
|
||||
|
||||
this.router.navigate(["/vault"]);
|
||||
}
|
||||
|
||||
@@ -64,25 +62,12 @@ export class AcceptProviderComponent extends BaseAcceptComponent {
|
||||
}
|
||||
|
||||
async register() {
|
||||
let queryParams: Params;
|
||||
let registerRoute = await firstValueFrom(this.registerRoute$);
|
||||
if (registerRoute === "/register") {
|
||||
queryParams = {
|
||||
email: this.email,
|
||||
};
|
||||
} else if (registerRoute === "/signup") {
|
||||
// We have to override the base component route as we don't need users to
|
||||
// complete email verification if they are coming directly an emailed invite.
|
||||
registerRoute = "/finish-signup";
|
||||
queryParams = {
|
||||
await this.router.navigate(["/signup"], {
|
||||
queryParams: {
|
||||
email: this.email,
|
||||
providerUserId: this.providerUserId,
|
||||
providerInviteToken: this.providerInviteToken,
|
||||
};
|
||||
}
|
||||
|
||||
await this.router.navigate([registerRoute], {
|
||||
queryParams: queryParams,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { Directive, ElementRef, NgZone, OnDestroy, OnInit, ViewChild } from "@angular/core";
|
||||
import { FormBuilder, Validators } from "@angular/forms";
|
||||
import { ActivatedRoute, NavigationSkipped, Router } from "@angular/router";
|
||||
@@ -10,11 +8,9 @@ import {
|
||||
LoginStrategyServiceAbstraction,
|
||||
LoginEmailServiceAbstraction,
|
||||
PasswordLoginCredentials,
|
||||
RegisterRouteService,
|
||||
} from "@bitwarden/auth/common";
|
||||
import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction";
|
||||
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||
import { WebAuthnLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login.service.abstraction";
|
||||
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||
@@ -38,17 +34,17 @@ import { CaptchaProtectedComponent } from "./captcha-protected.component";
|
||||
|
||||
@Directive()
|
||||
export class LoginComponentV1 extends CaptchaProtectedComponent implements OnInit, OnDestroy {
|
||||
@ViewChild("masterPasswordInput", { static: true }) masterPasswordInput: ElementRef;
|
||||
@ViewChild("masterPasswordInput", { static: true }) masterPasswordInput!: ElementRef;
|
||||
|
||||
showPassword = false;
|
||||
formPromise: Promise<AuthResult>;
|
||||
formPromise!: Promise<AuthResult>;
|
||||
|
||||
onSuccessfulLogin: () => Promise<any>;
|
||||
onSuccessfulLoginNavigate: (userId: UserId) => Promise<any>;
|
||||
onSuccessfulLoginTwoFactorNavigate: () => Promise<any>;
|
||||
onSuccessfulLoginForceResetNavigate: () => Promise<any>;
|
||||
onSuccessfulLogin!: () => Promise<any>;
|
||||
onSuccessfulLoginNavigate!: (userId: UserId) => Promise<any>;
|
||||
onSuccessfulLoginTwoFactorNavigate!: () => Promise<any>;
|
||||
onSuccessfulLoginForceResetNavigate!: () => Promise<any>;
|
||||
|
||||
showLoginWithDevice: boolean;
|
||||
showLoginWithDevice!: boolean;
|
||||
validatedEmail = false;
|
||||
paramEmailSet = false;
|
||||
|
||||
@@ -56,7 +52,7 @@ export class LoginComponentV1 extends CaptchaProtectedComponent implements OnIni
|
||||
return this.formGroup.controls.email;
|
||||
}
|
||||
|
||||
formGroup = this.formBuilder.group({
|
||||
formGroup = this.formBuilder.nonNullable.group({
|
||||
email: ["", [Validators.required, Validators.email]],
|
||||
masterPassword: [
|
||||
"",
|
||||
@@ -67,16 +63,10 @@ export class LoginComponentV1 extends CaptchaProtectedComponent implements OnIni
|
||||
|
||||
protected twoFactorRoute = "2fa";
|
||||
protected successRoute = "vault";
|
||||
// TODO: remove when email verification flag is removed
|
||||
protected registerRoute$ = this.registerRouteService.registerRoute$();
|
||||
protected forcePasswordResetRoute = "update-temp-password";
|
||||
|
||||
protected destroy$ = new Subject<void>();
|
||||
|
||||
get loggedEmail() {
|
||||
return this.formGroup.value.email;
|
||||
}
|
||||
|
||||
constructor(
|
||||
protected devicesApiService: DevicesApiServiceAbstraction,
|
||||
protected appIdService: AppIdService,
|
||||
@@ -95,8 +85,6 @@ export class LoginComponentV1 extends CaptchaProtectedComponent implements OnIni
|
||||
protected route: ActivatedRoute,
|
||||
protected loginEmailService: LoginEmailServiceAbstraction,
|
||||
protected ssoLoginService: SsoLoginServiceAbstraction,
|
||||
protected webAuthnLoginService: WebAuthnLoginServiceAbstraction,
|
||||
protected registerRouteService: RegisterRouteService,
|
||||
protected toastService: ToastService,
|
||||
) {
|
||||
super(environmentService, i18nService, platformUtilsService, toastService);
|
||||
@@ -145,9 +133,7 @@ export class LoginComponentV1 extends CaptchaProtectedComponent implements OnIni
|
||||
this.destroy$.complete();
|
||||
}
|
||||
|
||||
async submit(showToast = true) {
|
||||
const data = this.formGroup.value;
|
||||
|
||||
async submitLogin(showToast = true) {
|
||||
await this.setupCaptcha();
|
||||
|
||||
this.formGroup.markAllAsTouched();
|
||||
@@ -170,10 +156,10 @@ export class LoginComponentV1 extends CaptchaProtectedComponent implements OnIni
|
||||
|
||||
try {
|
||||
const credentials = new PasswordLoginCredentials(
|
||||
data.email,
|
||||
data.masterPassword,
|
||||
this.formGroup.controls.email.value,
|
||||
this.formGroup.controls.masterPassword.value,
|
||||
this.captchaToken,
|
||||
null,
|
||||
undefined,
|
||||
);
|
||||
|
||||
this.formPromise = this.loginStrategyService.logIn(credentials);
|
||||
@@ -231,12 +217,16 @@ export class LoginComponentV1 extends CaptchaProtectedComponent implements OnIni
|
||||
|
||||
togglePassword() {
|
||||
this.showPassword = !this.showPassword;
|
||||
if (this.ngZone.isStable) {
|
||||
document.getElementById("masterPassword").focus();
|
||||
const masterPasswordElement = document.getElementById("masterPassword");
|
||||
|
||||
if (masterPasswordElement) {
|
||||
if (this.ngZone.isStable) {
|
||||
masterPasswordElement.focus();
|
||||
} else {
|
||||
this.ngZone.onStable.pipe(take(1)).subscribe(() => masterPasswordElement.focus());
|
||||
}
|
||||
} else {
|
||||
this.ngZone.onStable
|
||||
.pipe(take(1))
|
||||
.subscribe(() => document.getElementById("masterPassword").focus());
|
||||
this.logService.warning("Element with ID 'masterPassword' not found.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +244,7 @@ export class LoginComponentV1 extends CaptchaProtectedComponent implements OnIni
|
||||
|
||||
async launchSsoBrowser(clientId: string, ssoRedirectUri: string) {
|
||||
// Save off email for SSO
|
||||
await this.ssoLoginService.setSsoEmail(this.formGroup.value.email);
|
||||
await this.ssoLoginService.setSsoEmail(this.formGroup.controls.email.value);
|
||||
|
||||
// Generate necessary sso params
|
||||
const passwordOptions: any = {
|
||||
@@ -295,12 +285,20 @@ export class LoginComponentV1 extends CaptchaProtectedComponent implements OnIni
|
||||
}
|
||||
|
||||
async validateEmail() {
|
||||
const email = this.formGroup.get("email");
|
||||
if (!email) {
|
||||
this.logService.warning(
|
||||
`No email in form group when attempting to ${this.validateEmail.name}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
this.formGroup.controls.email.markAsTouched();
|
||||
const emailValid = this.formGroup.get("email").valid;
|
||||
const emailValid = email.valid;
|
||||
|
||||
if (emailValid) {
|
||||
this.toggleValidateEmail(true);
|
||||
await this.getLoginWithDevice(this.loggedEmail);
|
||||
await this.getLoginWithDevice(this.formGroup.controls["email"].value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,8 +345,8 @@ export class LoginComponentV1 extends CaptchaProtectedComponent implements OnIni
|
||||
}
|
||||
|
||||
protected async saveEmailSettings() {
|
||||
this.loginEmailService.setLoginEmail(this.formGroup.value.email);
|
||||
this.loginEmailService.setRememberEmail(this.formGroup.value.rememberEmail);
|
||||
this.loginEmailService.setLoginEmail(this.formGroup.controls["email"].value);
|
||||
this.loginEmailService.setRememberEmail(this.formGroup.controls["rememberEmail"].value);
|
||||
await this.loginEmailService.saveEmailSettings();
|
||||
}
|
||||
|
||||
@@ -366,8 +364,8 @@ export class LoginComponentV1 extends CaptchaProtectedComponent implements OnIni
|
||||
return true;
|
||||
}
|
||||
|
||||
private getErrorToastMessage() {
|
||||
const error: AllValidationErrors = this.formValidationErrorService
|
||||
private getErrorToastMessage(): string {
|
||||
const error: AllValidationErrors | undefined = this.formValidationErrorService
|
||||
.getFormValidationErrors(this.formGroup.controls)
|
||||
.shift();
|
||||
|
||||
@@ -380,9 +378,12 @@ export class LoginComponentV1 extends CaptchaProtectedComponent implements OnIni
|
||||
default:
|
||||
return this.i18nService.t(this.errorTag(error));
|
||||
}
|
||||
} else {
|
||||
this.logService.warning(
|
||||
"formValidationErrorService produced no errors even when the form is invalid.",
|
||||
);
|
||||
return this.i18nService.t("errorOccurred");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
private errorTag(error: AllValidationErrors): string {
|
||||
|
||||
@@ -339,17 +339,9 @@ export class SsoComponent implements OnInit {
|
||||
}
|
||||
|
||||
private async handleChangePasswordRequired(orgIdentifier: string) {
|
||||
const emailVerification = await this.configService.getFeatureFlag(
|
||||
FeatureFlag.EmailVerification,
|
||||
);
|
||||
|
||||
if (emailVerification) {
|
||||
this.changePasswordRoute = "set-password-jit";
|
||||
}
|
||||
|
||||
await this.navigateViaCallbackOrRoute(
|
||||
this.onSuccessfulLoginChangePasswordNavigate,
|
||||
[this.changePasswordRoute],
|
||||
["set-password-jit"],
|
||||
{
|
||||
queryParams: {
|
||||
identifier: orgIdentifier,
|
||||
|
||||
@@ -481,16 +481,7 @@ export class SsoComponent implements OnInit {
|
||||
}
|
||||
|
||||
private async handleChangePasswordRequired(orgIdentifier: string) {
|
||||
const emailVerification = await this.configService.getFeatureFlag(
|
||||
FeatureFlag.EmailVerification,
|
||||
);
|
||||
|
||||
let route = "set-password";
|
||||
if (emailVerification) {
|
||||
route = "set-password-jit";
|
||||
}
|
||||
|
||||
await this.router.navigate([route], {
|
||||
await this.router.navigate(["set-password-jit"], {
|
||||
queryParams: {
|
||||
identifier: orgIdentifier,
|
||||
},
|
||||
|
||||
@@ -45,7 +45,7 @@ export class ToastComponent {
|
||||
message: string | string[];
|
||||
|
||||
/** An optional title to display over the message. */
|
||||
@Input() title: string;
|
||||
@Input() title: string | null;
|
||||
|
||||
/**
|
||||
* The percent width of the progress bar, from 0-100
|
||||
|
||||
@@ -20,6 +20,15 @@ export type ToastOptions = {
|
||||
export class ToastService {
|
||||
constructor(private toastrService: ToastrService) {}
|
||||
|
||||
/**
|
||||
* This will present the toast to a user.
|
||||
*
|
||||
* Note: The toast will be displayed for a minimum of 5 seconds if no timeout is provided in
|
||||
* the options.
|
||||
*
|
||||
* @param options Options for toasts. If no timeout is specified an appropriate duration will be
|
||||
* calculated on the size of the message being displayed.
|
||||
*/
|
||||
showToast(options: ToastOptions): void {
|
||||
const toastrConfig: Partial<IndividualConfig> = {
|
||||
payload: {
|
||||
|
||||
Reference in New Issue
Block a user