mirror of
https://github.com/bitwarden/browser
synced 2025-12-10 05:13:29 +00:00
389 lines
13 KiB
TypeScript
389 lines
13 KiB
TypeScript
// FIXME: Update this file to be type safe and remove this and next line
|
|
// @ts-strict-ignore
|
|
import { Jsonify } from "type-fest";
|
|
|
|
import { MemberDecryptionType } from "../../../auth/enums/sso";
|
|
import { ProductTierType } from "../../../billing/enums";
|
|
import { OrganizationId } from "../../../types/guid";
|
|
import { OrganizationUserStatusType, OrganizationUserType, ProviderType } from "../../enums";
|
|
import { PermissionsApi } from "../api/permissions.api";
|
|
import { OrganizationData } from "../data/organization.data";
|
|
|
|
export class Organization {
|
|
id: OrganizationId;
|
|
name: string;
|
|
status: OrganizationUserStatusType;
|
|
|
|
/**
|
|
* The member's role in the organization.
|
|
* Avoid using this for permission checks - use the getters instead (e.g. isOwner, isAdmin, canManageX), because they
|
|
* properly handle permission inheritance and relationships.
|
|
*/
|
|
type: OrganizationUserType;
|
|
|
|
enabled: boolean;
|
|
usePolicies: boolean;
|
|
useGroups: boolean;
|
|
useDirectory: boolean;
|
|
useEvents: boolean;
|
|
useTotp: boolean;
|
|
use2fa: boolean;
|
|
useApi: boolean;
|
|
useSso: boolean;
|
|
useOrganizationDomains: boolean;
|
|
useKeyConnector: boolean;
|
|
useScim: boolean;
|
|
useCustomPermissions: boolean;
|
|
useResetPassword: boolean;
|
|
useSecretsManager: boolean;
|
|
usePasswordManager: boolean;
|
|
useActivateAutofillPolicy: boolean;
|
|
selfHost: boolean;
|
|
usersGetPremium: boolean;
|
|
seats: number;
|
|
maxCollections: number;
|
|
maxStorageGb?: number;
|
|
ssoBound: boolean;
|
|
identifier: string;
|
|
permissions: PermissionsApi;
|
|
resetPasswordEnrolled: boolean;
|
|
userId: string;
|
|
organizationUserId: string;
|
|
hasPublicAndPrivateKeys: boolean;
|
|
providerId: string;
|
|
providerName: string;
|
|
providerType?: ProviderType;
|
|
/**
|
|
* Indicates that a user is a ProviderUser for the organization
|
|
*/
|
|
isProviderUser: boolean;
|
|
/**
|
|
* Indicates that a user is a member for the organization (may be `false` if they have access via a Provider only)
|
|
*/
|
|
isMember: boolean;
|
|
familySponsorshipFriendlyName: string;
|
|
familySponsorshipAvailable: boolean;
|
|
productTierType: ProductTierType;
|
|
keyConnectorEnabled: boolean;
|
|
keyConnectorUrl: string;
|
|
familySponsorshipLastSyncDate?: Date;
|
|
familySponsorshipValidUntil?: Date;
|
|
familySponsorshipToDelete?: boolean;
|
|
accessSecretsManager: boolean;
|
|
/**
|
|
* Refers to the ability for an organization to limit collection creation and deletion to owners and admins only
|
|
*/
|
|
limitCollectionCreation: boolean;
|
|
limitCollectionDeletion: boolean;
|
|
|
|
/**
|
|
* Refers to the ability for an owner/admin to access all collection items, regardless of assigned collections
|
|
*/
|
|
limitItemDeletion: boolean;
|
|
/**
|
|
* Refers to the ability to limit delete permission of collection items.
|
|
* If set to true, members can only delete items when they have a Can Manage permission over the collection.
|
|
* If set to false, members can delete items when they have a Can Manage OR Can Edit permission over the collection.
|
|
*/
|
|
allowAdminAccessToAllCollectionItems: boolean;
|
|
/**
|
|
* Indicates if this organization manages the user.
|
|
* A user is considered managed by an organization if their email domain
|
|
* matches one of the verified domains of that organization, and the user is a member of it.
|
|
*/
|
|
userIsManagedByOrganization: boolean;
|
|
useRiskInsights: boolean;
|
|
useAdminSponsoredFamilies: boolean;
|
|
isAdminInitiated: boolean;
|
|
ssoEnabled: boolean;
|
|
ssoMemberDecryptionType?: MemberDecryptionType;
|
|
|
|
constructor(obj?: OrganizationData) {
|
|
if (obj == null) {
|
|
return;
|
|
}
|
|
|
|
this.id = obj.id as OrganizationId;
|
|
this.name = obj.name;
|
|
this.status = obj.status;
|
|
this.type = obj.type;
|
|
this.enabled = obj.enabled;
|
|
this.usePolicies = obj.usePolicies;
|
|
this.useGroups = obj.useGroups;
|
|
this.useDirectory = obj.useDirectory;
|
|
this.useEvents = obj.useEvents;
|
|
this.useTotp = obj.useTotp;
|
|
this.use2fa = obj.use2fa;
|
|
this.useApi = obj.useApi;
|
|
this.useSso = obj.useSso;
|
|
this.useOrganizationDomains = obj.useOrganizationDomains;
|
|
this.useKeyConnector = obj.useKeyConnector;
|
|
this.useScim = obj.useScim;
|
|
this.useCustomPermissions = obj.useCustomPermissions;
|
|
this.useResetPassword = obj.useResetPassword;
|
|
this.useSecretsManager = obj.useSecretsManager;
|
|
this.usePasswordManager = obj.usePasswordManager;
|
|
this.useActivateAutofillPolicy = obj.useActivateAutofillPolicy;
|
|
this.selfHost = obj.selfHost;
|
|
this.usersGetPremium = obj.usersGetPremium;
|
|
this.seats = obj.seats;
|
|
this.maxCollections = obj.maxCollections;
|
|
this.maxStorageGb = obj.maxStorageGb;
|
|
this.ssoBound = obj.ssoBound;
|
|
this.identifier = obj.identifier;
|
|
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;
|
|
this.providerType = obj.providerType;
|
|
this.isProviderUser = obj.isProviderUser;
|
|
this.isMember = obj.isMember;
|
|
this.familySponsorshipFriendlyName = obj.familySponsorshipFriendlyName;
|
|
this.familySponsorshipAvailable = obj.familySponsorshipAvailable;
|
|
this.productTierType = obj.productTierType;
|
|
this.keyConnectorEnabled = obj.keyConnectorEnabled;
|
|
this.keyConnectorUrl = obj.keyConnectorUrl;
|
|
this.familySponsorshipLastSyncDate = obj.familySponsorshipLastSyncDate;
|
|
this.familySponsorshipValidUntil = obj.familySponsorshipValidUntil;
|
|
this.familySponsorshipToDelete = obj.familySponsorshipToDelete;
|
|
this.accessSecretsManager = obj.accessSecretsManager;
|
|
this.limitCollectionCreation = obj.limitCollectionCreation;
|
|
this.limitCollectionDeletion = obj.limitCollectionDeletion;
|
|
this.limitItemDeletion = obj.limitItemDeletion;
|
|
this.allowAdminAccessToAllCollectionItems = obj.allowAdminAccessToAllCollectionItems;
|
|
this.userIsManagedByOrganization = obj.userIsManagedByOrganization;
|
|
this.useRiskInsights = obj.useRiskInsights;
|
|
this.useAdminSponsoredFamilies = obj.useAdminSponsoredFamilies;
|
|
this.isAdminInitiated = obj.isAdminInitiated;
|
|
this.ssoEnabled = obj.ssoEnabled;
|
|
this.ssoMemberDecryptionType = obj.ssoMemberDecryptionType;
|
|
}
|
|
|
|
get canAccess() {
|
|
if (this.isOwner) {
|
|
return true;
|
|
}
|
|
return this.enabled && this.status === OrganizationUserStatusType.Confirmed;
|
|
}
|
|
|
|
/**
|
|
* Whether a user has Admin permissions or greater
|
|
*/
|
|
get isAdmin() {
|
|
return this.type === OrganizationUserType.Admin || this.isOwner;
|
|
}
|
|
|
|
/**
|
|
* Whether a user has Owner permissions (including ProviderUsers)
|
|
*/
|
|
get isOwner() {
|
|
return this.type === OrganizationUserType.Owner || this.isProviderUser;
|
|
}
|
|
|
|
get canAccessEventLogs() {
|
|
return (this.isAdmin || this.permissions.accessEventLogs) && this.useEvents;
|
|
}
|
|
|
|
/**
|
|
* Returns true if the user can access the Import page in the Admin Console.
|
|
* Note: this does not affect user access to the Import page in Password Manager, which can also be used to import
|
|
* into organization collections.
|
|
*/
|
|
get canAccessImport() {
|
|
return (
|
|
this.isProviderUser ||
|
|
this.type === OrganizationUserType.Owner ||
|
|
this.type === OrganizationUserType.Admin ||
|
|
this.permissions.accessImportExport
|
|
);
|
|
}
|
|
|
|
get canAccessExport() {
|
|
return (
|
|
this.isMember &&
|
|
(this.type === OrganizationUserType.Owner ||
|
|
this.type === OrganizationUserType.Admin ||
|
|
this.permissions.accessImportExport)
|
|
);
|
|
}
|
|
|
|
get canAccessReports() {
|
|
return this.isAdmin || this.permissions.accessReports;
|
|
}
|
|
|
|
get canCreateNewCollections() {
|
|
return !this.limitCollectionCreation || this.isAdmin || this.permissions.createNewCollections;
|
|
}
|
|
|
|
get canEditAnyCollection() {
|
|
// The allowAdminAccessToAllCollectionItems flag can restrict admins
|
|
// Providers and custom users with canEditAnyCollection are not affected by allowAdminAccessToAllCollectionItems flag
|
|
return (
|
|
this.isProviderUser ||
|
|
(this.type === OrganizationUserType.Custom && this.permissions.editAnyCollection) ||
|
|
(this.allowAdminAccessToAllCollectionItems && this.isAdmin)
|
|
);
|
|
}
|
|
|
|
get canEditUnmanagedCollections() {
|
|
// Any admin or custom user with editAnyCollection permission can edit unmanaged collections
|
|
return this.isAdmin || this.permissions.editAnyCollection;
|
|
}
|
|
|
|
get canEditUnassignedCiphers() {
|
|
return (
|
|
this.type === OrganizationUserType.Admin ||
|
|
this.type === OrganizationUserType.Owner ||
|
|
this.permissions.editAnyCollection
|
|
);
|
|
}
|
|
|
|
get canEditAllCiphers() {
|
|
// The allowAdminAccessToAllCollectionItems flag can restrict admins
|
|
// Custom users with canEditAnyCollection are not affected by allowAdminAccessToAllCollectionItems flag
|
|
return (
|
|
(this.type === OrganizationUserType.Custom && this.permissions.editAnyCollection) ||
|
|
(this.allowAdminAccessToAllCollectionItems &&
|
|
(this.type === OrganizationUserType.Admin || this.type === OrganizationUserType.Owner))
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @returns True if the user can delete any collection
|
|
*/
|
|
get canDeleteAnyCollection() {
|
|
// Providers and Users with DeleteAnyCollection permission can always delete collections
|
|
if (this.isProviderUser || this.permissions.deleteAnyCollection) {
|
|
return true;
|
|
}
|
|
|
|
// If AllowAdminAccessToAllCollectionItems is true, Owners and Admins can delete any collection, regardless of LimitCollectionDeletion setting
|
|
// Using explicit type checks because provider users are handled above and this mimics the server's permission checks closely
|
|
if (this.allowAdminAccessToAllCollectionItems) {
|
|
return this.type == OrganizationUserType.Owner || this.type == OrganizationUserType.Admin;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Whether the user can view all collection information, such as collection name and access.
|
|
* This does not indicate that the user can view items inside any collection - for that, see {@link canEditAllCiphers}
|
|
*/
|
|
get canViewAllCollections() {
|
|
// Admins can always see all collections even if collection management settings prevent them from editing them or seeing items
|
|
return (
|
|
this.isAdmin || this.permissions.editAnyCollection || this.permissions.deleteAnyCollection
|
|
);
|
|
}
|
|
|
|
get canManageGroups() {
|
|
return (this.isAdmin || this.permissions.manageGroups) && this.useGroups;
|
|
}
|
|
|
|
get canManageSso() {
|
|
return (this.isAdmin || this.permissions.manageSso) && this.useSso;
|
|
}
|
|
|
|
get canManageDomainVerification() {
|
|
return (this.isAdmin || this.permissions.manageSso) && this.useOrganizationDomains;
|
|
}
|
|
|
|
get canManageScim() {
|
|
return (this.isAdmin || this.permissions.manageScim) && this.useScim;
|
|
}
|
|
|
|
get canManagePolicies() {
|
|
return (this.isAdmin || this.permissions.managePolicies) && this.usePolicies;
|
|
}
|
|
|
|
get canManageUsers() {
|
|
return this.isAdmin || this.permissions.manageUsers;
|
|
}
|
|
|
|
get canManageUsersPassword() {
|
|
return this.isAdmin || this.permissions.manageResetPassword;
|
|
}
|
|
|
|
get canManageDeviceApprovals() {
|
|
return (this.isAdmin || this.permissions.manageResetPassword) && this.useSso;
|
|
}
|
|
|
|
get isExemptFromPolicies() {
|
|
return this.canManagePolicies;
|
|
}
|
|
|
|
get canViewSubscription() {
|
|
if (this.canEditSubscription) {
|
|
return true;
|
|
}
|
|
|
|
return this.hasBillableProvider ? this.isProviderUser : this.isOwner;
|
|
}
|
|
|
|
get canEditSubscription() {
|
|
return this.hasProvider ? this.isProviderUser : this.isOwner;
|
|
}
|
|
|
|
get canEditPaymentMethods() {
|
|
return this.canEditSubscription;
|
|
}
|
|
|
|
get canViewBillingHistory() {
|
|
return this.canEditSubscription;
|
|
}
|
|
|
|
get hasProvider() {
|
|
return this.providerId != null || this.providerName != null;
|
|
}
|
|
|
|
get hasBillableProvider() {
|
|
return (
|
|
this.hasProvider &&
|
|
(this.providerType === ProviderType.Msp || this.providerType === ProviderType.BusinessUnit)
|
|
);
|
|
}
|
|
|
|
get hasReseller() {
|
|
return this.hasProvider && this.providerType === ProviderType.Reseller;
|
|
}
|
|
|
|
get canAccessSecretsManager() {
|
|
return this.useSecretsManager && this.accessSecretsManager;
|
|
}
|
|
|
|
get isFreeOrg() {
|
|
// return true if organization needs to be upgraded from a free org
|
|
return !this.useTotp;
|
|
}
|
|
|
|
get canManageSponsorships() {
|
|
return this.familySponsorshipAvailable || this.familySponsorshipFriendlyName !== null;
|
|
}
|
|
|
|
static fromJSON(json: Jsonify<Organization>) {
|
|
if (json == null) {
|
|
return null;
|
|
}
|
|
|
|
return Object.assign(new Organization(), json, {
|
|
familySponsorshipLastSyncDate: new Date(json.familySponsorshipLastSyncDate),
|
|
familySponsorshipValidUntil: new Date(json.familySponsorshipValidUntil),
|
|
});
|
|
}
|
|
|
|
get canAccessIntegrations() {
|
|
return (
|
|
(this.productTierType === ProductTierType.Teams ||
|
|
this.productTierType === ProductTierType.Enterprise) &&
|
|
(this.isAdmin ||
|
|
this.permissions.manageUsers ||
|
|
this.permissions.manageGroups ||
|
|
this.permissions.accessEventLogs)
|
|
);
|
|
}
|
|
}
|