Skip to content

Commit 0e527f4

Browse files
move feature to EE
1 parent c7e2f5a commit 0e527f4

File tree

10 files changed

+44
-22
lines changed

10 files changed

+44
-22
lines changed

LICENSE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Copyright (c) 2025 Taqla Inc.
22

33
Portions of this software are licensed as follows:
44

5-
- All content that resides under the "ee/", "packages/web/src/ee/", and "packages/shared/src/ee/" directories of this repository, if these directories exist, is licensed under the license defined in "ee/LICENSE".
5+
- All content that resides under the "ee/", "packages/web/src/ee/", "packages/backend/src/ee/", and "packages/shared/src/ee/" directories of this repository, if these directories exist, is licensed under the license defined in "ee/LICENSE".
66
- All third party components incorporated into the Sourcebot Software are licensed under the original license provided by the owner of the applicable component.
77
- Content outside of the above mentioned directories or restrictions above is available under the "Functional Source License" as defined below.
88

packages/backend/src/repoPermissionSyncer.ts renamed to packages/backend/src/ee/repoPermissionSyncer.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ import { GithubConnectionConfig } from "@sourcebot/schemas/v3/github.type";
77
import { GitlabConnectionConfig } from "@sourcebot/schemas/v3/gitlab.type";
88
import { Job, Queue, Worker } from 'bullmq';
99
import { Redis } from 'ioredis';
10-
import { env } from "./env.js";
11-
import { createOctokitFromConfig, getUserIdsWithReadAccessToRepo } from "./github.js";
12-
import { RepoWithConnections } from "./types.js";
13-
import { PERMISSION_SYNC_SUPPORTED_CODE_HOST_TYPES } from "./constants.js";
10+
import { env } from "../env.js";
11+
import { createOctokitFromConfig, getUserIdsWithReadAccessToRepo } from "../github.js";
12+
import { RepoWithConnections } from "../types.js";
13+
import { PERMISSION_SYNC_SUPPORTED_CODE_HOST_TYPES } from "../constants.js";
14+
import { hasEntitlement } from "@sourcebot/shared";
1415

