1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-26 09:33:22 +00:00

[PM-32172] Redirect All Calls to PUT Policy VNext Endpoint (#19015)

* Redirect all remaining calls to VNextSavePolicy endpoint

* Remove unused code

---------

Co-authored-by: bnagawiecki <107435978+bnagawiecki@users.noreply.github.com>
This commit is contained in:
sven-bitwarden
2026-02-24 12:37:58 -06:00
committed by GitHub
parent bc14512a02
commit d50c5e1819
6 changed files with 65 additions and 39 deletions

View File

@@ -6,8 +6,10 @@ import { Constructor } from "type-fest";
import { PolicyType } from "@bitwarden/common/admin-console/enums";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { PolicyRequest } from "@bitwarden/common/admin-console/models/request/policy.request";
import { VNextSavePolicyRequest } from "@bitwarden/common/admin-console/models/request/v-next-save-policy.request";
import { PolicyStatusResponse } from "@bitwarden/common/admin-console/models/response/policy-status.response";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { OrgKey } from "@bitwarden/common/types/key";
import { DialogConfig, DialogRef, DialogService } from "@bitwarden/components";
import type { PolicyEditDialogData, PolicyEditDialogResult } from "./policy-edit-dialog.component";
@@ -103,6 +105,19 @@ export abstract class BasePolicyEditComponent implements OnInit {
}
}
async buildVNextRequest(orgKey: OrgKey): Promise<VNextSavePolicyRequest> {
if (!this.policy) {
throw new Error("Policy was not found");
}
const request: VNextSavePolicyRequest = {
policy: await this.buildRequest(),
metadata: null,
};
return request;
}
buildRequest() {
if (!this.policy) {
throw new Error("Policy was not found");

View File

@@ -3,7 +3,7 @@ import { lastValueFrom, map, Observable } from "rxjs";
import { PolicyType } from "@bitwarden/common/admin-console/enums";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { PolicyRequest } from "@bitwarden/common/admin-console/models/request/policy.request";
import { VNextSavePolicyRequest } from "@bitwarden/common/admin-console/models/request/v-next-save-policy.request";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
@@ -15,12 +15,9 @@ import { EncString } from "@bitwarden/sdk-internal";
import { SharedModule } from "../../../../shared";
import { BasePolicyEditDefinition, BasePolicyEditComponent } from "../base-policy-edit.component";
export interface VNextPolicyRequest {
policy: PolicyRequest;
metadata: {
defaultUserCollectionName: string;
};
}
type VNextSaveOrganizationDataOwnershipPolicyRequest = VNextSavePolicyRequest<{
defaultUserCollectionName: string;
}>;
export class OrganizationDataOwnershipPolicy extends BasePolicyEditDefinition {
name = "organizationDataOwnership";
@@ -69,14 +66,16 @@ export class OrganizationDataOwnershipPolicyComponent
return true;
}
async buildVNextRequest(orgKey: OrgKey): Promise<VNextPolicyRequest> {
async buildVNextRequest(
orgKey: OrgKey,
): Promise<VNextSaveOrganizationDataOwnershipPolicyRequest> {
if (!this.policy) {
throw new Error("Policy was not found");
}
const defaultUserCollectionName = await this.getEncryptedDefaultUserCollectionName(orgKey);
const request: VNextPolicyRequest = {
const request: VNextSaveOrganizationDataOwnershipPolicyRequest = {
policy: {
enabled: this.enabled.value ?? false,
data: this.buildRequestData(),

View File

@@ -6,6 +6,7 @@ import { mock } from "jest-mock-extended";
import { PolicyType } from "@bitwarden/common/admin-console/enums";
import { PolicyStatusResponse } from "@bitwarden/common/admin-console/models/response/policy-status.response";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { OrgKey } from "@bitwarden/common/types/key";
import {
RemoveUnlockWithPinPolicy,
@@ -96,4 +97,27 @@ describe("RemoveUnlockWithPinPolicyComponent", () => {
expect(bitLabelElement).not.toBeNull();
expect(bitLabelElement.nativeElement.textContent.trim()).toBe("Turn on");
});
it("buildVNextRequest should delegate to buildRequest and wrap with null metadata", async () => {
component.policy = new RemoveUnlockWithPinPolicy();
component.policyResponse = new PolicyStatusResponse({
organizationId: "org1",
type: PolicyType.RemoveUnlockWithPin,
enabled: true,
});
component.ngOnInit();
const buildRequestSpy = jest.spyOn(component, "buildRequest");
const result = await component.buildVNextRequest(mock<OrgKey>());
expect(buildRequestSpy).toHaveBeenCalled();
expect(result).toEqual({
policy: {
enabled: true,
data: null,
},
metadata: null,
});
});
});

View File

@@ -12,7 +12,7 @@ import { Observable } from "rxjs";
import { PolicyType } from "@bitwarden/common/admin-console/enums";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { PolicyRequest } from "@bitwarden/common/admin-console/models/request/policy.request";
import { VNextSavePolicyRequest } from "@bitwarden/common/admin-console/models/request/v-next-save-policy.request";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
@@ -24,12 +24,9 @@ import { SharedModule } from "../../../../shared";
import { BasePolicyEditDefinition, BasePolicyEditComponent } from "../base-policy-edit.component";
import { OrganizationDataOwnershipPolicyDialogComponent } from "../policy-edit-dialogs";
export interface VNextPolicyRequest {
policy: PolicyRequest;
metadata: {
defaultUserCollectionName: string;
};
}
type VNextSaveOrganizationDataOwnershipPolicyRequest = VNextSavePolicyRequest<{
defaultUserCollectionName: string;
}>;
export class vNextOrganizationDataOwnershipPolicy extends BasePolicyEditDefinition {
name = "centralizeDataOwnership";
@@ -67,14 +64,16 @@ export class vNextOrganizationDataOwnershipPolicyComponent
protected steps = [this.policyForm, this.warningContent];
async buildVNextRequest(orgKey: OrgKey): Promise<VNextPolicyRequest> {
async buildVNextRequest(
orgKey: OrgKey,
): Promise<VNextSaveOrganizationDataOwnershipPolicyRequest> {
if (!this.policy) {
throw new Error("Policy was not found");
}
const defaultUserCollectionName = await this.getEncryptedDefaultUserCollectionName(orgKey);
const request: VNextPolicyRequest = {
const request: VNextSaveOrganizationDataOwnershipPolicyRequest = {
policy: {
enabled: this.enabled.value ?? false,
data: this.buildRequestData(),

View File

@@ -11,6 +11,7 @@ import { Observable, map, firstValueFrom, switchMap, filter, of } from "rxjs";
import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction";
import { PolicyType } from "@bitwarden/common/admin-console/enums";
import { VNextSavePolicyRequest } from "@bitwarden/common/admin-console/models/request/v-next-save-policy.request";
import { PolicyResponse } from "@bitwarden/common/admin-console/models/response/policy.response";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { getUserId } from "@bitwarden/common/auth/services/account.service";
@@ -29,7 +30,6 @@ import { KeyService } from "@bitwarden/key-management";
import { SharedModule } from "../../../shared";
import { BasePolicyEditDefinition, BasePolicyEditComponent } from "./base-policy-edit.component";
import { VNextPolicyRequest } from "./policy-edit-definitions/organization-data-ownership.component";
export type PolicyEditDialogData = {
/**
@@ -91,7 +91,7 @@ export class PolicyEditDialogComponent implements AfterViewInit {
private hasVNextRequest(
component: BasePolicyEditComponent,
): component is BasePolicyEditComponent & {
buildVNextRequest: (orgKey: OrgKey) => Promise<VNextPolicyRequest>;
buildVNextRequest: (orgKey: OrgKey) => Promise<VNextSavePolicyRequest>;
} {
return "buildVNextRequest" in component && typeof component.buildVNextRequest === "function";
}
@@ -145,11 +145,7 @@ export class PolicyEditDialogComponent implements AfterViewInit {
}
try {
if (this.hasVNextRequest(this.policyComponent)) {
await this.handleVNextSubmission(this.policyComponent);
} else {
await this.handleStandardSubmission();
}
await this.handleVNextSubmission(this.policyComponent);
this.toastService.showToast({
variant: "success",
@@ -164,20 +160,7 @@ export class PolicyEditDialogComponent implements AfterViewInit {
}
};
private async handleStandardSubmission(): Promise<void> {
if (!this.policyComponent) {
throw new Error("PolicyComponent not initialized.");
}
const request = await this.policyComponent.buildRequest();
await this.policyApiService.putPolicy(this.data.organizationId, this.data.policy.type, request);
}
private async handleVNextSubmission(
policyComponent: BasePolicyEditComponent & {
buildVNextRequest: (orgKey: OrgKey) => Promise<VNextPolicyRequest>;
},
): Promise<void> {
private async handleVNextSubmission(policyComponent: BasePolicyEditComponent): Promise<void> {
const orgKey = await firstValueFrom(
this.accountService.activeAccount$.pipe(
getUserId,

View File

@@ -0,0 +1,6 @@
import { PolicyRequest } from "./policy.request";
export interface VNextSavePolicyRequest<TMetadata = Record<string, unknown>> {
policy: PolicyRequest;
metadata: TMetadata | null;
}