Cleanup - unused files / unused exports / duplicate exports
[ProtonMail-WebClient.git] / packages / shared / lib / organization / helper.ts
blob9c84e475206ca496c574746c3a3644c6253d205d
1 import { c } from 'ttag';
3 import { PLANS } from '@proton/payments';
4 import { getIsPasswordless } from '@proton/shared/lib/keys';
6 import { MEMBER_ROLE, MEMBER_SUBSCRIBER } from '../constants';
7 import type { Address, CachedOrganizationKey, Domain, Member, Organization } from '../interfaces';
8 import { DOMAIN_STATE, MEMBER_ORG_KEY_STATE } from '../interfaces';
10 export const isSuperAdmin = (members: Member[]) =>
11     (members || []).some(({ Subscriber, Self }) => Self === 1 && Subscriber === MEMBER_SUBSCRIBER.PAYER);
13 export const getHasOtherAdmins = (members: Member[]) =>
14     members.some(({ Role, Self }) => Self !== 1 && Role === MEMBER_ROLE.ORGANIZATION_ADMIN);
16 export const getNonPrivateMembers = (members: Member[]) => members.filter(({ Private }) => Private === 0);
17 export const getMemberHasAccessToOrgKey = (member: Member) =>
18     member.AccessToOrgKey === MEMBER_ORG_KEY_STATE.Active || member.AccessToOrgKey === MEMBER_ORG_KEY_STATE.Pending;
20 export const getMemberHasMissingOrgKey = (member: Member) => member.AccessToOrgKey === MEMBER_ORG_KEY_STATE.Missing;
22 export const isOrganizationDuo = (organization?: Organization) => organization?.PlanName === PLANS.DUO;
23 export const isOrganizationFamily = (organization?: Organization) => organization?.PlanName === PLANS.FAMILY;
24 export const isOrganizationPassFamily = (organization?: Organization) => organization?.PlanName === PLANS.PASS_FAMILY;
25 export const isOrganizationVisionary = (organization?: Organization) => organization?.PlanName === PLANS.VISIONARY;
27 export const getOrganizationDenomination = (organization?: Organization) => {
28     if (
29         isOrganizationDuo(organization) ||
30         isOrganizationFamily(organization) ||
31         isOrganizationPassFamily(organization)
32     ) {
33         return 'familyGroup';
34     }
35     return 'organization';
38 export const isOrganizationB2B = (organization?: Organization) => {
39     return [
40         PLANS.MAIL_PRO,
41         PLANS.MAIL_BUSINESS,
42         PLANS.DRIVE_PRO,
43         PLANS.BUNDLE_PRO,
44         PLANS.BUNDLE_PRO_2024,
45         PLANS.ENTERPRISE,
46         PLANS.FAMILY,
47         PLANS.PASS_FAMILY,
48         PLANS.DUO,
49         PLANS.VISIONARY,
50     ].includes(organization?.PlanName as PLANS);
53 /** True if user is part of an organization (works also for org admins) */
54 export const isOrganization = (organization?: Organization) =>
55     isOrganizationFamily(organization) ||
56     isOrganizationPassFamily(organization) ||
57     isOrganizationDuo(organization) ||
58     isOrganizationB2B(organization) ||
59     isOrganizationVisionary(organization);
61 export enum OrganizationKeyState {
62     NoKey,
63     Setup,
64     Activate,
65     Inactive,
66     Active,
69 export enum OrganizationKeyMode {
70     Legacy,
71     Passwordless,
74 export const getOrganizationKeyInfo = (
75     organization: Organization | undefined,
76     organizationKey: CachedOrganizationKey | undefined,
77     addresses: Address[] | undefined
78 ) => {
79     const organizationHasKeys = !!organization?.HasKeys && !organizationKey?.placeholder;
80     // If the user has the organization key (not the organization itself).
81     const userHasActivatedOrganizationKeys = !!organizationKey?.Key?.PrivateKey;
82     // If the user has the organization key, but it's not decrypted. Typically following a password reset
83     const userHasInactiveKey = userHasActivatedOrganizationKeys && !organizationKey?.privateKey;
84     const userHasActiveKey = organizationHasKeys && !!organizationKey?.privateKey;
85     const userHasNoKey = organizationKey?.Key.AccessToOrgKey === MEMBER_ORG_KEY_STATE.NoKey;
86     const userHasMissingKey = organizationKey?.Key.AccessToOrgKey === MEMBER_ORG_KEY_STATE.Missing;
88     if (getIsPasswordless(organizationKey?.Key)) {
89         let hasActivation = organizationHasKeys && !!organizationKey?.Key.SignatureAddress;
90         let hasActivationAddress = organizationKey?.Key.EncryptionAddressID
91             ? addresses?.find((address) => address.ID === organizationKey.Key.EncryptionAddressID)
92             : undefined;
94         return {
95             mode: OrganizationKeyMode.Passwordless,
96             state: (() => {
97                 if (userHasNoKey) {
98                     return OrganizationKeyState.NoKey;
99                 }
100                 if (!organizationHasKeys) {
101                     return OrganizationKeyState.Setup;
102                 }
103                 if (hasActivationAddress && hasActivation) {
104                     return OrganizationKeyState.Activate;
105                 }
106                 if (userHasInactiveKey || userHasMissingKey) {
107                     return OrganizationKeyState.Inactive;
108                 }
109                 if (userHasActiveKey) {
110                     return OrganizationKeyState.Active;
111                 }
112                 return OrganizationKeyState.Setup;
113             })(),
114         };
115     }
117     return {
118         mode: OrganizationKeyMode.Legacy,
119         state: (() => {
120             if (userHasNoKey) {
121                 return OrganizationKeyState.NoKey;
122             }
123             if (!organizationHasKeys) {
124                 return OrganizationKeyState.Setup;
125             }
126             // If the user does not have the organization key but the organization has keys setup, it's inactive
127             if (!userHasActivatedOrganizationKeys) {
128                 return OrganizationKeyState.Activate;
129             }
130             if (userHasInactiveKey) {
131                 return OrganizationKeyState.Inactive;
132             }
133             if (userHasActiveKey) {
134                 return OrganizationKeyState.Active;
135             }
136             return OrganizationKeyState.Setup;
137         })(),
138     };
141 export type OrganizationKeyInfo = ReturnType<typeof getOrganizationKeyInfo>;
143 export const validateOrganizationKey = (info: OrganizationKeyInfo) => {
144     if (info.state === OrganizationKeyState.NoKey) {
145         return c('passwordless').t`You need access to the organization key to perform this operation.`;
146     }
147     if (info.state === OrganizationKeyState.Activate) {
148         return c('passwordless').t`The organization key must be activated first.`;
149     }
150     if (info.state === OrganizationKeyState.Inactive) {
151         return c('passwordless').t`Permission denied, administrator privileges have been restricted.`;
152     }
153     if (info.state === OrganizationKeyState.Setup) {
154         return c('passwordless').t`Organization key does not exist.`;
155     }
158 // Active domains is one that's verified or in warning state, but it can be used to create addresses to
159 export const getIsDomainActive = (domain: Domain) => {
160     return (
161         (domain.State === DOMAIN_STATE.DOMAIN_STATE_VERIFIED || domain.State === DOMAIN_STATE.DOMAIN_STATE_WARN) &&
162         domain.Flags['mail-intent']
163     );