diff --git a/apps/web/src/app/auth/core/services/login/web-login.service.ts b/apps/web/src/app/auth/core/services/login/web-login.service.ts index d4a80b6de4..35c3558116 100644 --- a/apps/web/src/app/auth/core/services/login/web-login.service.ts +++ b/apps/web/src/app/auth/core/services/login/web-login.service.ts @@ -1,3 +1,21 @@ +import { inject } from "@angular/core"; +import { UrlTree } from "@angular/router"; + import { DefaultLoginService, LoginService } from "@bitwarden/auth/angular"; -export class WebLoginService extends DefaultLoginService implements LoginService {} +import { RouterService } from "../../../../core/router.service"; + +export class WebLoginService extends DefaultLoginService implements LoginService { + routerService = inject(RouterService); + + setPreviousUrl(route: UrlTree): void | null { + this.routerService.setPreviousUrl(route.toString()); + } + + async handleExistingOrgInvite(): Promise { + const orgInvite = await this.acceptOrganizationInviteService.getOrganizationInvite(); + if (orgInvite != null) { + await this.initPasswordPolicies(orgInvite); + } + } +} diff --git a/apps/web/src/app/auth/login/login.component.ts b/apps/web/src/app/auth/login/login.component.ts index 890ef713a3..4daa87d22c 100644 --- a/apps/web/src/app/auth/login/login.component.ts +++ b/apps/web/src/app/auth/login/login.component.ts @@ -127,6 +127,7 @@ export class LoginComponent extends BaseLoginComponent implements OnInit { }); this.routerService.setPreviousUrl(route.toString()); } + await super.ngOnInit(); }); diff --git a/libs/auth/src/angular/login/default-login.service.ts b/libs/auth/src/angular/login/default-login.service.ts index cf7514e60b..b6f17736a0 100644 --- a/libs/auth/src/angular/login/default-login.service.ts +++ b/libs/auth/src/angular/login/default-login.service.ts @@ -1,3 +1,13 @@ +import { UrlTree } from "@angular/router"; + import { LoginService } from "./login.service"; -export class DefaultLoginService implements LoginService {} +export class DefaultLoginService implements LoginService { + setPreviousUrl(route: UrlTree): void | null { + return null; + } + + async handleExistingOrgInvite(): Promise { + return null; + } +} diff --git a/libs/auth/src/angular/login/login.component.ts b/libs/auth/src/angular/login/login.component.ts index 18377392e4..40c27bbbaf 100644 --- a/libs/auth/src/angular/login/login.component.ts +++ b/libs/auth/src/angular/login/login.component.ts @@ -1,11 +1,13 @@ import { CommonModule } from "@angular/common"; import { Component, OnInit } from "@angular/core"; import { FormBuilder, ReactiveFormsModule, Validators } from "@angular/forms"; -import { ActivatedRoute, RouterModule } from "@angular/router"; -import { firstValueFrom, Subject, takeUntil } from "rxjs"; +import { ActivatedRoute, Router, RouterModule } from "@angular/router"; +import { first, firstValueFrom, Subject, takeUntil } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { LoginEmailServiceAbstraction } from "@bitwarden/auth/common"; +import { ClientType } from "@bitwarden/common/enums"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { AsyncActionsModule, ButtonModule, @@ -30,7 +32,9 @@ import { LoginService } from "./login.service"; ], }) export class LoginComponentV2 implements OnInit { - protected formGroup = this.formBuilder.group({ + clientType: ClientType; + + formGroup = this.formBuilder.group({ email: ["", [Validators.required, Validators.email]], rememberEmail: [false], }); @@ -42,9 +46,17 @@ export class LoginComponentV2 implements OnInit { private formBuilder: FormBuilder, private loginEmailService: LoginEmailServiceAbstraction, private loginService: LoginService, + private platformUtilsService: PlatformUtilsService, + private router: Router, ) {} async ngOnInit(): Promise { + this.clientType = this.platformUtilsService.getClientType(); + + if (this.clientType === ClientType.Web) { + await this.webOnInit(); + } + let paramEmailIsSet = false; this.activatedRoute.queryParams.pipe(takeUntil(this.destroy$)).subscribe((params) => { @@ -63,6 +75,8 @@ export class LoginComponentV2 implements OnInit { if (!paramEmailIsSet) { await this.loadEmailSettings(); } + // If there's an existing org invite, use it to get the password policies + await this.loginService.handleExistingOrgInvite(); } submit = async () => {}; @@ -87,4 +101,28 @@ export class LoginComponentV2 implements OnInit { } } } + + private async webOnInit(): Promise { + this.activatedRoute.queryParams.pipe(first(), takeUntil(this.destroy$)).subscribe((qParams) => { + // If there is an query parameter called 'org', set previousUrl to `/create-organization?org=paramValue` + if (qParams.org != null) { + const route = this.router.createUrlTree(["create-organization"], { + queryParams: { plan: qParams.org }, + }); + this.loginService.setPreviousUrl(route); + } + + /** + * If there is a query parameter called 'sponsorshipToken', that means they are coming + * from an email for sponsoring a families organization. If so, then set the prevousUrl + * to `/setup/families-for-enterprise?token=paramValue` + */ + if (qParams.sponsorshipToken != null) { + const route = this.router.createUrlTree(["setup/families-for-enterprise"], { + queryParams: { token: qParams.sponsorshipToken }, + }); + this.loginService.setPreviousUrl(route); + } + }); + } } diff --git a/libs/auth/src/angular/login/login.service.ts b/libs/auth/src/angular/login/login.service.ts index 22796fce47..1eb18a4675 100644 --- a/libs/auth/src/angular/login/login.service.ts +++ b/libs/auth/src/angular/login/login.service.ts @@ -1 +1,7 @@ -export abstract class LoginService {} +import { UrlTree } from "@angular/router"; + +export abstract class LoginService { + // Web specific + setPreviousUrl: (route: UrlTree) => void | null; + handleExistingOrgInvite: () => Promise; +}