@@ -23,7 +23,7 @@ import { render } from "@react-email/components";
23
23
import InviteUserEmail from "./emails/inviteUserEmail" ;
24
24
import { createTransport } from "nodemailer" ;
25
25
import { orgDomainSchema , orgNameSchema , repositoryQuerySchema } from "./lib/schemas" ;
26
- import { RepositoryQuery , TenancyMode } from "./lib/types" ;
26
+ import { TenancyMode } from "./lib/types" ;
27
27
import { MOBILE_UNSUPPORTED_SPLASH_SCREEN_DISMISSED_COOKIE_NAME , SINGLE_TENANT_USER_EMAIL , SINGLE_TENANT_USER_ID } from "./lib/constants" ;
28
28
import { stripeClient } from "./lib/stripe" ;
29
29
import { IS_BILLING_ENABLED } from "./lib/stripe" ;
@@ -32,19 +32,27 @@ const ajv = new Ajv({
32
32
validateFormats : false ,
33
33
} ) ;
34
34
35
- export const withAuth = async < T > ( fn : ( session : Session ) => Promise < T > ) => {
36
- if ( env . SOURCEBOT_TENANCY_MODE === 'single' ) {
37
- return fn ( {
38
- user : {
39
- id : SINGLE_TENANT_USER_ID ,
40
- email : SINGLE_TENANT_USER_EMAIL ,
41
- } ,
42
- expires : new Date ( Date . now ( ) + 1000 * 60 * 60 * 24 * 30 ) . toISOString ( ) ,
43
- } ) ;
44
- }
45
-
35
+ export const withAuth = async < T > ( fn : ( session : Session ) => Promise < T > , allowSingleTenantUnauthedAccess : boolean = false ) => {
46
36
const session = await auth ( ) ;
47
37
if ( ! session ) {
38
+ if (
39
+ env . SOURCEBOT_TENANCY_MODE === 'single' &&
40
+ env . SOURCEBOT_AUTH_ENABLED === 'false' &&
41
+ allowSingleTenantUnauthedAccess === true
42
+ ) {
43
+ // To allow for unauthed acccess in single-tenant mode, we can
44
+ // create a fake session with the default user. This user has membership
45
+ // in the default org.
46
+ // @see : initialize.ts
47
+ return fn ( {
48
+ user : {
49
+ id : SINGLE_TENANT_USER_ID ,
50
+ email : SINGLE_TENANT_USER_EMAIL ,
51
+ } ,
52
+ expires : new Date ( Date . now ( ) + 1000 * 60 * 60 * 24 * 30 ) . toISOString ( ) ,
53
+ } ) ;
54
+ }
55
+
48
56
return notAuthenticated ( ) ;
49
57
}
50
58
return fn ( session ) ;
@@ -135,28 +143,27 @@ export const createOrg = (name: string, domain: string): Promise<{ id: number }
135
143
} ) ) ;
136
144
137
145
export const updateOrgName = async ( name : string , domain : string ) =>
138
- withTenancyModeEnforcement ( 'multi' , ( ) =>
139
- withAuth ( ( session ) =>
140
- withOrgMembership ( session , domain , async ( { orgId } ) => {
141
- const { success } = orgNameSchema . safeParse ( name ) ;
142
- if ( ! success ) {
143
- return {
144
- statusCode : StatusCodes . BAD_REQUEST ,
145
- errorCode : ErrorCode . INVALID_REQUEST_BODY ,
146
- message : "Invalid organization url" ,
147
- } satisfies ServiceError ;
148
- }
146
+ withAuth ( ( session ) =>
147
+ withOrgMembership ( session , domain , async ( { orgId } ) => {
148
+ const { success } = orgNameSchema . safeParse ( name ) ;
149
+ if ( ! success ) {
150
+ return {
151
+ statusCode : StatusCodes . BAD_REQUEST ,
152
+ errorCode : ErrorCode . INVALID_REQUEST_BODY ,
153
+ message : "Invalid organization url" ,
154
+ } satisfies ServiceError ;
155
+ }
149
156
150
- await prisma . org . update ( {
151
- where : { id : orgId } ,
152
- data : { name } ,
153
- } ) ;
157
+ await prisma . org . update ( {
158
+ where : { id : orgId } ,
159
+ data : { name } ,
160
+ } ) ;
154
161
155
- return {
156
- success : true ,
157
- }
158
- } , /* minRequiredRole = */ OrgRole . OWNER )
159
- ) ) ;
162
+ return {
163
+ success : true ,
164
+ }
165
+ } , /* minRequiredRole = */ OrgRole . OWNER )
166
+ ) ;
160
167
161
168
export const updateOrgDomain = async ( newDomain : string , existingDomain : string ) =>
162
169
withTenancyModeEnforcement ( 'multi' , ( ) =>
@@ -226,25 +233,23 @@ export const completeOnboarding = async (domain: string): Promise<{ success: boo
226
233
) ;
227
234
228
235
export const getSecrets = ( domain : string ) : Promise < { createdAt : Date ; key : string ; } [ ] | ServiceError > =>
229
- withTenancyModeEnforcement ( 'multi' , ( ) =>
230
- withAuth ( ( session ) =>
231
- withOrgMembership ( session , domain , async ( { orgId } ) => {
232
- const secrets = await prisma . secret . findMany ( {
233
- where : {
234
- orgId,
235
- } ,
236
- select : {
237
- key : true ,
238
- createdAt : true
239
- }
240
- } ) ;
241
-
242
- return secrets . map ( ( secret ) => ( {
243
- key : secret . key ,
244
- createdAt : secret . createdAt ,
245
- } ) ) ;
236
+ withAuth ( ( session ) =>
237
+ withOrgMembership ( session , domain , async ( { orgId } ) => {
238
+ const secrets = await prisma . secret . findMany ( {
239
+ where : {
240
+ orgId,
241
+ } ,
242
+ select : {
243
+ key : true ,
244
+ createdAt : true
245
+ }
246
+ } ) ;
246
247
247
- } ) ) ) ;
248
+ return secrets . map ( ( secret ) => ( {
249
+ key : secret . key ,
250
+ createdAt : secret . createdAt ,
251
+ } ) ) ;
252
+ } ) ) ;
248
253
249
254
export const createSecret = async ( key : string , value : string , domain : string ) : Promise < { success : boolean } | ServiceError > =>
250
255
withAuth ( ( session ) =>
@@ -294,8 +299,7 @@ export const checkIfSecretExists = async (key: string, domain: string): Promise<
294
299
} ) ;
295
300
296
301
return ! ! secret ;
297
- } )
298
- ) ;
302
+ } ) ) ;
299
303
300
304
export const deleteSecret = async ( key : string , domain : string ) : Promise < { success : boolean } | ServiceError > =>
301
305
withAuth ( ( session ) =>
@@ -379,9 +383,9 @@ export const getConnectionInfo = async (connectionId: number, domain: string) =>
379
383
numLinkedRepos : connection . repos . length ,
380
384
}
381
385
} )
382
- )
386
+ ) ;
383
387
384
- export const getRepos = async ( domain : string , filter : { status ?: RepoIndexingStatus [ ] , connectionId ?: number } = { } ) : Promise < RepositoryQuery [ ] | ServiceError > =>
388
+ export const getRepos = async ( domain : string , filter : { status ?: RepoIndexingStatus [ ] , connectionId ?: number } = { } ) =>
385
389
withAuth ( ( session ) =>
386
390
withOrgMembership ( session , domain , async ( { orgId } ) => {
387
391
const repos = await prisma . repo . findMany ( {
@@ -420,8 +424,8 @@ export const getRepos = async (domain: string, filter: { status?: RepoIndexingSt
420
424
indexedAt : repo . indexedAt ?? undefined ,
421
425
repoIndexingStatus : repo . repoIndexingStatus ,
422
426
} ) ) ;
423
- } )
424
- ) ;
427
+ }
428
+ ) , /* allowSingleTenantUnauthedAccess = */ true ) ;
425
429
426
430
export const createConnection = async ( name : string , type : string , connectionConfig : string , domain : string ) : Promise < { id : number } | ServiceError > =>
427
431
withAuth ( ( session ) =>
@@ -443,7 +447,8 @@ export const createConnection = async (name: string, type: string, connectionCon
443
447
return {
444
448
id : connection . id ,
445
449
}
446
- } ) ) ;
450
+ } )
451
+ ) ;
447
452
448
453
export const updateConnectionDisplayName = async ( connectionId : number , name : string , domain : string ) : Promise < { success : boolean } | ServiceError > =>
449
454
withAuth ( ( session ) =>
@@ -1085,7 +1090,7 @@ export const createStripeCheckoutSession = async (domain: string) =>
1085
1090
url : stripeSession . url ,
1086
1091
}
1087
1092
} )
1088
- )
1093
+ ) ;
1089
1094
1090
1095
export const getCustomerPortalSessionLink = async ( domain : string ) : Promise < string | ServiceError > =>
1091
1096
withAuth ( ( session ) =>
0 commit comments