1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-20 10:13:31 +00:00

Merge branch 'main' into autofill/pm-8027-inline-menu-appears-within-input-fields-that-do-not-relate-to-user-login

This commit is contained in:
Cesar Gonzalez
2024-06-11 08:35:38 -05:00
committed by GitHub
103 changed files with 1678 additions and 1027 deletions

View File

@@ -20,8 +20,6 @@ export class UserTypePipe implements PipeTransform {
return this.i18nService.t("admin");
case OrganizationUserType.User:
return this.i18nService.t("user");
case OrganizationUserType.Manager:
return this.i18nService.t("manager");
case OrganizationUserType.Custom:
return this.i18nService.t("custom");
}

View File

@@ -1,4 +1,4 @@
import { Observable, Subject, Subscription, firstValueFrom, throwError, timeout } from "rxjs";
import { firstValueFrom, Observable, Subject, Subscription, throwError, timeout } from "rxjs";
/** Test class to enable async awaiting of observable emissions */
export class ObservableTracker<T> {
@@ -43,6 +43,9 @@ export class ObservableTracker<T> {
private trackEmissions(observable: Observable<T>): T[] {
const emissions: T[] = [];
this.emissionReceived.subscribe((value) => {
emissions.push(value);
});
this.subscription = observable.subscribe((value) => {
if (value == null) {
this.emissionReceived.next(null);
@@ -64,9 +67,7 @@ export class ObservableTracker<T> {
}
}
});
this.emissionReceived.subscribe((value) => {
emissions.push(value);
});
return emissions;
}
}

View File

@@ -5,7 +5,6 @@ import { SelectionReadOnlyRequest } from "../../../models/request/selection-read
export class OrganizationUserInviteRequest {
emails: string[] = [];
type: OrganizationUserType;
accessAll: boolean;
accessSecretsManager: boolean;
collections: SelectionReadOnlyRequest[] = [];
groups: string[];

View File

@@ -4,7 +4,6 @@ import { SelectionReadOnlyRequest } from "../../../models/request/selection-read
export class OrganizationUserUpdateRequest {
type: OrganizationUserType;
accessAll: boolean;
accessSecretsManager: boolean;
collections: SelectionReadOnlyRequest[] = [];
groups: string[] = [];

View File

@@ -10,11 +10,6 @@ export class OrganizationUserResponse extends BaseResponse {
type: OrganizationUserType;
status: OrganizationUserStatusType;
externalId: string;
/**
* @deprecated
* To be removed after Flexible Collections.
**/
accessAll: boolean;
accessSecretsManager: boolean;
permissions: PermissionsApi;
resetPasswordEnrolled: boolean;
@@ -30,7 +25,6 @@ export class OrganizationUserResponse extends BaseResponse {
this.status = this.getResponseProperty("Status");
this.permissions = new PermissionsApi(this.getResponseProperty("Permissions"));
this.externalId = this.getResponseProperty("ExternalId");
this.accessAll = this.getResponseProperty("AccessAll");
this.accessSecretsManager = this.getResponseProperty("AccessSecretsManager");
this.resetPasswordEnrolled = this.getResponseProperty("ResetPasswordEnrolled");
this.hasMasterPassword = this.getResponseProperty("HasMasterPassword");

View File

@@ -7,7 +7,7 @@ import { OrganizationData } from "../../models/data/organization.data";
import { Organization } from "../../models/domain/organization";
export function canAccessVaultTab(org: Organization): boolean {
return org.canViewAssignedCollections || org.canViewAllCollections;
return org.canViewAllCollections;
}
export function canAccessSettingsTab(org: Organization): boolean {
@@ -77,10 +77,7 @@ export function canAccessImportExport(i18nService: I18nService) {
export function canAccessImport(i18nService: I18nService) {
return map<Organization[], Organization[]>((orgs) =>
orgs
.filter(
(org) =>
org.canAccessImportExport || (org.canCreateNewCollections && org.flexibleCollections),
)
.filter((org) => org.canAccessImportExport || org.canCreateNewCollections)
.sort(Utils.getSortFunction(i18nService, "name")),
);
}

View File

@@ -39,6 +39,7 @@ describe("ORGANIZATIONS state", () => {
permissions: undefined,
resetPasswordEnrolled: false,
userId: "userId",
organizationUserId: "organizationUserId",
hasPublicAndPrivateKeys: false,
providerId: "providerId",
providerName: "providerName",

View File

@@ -36,6 +36,7 @@ export class OrganizationData {
permissions: PermissionsApi;
resetPasswordEnrolled: boolean;
userId: string;
organizationUserId: string;
hasPublicAndPrivateKeys: boolean;
providerId: string;
providerName: string;
@@ -96,6 +97,7 @@ export class OrganizationData {
this.permissions = response.permissions;
this.resetPasswordEnrolled = response.resetPasswordEnrolled;
this.userId = response.userId;
this.organizationUserId = response.organizationUserId;
this.hasPublicAndPrivateKeys = response.hasPublicAndPrivateKeys;
this.providerId = response.providerId;
this.providerName = response.providerName;

View File

@@ -43,6 +43,7 @@ export class Organization {
permissions: PermissionsApi;
resetPasswordEnrolled: boolean;
userId: string;
organizationUserId: string;
hasPublicAndPrivateKeys: boolean;
providerId: string;
providerName: string;
@@ -113,6 +114,7 @@ export class Organization {
this.permissions = obj.permissions;
this.resetPasswordEnrolled = obj.resetPasswordEnrolled;
this.userId = obj.userId;
this.organizationUserId = obj.organizationUserId;
this.hasPublicAndPrivateKeys = obj.hasPublicAndPrivateKeys;
this.providerId = obj.providerId;
this.providerName = obj.providerName;
@@ -140,16 +142,6 @@ export class Organization {
return this.enabled && this.status === OrganizationUserStatusType.Confirmed;
}
/**
* Whether a user has Manager permissions or greater
*
* @deprecated
* This is deprecated with the introduction of Flexible Collections.
*/
get isManager() {
return this.type === OrganizationUserType.Manager || this.isAdmin;
}
/**
* Whether a user has Admin permissions or greater
*/
@@ -177,19 +169,13 @@ export class Organization {
}
get canCreateNewCollections() {
if (this.flexibleCollections) {
return (
!this.limitCollectionCreationDeletion ||
this.isAdmin ||
this.permissions.createNewCollections
);
}
return this.isManager || this.permissions.createNewCollections;
return (
!this.limitCollectionCreationDeletion || this.isAdmin || this.permissions.createNewCollections
);
}
canEditAnyCollection(flexibleCollectionsV1Enabled: boolean) {
if (!this.flexibleCollections || !flexibleCollectionsV1Enabled) {
if (!flexibleCollectionsV1Enabled) {
// Pre-Flexible Collections v1 logic
return this.isAdmin || this.permissions.editAnyCollection;
}
@@ -219,8 +205,8 @@ export class Organization {
flexibleCollectionsV1Enabled: boolean,
restrictProviderAccessFlagEnabled: boolean,
) {
// Before Flexible Collections, any admin or anyone with editAnyCollection permission could edit all ciphers
if (!this.flexibleCollections || !flexibleCollectionsV1Enabled || !this.flexibleCollections) {
// Before Flexible Collections V1, any admin or anyone with editAnyCollection permission could edit all ciphers
if (!flexibleCollectionsV1Enabled) {
return this.isAdmin || this.permissions.editAnyCollection;
}
@@ -267,33 +253,6 @@ export class Organization {
);
}
/**
* @deprecated
* This is deprecated with the introduction of Flexible Collections.
* This will always return false if FlexibleCollections flag is on.
*/
get canEditAssignedCollections() {
return this.isManager || this.permissions.editAssignedCollections;
}
/**
* @deprecated
* This is deprecated with the introduction of Flexible Collections.
* This will always return false if FlexibleCollections flag is on.
*/
get canDeleteAssignedCollections() {
return this.isManager || this.permissions.deleteAssignedCollections;
}
/**
* @deprecated
* This is deprecated with the introduction of Flexible Collections.
* This will always return false if FlexibleCollections flag is on.
*/
get canViewAssignedCollections() {
return this.canDeleteAssignedCollections || this.canEditAssignedCollections;
}
get canManageGroups() {
return (this.isAdmin || this.permissions.manageGroups) && this.useGroups;
}

View File

@@ -36,6 +36,7 @@ export class ProfileOrganizationResponse extends BaseResponse {
permissions: PermissionsApi;
resetPasswordEnrolled: boolean;
userId: string;
organizationUserId: string;
providerId: string;
providerName: string;
providerType?: ProviderType;
@@ -86,6 +87,7 @@ export class ProfileOrganizationResponse extends BaseResponse {
this.permissions = new PermissionsApi(this.getResponseProperty("permissions"));
this.resetPasswordEnrolled = this.getResponseProperty("ResetPasswordEnrolled");
this.userId = this.getResponseProperty("UserId");
this.organizationUserId = this.getResponseProperty("OrganizationUserId");
this.providerId = this.getResponseProperty("ProviderId");
this.providerName = this.getResponseProperty("ProviderName");
this.providerType = this.getResponseProperty("ProviderType");

View File

@@ -49,15 +49,11 @@ export class CollectionView implements View, ITreeNodeObject {
);
}
if (org?.flexibleCollections) {
return (
org?.canEditAllCiphers(v1FlexibleCollections, restrictProviderAccess) ||
this.manage ||
(this.assigned && !this.readOnly)
);
}
return org?.canEditAnyCollection(false) || (org?.canEditAssignedCollections && this.assigned);
return (
org?.canEditAllCiphers(v1FlexibleCollections, restrictProviderAccess) ||
this.manage ||
(this.assigned && !this.readOnly)
);
}
/**

View File

@@ -256,17 +256,14 @@ export class ImportComponent implements OnInit, OnDestroy {
if (!this._importBlockedByPolicy) {
this.formGroup.controls.targetSelector.enable();
}
const flexCollectionEnabled =
organizations.find((x) => x.id == this.organizationId)?.flexibleCollections ?? false;
if (value) {
this.collections$ = Utils.asyncToObservable(() =>
this.collectionService
.getAllDecrypted()
.then((decryptedCollections) =>
decryptedCollections
.filter(
(c2) => c2.organizationId === value && (!flexCollectionEnabled || c2.manage),
)
.filter((c2) => c2.organizationId === value && c2.manage)
.sort(Utils.getSortFunction(this.i18nService, "name")),
),
);

View File

@@ -167,11 +167,7 @@ export class ExportComponent implements OnInit, OnDestroy {
}
this.organizations$ = this.organizationService.memberOrganizations$.pipe(
map((orgs) =>
orgs
.filter((org) => org.flexibleCollections)
.sort(Utils.getSortFunction(this.i18nService, "name")),
),
map((orgs) => orgs.sort(Utils.getSortFunction(this.i18nService, "name"))),
);
this.exportForm.controls.vaultSelector.valueChanges