Use same lock values as mobile clients
[ProtonMail-WebClient.git] / packages / shared / lib / helpers / addons.ts
blob711f4796229c2c63b4477d4df37d6d9ba28bc5c2
1 import {
2     ADDON_NAMES,
3     DOMAIN_ADDON_PREFIX,
4     type FreeSubscription,
5     IP_ADDON_PREFIX,
6     MEMBER_ADDON_PREFIX,
7     PLANS,
8     SCRIBE_ADDON_PREFIX,
9     isFreeSubscription,
10 } from '../constants';
11 import type { Addon, PlanIDs, SubscriptionModel } from '../interfaces';
13 type AddonOrName = Addon | ADDON_NAMES | PLANS;
15 function isAddonType(addonOrName: AddonOrName, addonPrefix: string): boolean {
16     let addonName: ADDON_NAMES | PLANS;
17     if (typeof addonOrName === 'string') {
18         addonName = addonOrName;
19     } else {
20         addonName = addonOrName.Name;
21     }
23     return addonName.startsWith(addonPrefix);
26 export const isScribeAddon: AddonGuard = (addonOrName): boolean => {
27     return isAddonType(addonOrName, SCRIBE_ADDON_PREFIX);
30 export function hasScribeAddon(subscriptionOrPlanIds: SubscriptionModel | FreeSubscription | undefined): boolean {
31     const subscription = subscriptionOrPlanIds;
33     if (!subscription || isFreeSubscription(subscription)) {
34         return false;
35     }
37     const plans = subscription.Plans;
38     return plans.some((plan) => isScribeAddon(plan.Name));
41 export type AddonGuard = (addonOrName: AddonOrName) => boolean;
43 const ORG_SIZE_ADDONS = [
44     ADDON_NAMES.MEMBER_VPN_BUSINESS,
45     ADDON_NAMES.MEMBER_VPN_PRO,
46     ADDON_NAMES.MEMBER_PASS_BUSINESS,
47     ADDON_NAMES.MEMBER_PASS_PRO,
50 export const isOrgSizeAddon: AddonGuard = (addonOrName): boolean => {
51     return ORG_SIZE_ADDONS.some((name) => addonOrName === name);
54 export const isMemberAddon: AddonGuard = (addonOrName): boolean => {
55     return isAddonType(addonOrName, MEMBER_ADDON_PREFIX);
58 export const isDomainAddon: AddonGuard = (addonOrName): boolean => {
59     return isAddonType(addonOrName, DOMAIN_ADDON_PREFIX);
62 export const isIpAddon: AddonGuard = (addonOrName): boolean => {
63     return isAddonType(addonOrName, IP_ADDON_PREFIX);
66 export const removeAddon = (originalPlanIDs: PlanIDs, addonGuard: AddonGuard): PlanIDs => {
67     const planIDs: PlanIDs = { ...originalPlanIDs };
69     // if guard returns true, it means that the addon should be removed
70     for (const addonName of Object.keys(planIDs) as (ADDON_NAMES | PLANS)[]) {
71         if (addonGuard(addonName)) {
72             delete planIDs[addonName];
73         }
74     }
76     return planIDs;
79 export const countAddonsByType = (planIDs: PlanIDs, addonGuard: AddonGuard): number => {
80     return Object.keys(planIDs).reduce((acc, key) => {
81         const addonName = key as ADDON_NAMES | PLANS;
83         if (addonGuard(addonName)) {
84             return acc + (planIDs[addonName] ?? 0);
85         }
86         return acc;
87     }, 0);
90 const {
91     MAIL,
92     DRIVE,
93     MAIL_BUSINESS,
94     ENTERPRISE,
95     BUNDLE,
96     BUNDLE_PRO,
97     BUNDLE_PRO_2024,
98     MAIL_PRO,
99     DRIVE_PRO,
100     VPN_PRO,
101     VPN_BUSINESS,
102     PASS_PRO,
103     PASS_BUSINESS,
104 } = PLANS;
106 export type SupportedAddons = Partial<Record<ADDON_NAMES, boolean>>;
108 export function getSupportedB2CAddons(planIDs: PlanIDs): SupportedAddons {
109     const supported: SupportedAddons = {};
111     // Re-enable the scribe addons when/if B2C plans trully support them
113     if (planIDs[MAIL]) {
114         // supported[ADDON_NAMES.MEMBER_SCRIBE_MAILPLUS] = true;
115     }
117     if (planIDs[DRIVE]) {
118         // supported[ADDON_NAMES.MEMBER_SCRIBE_DRIVEPLUS] = true;
119     }
121     if (planIDs[BUNDLE]) {
122         // supported[ADDON_NAMES.MEMBER_SCRIBE_BUNDLE] = true;
123     }
125     return supported;
128 export function getSupportedB2BAddons(planIDs: PlanIDs): SupportedAddons {
129     const supported: SupportedAddons = {};
131     if (planIDs[MAIL_PRO]) {
132         supported[ADDON_NAMES.MEMBER_MAIL_PRO] = true;
133         supported[ADDON_NAMES.MEMBER_SCRIBE_MAIL_PRO] = true;
134     }
136     if (planIDs[MAIL_BUSINESS]) {
137         supported[ADDON_NAMES.MEMBER_MAIL_BUSINESS] = true;
138         supported[ADDON_NAMES.MEMBER_SCRIBE_MAIL_BUSINESS] = true;
139     }
141     if (planIDs[DRIVE_PRO]) {
142         supported[ADDON_NAMES.MEMBER_DRIVE_PRO] = true;
143     }
145     if (planIDs[BUNDLE_PRO]) {
146         supported[ADDON_NAMES.MEMBER_BUNDLE_PRO] = true;
147         supported[ADDON_NAMES.DOMAIN_BUNDLE_PRO] = true;
148         supported[ADDON_NAMES.MEMBER_SCRIBE_BUNDLE_PRO] = true;
149     }
151     if (planIDs[BUNDLE_PRO_2024]) {
152         supported[ADDON_NAMES.MEMBER_BUNDLE_PRO_2024] = true;
153         supported[ADDON_NAMES.DOMAIN_BUNDLE_PRO_2024] = true;
154         supported[ADDON_NAMES.MEMBER_SCRIBE_BUNDLE_PRO_2024] = true;
155     }
157     if (planIDs[ENTERPRISE]) {
158         supported[ADDON_NAMES.MEMBER_ENTERPRISE] = true;
159         supported[ADDON_NAMES.DOMAIN_ENTERPRISE] = true;
160     }
162     if (planIDs[VPN_PRO]) {
163         supported[ADDON_NAMES.MEMBER_VPN_PRO] = true;
164     }
166     if (planIDs[VPN_BUSINESS]) {
167         supported[ADDON_NAMES.MEMBER_VPN_BUSINESS] = true;
168         supported[ADDON_NAMES.IP_VPN_BUSINESS] = true;
169     }
171     if (planIDs[PASS_PRO]) {
172         supported[ADDON_NAMES.MEMBER_PASS_PRO] = true;
173     }
175     if (planIDs[PASS_BUSINESS]) {
176         supported[ADDON_NAMES.MEMBER_PASS_BUSINESS] = true;
177     }
179     return supported;
182 export const getSupportedAddons = (planIDs: PlanIDs): SupportedAddons => {
183     const supported: SupportedAddons = {
184         ...getSupportedB2CAddons(planIDs),
185         ...getSupportedB2BAddons(planIDs),
186     };
188     return supported;