Files
speckle-server/packages/server/modules/gatekeeper/services/featureAuthorization.ts
T
Gergő Jedlicska 6982023dca feat(gatekeeper): add per workspace feature flags (#5303)
* feat(gatekeeper): add per workspace feature flags

* feat(workspaces): add admin api for granting and removing access to
workspace features

* fix(workspaces): use the correct constant name

* fix(workspaces): more test type fixes

* fix(shared): fix tests and types

* fix(workspaces): properly use exhaustive switch statement

* fix(workspaces): add new workspace plan feature to switch

* fix(workspaces): use regular integer, its fine for now...

* fix(workspaces): feature flag retention post checkout

* fix(gatekeeper): fix upsert plan tests
2025-08-26 10:23:02 +01:00

66 lines
2.1 KiB
TypeScript

import type { GetWorkspacePlan } from '@/modules/gatekeeper/domain/billing'
import type {
CanWorkspaceAccessFeature,
WorkspaceFeatureAccessFunction
} from '@/modules/gatekeeper/domain/operations'
import { getFeatureFlags } from '@/modules/shared/helpers/envHelper'
import {
throwUncoveredError,
workspacePlanHasAccessToFeature,
isPlanFeature,
isWorkspaceFeatureFlagOn
} from '@speckle/shared'
export const canWorkspaceAccessFeatureFactory =
({
getWorkspacePlan
}: {
getWorkspacePlan: GetWorkspacePlan
}): CanWorkspaceAccessFeature =>
async ({ workspaceId, workspaceFeature }) => {
const workspacePlan = await getWorkspacePlan({ workspaceId })
if (!workspacePlan) return false
switch (workspacePlan.status) {
case 'valid':
case 'paymentFailed':
case 'cancelationScheduled':
break
case 'canceled':
return false
default:
throwUncoveredError(workspacePlan)
}
if (isPlanFeature(workspaceFeature))
return workspacePlanHasAccessToFeature({
plan: workspacePlan.name,
feature: workspaceFeature,
featureFlags: getFeatureFlags()
})
const isFlagOn = isWorkspaceFeatureFlagOn({
workspaceFeatureFlags: workspacePlan.featureFlags,
feature: workspaceFeature
})
return isFlagOn
}
export const canWorkspaceUseOidcSsoFactory =
(deps: { getWorkspacePlan: GetWorkspacePlan }): WorkspaceFeatureAccessFunction =>
async ({ workspaceId }) =>
canWorkspaceAccessFeatureFactory(deps)({ workspaceId, workspaceFeature: 'oidcSso' })
export const canWorkspaceUseRegionsFactory =
(deps: { getWorkspacePlan: GetWorkspacePlan }): WorkspaceFeatureAccessFunction =>
async ({ workspaceId }) =>
canWorkspaceAccessFeatureFactory(deps)({
workspaceId,
workspaceFeature: 'workspaceDataRegionSpecificity'
})
export const canWorkspaceUseDomainBasedSecurityPolicies =
(deps: { getWorkspacePlan: GetWorkspacePlan }): WorkspaceFeatureAccessFunction =>
async ({ workspaceId }) =>
canWorkspaceAccessFeatureFactory(deps)({
workspaceId,
workspaceFeature: 'domainBasedSecurityPolicies'
})