1516
type RepoPermissionSyncJob = {
1617
jobId: string;
@@ -41,6 +42,10 @@ export class RepoPermissionSyncer {
4142
}
4243

4344
public startScheduler() {
45+
if (!hasEntitlement('permission-syncing')) {
46+
throw new Error('Permission syncing is not supported in current plan.');
47+
}
48+
4449
logger.debug('Starting scheduler');
4550

4651
return setInterval(async () => {

packages/backend/src/userPermissionSyncer.ts renamed to packages/backend/src/ee/userPermissionSyncer.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ import { PrismaClient, User, UserPermissionSyncJobStatus } from "@sourcebot/db";
44
import { createLogger } from "@sourcebot/logger";
55
import { Job, Queue, Worker } from "bullmq";
66
import { Redis } from "ioredis";
7-
import { PERMISSION_SYNC_SUPPORTED_CODE_HOST_TYPES } from "./constants.js";
8-
import { env } from "./env.js";
9-
import { getReposThatAuthenticatedUserHasReadAccessTo } from "./github.js";
7+
import { PERMISSION_SYNC_SUPPORTED_CODE_HOST_TYPES } from "../constants.js";
8+
import { env } from "../env.js";
9+
import { getReposThatAuthenticatedUserHasReadAccessTo } from "../github.js";
10+
import { hasEntitlement } from "@sourcebot/shared";
1011

1112
const logger = createLogger('user-permission-syncer');
1213

@@ -37,6 +38,10 @@ export class UserPermissionSyncer {
3738
}
3839

3940
public startScheduler() {
41+
if (!hasEntitlement('permission-syncing')) {
42+
throw new Error('Permission syncing is not supported in current plan.');
43+
}
44+
4045
logger.debug('Starting scheduler');
4146

4247
return setInterval(async () => {

packages/backend/src/env.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export const env = createEnv({
5353

5454
GITLAB_CLIENT_QUERY_TIMEOUT_SECONDS: numberSchema.default(60 * 10),
5555

56-
EXPERIMENT_PERMISSION_SYNC_ENABLED: booleanSchema.default("false"),
56+
EXPERIMENT_EE_PERMISSION_SYNC_ENABLED: booleanSchema.default('false'),
5757
},
5858
runtimeEnv: process.env,
5959
emptyStringAsUndefined: true,

packages/backend/src/index.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@ import "./instrument.js";
22

33
import { PrismaClient } from "@sourcebot/db";
44
import { createLogger } from "@sourcebot/logger";
5-
import { loadConfig } from '@sourcebot/shared';
5+
import { hasEntitlement, loadConfig } from '@sourcebot/shared';
66
import { existsSync } from 'fs';
77
import { mkdir } from 'fs/promises';
88
import { Redis } from 'ioredis';
99
import path from 'path';
1010
import { ConnectionManager } from './connectionManager.js';
1111
import { DEFAULT_SETTINGS } from './constants.js';
1212
import { env } from "./env.js";
13-
import { RepoPermissionSyncer } from './repoPermissionSyncer.js';
13+
import { RepoPermissionSyncer } from './ee/repoPermissionSyncer.js';
1414
import { PromClient } from './promClient.js';
1515
import { RepoManager } from './repoManager.js';
1616
import { AppContext } from "./types.js";
17-
import { UserPermissionSyncer } from "./userPermissionSyncer.js";
17+
import { UserPermissionSyncer } from "./ee/userPermissionSyncer.js";
1818

1919

2020
const logger = createLogger('backend-entrypoint');
@@ -76,9 +76,18 @@ await repoManager.validateIndexedReposHaveShards();
7676

7777
const connectionManagerInterval = connectionManager.startScheduler();
7878
const repoManagerInterval = repoManager.startScheduler();
79-
const repoPermissionSyncerInterval = env.EXPERIMENT_PERMISSION_SYNC_ENABLED === 'true' ? repoPermissionSyncer.startScheduler() : null;
80-
const userPermissionSyncerInterval = env.EXPERIMENT_PERMISSION_SYNC_ENABLED === 'true' ? userPermissionSyncer.startScheduler() : null;
8179

80+
let repoPermissionSyncerInterval: NodeJS.Timeout | null = null;
81+
let userPermissionSyncerInterval: NodeJS.Timeout | null = null;
82+
83+
if (env.EXPERIMENT_EE_PERMISSION_SYNC_ENABLED === 'true' && !hasEntitlement('permission-syncing')) {
84+
logger.error('Permission syncing is not supported in current plan. Please contact [email protected] for assistance.');
85+
process.exit(1);
86+
}
87+
else if (env.EXPERIMENT_EE_PERMISSION_SYNC_ENABLED === 'true' && hasEntitlement('permission-syncing')) {
88+
repoPermissionSyncerInterval = repoPermissionSyncer.startScheduler();
89+
userPermissionSyncerInterval = userPermissionSyncer.startScheduler();
90+
}
8291

8392
const cleanup = async (signal: string) => {
8493
logger.info(`Recieved ${signal}, cleaning up...`);

packages/shared/src/entitlements.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,16 @@ const entitlements = [
3838
"sso",
3939
"code-nav",
4040
"audit",
41-
"analytics"
41+
"analytics",
42+
"permission-syncing"
4243
] as const;
4344
export type Entitlement = (typeof entitlements)[number];
4445

4546
const entitlementsByPlan: Record<Plan, Entitlement[]> = {
4647
oss: ["anonymous-access"],
4748
"cloud:team": ["billing", "multi-tenancy", "sso", "code-nav"],
48-
"self-hosted:enterprise": ["search-contexts", "sso", "code-nav", "audit", "analytics"],
49-
"self-hosted:enterprise-unlimited": ["search-contexts", "anonymous-access", "sso", "code-nav", "audit", "analytics"],
49+
"self-hosted:enterprise": ["search-contexts", "sso", "code-nav", "audit", "analytics", "permission-syncing"],
50+
"self-hosted:enterprise-unlimited": ["search-contexts", "anonymous-access", "sso", "code-nav", "audit", "analytics", "permission-syncing"],
5051
// Special entitlement for https://demo.sourcebot.dev
5152
"cloud:demo": ["anonymous-access", "code-nav", "search-contexts"],
5253
} as const;

packages/web/src/actions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1035,7 +1035,7 @@ export const flagReposForIndex = async (repoIds: number[], domain: string) => se
10351035
where: {
10361036
id: { in: repoIds },
10371037
orgId: org.id,
1038-
...(env.EXPERIMENT_PERMISSION_SYNC_ENABLED === 'true' ? {
1038+
...(env.EXPERIMENT_EE_PERMISSION_SYNC_ENABLED === 'true' ? {
10391039
permittedUsers: {
10401040
some: {
10411041
userId: userId,

packages/web/src/ee/features/sso/sso.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import Credentials from "next-auth/providers/credentials";
1212
import type { User as AuthJsUser } from "next-auth";
1313
import { onCreateUser } from "@/lib/authUtils";
1414
import { createLogger } from "@sourcebot/logger";
15+
import { hasEntitlement } from "@sourcebot/shared";
1516

1617
const logger = createLogger('web-sso');
1718

@@ -30,10 +31,10 @@ export const getSSOProviders = (): Provider[] => {
3031
scope: [
3132
'read:user',
3233
'user:email',
33-
// Permission syncing requires the `repo` in order to fetch repositories
34+
// Permission syncing requires the `repo` scope in order to fetch repositories
3435
// for the authenticated user.
3536
// @see: https://docs.github.com/en/rest/repos/repos?apiVersion=2022-11-28#list-repositories-for-the-authenticated-user
36-
...(env.EXPERIMENT_PERMISSION_SYNC_ENABLED === 'true' ?
37+
...(env.EXPERIMENT_EE_PERMISSION_SYNC_ENABLED === 'true' && hasEntitlement('permission-syncing') ?
3738
['repo'] :
3839
[]
3940
),

packages/web/src/env.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ export const env = createEnv({
137137
// @NOTE: Take care to update actions.ts when changing the name of this.
138138
EXPERIMENT_SELF_SERVE_REPO_INDEXING_GITHUB_TOKEN: z.string().optional(),
139139

140-
EXPERIMENT_PERMISSION_SYNC_ENABLED: booleanSchema.default('false'),
140+
EXPERIMENT_EE_PERMISSION_SYNC_ENABLED: booleanSchema.default('false'),
141141
},
142142
// @NOTE: Please make sure of the following:
143143
// - Make sure you destructure all client variables in

packages/web/src/prisma.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'server-only';
22
import { env } from "@/env.mjs";
33
import { Prisma, PrismaClient } from "@sourcebot/db";
4+
import { hasEntitlement } from "@sourcebot/shared";
45

56
// @see: https://authjs.dev/getting-started/adapters/prisma
67
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient }
@@ -24,7 +25,7 @@ export const userScopedPrismaClientExtension = (userId?: string) => {
2425
(prisma) => {
2526
return prisma.$extends({
2627
query: {
27-
...(env.EXPERIMENT_PERMISSION_SYNC_ENABLED === 'true' ? {
28+
...(env.EXPERIMENT_EE_PERMISSION_SYNC_ENABLED === 'true' && hasEntitlement('permission-syncing') ? {
2829
repo: {
2930
$allOperations({ args, query }) {
3031
if ('where' in args) {

0 commit comments

Comments
 (0)