mirror of
https://github.com/AppFlowy-IO/AppFlowy-Web.git
synced 2026-03-13 10:00:26 +08:00
77 lines
2.5 KiB
TypeScript
77 lines
2.5 KiB
TypeScript
/**
|
|
* Check if the current host is an official AppFlowy host by looking at the backend base URL.
|
|
* Official hosts are beta.appflowy.cloud and test.appflowy.cloud.
|
|
* Include localhost:8000 to cover the default dev backend when APPFLOWY_BASE_URL isn't updated.
|
|
* Self-hosted instances are not official hosts.
|
|
*/
|
|
import { Subscription, SubscriptionPlan } from '@/application/types';
|
|
import { getConfigValue } from '@/utils/runtime-config';
|
|
|
|
const OFFICIAL_HOSTNAMES = new Set(['beta.appflowy.cloud', 'test.appflowy.cloud', 'localhost']);
|
|
const PRO_ACCESS_PLANS = new Set([SubscriptionPlan.Pro, SubscriptionPlan.Team]);
|
|
|
|
function getBaseUrlHostname(): string | null {
|
|
const baseUrl = getConfigValue('APPFLOWY_BASE_URL', '').trim();
|
|
|
|
if (!baseUrl) return null;
|
|
|
|
try {
|
|
return new URL(baseUrl).hostname;
|
|
} catch (primaryError) {
|
|
// Allow hostnames without a protocol, e.g. "beta.appflowy.cloud"
|
|
try {
|
|
return new URL(`https://${baseUrl}`).hostname;
|
|
} catch (secondaryError) {
|
|
console.warn('Invalid APPFLOWY_BASE_URL provided:', secondaryError);
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
function isOfficialHostname(hostname: string | undefined | null): boolean {
|
|
if (!hostname) return false;
|
|
return OFFICIAL_HOSTNAMES.has(hostname);
|
|
}
|
|
|
|
function resolveHostname(): string | null {
|
|
const baseUrlHostname = getBaseUrlHostname();
|
|
|
|
if (baseUrlHostname) {
|
|
return baseUrlHostname;
|
|
}
|
|
|
|
if (typeof window === 'undefined') {
|
|
return null;
|
|
}
|
|
|
|
return window.location.hostname;
|
|
}
|
|
|
|
/**
|
|
* Check if the current environment is an official AppFlowy hosted instance.
|
|
*
|
|
* For testing self-hosted behavior, you can:
|
|
* 1. Set localStorage.setItem('__test_force_self_hosted', 'true') in Cypress
|
|
* 2. This will make isAppFlowyHosted() return false
|
|
*/
|
|
export function isAppFlowyHosted(): boolean {
|
|
// Allow tests to override and simulate self-hosted environment
|
|
if (typeof window !== 'undefined' && window.localStorage?.getItem('__test_force_self_hosted') === 'true') {
|
|
return false;
|
|
}
|
|
|
|
return isOfficialHostname(resolveHostname());
|
|
}
|
|
|
|
export function hasProAccessFromPlans(plans?: SubscriptionPlan[] | null): boolean {
|
|
if (!plans || plans.length === 0) return false;
|
|
return plans.some((plan) => PRO_ACCESS_PLANS.has(plan));
|
|
}
|
|
|
|
export function getProAccessPlanFromSubscriptions(subscriptions?: Subscription[] | null): SubscriptionPlan {
|
|
if (!subscriptions || subscriptions.length === 0) return SubscriptionPlan.Free;
|
|
return subscriptions.some((subscription) => PRO_ACCESS_PLANS.has(subscription.plan))
|
|
? SubscriptionPlan.Pro
|
|
: SubscriptionPlan.Free;
|
|
}
|