From 9e6d0cce35196a53c9305820333dc701207d9280 Mon Sep 17 00:00:00 2001 From: rr-bw <102181210+rr-bw@users.noreply.github.com> Date: Wed, 19 Nov 2025 19:00:18 -0800 Subject: [PATCH] feat(marketing-initiated-premium): Auth [PM-27542] Write fromMarketing value to state (#17470) --- .../registration-finish.component.ts | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/libs/auth/src/angular/registration/registration-finish/registration-finish.component.ts b/libs/auth/src/angular/registration/registration-finish/registration-finish.component.ts index 7e7b9131fa..19e7c1feab 100644 --- a/libs/auth/src/angular/registration/registration-finish/registration-finish.component.ts +++ b/libs/auth/src/angular/registration/registration-finish/registration-finish.component.ts @@ -5,6 +5,7 @@ import { Component, OnDestroy, OnInit } from "@angular/core"; import { ActivatedRoute, Params, Router, RouterModule } from "@angular/router"; import { Subject, firstValueFrom } from "rxjs"; +import { PremiumInterestStateService } from "@bitwarden/angular/billing/services/premium-interest/premium-interest-state.service.abstraction"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; import { AccountApiService } from "@bitwarden/common/auth/abstractions/account-api.service"; @@ -31,6 +32,12 @@ import { PasswordInputResult } from "../../input-password/password-input-result" import { RegistrationFinishService } from "./registration-finish.service"; +const MarketingInitiative = Object.freeze({ + Premium: "premium", +} as const); + +type MarketingInitiative = (typeof MarketingInitiative)[keyof typeof MarketingInitiative]; + // FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ @@ -46,6 +53,12 @@ export class RegistrationFinishComponent implements OnInit, OnDestroy { submitting = false; email: string; + /** + * Indicates that the user is coming from a marketing page designed to streamline + * users who intend to setup a premium subscription after registration. + */ + premiumInterest = false; + // Note: this token is the email verification token. When it is supplied as a query param, // it either comes from the email verification email or, if email verification is disabled server side // via global settings, it comes directly from the registration-start component directly. @@ -79,6 +92,7 @@ export class RegistrationFinishComponent implements OnInit, OnDestroy { private logService: LogService, private anonLayoutWrapperDataService: AnonLayoutWrapperDataService, private loginSuccessHandlerService: LoginSuccessHandlerService, + private premiumInterestStateService: PremiumInterestStateService, ) {} async ngOnInit() { @@ -126,6 +140,10 @@ export class RegistrationFinishComponent implements OnInit, OnDestroy { this.providerInviteToken = qParams.providerInviteToken; this.providerUserId = qParams.providerUserId; } + + if (qParams.fromMarketing != null && qParams.fromMarketing === MarketingInitiative.Premium) { + this.premiumInterest = true; + } } private async initOrgInviteFlowIfPresent(): Promise { @@ -190,6 +208,13 @@ export class RegistrationFinishComponent implements OnInit, OnDestroy { await this.loginSuccessHandlerService.run(authenticationResult.userId); + if (this.premiumInterest) { + await this.premiumInterestStateService.setPremiumInterest( + authenticationResult.userId, + true, + ); + } + await this.router.navigate(["/vault"]); } catch (e) { // If login errors, redirect to login page per product. Don't show error