1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-07 04:03:29 +00:00

fix(change-password-component): Change Password Update [18720] - Split up org invite service into client specific implementations and have them injected into clients properly

This commit is contained in:
Patrick Pimentel
2025-06-23 15:34:24 -04:00
parent 2d882436e7
commit c3ff1413e9
19 changed files with 118 additions and 19 deletions

View File

@@ -49,6 +49,8 @@ import {
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
import { DefaultOrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/default-organization-invite.service";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite.service";
import {
AutofillSettingsService,
AutofillSettingsServiceAbstraction,
@@ -543,6 +545,11 @@ const safeProviders: SafeProvider[] = [
provide: CLIENT_TYPE,
useValue: ClientType.Browser,
}),
safeProvider({
provide: OrganizationInviteService,
useClass: DefaultOrganizationInviteService,
deps: [],
}),
safeProvider({
provide: LockComponentService,
useClass: ExtensionLockComponentService,

View File

@@ -49,6 +49,8 @@ import {
} from "@bitwarden/common/auth/abstractions/auth.service";
import { MasterPasswordApiService } from "@bitwarden/common/auth/abstractions/master-password-api.service.abstraction";
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
import { DefaultOrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/default-organization-invite.service";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite.service";
import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service";
import { ClientType } from "@bitwarden/common/enums";
import { ProcessReloadServiceAbstraction } from "@bitwarden/common/key-management/abstractions/process-reload.service";
@@ -376,6 +378,11 @@ const safeProviders: SafeProvider[] = [
provide: CLIENT_TYPE,
useValue: ClientType.Desktop,
}),
safeProvider({
provide: OrganizationInviteService,
useValue: DefaultOrganizationInviteService,
deps: [],
}),
safeProvider({
provide: SetPasswordJitService,
useClass: DesktopSetPasswordJitService,

View File

@@ -4,7 +4,7 @@ import {
LoginDecryptionOptionsService,
DefaultLoginDecryptionOptionsService,
} from "@bitwarden/auth/angular";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite-service";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite.service";
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
import { RouterService } from "../../../../core/router.service";

View File

@@ -16,7 +16,7 @@ import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
import { getUserId } from "@bitwarden/common/auth/services/account.service";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite-service";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite.service";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";

View File

@@ -10,7 +10,7 @@ import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/mod
import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
import { AccountApiService } from "@bitwarden/common/auth/abstractions/account-api.service";
import { OrganizationInvite } from "@bitwarden/common/auth/services/organization-invite/organization-invite";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite-service";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";

View File

@@ -13,7 +13,7 @@ import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/mod
import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
import { AccountApiService } from "@bitwarden/common/auth/abstractions/account-api.service";
import { RegisterFinishRequest } from "@bitwarden/common/auth/models/request/registration/register-finish.request";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite-service";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { EncryptedString, EncString } from "@bitwarden/common/platform/models/domain/enc-string";
import { KeyService } from "@bitwarden/key-management";

View File

@@ -9,7 +9,7 @@ import {
import { InternalUserDecryptionOptionsServiceAbstraction } from "@bitwarden/auth/common";
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction";
import { MasterPasswordApiService } from "@bitwarden/common/auth/abstractions/master-password-api.service.abstraction";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite-service";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite.service";
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";

View File

@@ -5,7 +5,7 @@ import { ActivatedRoute, Params, Router } from "@angular/router";
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { OrganizationInvite } from "@bitwarden/common/auth/services/organization-invite/organization-invite";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite-service";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";

View File

@@ -16,8 +16,8 @@ import { OrganizationKeysResponse } from "@bitwarden/common/admin-console/models
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { OrganizationInvite } from "@bitwarden/common/auth/services/organization-invite/organization-invite";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite-service";
import { ORGANIZATION_INVITE } from "@bitwarden/common/auth/services/organization-invite/organization-invite-state";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite.service";
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { Utils } from "@bitwarden/common/platform/misc/utils";

View File

@@ -18,7 +18,7 @@ import { OrganizationKeysRequest } from "@bitwarden/common/admin-console/models/
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { OrganizationInvite } from "@bitwarden/common/auth/services/organization-invite/organization-invite";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite-service";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite.service";
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
@@ -26,6 +26,11 @@ import { Utils } from "@bitwarden/common/platform/misc/utils";
import { OrgKey } from "@bitwarden/common/types/key";
import { KeyService } from "@bitwarden/key-management";
/**
* We'd like to consolidate the feature service and the organization-invite.service.ts. There should
* be a default-organization-invite.service.ts and a web-organization-invite.service which this
* file could be.
*/
@Injectable()
export class AcceptOrganizationInviteService {
private orgNameSubject: BehaviorSubject<string> = new BehaviorSubject<string>(null);

View File

@@ -1,7 +1,7 @@
import { Component, inject } from "@angular/core";
import { SetPasswordComponent as BaseSetPasswordComponent } from "@bitwarden/angular/auth/components/set-password.component";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite-service";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite.service";
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
import { MasterKey, UserKey } from "@bitwarden/common/types/key";

View File

@@ -1,7 +1,7 @@
import { Component, inject } from "@angular/core";
import { UpdatePasswordComponent as BaseUpdatePasswordComponent } from "@bitwarden/angular/auth/components/update-password.component";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite-service";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite.service";
import { RouterService } from "../core";

View File

@@ -18,7 +18,7 @@ import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/mod
import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { getUserId } from "@bitwarden/common/auth/services/account.service";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite-service";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite.service";
import {
OrganizationBillingServiceAbstraction as OrganizationBillingService,
OrganizationInformation,

View File

@@ -51,7 +51,8 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { MasterPasswordApiService } from "@bitwarden/common/auth/abstractions/master-password-api.service.abstraction";
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite-service";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite.service";
import { WebOrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/web-organization-invite.service";
import { ClientType } from "@bitwarden/common/enums";
import { ProcessReloadServiceAbstraction } from "@bitwarden/common/key-management/abstractions/process-reload.service";
import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service";
@@ -244,6 +245,11 @@ const safeProviders: SafeProvider[] = [
provide: CLIENT_TYPE,
useValue: ClientType.Web,
}),
safeProvider({
provide: OrganizationInviteService,
useClass: WebOrganizationInviteService,
deps: [GlobalStateProvider],
}),
safeProvider({
provide: RegistrationFinishServiceAbstraction,
useClass: WebRegistrationFinishService,

View File

@@ -1,10 +1,12 @@
import { Component, Input, OnInit } from "@angular/core";
import { firstValueFrom } from "rxjs";
import { MasterPasswordPolicyServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/master-password-policy.service.abstraction";
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options";
import { Account, AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite.service";
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
@@ -58,7 +60,9 @@ export class ChangePasswordComponent implements OnInit {
private changePasswordService: ChangePasswordService,
private i18nService: I18nService,
private masterPasswordService: InternalMasterPasswordServiceAbstraction,
private masterPasswordPolicyOptionsService: MasterPasswordPolicyServiceAbstraction,
private anonLayoutWrapperDataService: AnonLayoutWrapperDataService,
private organizationInviteService: OrganizationInviteService,
private messagingService: MessagingService,
private policyService: PolicyService,
private toastService: ToastService,
@@ -81,7 +85,6 @@ export class ChangePasswordComponent implements OnInit {
throw new Error("userId not found");
}
// New Master Password Policy Options service
// this.masterPasswordPolicyOptions = await firstValueFrom(
// this.policyService.postAuthenticatedMasterPasswordPolicyOptions$(this.userId)
// ) ?? undefined;
@@ -90,6 +93,30 @@ export class ChangePasswordComponent implements OnInit {
this.masterPasswordService.forceSetPasswordReason$(this.userId),
);
// New Master Password Policy Options service
const orgInvite = await this.organizationInviteService.getOrganizationInvite();
switch (this.forceSetPasswordReason) {
case ForceSetPasswordReason.WeakMasterPassword:
if (orgInvite) {
if (!orgInvite.token) {
this.logService.error("No org token found when trying to retrieve policies.");
return;
}
this.masterPasswordPolicyOptions =
await this.masterPasswordPolicyOptionsService.getForInvitedMember(orgInvite.token);
} else {
this.masterPasswordPolicyOptions =
await this.masterPasswordPolicyOptionsService.getByUserId(this.userId);
}
break;
case ForceSetPasswordReason.AdminForcePasswordReset:
default:
this.masterPasswordPolicyOptions =
await this.masterPasswordPolicyOptionsService.getByUserId(this.userId);
break;
}
if (this.forceSetPasswordReason === ForceSetPasswordReason.AdminForcePasswordReset) {
this.anonLayoutWrapperDataService.setAnonLayoutWrapperData({
pageIcon: LockIcon,

View File

@@ -6,12 +6,12 @@ export abstract class MasterPasswordPolicyServiceAbstraction {
* Used for a logged-in user is changing their password. Would probably be deprecated once
* PolicyService is refactored.
*/
abstract getForLoggedInUser: (currentUserId: UserId) => MasterPasswordPolicyOptions;
abstract getByUserId: (loggedInUserId: UserId) => Promise<MasterPasswordPolicyOptions>;
/**
* Used to evaluate compliance before accepting an invite.
*/
abstract getForInvitedMember: (inviteToken: string) => MasterPasswordPolicyOptions;
abstract getForInvitedMember: (inviteToken: string) => Promise<MasterPasswordPolicyOptions>;
/**
* Used when resetting a grantor's password during an emergency access takeover.
@@ -21,8 +21,8 @@ export abstract class MasterPasswordPolicyServiceAbstraction {
/**
* Used when resetting a member's password during an account recovery. Gets the master
* password policy options for the user who is having their account reset. This makes sure
* that an admin is keeping the user in compliance with the user's whose password
* they are setting and not using the policies that they are apart of.
* that an admin is keeping the user in compliance with the users whose password
* they are setting and not using the policies that they are a part of.
*/
abstract getForAccountRecoveryMember: (userId: UserId) => MasterPasswordPolicyOptions;
abstract getForAccountRecoveryMember: (userId: UserId) => Promise<MasterPasswordPolicyOptions>;
}

View File

@@ -0,0 +1,26 @@
import { OrganizationInvite } from "@bitwarden/common/auth/services/organization-invite/organization-invite";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite.service";
export class DefaultOrganizationInviteService implements OrganizationInviteService {
/**
* No-op implementation.
*/
async getOrganizationInvite(): Promise<OrganizationInvite | null> {
return null;
}
/**
* No-op implementation.
* @param invite an organization invite
*/
async setOrganizationInvitation(invite: OrganizationInvite): Promise<void> {
return;
}
/**
* No-op implementation.
* */
async clearOrganizationInvitation(): Promise<void> {
return;
}
}

View File

@@ -0,0 +1,20 @@
import { OrganizationInvite } from "@bitwarden/common/auth/services/organization-invite/organization-invite";
export abstract class OrganizationInviteService {
/**
* Returns the currently stored organization invite
*/
abstract getOrganizationInvite: () => Promise<OrganizationInvite | null>;
/**
* Stores a new organization invite
* @param invite an organization invite
* @throws if the invite is nullish
*/
abstract setOrganizationInvitation: (invite: OrganizationInvite) => Promise<void>;
/**
* Clears the currently stored organization invite
*/
abstract clearOrganizationInvitation: () => Promise<void>;
}

View File

@@ -2,9 +2,10 @@ import { firstValueFrom } from "rxjs";
import { OrganizationInvite } from "@bitwarden/common/auth/services/organization-invite/organization-invite";
import { ORGANIZATION_INVITE } from "@bitwarden/common/auth/services/organization-invite/organization-invite-state";
import { OrganizationInviteService } from "@bitwarden/common/auth/services/organization-invite/organization-invite.service";
import { GlobalState, GlobalStateProvider } from "@bitwarden/common/platform/state";
export class OrganizationInviteService {
export class WebOrganizationInviteService implements OrganizationInviteService {
private organizationInvitationState: GlobalState<OrganizationInvite | null>;
constructor(private readonly globalStateProvider: GlobalStateProvider) {