mirror of
https://github.com/bitwarden/browser
synced 2025-12-14 07:13:32 +00:00
[PM-18566] Wire up vNextPolicyService for Clients (#13678)
* wire up vNext impl * wire up vNextPolicyService for browser * wire up vNextPolicyService for desktop * wire up vNextPolicyService for cli * fix test * fix missed caller * cleanup * fix missing property assignment * fix QA bug for PM-19205 * fix QA bug for PM-19206 * fix QA bug for pm-19228 * cleanup
This commit is contained in:
@@ -99,7 +99,7 @@ describe("AccountSecurityComponent", () => {
|
||||
|
||||
it("pin enabled when RemoveUnlockWithPin policy is not set", async () => {
|
||||
// @ts-strict-ignore
|
||||
policyService.get$.mockReturnValue(of(null));
|
||||
policyService.policiesByType$.mockReturnValue(of([null]));
|
||||
|
||||
await component.ngOnInit();
|
||||
|
||||
@@ -111,7 +111,7 @@ describe("AccountSecurityComponent", () => {
|
||||
policy.type = PolicyType.RemoveUnlockWithPin;
|
||||
policy.enabled = false;
|
||||
|
||||
policyService.get$.mockReturnValue(of(policy));
|
||||
policyService.policiesByType$.mockReturnValue(of([policy]));
|
||||
|
||||
await component.ngOnInit();
|
||||
|
||||
@@ -129,7 +129,7 @@ describe("AccountSecurityComponent", () => {
|
||||
policy.type = PolicyType.RemoveUnlockWithPin;
|
||||
policy.enabled = true;
|
||||
|
||||
policyService.get$.mockReturnValue(of(policy));
|
||||
policyService.policiesByType$.mockReturnValue(of([policy]));
|
||||
|
||||
await component.ngOnInit();
|
||||
|
||||
@@ -143,7 +143,7 @@ describe("AccountSecurityComponent", () => {
|
||||
|
||||
it("pin visible when RemoveUnlockWithPin policy is not set", async () => {
|
||||
// @ts-strict-ignore
|
||||
policyService.get$.mockReturnValue(of(null));
|
||||
policyService.policiesByType$.mockReturnValue(of([null]));
|
||||
|
||||
await component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
@@ -158,7 +158,7 @@ describe("AccountSecurityComponent", () => {
|
||||
policy.type = PolicyType.RemoveUnlockWithPin;
|
||||
policy.enabled = false;
|
||||
|
||||
policyService.get$.mockReturnValue(of(policy));
|
||||
policyService.policiesByType$.mockReturnValue(of([policy]));
|
||||
|
||||
await component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
@@ -173,7 +173,7 @@ describe("AccountSecurityComponent", () => {
|
||||
policy.type = PolicyType.RemoveUnlockWithPin;
|
||||
policy.enabled = true;
|
||||
|
||||
policyService.get$.mockReturnValue(of(policy));
|
||||
policyService.policiesByType$.mockReturnValue(of([policy]));
|
||||
|
||||
pinServiceAbstraction.isPinSet.mockResolvedValue(true);
|
||||
|
||||
@@ -190,7 +190,7 @@ describe("AccountSecurityComponent", () => {
|
||||
policy.type = PolicyType.RemoveUnlockWithPin;
|
||||
policy.enabled = true;
|
||||
|
||||
policyService.get$.mockReturnValue(of(policy));
|
||||
policyService.policiesByType$.mockReturnValue(of([policy]));
|
||||
|
||||
await component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
|
||||
@@ -27,8 +27,10 @@ import { FingerprintDialogComponent, VaultTimeoutInputComponent } from "@bitward
|
||||
import { PinServiceAbstraction } from "@bitwarden/auth/common";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { getFirstPolicy } from "@bitwarden/common/admin-console/services/policy/default-policy.service";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { DeviceType } from "@bitwarden/common/enums";
|
||||
import {
|
||||
VaultTimeout,
|
||||
@@ -152,8 +154,14 @@ export class AccountSecurityComponent implements OnInit, OnDestroy {
|
||||
|
||||
const hasMasterPassword = await this.userVerificationService.hasMasterPassword();
|
||||
this.showMasterPasswordOnClientRestartOption = hasMasterPassword;
|
||||
const maximumVaultTimeoutPolicy = this.policyService.get$(PolicyType.MaximumVaultTimeout);
|
||||
if ((await firstValueFrom(this.policyService.get$(PolicyType.MaximumVaultTimeout))) != null) {
|
||||
const maximumVaultTimeoutPolicy = this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.policiesByType$(PolicyType.MaximumVaultTimeout, userId),
|
||||
),
|
||||
getFirstPolicy,
|
||||
);
|
||||
if ((await firstValueFrom(maximumVaultTimeoutPolicy)) != null) {
|
||||
this.hasVaultTimeoutPolicy = true;
|
||||
}
|
||||
|
||||
@@ -195,7 +203,12 @@ export class AccountSecurityComponent implements OnInit, OnDestroy {
|
||||
timeout = VaultTimeoutStringType.OnRestart;
|
||||
}
|
||||
|
||||
this.pinEnabled$ = this.policyService.get$(PolicyType.RemoveUnlockWithPin).pipe(
|
||||
this.pinEnabled$ = this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.policiesByType$(PolicyType.RemoveUnlockWithPin, userId),
|
||||
),
|
||||
getFirstPolicy,
|
||||
map((policy) => {
|
||||
return policy == null || !policy.enabled;
|
||||
}),
|
||||
|
||||
@@ -8,6 +8,9 @@ import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authenticatio
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/spec";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
|
||||
import { BrowserApi } from "../../platform/browser/browser-api";
|
||||
import { ScriptInjectorService } from "../../platform/services/abstractions/script-injector.service";
|
||||
@@ -35,10 +38,12 @@ describe("AutoSubmitLoginBackground", () => {
|
||||
let configService: MockProxy<ConfigService>;
|
||||
let platformUtilsService: MockProxy<PlatformUtilsService>;
|
||||
let policyDetails: MockProxy<Policy>;
|
||||
let automaticAppLogInPolicy$: BehaviorSubject<Policy>;
|
||||
let policyAppliesToActiveUser$: BehaviorSubject<boolean>;
|
||||
let automaticAppLogInPolicy$: BehaviorSubject<Policy[]>;
|
||||
let policyAppliesToUser$: BehaviorSubject<boolean>;
|
||||
let policyService: MockProxy<PolicyService>;
|
||||
let autoSubmitLoginBackground: AutoSubmitLoginBackground;
|
||||
let accountService: FakeAccountService;
|
||||
const mockUserId = Utils.newGuid() as UserId;
|
||||
const validIpdUrl1 = "https://example.com";
|
||||
const validIpdUrl2 = "https://subdomain.example3.com";
|
||||
const validAutoSubmitHost = "some-valid-url.com";
|
||||
@@ -61,12 +66,13 @@ describe("AutoSubmitLoginBackground", () => {
|
||||
idpHost: `${validIpdUrl1} , https://example2.com/some/sub-route ,${validIpdUrl2}, [invalidValue] ,,`,
|
||||
},
|
||||
});
|
||||
automaticAppLogInPolicy$ = new BehaviorSubject<Policy>(policyDetails);
|
||||
policyAppliesToActiveUser$ = new BehaviorSubject<boolean>(true);
|
||||
automaticAppLogInPolicy$ = new BehaviorSubject<Policy[]>([policyDetails]);
|
||||
policyAppliesToUser$ = new BehaviorSubject<boolean>(true);
|
||||
policyService = mock<PolicyService>({
|
||||
get$: jest.fn().mockReturnValue(automaticAppLogInPolicy$),
|
||||
policyAppliesToActiveUser$: jest.fn().mockReturnValue(policyAppliesToActiveUser$),
|
||||
policiesByType$: jest.fn().mockReturnValue(automaticAppLogInPolicy$),
|
||||
policyAppliesToUser$: jest.fn().mockReturnValue(policyAppliesToUser$),
|
||||
});
|
||||
accountService = mockAccountServiceWith(mockUserId);
|
||||
autoSubmitLoginBackground = new AutoSubmitLoginBackground(
|
||||
logService,
|
||||
autofillService,
|
||||
@@ -75,6 +81,7 @@ describe("AutoSubmitLoginBackground", () => {
|
||||
configService,
|
||||
platformUtilsService,
|
||||
policyService,
|
||||
accountService,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -84,7 +91,7 @@ describe("AutoSubmitLoginBackground", () => {
|
||||
|
||||
describe("when the AutoSubmitLoginBackground feature is disabled", () => {
|
||||
it("destroys all event listeners when the AutomaticAppLogIn policy is not enabled", async () => {
|
||||
automaticAppLogInPolicy$.next(mock<Policy>({ ...policyDetails, enabled: false }));
|
||||
automaticAppLogInPolicy$.next([mock<Policy>({ ...policyDetails, enabled: false })]);
|
||||
|
||||
await autoSubmitLoginBackground.init();
|
||||
|
||||
@@ -92,7 +99,7 @@ describe("AutoSubmitLoginBackground", () => {
|
||||
});
|
||||
|
||||
it("destroys all event listeners when the AutomaticAppLogIn policy does not apply to the current user", async () => {
|
||||
policyAppliesToActiveUser$.next(false);
|
||||
policyAppliesToUser$.next(false);
|
||||
|
||||
await autoSubmitLoginBackground.init();
|
||||
|
||||
@@ -100,7 +107,7 @@ describe("AutoSubmitLoginBackground", () => {
|
||||
});
|
||||
|
||||
it("destroys all event listeners when the idpHost is not specified in the AutomaticAppLogIn policy", async () => {
|
||||
automaticAppLogInPolicy$.next(mock<Policy>({ ...policyDetails, data: { idpHost: "" } }));
|
||||
automaticAppLogInPolicy$.next([mock<Policy>({ ...policyDetails, data: { idpHost: "" } })]);
|
||||
|
||||
await autoSubmitLoginBackground.init();
|
||||
|
||||
@@ -264,6 +271,7 @@ describe("AutoSubmitLoginBackground", () => {
|
||||
configService,
|
||||
platformUtilsService,
|
||||
policyService,
|
||||
accountService,
|
||||
);
|
||||
jest.spyOn(BrowserApi, "getTabFromCurrentWindow").mockResolvedValue(tab);
|
||||
});
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { firstValueFrom } from "rxjs";
|
||||
import { firstValueFrom, switchMap } from "rxjs";
|
||||
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
|
||||
import { getFirstPolicy } from "@bitwarden/common/admin-console/services/policy/default-policy.service";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
@@ -42,6 +45,7 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr
|
||||
private configService: ConfigService,
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
private policyService: PolicyService,
|
||||
private accountService: AccountService,
|
||||
) {
|
||||
this.isSafariBrowser = this.platformUtilsService.isSafari();
|
||||
}
|
||||
@@ -56,8 +60,14 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr
|
||||
FeatureFlag.IdpAutoSubmitLogin,
|
||||
);
|
||||
if (featureFlagEnabled) {
|
||||
this.policyService
|
||||
.get$(PolicyType.AutomaticAppLogIn)
|
||||
this.accountService.activeAccount$
|
||||
.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.policiesByType$(PolicyType.AutomaticAppLogIn, userId),
|
||||
),
|
||||
getFirstPolicy,
|
||||
)
|
||||
.subscribe(this.handleAutoSubmitLoginPolicySubscription.bind(this));
|
||||
}
|
||||
}
|
||||
@@ -86,7 +96,12 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr
|
||||
*/
|
||||
private applyPolicyToActiveUser = async (policy: Policy) => {
|
||||
const policyAppliesToUser = await firstValueFrom(
|
||||
this.policyService.policyAppliesToActiveUser$(PolicyType.AutomaticAppLogIn),
|
||||
this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.policyAppliesToUser$(PolicyType.AutomaticAppLogIn, userId),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if (!policyAppliesToUser) {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { mock, MockProxy } from "jest-mock-extended";
|
||||
import { BehaviorSubject, firstValueFrom } from "rxjs";
|
||||
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/services/policy/policy.service";
|
||||
import { DefaultPolicyService } from "@bitwarden/common/admin-console/services/policy/default-policy.service";
|
||||
import { AccountInfo, AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||
import { AuthService } from "@bitwarden/common/auth/services/auth.service";
|
||||
@@ -51,7 +51,7 @@ describe("NotificationBackground", () => {
|
||||
const cipherService = mock<CipherService>();
|
||||
let activeAccountStatusMock$: BehaviorSubject<AuthenticationStatus>;
|
||||
let authService: MockProxy<AuthService>;
|
||||
const policyService = mock<PolicyService>();
|
||||
const policyService = mock<DefaultPolicyService>();
|
||||
const folderService = mock<FolderService>();
|
||||
const userNotificationSettingsService = mock<UserNotificationSettingsService>();
|
||||
const domainSettingsService = mock<DomainSettingsService>();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { firstValueFrom } from "rxjs";
|
||||
import { firstValueFrom, switchMap } from "rxjs";
|
||||
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
@@ -8,7 +8,7 @@ import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||
import { getOptionalUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { getOptionalUserId, getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import {
|
||||
ExtensionCommand,
|
||||
ExtensionCommandType,
|
||||
@@ -743,7 +743,12 @@ export default class NotificationBackground {
|
||||
|
||||
private async removeIndividualVault(): Promise<boolean> {
|
||||
return await firstValueFrom(
|
||||
this.policyService.policyAppliesToActiveUser$(PolicyType.PersonalOwnership),
|
||||
this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.policyAppliesToUser$(PolicyType.PersonalOwnership, userId),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abs
|
||||
import { InternalPolicyService as InternalPolicyServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { ProviderService as ProviderServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/provider.service";
|
||||
import { DefaultOrganizationService } from "@bitwarden/common/admin-console/services/organization/default-organization.service";
|
||||
import { DefaultPolicyService } from "@bitwarden/common/admin-console/services/policy/default-policy.service";
|
||||
import { PolicyApiService } from "@bitwarden/common/admin-console/services/policy/policy-api.service";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/services/policy/policy.service";
|
||||
import { ProviderService } from "@bitwarden/common/admin-console/services/provider.service";
|
||||
import { AccountService as AccountServiceAbstraction } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { AuthService as AuthServiceAbstraction } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||
@@ -685,7 +685,7 @@ export default class MainBackground {
|
||||
|
||||
this.userDecryptionOptionsService = new UserDecryptionOptionsService(this.stateProvider);
|
||||
this.organizationService = new DefaultOrganizationService(this.stateProvider);
|
||||
this.policyService = new PolicyService(this.stateProvider, this.organizationService);
|
||||
this.policyService = new DefaultPolicyService(this.stateProvider, this.organizationService);
|
||||
|
||||
this.vaultTimeoutSettingsService = new DefaultVaultTimeoutSettingsService(
|
||||
this.accountService,
|
||||
@@ -728,9 +728,14 @@ export default class MainBackground {
|
||||
this.autofillSettingsService = new AutofillSettingsService(
|
||||
this.stateProvider,
|
||||
this.policyService,
|
||||
this.accountService,
|
||||
);
|
||||
this.badgeSettingsService = new BadgeSettingsService(this.stateProvider);
|
||||
this.policyApiService = new PolicyApiService(this.policyService, this.apiService);
|
||||
this.policyApiService = new PolicyApiService(
|
||||
this.policyService,
|
||||
this.apiService,
|
||||
this.accountService,
|
||||
);
|
||||
this.keyConnectorService = new KeyConnectorService(
|
||||
this.accountService,
|
||||
this.masterPasswordService,
|
||||
@@ -1202,6 +1207,7 @@ export default class MainBackground {
|
||||
this.configService,
|
||||
this.platformUtilsService,
|
||||
this.policyService,
|
||||
this.accountService,
|
||||
);
|
||||
|
||||
const contextMenuClickedHandler = new ContextMenuClickedHandler(
|
||||
|
||||
@@ -51,7 +51,7 @@ describe("FamiliesPolicyService", () => {
|
||||
organizationService.organizations$.mockReturnValue(of(organizations));
|
||||
|
||||
const policies = [{ organizationId: "org1", enabled: true }] as Policy[];
|
||||
policyService.getAll$.mockReturnValue(of(policies));
|
||||
policyService.policiesByType$.mockReturnValue(of(policies));
|
||||
|
||||
const result = await firstValueFrom(service.isFreeFamilyPolicyEnabled$());
|
||||
expect(result).toBe(true);
|
||||
@@ -64,7 +64,7 @@ describe("FamiliesPolicyService", () => {
|
||||
organizationService.organizations$.mockReturnValue(of(organizations));
|
||||
|
||||
const policies = [{ organizationId: "org1", enabled: false }] as Policy[];
|
||||
policyService.getAll$.mockReturnValue(of(policies));
|
||||
policyService.policiesByType$.mockReturnValue(of(policies));
|
||||
|
||||
const result = await firstValueFrom(service.isFreeFamilyPolicyEnabled$());
|
||||
expect(result).toBe(false);
|
||||
|
||||
@@ -47,7 +47,7 @@ export class FamiliesPolicyService {
|
||||
map((organizations) => organizations.find((org) => org.canManageSponsorships)?.id),
|
||||
switchMap((enterpriseOrgId) =>
|
||||
this.policyService
|
||||
.getAll$(PolicyType.FreeFamiliesSponsorshipPolicy, userId)
|
||||
.policiesByType$(PolicyType.FreeFamiliesSponsorshipPolicy, userId)
|
||||
.pipe(
|
||||
map(
|
||||
(policies) =>
|
||||
|
||||
@@ -482,7 +482,7 @@ const safeProviders: SafeProvider[] = [
|
||||
safeProvider({
|
||||
provide: AutofillSettingsServiceAbstraction,
|
||||
useClass: AutofillSettingsService,
|
||||
deps: [StateProvider, PolicyService],
|
||||
deps: [StateProvider, PolicyService, AccountService],
|
||||
}),
|
||||
safeProvider({
|
||||
provide: UserNotificationSettingsServiceAbstraction,
|
||||
|
||||
@@ -64,7 +64,7 @@ describe("SendV2Component", () => {
|
||||
});
|
||||
|
||||
policyService = mock<PolicyService>();
|
||||
policyService.policyAppliesToActiveUser$.mockReturnValue(of(true)); // Return `true` by default
|
||||
policyService.policyAppliesToUser$.mockReturnValue(of(true)); // Return `true` by default
|
||||
|
||||
sendListFiltersService = new SendListFiltersService(mock(), new FormBuilder());
|
||||
|
||||
|
||||
@@ -2,11 +2,13 @@ import { CommonModule } from "@angular/common";
|
||||
import { Component, OnDestroy, OnInit } from "@angular/core";
|
||||
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||
import { RouterLink } from "@angular/router";
|
||||
import { combineLatest } from "rxjs";
|
||||
import { combineLatest, switchMap } from "rxjs";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
|
||||
import { ButtonModule, CalloutModule, Icons, NoItemsModule } from "@bitwarden/components";
|
||||
import {
|
||||
@@ -66,6 +68,7 @@ export class SendV2Component implements OnInit, OnDestroy {
|
||||
protected sendItemsService: SendItemsService,
|
||||
protected sendListFiltersService: SendListFiltersService,
|
||||
private policyService: PolicyService,
|
||||
private accountService: AccountService,
|
||||
) {
|
||||
combineLatest([
|
||||
this.sendItemsService.emptyList$,
|
||||
@@ -93,9 +96,14 @@ export class SendV2Component implements OnInit, OnDestroy {
|
||||
this.listState = null;
|
||||
});
|
||||
|
||||
this.policyService
|
||||
.policyAppliesToActiveUser$(PolicyType.DisableSend)
|
||||
.pipe(takeUntilDestroyed())
|
||||
this.accountService.activeAccount$
|
||||
.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.policyAppliesToUser$(PolicyType.DisableSend, userId),
|
||||
),
|
||||
takeUntilDestroyed(),
|
||||
)
|
||||
.subscribe((sendsDisabled) => {
|
||||
this.sendsDisabled = sendsDisabled;
|
||||
});
|
||||
|
||||
@@ -36,7 +36,7 @@ describe("VaultPopupListFiltersService", () => {
|
||||
let folderViews$ = new BehaviorSubject([]);
|
||||
const cipherViews$ = new BehaviorSubject({});
|
||||
let decryptedCollections$ = new BehaviorSubject<CollectionView[]>([]);
|
||||
const policyAppliesToActiveUser$ = new BehaviorSubject<boolean>(false);
|
||||
const policyAppliesToUser$ = new BehaviorSubject<boolean>(false);
|
||||
let viewCacheService: {
|
||||
signal: jest.Mock;
|
||||
mockSignal: WritableSignal<CachedFilterState>;
|
||||
@@ -65,7 +65,7 @@ describe("VaultPopupListFiltersService", () => {
|
||||
} as I18nService;
|
||||
|
||||
const policyService = {
|
||||
policyAppliesToActiveUser$: jest.fn(() => policyAppliesToActiveUser$),
|
||||
policyAppliesToUser$: jest.fn(() => policyAppliesToUser$),
|
||||
};
|
||||
|
||||
const state$ = new BehaviorSubject<boolean>(false);
|
||||
@@ -75,8 +75,8 @@ describe("VaultPopupListFiltersService", () => {
|
||||
_memberOrganizations$ = new BehaviorSubject<Organization[]>([]); // Fresh instance per test
|
||||
folderViews$ = new BehaviorSubject([]); // Fresh instance per test
|
||||
decryptedCollections$ = new BehaviorSubject<CollectionView[]>([]); // Fresh instance per test
|
||||
policyAppliesToActiveUser$.next(false);
|
||||
policyService.policyAppliesToActiveUser$.mockClear();
|
||||
policyAppliesToUser$.next(false);
|
||||
policyService.policyAppliesToUser$.mockClear();
|
||||
|
||||
const accountService = mockAccountServiceWith("userId" as UserId);
|
||||
const mockCachedSignal = createMockSignal<CachedFilterState>({});
|
||||
@@ -196,14 +196,15 @@ describe("VaultPopupListFiltersService", () => {
|
||||
});
|
||||
|
||||
describe("PersonalOwnership policy", () => {
|
||||
it('calls policyAppliesToActiveUser$ with "PersonalOwnership"', () => {
|
||||
expect(policyService.policyAppliesToActiveUser$).toHaveBeenCalledWith(
|
||||
it('calls policyAppliesToUser$ with "PersonalOwnership"', () => {
|
||||
expect(policyService.policyAppliesToUser$).toHaveBeenCalledWith(
|
||||
PolicyType.PersonalOwnership,
|
||||
"userId",
|
||||
);
|
||||
});
|
||||
|
||||
it("returns an empty array when the policy applies and there is a single organization", (done) => {
|
||||
policyAppliesToActiveUser$.next(true);
|
||||
policyAppliesToUser$.next(true);
|
||||
_memberOrganizations$.next([
|
||||
{ name: "bobby's org", id: "1234-3323-23223" },
|
||||
] as Organization[]);
|
||||
@@ -215,7 +216,7 @@ describe("VaultPopupListFiltersService", () => {
|
||||
});
|
||||
|
||||
it('adds "myVault" when the policy does not apply and there are multiple organizations', (done) => {
|
||||
policyAppliesToActiveUser$.next(false);
|
||||
policyAppliesToUser$.next(false);
|
||||
const orgs = [
|
||||
{ name: "bobby's org", id: "1234-3323-23223" },
|
||||
{ name: "alice's org", id: "2223-4343-99888" },
|
||||
@@ -234,7 +235,7 @@ describe("VaultPopupListFiltersService", () => {
|
||||
});
|
||||
|
||||
it('does not add "myVault" the policy applies and there are multiple organizations', (done) => {
|
||||
policyAppliesToActiveUser$.next(true);
|
||||
policyAppliesToUser$.next(true);
|
||||
const orgs = [
|
||||
{ name: "bobby's org", id: "1234-3323-23223" },
|
||||
{ name: "alice's org", id: "2223-3242-99888" },
|
||||
@@ -679,7 +680,7 @@ function createSeededVaultPopupListFiltersService(
|
||||
} as any;
|
||||
|
||||
const policyServiceMock = {
|
||||
policyAppliesToActiveUser$: jest.fn(() => new BehaviorSubject(false)),
|
||||
policyAppliesToUser$: jest.fn(() => new BehaviorSubject(false)),
|
||||
} as any;
|
||||
|
||||
const stateProviderMock = {
|
||||
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
filter,
|
||||
map,
|
||||
Observable,
|
||||
of,
|
||||
shareReplay,
|
||||
startWith,
|
||||
switchMap,
|
||||
@@ -23,6 +22,7 @@ import { PolicyService } from "@bitwarden/common/admin-console/abstractions/poli
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { ProductTierType } from "@bitwarden/common/billing/enums";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
@@ -288,68 +288,70 @@ export class VaultPopupListFiltersService {
|
||||
/**
|
||||
* Organization array structured to be directly passed to `ChipSelectComponent`
|
||||
*/
|
||||
organizations$: Observable<ChipSelectOption<Organization>[]> = combineLatest([
|
||||
|
||||
organizations$: Observable<ChipSelectOption<Organization>[]> =
|
||||
this.accountService.activeAccount$.pipe(
|
||||
switchMap((account) =>
|
||||
account === null ? of([]) : this.organizationService.memberOrganizations$(account.id),
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
combineLatest([
|
||||
this.organizationService.memberOrganizations$(userId),
|
||||
this.policyService.policyAppliesToUser$(PolicyType.PersonalOwnership, userId),
|
||||
]),
|
||||
),
|
||||
),
|
||||
this.policyService.policyAppliesToActiveUser$(PolicyType.PersonalOwnership),
|
||||
]).pipe(
|
||||
map(([orgs, personalOwnershipApplies]): [Organization[], boolean] => [
|
||||
orgs.sort(Utils.getSortFunction(this.i18nService, "name")),
|
||||
personalOwnershipApplies,
|
||||
]),
|
||||
map(([orgs, personalOwnershipApplies]) => {
|
||||
// When there are no organizations return an empty array,
|
||||
// resulting in the org filter being hidden
|
||||
if (!orgs.length) {
|
||||
return [];
|
||||
}
|
||||
map(([orgs, personalOwnershipApplies]): [Organization[], boolean] => [
|
||||
orgs.sort(Utils.getSortFunction(this.i18nService, "name")),
|
||||
personalOwnershipApplies,
|
||||
]),
|
||||
map(([orgs, personalOwnershipApplies]) => {
|
||||
// When there are no organizations return an empty array,
|
||||
// resulting in the org filter being hidden
|
||||
if (!orgs.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// When there is only one organization and personal ownership policy applies,
|
||||
// return an empty array, resulting in the org filter being hidden
|
||||
if (orgs.length === 1 && personalOwnershipApplies) {
|
||||
return [];
|
||||
}
|
||||
// When there is only one organization and personal ownership policy applies,
|
||||
// return an empty array, resulting in the org filter being hidden
|
||||
if (orgs.length === 1 && personalOwnershipApplies) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const myVaultOrg: ChipSelectOption<Organization>[] = [];
|
||||
const myVaultOrg: ChipSelectOption<Organization>[] = [];
|
||||
|
||||
// Only add "My vault" if personal ownership policy does not apply
|
||||
if (!personalOwnershipApplies) {
|
||||
myVaultOrg.push({
|
||||
value: { id: MY_VAULT_ID } as Organization,
|
||||
label: this.i18nService.t("myVault"),
|
||||
icon: "bwi-user",
|
||||
});
|
||||
}
|
||||
// Only add "My vault" if personal ownership policy does not apply
|
||||
if (!personalOwnershipApplies) {
|
||||
myVaultOrg.push({
|
||||
value: { id: MY_VAULT_ID } as Organization,
|
||||
label: this.i18nService.t("myVault"),
|
||||
icon: "bwi-user",
|
||||
});
|
||||
}
|
||||
|
||||
return [
|
||||
...myVaultOrg,
|
||||
...orgs.map((org) => {
|
||||
let icon = "bwi-business";
|
||||
return [
|
||||
...myVaultOrg,
|
||||
...orgs.map((org) => {
|
||||
let icon = "bwi-business";
|
||||
|
||||
if (!org.enabled) {
|
||||
// Show a warning icon if the organization is deactivated
|
||||
icon = "bwi-exclamation-triangle tw-text-danger";
|
||||
} else if (
|
||||
org.productTierType === ProductTierType.Families ||
|
||||
org.productTierType === ProductTierType.Free
|
||||
) {
|
||||
// Show a family icon if the organization is a family or free org
|
||||
icon = "bwi-family";
|
||||
}
|
||||
if (!org.enabled) {
|
||||
// Show a warning icon if the organization is deactivated
|
||||
icon = "bwi-exclamation-triangle tw-text-danger";
|
||||
} else if (
|
||||
org.productTierType === ProductTierType.Families ||
|
||||
org.productTierType === ProductTierType.Free
|
||||
) {
|
||||
// Show a family icon if the organization is a family or free org
|
||||
icon = "bwi-family";
|
||||
}
|
||||
|
||||
return {
|
||||
value: org,
|
||||
label: org.name,
|
||||
icon,
|
||||
};
|
||||
}),
|
||||
];
|
||||
}),
|
||||
shareReplay({ refCount: true, bufferSize: 1 }),
|
||||
);
|
||||
return {
|
||||
value: org,
|
||||
label: org.name,
|
||||
icon,
|
||||
};
|
||||
}),
|
||||
];
|
||||
}),
|
||||
shareReplay({ refCount: true, bufferSize: 1 }),
|
||||
);
|
||||
|
||||
/**
|
||||
* Folder array structured to be directly passed to `ChipSelectComponent`
|
||||
|
||||
@@ -5,7 +5,7 @@ import * as http from "http";
|
||||
import { OptionValues } from "commander";
|
||||
import * as inquirer from "inquirer";
|
||||
import Separator from "inquirer/lib/objects/separator";
|
||||
import { firstValueFrom, map } from "rxjs";
|
||||
import { firstValueFrom, map, switchMap } from "rxjs";
|
||||
|
||||
import {
|
||||
LoginStrategyServiceAbstraction,
|
||||
@@ -29,6 +29,7 @@ import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/ide
|
||||
import { PasswordRequest } from "@bitwarden/common/auth/models/request/password.request";
|
||||
import { TwoFactorEmailRequest } from "@bitwarden/common/auth/models/request/two-factor-email.request";
|
||||
import { UpdateTempPasswordRequest } from "@bitwarden/common/auth/models/request/update-temp-password.request";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { ClientType } from "@bitwarden/common/enums";
|
||||
import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service";
|
||||
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
||||
@@ -555,7 +556,10 @@ export class LoginCommand {
|
||||
);
|
||||
|
||||
const enforcedPolicyOptions = await firstValueFrom(
|
||||
this.policyService.masterPasswordPolicyOptions$(),
|
||||
this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) => this.policyService.masterPasswordPolicyOptions$(userId)),
|
||||
),
|
||||
);
|
||||
|
||||
// Verify master password meets policy requirements
|
||||
|
||||
@@ -28,8 +28,8 @@ import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abs
|
||||
import { ProviderApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/provider/provider-api.service.abstraction";
|
||||
import { DefaultOrganizationService } from "@bitwarden/common/admin-console/services/organization/default-organization.service";
|
||||
import { OrganizationApiService } from "@bitwarden/common/admin-console/services/organization/organization-api.service";
|
||||
import { DefaultPolicyService } from "@bitwarden/common/admin-console/services/policy/default-policy.service";
|
||||
import { PolicyApiService } from "@bitwarden/common/admin-console/services/policy/policy-api.service";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/services/policy/policy.service";
|
||||
import { ProviderApiService } from "@bitwarden/common/admin-console/services/provider/provider-api.service";
|
||||
import { ProviderService } from "@bitwarden/common/admin-console/services/provider.service";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
@@ -237,7 +237,7 @@ export class ServiceContainer {
|
||||
cryptoFunctionService: NodeCryptoFunctionService;
|
||||
encryptService: EncryptServiceImplementation;
|
||||
authService: AuthService;
|
||||
policyService: PolicyService;
|
||||
policyService: DefaultPolicyService;
|
||||
policyApiService: PolicyApiServiceAbstraction;
|
||||
logService: ConsoleLogService;
|
||||
sendService: SendService;
|
||||
@@ -469,7 +469,7 @@ export class ServiceContainer {
|
||||
this.ssoUrlService = new SsoUrlService();
|
||||
|
||||
this.organizationService = new DefaultOrganizationService(this.stateProvider);
|
||||
this.policyService = new PolicyService(this.stateProvider, this.organizationService);
|
||||
this.policyService = new DefaultPolicyService(this.stateProvider, this.organizationService);
|
||||
|
||||
this.vaultTimeoutSettingsService = new DefaultVaultTimeoutSettingsService(
|
||||
this.accountService,
|
||||
@@ -560,7 +560,11 @@ export class ServiceContainer {
|
||||
|
||||
this.providerService = new ProviderService(this.stateProvider);
|
||||
|
||||
this.policyApiService = new PolicyApiService(this.policyService, this.apiService);
|
||||
this.policyApiService = new PolicyApiService(
|
||||
this.policyService,
|
||||
this.apiService,
|
||||
this.accountService,
|
||||
);
|
||||
|
||||
this.keyConnectorService = new KeyConnectorService(
|
||||
this.accountService,
|
||||
@@ -672,6 +676,7 @@ export class ServiceContainer {
|
||||
this.autofillSettingsService = new AutofillSettingsService(
|
||||
this.stateProvider,
|
||||
this.policyService,
|
||||
this.accountService,
|
||||
);
|
||||
|
||||
this.cipherService = new CipherService(
|
||||
|
||||
@@ -2,10 +2,13 @@
|
||||
// @ts-strict-ignore
|
||||
import { OptionValues } from "commander";
|
||||
import * as inquirer from "inquirer";
|
||||
import { firstValueFrom, switchMap } from "rxjs";
|
||||
|
||||
import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { EventType } from "@bitwarden/common/enums";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
@@ -26,14 +29,19 @@ export class ExportCommand {
|
||||
private exportService: VaultExportServiceAbstraction,
|
||||
private policyService: PolicyService,
|
||||
private eventCollectionService: EventCollectionService,
|
||||
private accountService: AccountService,
|
||||
private configService: ConfigService,
|
||||
) {}
|
||||
|
||||
async run(options: OptionValues): Promise<Response> {
|
||||
if (
|
||||
options.organizationid == null &&
|
||||
(await this.policyService.policyAppliesToUser(PolicyType.DisablePersonalVaultExport))
|
||||
) {
|
||||
const policyApplies$ = this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.policyAppliesToUser$(PolicyType.DisablePersonalVaultExport, userId),
|
||||
),
|
||||
);
|
||||
|
||||
if (options.organizationid == null && (await firstValueFrom(policyApplies$))) {
|
||||
return Response.badRequest(
|
||||
"One or more organization policies prevents you from exporting your personal vault.",
|
||||
);
|
||||
|
||||
@@ -501,6 +501,7 @@ export class VaultProgram extends BaseProgram {
|
||||
this.serviceContainer.exportService,
|
||||
this.serviceContainer.policyService,
|
||||
this.serviceContainer.eventCollectionService,
|
||||
this.serviceContainer.accountService,
|
||||
this.serviceContainer.configService,
|
||||
);
|
||||
const response = await command.run(options);
|
||||
|
||||
@@ -153,7 +153,7 @@ describe("SettingsComponent", () => {
|
||||
|
||||
it("pin enabled when RemoveUnlockWithPin policy is not set", async () => {
|
||||
// @ts-strict-ignore
|
||||
policyService.get$.mockReturnValue(of(null));
|
||||
policyService.policiesByType$.mockReturnValue(of([null]));
|
||||
|
||||
await component.ngOnInit();
|
||||
|
||||
@@ -164,7 +164,7 @@ describe("SettingsComponent", () => {
|
||||
const policy = new Policy();
|
||||
policy.type = PolicyType.RemoveUnlockWithPin;
|
||||
policy.enabled = false;
|
||||
policyService.get$.mockReturnValue(of(policy));
|
||||
policyService.policiesByType$.mockReturnValue(of([policy]));
|
||||
|
||||
await component.ngOnInit();
|
||||
|
||||
@@ -175,7 +175,7 @@ describe("SettingsComponent", () => {
|
||||
const policy = new Policy();
|
||||
policy.type = PolicyType.RemoveUnlockWithPin;
|
||||
policy.enabled = true;
|
||||
policyService.get$.mockReturnValue(of(policy));
|
||||
policyService.policiesByType$.mockReturnValue(of([policy]));
|
||||
|
||||
await component.ngOnInit();
|
||||
|
||||
@@ -184,7 +184,7 @@ describe("SettingsComponent", () => {
|
||||
|
||||
it("pin visible when RemoveUnlockWithPin policy is not set", async () => {
|
||||
// @ts-strict-ignore
|
||||
policyService.get$.mockReturnValue(of(null));
|
||||
policyService.policiesByType$.mockReturnValue(of([null]));
|
||||
|
||||
await component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
@@ -201,7 +201,7 @@ describe("SettingsComponent", () => {
|
||||
const policy = new Policy();
|
||||
policy.type = PolicyType.RemoveUnlockWithPin;
|
||||
policy.enabled = false;
|
||||
policyService.get$.mockReturnValue(of(policy));
|
||||
policyService.policiesByType$.mockReturnValue(of([policy]));
|
||||
|
||||
await component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
@@ -218,7 +218,7 @@ describe("SettingsComponent", () => {
|
||||
const policy = new Policy();
|
||||
policy.type = PolicyType.RemoveUnlockWithPin;
|
||||
policy.enabled = true;
|
||||
policyService.get$.mockReturnValue(of(policy));
|
||||
policyService.policiesByType$.mockReturnValue(of([policy]));
|
||||
pinServiceAbstraction.isPinSet.mockResolvedValue(true);
|
||||
|
||||
await component.ngOnInit();
|
||||
@@ -236,7 +236,7 @@ describe("SettingsComponent", () => {
|
||||
const policy = new Policy();
|
||||
policy.type = PolicyType.RemoveUnlockWithPin;
|
||||
policy.enabled = true;
|
||||
policyService.get$.mockReturnValue(of(policy));
|
||||
policyService.policiesByType$.mockReturnValue(of([policy]));
|
||||
|
||||
await component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
@@ -255,7 +255,7 @@ describe("SettingsComponent", () => {
|
||||
const policy = new Policy();
|
||||
policy.type = PolicyType.RemoveUnlockWithPin;
|
||||
policy.enabled = false;
|
||||
policyService.get$.mockReturnValue(of(policy));
|
||||
policyService.policiesByType$.mockReturnValue(of([policy]));
|
||||
platformUtilsService.getDevice.mockReturnValue(DeviceType.WindowsDesktop);
|
||||
i18nService.t.mockImplementation((id: string) => {
|
||||
if (id === "requirePasswordOnStart") {
|
||||
@@ -290,7 +290,7 @@ describe("SettingsComponent", () => {
|
||||
const policy = new Policy();
|
||||
policy.type = PolicyType.RemoveUnlockWithPin;
|
||||
policy.enabled = true;
|
||||
policyService.get$.mockReturnValue(of(policy));
|
||||
policyService.policiesByType$.mockReturnValue(of([policy]));
|
||||
platformUtilsService.getDevice.mockReturnValue(DeviceType.WindowsDesktop);
|
||||
i18nService.t.mockImplementation((id: string) => {
|
||||
if (id === "requirePasswordOnStart") {
|
||||
|
||||
@@ -17,8 +17,10 @@ import {
|
||||
import { PinServiceAbstraction } from "@bitwarden/auth/common";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { getFirstPolicy } from "@bitwarden/common/admin-console/services/policy/default-policy.service";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { UserVerificationService as UserVerificationServiceAbstraction } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service";
|
||||
import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service";
|
||||
import { DeviceType } from "@bitwarden/common/enums";
|
||||
@@ -235,7 +237,12 @@ export class SettingsComponent implements OnInit, OnDestroy {
|
||||
);
|
||||
|
||||
// Load timeout policy
|
||||
this.vaultTimeoutPolicyCallout = this.policyService.get$(PolicyType.MaximumVaultTimeout).pipe(
|
||||
this.vaultTimeoutPolicyCallout = this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.policiesByType$(PolicyType.MaximumVaultTimeout, userId),
|
||||
),
|
||||
getFirstPolicy,
|
||||
filter((policy) => policy != null),
|
||||
map((policy) => {
|
||||
let timeout;
|
||||
@@ -259,7 +266,12 @@ export class SettingsComponent implements OnInit, OnDestroy {
|
||||
// Load initial values
|
||||
this.userHasPinSet = await this.pinService.isPinSet(activeAccount.id);
|
||||
|
||||
this.pinEnabled$ = this.policyService.get$(PolicyType.RemoveUnlockWithPin).pipe(
|
||||
this.pinEnabled$ = this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.policiesByType$(PolicyType.RemoveUnlockWithPin, userId),
|
||||
),
|
||||
getFirstPolicy,
|
||||
map((policy) => {
|
||||
return policy == null || !policy.enabled;
|
||||
}),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { firstValueFrom } from "rxjs";
|
||||
import { firstValueFrom, switchMap } from "rxjs";
|
||||
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
@@ -144,10 +144,14 @@ export class EncryptedMessageHandlerService {
|
||||
|
||||
const credentialCreatePayload = payload as CredentialCreatePayload;
|
||||
|
||||
if (
|
||||
credentialCreatePayload.name == null ||
|
||||
(await this.policyService.policyAppliesToUser(PolicyType.PersonalOwnership))
|
||||
) {
|
||||
const policyApplies$ = this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.policyAppliesToUser$(PolicyType.PersonalOwnership, userId),
|
||||
),
|
||||
);
|
||||
|
||||
if (credentialCreatePayload.name == null || (await firstValueFrom(policyApplies$))) {
|
||||
return { status: "failure" };
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { firstValueFrom, Subject } from "rxjs";
|
||||
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/billing-api.service.abstraction";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
@@ -48,6 +49,7 @@ export class VaultFilterComponent
|
||||
protected billingApiService: BillingApiServiceAbstraction,
|
||||
protected dialogService: DialogService,
|
||||
protected configService: ConfigService,
|
||||
protected accountService: AccountService,
|
||||
) {
|
||||
super(
|
||||
vaultFilterService,
|
||||
@@ -58,6 +60,7 @@ export class VaultFilterComponent
|
||||
billingApiService,
|
||||
dialogService,
|
||||
configService,
|
||||
accountService,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -118,7 +118,10 @@ export class OrganizationLayoutComponent implements OnInit {
|
||||
),
|
||||
);
|
||||
|
||||
this.hideNewOrgButton$ = this.policyService.policyAppliesToActiveUser$(PolicyType.SingleOrg);
|
||||
this.hideNewOrgButton$ = this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) => this.policyService.policyAppliesToUser$(PolicyType.SingleOrg, userId)),
|
||||
);
|
||||
|
||||
const provider$ = this.organization$.pipe(
|
||||
switchMap((organization) => this.providerService.get$(organization.providerId)),
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog";
|
||||
import { Component, Inject, OnDestroy, OnInit, ViewChild } from "@angular/core";
|
||||
import { FormBuilder, Validators } from "@angular/forms";
|
||||
import { Subject, takeUntil } from "rxjs";
|
||||
import { Subject, switchMap, takeUntil } from "rxjs";
|
||||
|
||||
import { PasswordStrengthV2Component } from "@bitwarden/angular/tools/password-strength/password-strength-v2.component";
|
||||
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 { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.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";
|
||||
@@ -81,12 +83,16 @@ export class ResetPasswordComponent implements OnInit, OnDestroy {
|
||||
private toastService: ToastService,
|
||||
private formBuilder: FormBuilder,
|
||||
private dialogRef: DialogRef<ResetPasswordDialogResult>,
|
||||
private accountService: AccountService,
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
this.policyService
|
||||
.masterPasswordPolicyOptions$()
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
this.accountService.activeAccount$
|
||||
.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) => this.policyService.masterPasswordPolicyOptions$(userId)),
|
||||
takeUntil(this.destroy$),
|
||||
)
|
||||
.subscribe(
|
||||
(enforcedPasswordPolicyOptions) =>
|
||||
(this.enforcedPolicyOptions = enforcedPasswordPolicyOptions),
|
||||
|
||||
@@ -43,6 +43,7 @@ import { Organization } from "@bitwarden/common/admin-console/models/domain/orga
|
||||
import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
|
||||
import { OrganizationKeysRequest } from "@bitwarden/common/admin-console/models/request/organization-keys.request";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/billing-api.service.abstraction";
|
||||
import { isNotSelfUpgradable, ProductTierType } from "@bitwarden/common/billing/enums";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
@@ -168,15 +169,18 @@ export class MembersComponent extends BaseMembersComponent<OrganizationUserView>
|
||||
|
||||
this.canUseSecretsManager$ = organization$.pipe(map((org) => org.useSecretsManager));
|
||||
|
||||
const policies$ = organization$.pipe(
|
||||
switchMap((organization) => {
|
||||
const policies$ = combineLatest([
|
||||
this.accountService.activeAccount$.pipe(getUserId),
|
||||
organization$,
|
||||
]).pipe(
|
||||
switchMap(([userId, organization]) => {
|
||||
if (organization.isProviderUser) {
|
||||
return from(this.policyApiService.getPolicies(organization.id)).pipe(
|
||||
map((response) => Policy.fromListResponse(response)),
|
||||
);
|
||||
}
|
||||
|
||||
return this.policyService.policies$;
|
||||
return this.policyService.policies$(userId);
|
||||
}),
|
||||
);
|
||||
|
||||
|
||||
@@ -8,11 +8,15 @@ import { InternalPolicyService } from "@bitwarden/common/admin-console/abstracti
|
||||
import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options";
|
||||
import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
|
||||
import { ResetPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/reset-password-policy-options";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/spec";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy";
|
||||
|
||||
// FIXME: remove `src` and fix import
|
||||
@@ -38,6 +42,8 @@ describe("WebLoginComponentService", () => {
|
||||
let passwordGenerationService: MockProxy<PasswordGenerationServiceAbstraction>;
|
||||
let platformUtilsService: MockProxy<PlatformUtilsService>;
|
||||
let ssoLoginService: MockProxy<SsoLoginServiceAbstraction>;
|
||||
const mockUserId = Utils.newGuid() as UserId;
|
||||
let accountService: FakeAccountService;
|
||||
|
||||
beforeEach(() => {
|
||||
acceptOrganizationInviteService = mock<AcceptOrganizationInviteService>();
|
||||
@@ -50,6 +56,7 @@ describe("WebLoginComponentService", () => {
|
||||
passwordGenerationService = mock<PasswordGenerationServiceAbstraction>();
|
||||
platformUtilsService = mock<PlatformUtilsService>();
|
||||
ssoLoginService = mock<SsoLoginServiceAbstraction>();
|
||||
accountService = mockAccountServiceWith(mockUserId);
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
@@ -65,6 +72,7 @@ describe("WebLoginComponentService", () => {
|
||||
{ provide: PasswordGenerationServiceAbstraction, useValue: passwordGenerationService },
|
||||
{ provide: PlatformUtilsService, useValue: platformUtilsService },
|
||||
{ provide: SsoLoginServiceAbstraction, useValue: ssoLoginService },
|
||||
{ provide: AccountService, useValue: accountService },
|
||||
],
|
||||
});
|
||||
service = TestBed.inject(WebLoginComponentService);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// @ts-strict-ignore
|
||||
import { Injectable } from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
import { firstValueFrom, switchMap } from "rxjs";
|
||||
|
||||
import {
|
||||
DefaultLoginComponentService,
|
||||
@@ -12,7 +12,9 @@ import {
|
||||
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";
|
||||
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 { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
@@ -39,6 +41,7 @@ export class WebLoginComponentService
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
ssoLoginService: SsoLoginServiceAbstraction,
|
||||
private router: Router,
|
||||
private accountService: AccountService,
|
||||
) {
|
||||
super(
|
||||
cryptoFunctionService,
|
||||
@@ -93,7 +96,10 @@ export class WebLoginComponentService
|
||||
resetPasswordPolicy[1] && resetPasswordPolicy[0].autoEnrollEnabled;
|
||||
|
||||
const enforcedPasswordPolicyOptions = await firstValueFrom(
|
||||
this.policyService.masterPasswordPolicyOptions$(policies),
|
||||
this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) => this.policyService.masterPasswordPolicyOptions$(userId)),
|
||||
),
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
@@ -10,9 +10,12 @@ 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 { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
|
||||
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
||||
import { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/spec";
|
||||
import { CsprngArray } from "@bitwarden/common/types/csprng";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
import { MasterKey, UserKey } from "@bitwarden/common/types/key";
|
||||
import { DEFAULT_KDF_CONFIG, KeyService } from "@bitwarden/key-management";
|
||||
|
||||
@@ -30,6 +33,8 @@ describe("WebRegistrationFinishService", () => {
|
||||
let policyApiService: MockProxy<PolicyApiServiceAbstraction>;
|
||||
let logService: MockProxy<LogService>;
|
||||
let policyService: MockProxy<PolicyService>;
|
||||
const mockUserId = Utils.newGuid() as UserId;
|
||||
let accountService: FakeAccountService;
|
||||
|
||||
beforeEach(() => {
|
||||
keyService = mock<KeyService>();
|
||||
@@ -38,6 +43,7 @@ describe("WebRegistrationFinishService", () => {
|
||||
policyApiService = mock<PolicyApiServiceAbstraction>();
|
||||
logService = mock<LogService>();
|
||||
policyService = mock<PolicyService>();
|
||||
accountService = mockAccountServiceWith(mockUserId);
|
||||
|
||||
service = new WebRegistrationFinishService(
|
||||
keyService,
|
||||
@@ -46,6 +52,7 @@ describe("WebRegistrationFinishService", () => {
|
||||
policyApiService,
|
||||
logService,
|
||||
policyService,
|
||||
accountService,
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import { PolicyService } from "@bitwarden/common/admin-console/abstractions/poli
|
||||
import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options";
|
||||
import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
|
||||
import { AccountApiService } from "@bitwarden/common/auth/abstractions/account-api.service";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { RegisterFinishRequest } from "@bitwarden/common/auth/models/request/registration/register-finish.request";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { EncryptedString, EncString } from "@bitwarden/common/platform/models/domain/enc-string";
|
||||
@@ -30,6 +31,7 @@ export class WebRegistrationFinishService
|
||||
private policyApiService: PolicyApiServiceAbstraction,
|
||||
private logService: LogService,
|
||||
private policyService: PolicyService,
|
||||
private accountService: AccountService,
|
||||
) {
|
||||
super(keyService, accountApiService);
|
||||
}
|
||||
@@ -68,7 +70,7 @@ export class WebRegistrationFinishService
|
||||
}
|
||||
|
||||
const masterPasswordPolicyOpts: MasterPasswordPolicyOptions = await firstValueFrom(
|
||||
this.policyService.masterPasswordPolicyOptions$(policies),
|
||||
this.policyService.masterPasswordPolicyOptions$(null, policies),
|
||||
);
|
||||
|
||||
return masterPasswordPolicyOpts;
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
import { DialogConfig, DialogRef, DIALOG_DATA } from "@angular/cdk/dialog";
|
||||
import { Component, OnDestroy, OnInit, Inject, Input } from "@angular/core";
|
||||
import { FormBuilder, Validators } from "@angular/forms";
|
||||
import { takeUntil } from "rxjs";
|
||||
import { switchMap, takeUntil } from "rxjs";
|
||||
|
||||
import { ChangePasswordComponent } from "@bitwarden/angular/auth/components/change-password.component";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.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";
|
||||
@@ -79,9 +80,12 @@ export class EmergencyAccessTakeoverComponent
|
||||
const policies = await this.emergencyAccessService.getGrantorPolicies(
|
||||
this.params.emergencyAccessId,
|
||||
);
|
||||
this.policyService
|
||||
.masterPasswordPolicyOptions$(policies)
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
this.accountService.activeAccount$
|
||||
.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) => this.policyService.masterPasswordPolicyOptions$(userId, policies)),
|
||||
takeUntil(this.destroy$),
|
||||
)
|
||||
.subscribe((enforcedPolicyOptions) => (this.enforcedPolicyOptions = enforcedPolicyOptions));
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import { TwoFactorDuoResponse } from "@bitwarden/common/auth/models/response/two
|
||||
import { TwoFactorEmailResponse } from "@bitwarden/common/auth/models/response/two-factor-email.response";
|
||||
import { TwoFactorWebAuthnResponse } from "@bitwarden/common/auth/models/response/two-factor-web-authn.response";
|
||||
import { TwoFactorYubiKeyResponse } from "@bitwarden/common/auth/models/response/two-factor-yubi-key.response";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { TwoFactorProviders } from "@bitwarden/common/auth/services/two-factor.service";
|
||||
import { AuthResponse } from "@bitwarden/common/auth/types/auth-response";
|
||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||
@@ -109,13 +110,17 @@ export class TwoFactorSetupComponent implements OnInit, OnDestroy {
|
||||
|
||||
this.providers.sort((a: any, b: any) => a.sort - b.sort);
|
||||
|
||||
this.policyService
|
||||
.policyAppliesToActiveUser$(PolicyType.TwoFactorAuthentication)
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
this.accountService.activeAccount$
|
||||
.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.policyAppliesToUser$(PolicyType.TwoFactorAuthentication, userId),
|
||||
),
|
||||
takeUntil(this.destroy$),
|
||||
)
|
||||
.subscribe((policyAppliesToActiveUser) => {
|
||||
this.twoFactorAuthPolicyAppliesToActiveUser = policyAppliesToActiveUser;
|
||||
});
|
||||
|
||||
await this.load();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { Component, HostBinding, OnDestroy, OnInit } from "@angular/core";
|
||||
import { Subject, takeUntil } from "rxjs";
|
||||
import { Subject, switchMap, takeUntil } from "rxjs";
|
||||
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
|
||||
import { WebauthnLoginAdminService } from "../../core";
|
||||
@@ -35,6 +37,7 @@ export class WebauthnLoginSettingsComponent implements OnInit, OnDestroy {
|
||||
private webauthnService: WebauthnLoginAdminService,
|
||||
private dialogService: DialogService,
|
||||
private policyService: PolicyService,
|
||||
private accountService: AccountService,
|
||||
) {}
|
||||
|
||||
@HostBinding("attr.aria-busy")
|
||||
@@ -57,9 +60,14 @@ export class WebauthnLoginSettingsComponent implements OnInit, OnDestroy {
|
||||
requireSsoPolicyEnabled = false;
|
||||
|
||||
ngOnInit(): void {
|
||||
this.policyService
|
||||
.policyAppliesToActiveUser$(PolicyType.RequireSso)
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
this.accountService.activeAccount$
|
||||
.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.policyAppliesToUser$(PolicyType.RequireSso, userId),
|
||||
),
|
||||
takeUntil(this.destroy$),
|
||||
)
|
||||
.subscribe((enabled) => {
|
||||
this.requireSsoPolicyEnabled = enabled;
|
||||
});
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
} from "@angular/core";
|
||||
import { FormBuilder, Validators } from "@angular/forms";
|
||||
import { Router } from "@angular/router";
|
||||
import { Subject, firstValueFrom, map, takeUntil } from "rxjs";
|
||||
import { Subject, firstValueFrom, map, switchMap, takeUntil } from "rxjs";
|
||||
|
||||
import { ManageTaxInformationComponent } from "@bitwarden/angular/billing/components";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
@@ -28,6 +28,7 @@ import { Organization } from "@bitwarden/common/admin-console/models/domain/orga
|
||||
import { OrganizationKeysRequest } from "@bitwarden/common/admin-console/models/request/organization-keys.request";
|
||||
import { OrganizationUpgradeRequest } from "@bitwarden/common/admin-console/models/request/organization-upgrade.request";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import {
|
||||
BillingApiServiceAbstraction,
|
||||
BillingInformation,
|
||||
@@ -265,9 +266,14 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
this.upgradeFlowPrefillForm();
|
||||
|
||||
this.policyService
|
||||
.policyAppliesToActiveUser$(PolicyType.SingleOrg)
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
this.accountService.activeAccount$
|
||||
.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.policyAppliesToUser$(PolicyType.SingleOrg, userId),
|
||||
),
|
||||
takeUntil(this.destroy$),
|
||||
)
|
||||
.subscribe((policyAppliesToActiveUser) => {
|
||||
this.singleOrgPolicyAppliesToActiveUser = policyAppliesToActiveUser;
|
||||
});
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
import { FormBuilder, Validators } from "@angular/forms";
|
||||
import { Router } from "@angular/router";
|
||||
import { Subject, firstValueFrom, takeUntil } from "rxjs";
|
||||
import { debounceTime, map } from "rxjs/operators";
|
||||
import { debounceTime, map, switchMap } from "rxjs/operators";
|
||||
|
||||
import { ManageTaxInformationComponent } from "@bitwarden/angular/billing/components";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
@@ -31,6 +31,7 @@ import { OrganizationUpgradeRequest } from "@bitwarden/common/admin-console/mode
|
||||
import { ProviderOrganizationCreateRequest } from "@bitwarden/common/admin-console/models/request/provider/provider-organization-create.request";
|
||||
import { ProviderResponse } from "@bitwarden/common/admin-console/models/response/provider/provider.response";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions";
|
||||
import { TaxServiceAbstraction } from "@bitwarden/common/billing/abstractions/tax.service.abstraction";
|
||||
import { PaymentMethodType, PlanType, ProductTierType } from "@bitwarden/common/billing/enums";
|
||||
@@ -240,9 +241,14 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy {
|
||||
this.formGroup.controls.billingEmail.addValidators(Validators.required);
|
||||
}
|
||||
|
||||
this.policyService
|
||||
.policyAppliesToActiveUser$(PolicyType.SingleOrg)
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
this.accountService.activeAccount$
|
||||
.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.policyAppliesToUser$(PolicyType.SingleOrg, userId),
|
||||
),
|
||||
takeUntil(this.destroy$),
|
||||
)
|
||||
.subscribe((policyAppliesToActiveUser) => {
|
||||
this.singleOrgPolicyAppliesToActiveUser = policyAppliesToActiveUser;
|
||||
});
|
||||
|
||||
@@ -96,7 +96,7 @@ export class FreeFamiliesPolicyService {
|
||||
return this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.getAll$(PolicyType.FreeFamiliesSponsorshipPolicy, userId),
|
||||
this.policyService.policiesByType$(PolicyType.FreeFamiliesSponsorshipPolicy, userId),
|
||||
),
|
||||
map((policies) => ({
|
||||
isFreeFamilyPolicyEnabled: policies.some(
|
||||
|
||||
@@ -89,7 +89,7 @@ export class SponsoredFamiliesComponent implements OnInit, OnDestroy {
|
||||
|
||||
this.availableSponsorshipOrgs$ = combineLatest([
|
||||
this.organizationService.organizations$(userId),
|
||||
this.policyService.getAll$(PolicyType.FreeFamiliesSponsorshipPolicy, userId),
|
||||
this.policyService.policiesByType$(PolicyType.FreeFamiliesSponsorshipPolicy, userId),
|
||||
]).pipe(
|
||||
map(([organizations, policies]) =>
|
||||
organizations
|
||||
|
||||
@@ -10,7 +10,6 @@ import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { DialogService, ToastService } from "@bitwarden/components";
|
||||
@@ -36,7 +35,6 @@ export class SponsoringOrgRowComponent implements OnInit {
|
||||
private logService: LogService,
|
||||
private dialogService: DialogService,
|
||||
private toastService: ToastService,
|
||||
private configService: ConfigService,
|
||||
private policyService: PolicyService,
|
||||
private accountService: AccountService,
|
||||
) {}
|
||||
@@ -54,7 +52,7 @@ export class SponsoringOrgRowComponent implements OnInit {
|
||||
this.isFreeFamilyPolicyEnabled$ = this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.getAll$(PolicyType.FreeFamiliesSponsorshipPolicy, userId),
|
||||
this.policyService.policiesByType$(PolicyType.FreeFamiliesSponsorshipPolicy, userId),
|
||||
),
|
||||
map(
|
||||
(policies) =>
|
||||
|
||||
@@ -4,7 +4,7 @@ import { StepperSelectionEvent } from "@angular/cdk/stepper";
|
||||
import { Component, OnDestroy, OnInit, ViewChild } from "@angular/core";
|
||||
import { FormBuilder, Validators } from "@angular/forms";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
import { firstValueFrom, Subject, takeUntil } from "rxjs";
|
||||
import { firstValueFrom, Subject, switchMap, takeUntil } from "rxjs";
|
||||
|
||||
import { PasswordInputResult, RegistrationFinishService } from "@bitwarden/auth/angular";
|
||||
import { LoginStrategyServiceAbstraction, PasswordLoginCredentials } from "@bitwarden/auth/common";
|
||||
@@ -12,6 +12,8 @@ import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abs
|
||||
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 { 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 {
|
||||
OrganizationBillingServiceAbstraction as OrganizationBillingService,
|
||||
OrganizationInformation,
|
||||
@@ -106,6 +108,7 @@ export class CompleteTrialInitiationComponent implements OnInit, OnDestroy {
|
||||
private validationService: ValidationService,
|
||||
private loginStrategyService: LoginStrategyServiceAbstraction,
|
||||
private configService: ConfigService,
|
||||
private accountService: AccountService,
|
||||
) {}
|
||||
|
||||
async ngOnInit(): Promise<void> {
|
||||
@@ -173,9 +176,12 @@ export class CompleteTrialInitiationComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
if (policies !== null) {
|
||||
this.policyService
|
||||
.masterPasswordPolicyOptions$(policies)
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
this.accountService.activeAccount$
|
||||
.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) => this.policyService.masterPasswordPolicyOptions$(userId, policies)),
|
||||
takeUntil(this.destroy$),
|
||||
)
|
||||
.subscribe((enforcedPasswordPolicyOptions) => {
|
||||
this.enforcedPolicyOptions = enforcedPasswordPolicyOptions;
|
||||
});
|
||||
|
||||
@@ -256,6 +256,7 @@ const safeProviders: SafeProvider[] = [
|
||||
PolicyApiServiceAbstraction,
|
||||
LogService,
|
||||
PolicyService,
|
||||
AccountService,
|
||||
],
|
||||
}),
|
||||
safeProvider({
|
||||
@@ -311,6 +312,7 @@ const safeProviders: SafeProvider[] = [
|
||||
PlatformUtilsService,
|
||||
SsoLoginServiceAbstraction,
|
||||
Router,
|
||||
AccountService,
|
||||
],
|
||||
}),
|
||||
safeProvider({
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { Injectable } from "@angular/core";
|
||||
import { switchMap } from "rxjs";
|
||||
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
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 { DeviceType, EventType } from "@bitwarden/common/enums";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { EventResponse } from "@bitwarden/common/models/response/event.response";
|
||||
@@ -19,10 +22,16 @@ export class EventService {
|
||||
private i18nService: I18nService,
|
||||
policyService: PolicyService,
|
||||
private configService: ConfigService,
|
||||
private accountService: AccountService,
|
||||
) {
|
||||
policyService.policies$.subscribe((policies) => {
|
||||
this.policies = policies;
|
||||
});
|
||||
accountService.activeAccount$
|
||||
.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) => policyService.policies$(userId)),
|
||||
)
|
||||
.subscribe((policies) => {
|
||||
this.policies = policies;
|
||||
});
|
||||
}
|
||||
|
||||
getDefaultDateFilters() {
|
||||
|
||||
@@ -2,11 +2,23 @@
|
||||
// @ts-strict-ignore
|
||||
import { Component, OnDestroy, OnInit } from "@angular/core";
|
||||
import { FormBuilder } from "@angular/forms";
|
||||
import { concatMap, filter, firstValueFrom, map, Observable, Subject, takeUntil, tap } from "rxjs";
|
||||
import {
|
||||
concatMap,
|
||||
filter,
|
||||
firstValueFrom,
|
||||
map,
|
||||
Observable,
|
||||
Subject,
|
||||
switchMap,
|
||||
takeUntil,
|
||||
tap,
|
||||
} from "rxjs";
|
||||
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { getFirstPolicy } from "@bitwarden/common/admin-console/services/policy/default-policy.service";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service";
|
||||
import {
|
||||
VaultTimeout,
|
||||
@@ -100,7 +112,12 @@ export class PreferencesComponent implements OnInit, OnDestroy {
|
||||
this.availableVaultTimeoutActions$ =
|
||||
this.vaultTimeoutSettingsService.availableVaultTimeoutActions$();
|
||||
|
||||
this.vaultTimeoutPolicyCallout = this.policyService.get$(PolicyType.MaximumVaultTimeout).pipe(
|
||||
this.vaultTimeoutPolicyCallout = this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.policiesByType$(PolicyType.MaximumVaultTimeout, userId),
|
||||
),
|
||||
getFirstPolicy,
|
||||
filter((policy) => policy != null),
|
||||
map((policy) => {
|
||||
let timeout;
|
||||
|
||||
@@ -75,8 +75,10 @@ export class OrganizationOptionsComponent implements OnInit, OnDestroy {
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
const resetPasswordPolicies$ = this.policyService.policies$.pipe(
|
||||
map((policies) => policies.filter((policy) => policy.type === PolicyType.ResetPassword)),
|
||||
const resetPasswordPolicies$ = this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) => this.policyService.policies$(userId)),
|
||||
map((policies) => policies.filter((p) => p.type == PolicyType.ResetPassword)),
|
||||
);
|
||||
|
||||
const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$));
|
||||
|
||||
@@ -6,6 +6,9 @@ import { firstValueFrom, merge, Subject, switchMap, takeUntil } from "rxjs";
|
||||
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { getFirstPolicy } from "@bitwarden/common/admin-console/services/policy/default-policy.service";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/billing-api.service.abstraction";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
@@ -101,6 +104,7 @@ export class VaultFilterComponent implements OnInit, OnDestroy {
|
||||
protected billingApiService: BillingApiServiceAbstraction,
|
||||
protected dialogService: DialogService,
|
||||
protected configService: ConfigService,
|
||||
protected accountService: AccountService,
|
||||
) {}
|
||||
|
||||
async ngOnInit(): Promise<void> {
|
||||
@@ -110,10 +114,18 @@ export class VaultFilterComponent implements OnInit, OnDestroy {
|
||||
this.isLoaded = true;
|
||||
|
||||
// Without refactoring the entire component, we need to manually update the organization filter whenever the policies update
|
||||
merge(
|
||||
this.policyService.get$(PolicyType.SingleOrg),
|
||||
this.policyService.get$(PolicyType.PersonalOwnership),
|
||||
)
|
||||
this.accountService.activeAccount$
|
||||
.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
merge(
|
||||
this.policyService.policiesByType$(PolicyType.SingleOrg, userId).pipe(getFirstPolicy),
|
||||
this.policyService
|
||||
.policiesByType$(PolicyType.PersonalOwnership, userId)
|
||||
.pipe(getFirstPolicy),
|
||||
),
|
||||
),
|
||||
)
|
||||
.pipe(
|
||||
switchMap(() => this.addOrganizationFilter()),
|
||||
takeUntil(this.destroy$),
|
||||
@@ -190,9 +202,22 @@ export class VaultFilterComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
protected async addOrganizationFilter(): Promise<VaultFilterSection> {
|
||||
const singleOrgPolicy = await this.policyService.policyAppliesToUser(PolicyType.SingleOrg);
|
||||
const personalVaultPolicy = await this.policyService.policyAppliesToUser(
|
||||
PolicyType.PersonalOwnership,
|
||||
const singleOrgPolicy = await firstValueFrom(
|
||||
this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.policyAppliesToUser$(PolicyType.SingleOrg, userId),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
const personalVaultPolicy = await firstValueFrom(
|
||||
this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.policyAppliesToUser$(PolicyType.PersonalOwnership, userId),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
const addAction = !singleOrgPolicy
|
||||
|
||||
@@ -65,11 +65,11 @@ describe("vault filter service", () => {
|
||||
organizationService.memberOrganizations$.mockReturnValue(organizations);
|
||||
folderService.folderViews$.mockReturnValue(folderViews);
|
||||
collectionService.decryptedCollections$ = collectionViews;
|
||||
policyService.policyAppliesToActiveUser$
|
||||
.calledWith(PolicyType.PersonalOwnership)
|
||||
policyService.policyAppliesToUser$
|
||||
.calledWith(PolicyType.PersonalOwnership, mockUserId)
|
||||
.mockReturnValue(personalOwnershipPolicy);
|
||||
policyService.policyAppliesToActiveUser$
|
||||
.calledWith(PolicyType.SingleOrg)
|
||||
policyService.policyAppliesToUser$
|
||||
.calledWith(PolicyType.SingleOrg, mockUserId)
|
||||
.mockReturnValue(singleOrgPolicy);
|
||||
cipherService.cipherViews$.mockReturnValue(cipherViews);
|
||||
|
||||
|
||||
@@ -55,8 +55,14 @@ export class VaultFilterService implements VaultFilterServiceAbstraction {
|
||||
|
||||
organizationTree$: Observable<TreeNode<OrganizationFilter>> = combineLatest([
|
||||
this.memberOrganizations$,
|
||||
this.policyService.policyAppliesToActiveUser$(PolicyType.SingleOrg),
|
||||
this.policyService.policyAppliesToActiveUser$(PolicyType.PersonalOwnership),
|
||||
this.activeUserId$.pipe(
|
||||
switchMap((userId) => this.policyService.policyAppliesToUser$(PolicyType.SingleOrg, userId)),
|
||||
),
|
||||
this.activeUserId$.pipe(
|
||||
switchMap((userId) =>
|
||||
this.policyService.policyAppliesToUser$(PolicyType.PersonalOwnership, userId),
|
||||
),
|
||||
),
|
||||
]).pipe(
|
||||
switchMap(([orgs, singleOrgPolicy, personalOwnershipPolicy]) =>
|
||||
this.buildOrganizationTree(orgs, singleOrgPolicy, personalOwnershipPolicy),
|
||||
|
||||
@@ -142,13 +142,13 @@ describe("VaultOnboardingComponent", () => {
|
||||
});
|
||||
|
||||
describe("individualVaultPolicyCheck", () => {
|
||||
it("should set isIndividualPolicyVault to true", async () => {
|
||||
it("should set isIndividualPolicyVault to true", () => {
|
||||
individualVaultPolicyCheckSpy.mockRestore();
|
||||
const spy = jest
|
||||
.spyOn((component as any).policyService, "policyAppliesToActiveUser$")
|
||||
.spyOn((component as any).policyService, "policyAppliesToUser$")
|
||||
.mockReturnValue(of(true));
|
||||
|
||||
await component.individualVaultPolicyCheck();
|
||||
component.individualVaultPolicyCheck();
|
||||
fixture.detectChanges();
|
||||
expect(spy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
SimpleChanges,
|
||||
OnChanges,
|
||||
} from "@angular/core";
|
||||
import { Subject, takeUntil, Observable, firstValueFrom, fromEvent } from "rxjs";
|
||||
import { Subject, takeUntil, Observable, firstValueFrom, fromEvent, switchMap } from "rxjs";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
@@ -20,7 +20,6 @@ import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
import { CipherType } from "@bitwarden/common/vault/enums/cipher-type";
|
||||
@@ -67,7 +66,6 @@ export class VaultOnboardingComponent implements OnInit, OnChanges, OnDestroy {
|
||||
protected policyService: PolicyService,
|
||||
private apiService: ApiService,
|
||||
private vaultOnboardingService: VaultOnboardingServiceAbstraction,
|
||||
private configService: ConfigService,
|
||||
private accountService: AccountService,
|
||||
) {}
|
||||
|
||||
@@ -165,9 +163,14 @@ export class VaultOnboardingComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}
|
||||
|
||||
individualVaultPolicyCheck() {
|
||||
this.policyService
|
||||
.policyAppliesToActiveUser$(PolicyType.PersonalOwnership)
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
this.accountService.activeAccount$
|
||||
.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.policyAppliesToUser$(PolicyType.PersonalOwnership, userId),
|
||||
),
|
||||
takeUntil(this.destroy$),
|
||||
)
|
||||
.subscribe((data) => {
|
||||
this.isIndividualPolicyVault = data;
|
||||
});
|
||||
|
||||
@@ -38,7 +38,7 @@ describe("AdminConsoleCipherFormConfigService", () => {
|
||||
status: OrganizationUserStatusType.Confirmed,
|
||||
userId: "UserId",
|
||||
};
|
||||
const policyAppliesToActiveUser$ = new BehaviorSubject<boolean>(true);
|
||||
const policyAppliesToUser$ = new BehaviorSubject<boolean>(true);
|
||||
const collection = {
|
||||
id: "12345-5555",
|
||||
organizationId: "234534-34334",
|
||||
@@ -75,7 +75,7 @@ describe("AdminConsoleCipherFormConfigService", () => {
|
||||
},
|
||||
{
|
||||
provide: PolicyService,
|
||||
useValue: { policyAppliesToActiveUser$: () => policyAppliesToActiveUser$ },
|
||||
useValue: { policyAppliesToUser$: () => policyAppliesToUser$ },
|
||||
},
|
||||
{
|
||||
provide: RoutedVaultFilterService,
|
||||
@@ -129,13 +129,13 @@ describe("AdminConsoleCipherFormConfigService", () => {
|
||||
});
|
||||
|
||||
it("sets `allowPersonalOwnership`", async () => {
|
||||
policyAppliesToActiveUser$.next(true);
|
||||
policyAppliesToUser$.next(true);
|
||||
|
||||
let result = await adminConsoleConfigService.buildConfig("clone", cipherId);
|
||||
|
||||
expect(result.allowPersonalOwnership).toBe(false);
|
||||
|
||||
policyAppliesToActiveUser$.next(false);
|
||||
policyAppliesToUser$.next(false);
|
||||
|
||||
result = await adminConsoleConfigService.buildConfig("clone", cipherId);
|
||||
|
||||
@@ -143,7 +143,7 @@ describe("AdminConsoleCipherFormConfigService", () => {
|
||||
});
|
||||
|
||||
it("disables personal ownership when not cloning", async () => {
|
||||
policyAppliesToActiveUser$.next(false);
|
||||
policyAppliesToUser$.next(false);
|
||||
|
||||
let result = await adminConsoleConfigService.buildConfig("add", cipherId);
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import { PolicyService } from "@bitwarden/common/admin-console/abstractions/poli
|
||||
import { OrganizationUserStatusType, PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { CipherId, UserId } from "@bitwarden/common/types/guid";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { CipherType } from "@bitwarden/common/vault/enums";
|
||||
@@ -30,9 +31,13 @@ export class AdminConsoleCipherFormConfigService implements CipherFormConfigServ
|
||||
private apiService: ApiService = inject(ApiService);
|
||||
private accountService: AccountService = inject(AccountService);
|
||||
|
||||
private allowPersonalOwnership$ = this.policyService
|
||||
.policyAppliesToActiveUser$(PolicyType.PersonalOwnership)
|
||||
.pipe(map((p) => !p));
|
||||
private allowPersonalOwnership$ = this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) =>
|
||||
this.policyService.policyAppliesToUser$(PolicyType.PersonalOwnership, userId),
|
||||
),
|
||||
map((p) => !p),
|
||||
);
|
||||
|
||||
private organizationId$ = this.routedVaultFilterService.filter$.pipe(
|
||||
map((filter) => filter.organizationId),
|
||||
|
||||
Reference in New Issue
Block a user