1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-10 21:33:27 +00:00

add encrypted collection name to confirmUser request (#15156)

This commit is contained in:
Brandon Treston
2025-06-24 09:34:48 -04:00
committed by GitHub
parent 1c237a3753
commit 012ce25e49
4 changed files with 95 additions and 12 deletions

View File

@@ -83,6 +83,7 @@ import {
ResetPasswordDialogResult,
} from "./components/reset-password.component";
import { DeleteManagedMemberWarningService } from "./services/delete-managed-member/delete-managed-member-warning.service";
import { OrganizationUserService } from "./services/organization-user/organization-user.service";
class MembersTableDataSource extends PeopleTableDataSource<OrganizationUserView> {
protected statusType = OrganizationUserStatusType;
@@ -141,6 +142,7 @@ export class MembersComponent extends BaseMembersComponent<OrganizationUserView>
private billingApiService: BillingApiServiceAbstraction,
protected deleteManagedMemberWarningService: DeleteManagedMemberWarningService,
private configService: ConfigService,
private organizationUserService: OrganizationUserService,
) {
super(
apiService,
@@ -327,15 +329,24 @@ export class MembersComponent extends BaseMembersComponent<OrganizationUserView>
}
async confirmUser(user: OrganizationUserView, publicKey: Uint8Array): Promise<void> {
const orgKey = await this.keyService.getOrgKey(this.organization.id);
const key = await this.encryptService.encapsulateKeyUnsigned(orgKey, publicKey);
const request = new OrganizationUserConfirmRequest();
request.key = key.encryptedString;
await this.organizationUserApiService.postOrganizationUserConfirm(
this.organization.id,
user.id,
request,
);
if (
await firstValueFrom(this.configService.getFeatureFlag$(FeatureFlag.CreateDefaultLocation))
) {
this.organizationUserService
.confirmUser(this.organization, user, publicKey)
.pipe(takeUntilDestroyed())
.subscribe();
} else {
const orgKey = await this.keyService.getOrgKey(this.organization.id);
const key = await this.encryptService.encapsulateKeyUnsigned(orgKey, publicKey);
const request = new OrganizationUserConfirmRequest();
request.key = key.encryptedString;
await this.organizationUserApiService.postOrganizationUserConfirm(
this.organization.id,
user.id,
request,
);
}
}
async revoke(user: OrganizationUserView) {

View File

@@ -0,0 +1,69 @@
import { Injectable } from "@angular/core";
import { combineLatest, filter, map, Observable, switchMap } from "rxjs";
import {
OrganizationUserConfirmRequest,
OrganizationUserApiService,
} from "@bitwarden/admin-console/common";
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 { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { OrganizationId } from "@bitwarden/common/types/guid";
import { KeyService } from "@bitwarden/key-management";
import { OrganizationUserView } from "../../../core/views/organization-user.view";
@Injectable({
providedIn: "root",
})
export class OrganizationUserService {
constructor(
protected keyService: KeyService,
private encryptService: EncryptService,
private organizationUserApiService: OrganizationUserApiService,
private accountService: AccountService,
private i18nService: I18nService,
) {}
private orgKey$(organization: Organization) {
return this.accountService.activeAccount$.pipe(
getUserId,
switchMap((userId) => this.keyService.orgKeys$(userId)),
filter((orgKeys) => !!orgKeys),
map((organizationKeysById) => organizationKeysById[organization.id as OrganizationId]),
);
}
confirmUser(
organization: Organization,
user: OrganizationUserView,
publicKey: Uint8Array,
): Observable<void> {
const encryptedCollectionName$ = this.orgKey$(organization).pipe(
switchMap((orgKey) =>
this.encryptService.encryptString(this.i18nService.t("My Itmes"), orgKey),
),
);
const encryptedKey$ = this.orgKey$(organization).pipe(
switchMap((orgKey) => this.encryptService.encapsulateKeyUnsigned(orgKey, publicKey)),
);
return combineLatest([encryptedKey$, encryptedCollectionName$]).pipe(
switchMap(([key, collectionName]) => {
const request: OrganizationUserConfirmRequest = {
key: key.encryptedString,
defaultUserCollectionName: collectionName.encryptedString,
};
return this.organizationUserApiService.postOrganizationUserConfirm(
organization.id,
user.id,
request,
);
}),
);
}
}

View File

@@ -1,5 +1,6 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { EncryptedString } from "@bitwarden/common/platform/models/domain/enc-string";
export class OrganizationUserConfirmRequest {
key: string;
key: EncryptedString | undefined;
defaultUserCollectionName: EncryptedString | undefined;
}

View File

@@ -13,6 +13,7 @@ export enum FeatureFlag {
/* Admin Console Team */
SeparateCustomRolePermissions = "pm-19917-separate-custom-role-permissions",
OptimizeNestedTraverseTypescript = "pm-21695-optimize-nested-traverse-typescript",
CreateDefaultLocation = "pm-19467-create-default-location",
/* Auth */
PM16117_SetInitialPasswordRefactor = "pm-16117-set-initial-password-refactor",
@@ -77,6 +78,7 @@ export const DefaultFeatureFlagValue = {
/* Admin Console Team */
[FeatureFlag.SeparateCustomRolePermissions]: FALSE,
[FeatureFlag.OptimizeNestedTraverseTypescript]: FALSE,
[FeatureFlag.CreateDefaultLocation]: FALSE,
/* Autofill */
[FeatureFlag.BlockBrowserInjectionsByDomain]: FALSE,