mirror of
https://github.com/sourcebot-dev/sourcebot.git
synced 2025-12-11 20:05:25 +00:00
fix: Fix issue with how entitlements are resolved for cloud (#319)
This commit is contained in:
parent
0b52830b4f
commit
65cdaaa658
3 changed files with 11 additions and 35 deletions
|
|
@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Fixed issue with how entitlements are resolved for cloud. [#319](https://github.com/sourcebot-dev/sourcebot/pull/319)
|
||||||
|
|
||||||
## [4.0.0] - 2025-05-28
|
## [4.0.0] - 2025-05-28
|
||||||
|
|
||||||
Sourcebot V4 introduces authentication, performance improvements and code navigation. Checkout the [migration guide](https://docs.sourcebot.dev/self-hosting/upgrade/v3-to-v4-guide) for information on upgrading your instance to v4.
|
Sourcebot V4 introduces authentication, performance improvements and code navigation. Checkout the [migration guide](https://docs.sourcebot.dev/self-hosting/upgrade/v3-to-v4-guide) for information on upgrading your instance to v4.
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@
|
||||||
const planLabels = {
|
const planLabels = {
|
||||||
oss: "OSS",
|
oss: "OSS",
|
||||||
"cloud:team": "Team",
|
"cloud:team": "Team",
|
||||||
|
"cloud:demo": "Demo",
|
||||||
"self-hosted:enterprise": "Enterprise (Self-Hosted)",
|
"self-hosted:enterprise": "Enterprise (Self-Hosted)",
|
||||||
"self-hosted:enterprise-unlimited": "Enterprise (Self-Hosted) Unlimited",
|
"self-hosted:enterprise-unlimited": "Enterprise (Self-Hosted) Unlimited",
|
||||||
"self-hosted:enterprise-custom": "Enterprise (Self-Hosted) Custom",
|
|
||||||
} as const;
|
} as const;
|
||||||
export type Plan = keyof typeof planLabels;
|
export type Plan = keyof typeof planLabels;
|
||||||
|
|
||||||
|
|
@ -21,14 +21,11 @@ const entitlements = [
|
||||||
] as const;
|
] as const;
|
||||||
export type Entitlement = (typeof entitlements)[number];
|
export type Entitlement = (typeof entitlements)[number];
|
||||||
|
|
||||||
export const isValidEntitlement = (entitlement: string): entitlement is Entitlement => {
|
|
||||||
return entitlements.includes(entitlement as Entitlement);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const entitlementsByPlan: Record<Plan, Entitlement[]> = {
|
export const entitlementsByPlan: Record<Plan, Entitlement[]> = {
|
||||||
oss: [],
|
oss: [],
|
||||||
"cloud:team": ["billing", "multi-tenancy", "sso", "code-nav"],
|
"cloud:team": ["billing", "multi-tenancy", "sso", "code-nav"],
|
||||||
"self-hosted:enterprise": ["search-contexts", "sso", "code-nav"],
|
"self-hosted:enterprise": ["search-contexts", "sso", "code-nav"],
|
||||||
"self-hosted:enterprise-unlimited": ["search-contexts", "public-access", "sso", "code-nav"],
|
"self-hosted:enterprise-unlimited": ["search-contexts", "public-access", "sso", "code-nav"],
|
||||||
"self-hosted:enterprise-custom": [],
|
// Special entitlement for https://demo.sourcebot.dev
|
||||||
|
"cloud:demo": ["public-access", "code-nav", "search-contexts"],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { env } from "@/env.mjs"
|
import { env } from "@/env.mjs"
|
||||||
import { Entitlement, entitlementsByPlan, Plan, isValidEntitlement } from "./constants"
|
import { Entitlement, entitlementsByPlan, Plan } from "./constants"
|
||||||
import { base64Decode } from "@/lib/utils";
|
import { base64Decode } from "@/lib/utils";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { SOURCEBOT_SUPPORT_EMAIL } from "@/lib/constants";
|
import { SOURCEBOT_SUPPORT_EMAIL } from "@/lib/constants";
|
||||||
|
|
@ -12,7 +12,6 @@ const eeLicenseKeyPayloadSchema = z.object({
|
||||||
seats: z.number(),
|
seats: z.number(),
|
||||||
// ISO 8601 date string
|
// ISO 8601 date string
|
||||||
expiryDate: z.string().datetime(),
|
expiryDate: z.string().datetime(),
|
||||||
customEntitlements: z.array(z.string()).optional()
|
|
||||||
});
|
});
|
||||||
|
|
||||||
type LicenseKeyPayload = z.infer<typeof eeLicenseKeyPayloadSchema>;
|
type LicenseKeyPayload = z.infer<typeof eeLicenseKeyPayloadSchema>;
|
||||||
|
|
@ -39,6 +38,10 @@ export const getLicenseKey = (): LicenseKeyPayload | null => {
|
||||||
|
|
||||||
export const getPlan = (): Plan => {
|
export const getPlan = (): Plan => {
|
||||||
if (env.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT) {
|
if (env.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT) {
|
||||||
|
if (env.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT === "demo") {
|
||||||
|
return "cloud:demo";
|
||||||
|
}
|
||||||
|
|
||||||
return "cloud:team";
|
return "cloud:team";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,9 +53,6 @@ export const getPlan = (): Plan => {
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (licenseKey.customEntitlements) {
|
|
||||||
return "self-hosted:enterprise-custom";
|
|
||||||
}
|
|
||||||
return licenseKey.seats === SOURCEBOT_UNLIMITED_SEATS ? "self-hosted:enterprise-unlimited" : "self-hosted:enterprise";
|
return licenseKey.seats === SOURCEBOT_UNLIMITED_SEATS ? "self-hosted:enterprise-unlimited" : "self-hosted:enterprise";
|
||||||
} else {
|
} else {
|
||||||
console.info(`No valid license key found. Falling back to oss plan.`);
|
console.info(`No valid license key found. Falling back to oss plan.`);
|
||||||
|
|
@ -71,30 +71,6 @@ export const hasEntitlement = (entitlement: Entitlement) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getEntitlements = (): Entitlement[] => {
|
export const getEntitlements = (): Entitlement[] => {
|
||||||
const licenseKey = getLicenseKey();
|
|
||||||
if (!licenseKey) {
|
|
||||||
return entitlementsByPlan["oss"];
|
|
||||||
}
|
|
||||||
|
|
||||||
const plan = getPlan();
|
const plan = getPlan();
|
||||||
if (plan === "self-hosted:enterprise-custom") {
|
|
||||||
const customEntitlements = licenseKey.customEntitlements;
|
|
||||||
if (!customEntitlements) {
|
|
||||||
console.error(`The provided license key is under the self-hosted:enterprise-custom plan but has no custom entitlements. Returning oss entitlements.`);
|
|
||||||
return entitlementsByPlan["oss"];
|
|
||||||
}
|
|
||||||
|
|
||||||
const validCustomEntitlements: Entitlement[] = [];
|
|
||||||
for (const entitlement of customEntitlements) {
|
|
||||||
if (!isValidEntitlement(entitlement)) {
|
|
||||||
console.error(`Invalid custom entitlement "${entitlement}" provided in license key. Skipping.`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
validCustomEntitlements.push(entitlement as Entitlement);
|
|
||||||
}
|
|
||||||
|
|
||||||
return validCustomEntitlements;
|
|
||||||
}
|
|
||||||
|
|
||||||
return entitlementsByPlan[plan];
|
return entitlementsByPlan[plan];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue