11import { AuditAction , AuditResourceType } from '@sim/audit'
22import { db } from '@sim/db'
3- import { scimGroup } from '@sim/db/schema'
3+ import { type ScimConnectionSettings , scimConnection , scimGroup } from '@sim/db/schema'
44import { and , eq , ne } from 'drizzle-orm'
55import type { ScimPatchOperation } from '@/lib/api/contracts/scim'
66import { acquireOrganizationMutationLock } from '@/lib/billing/organizations/membership'
@@ -57,11 +57,26 @@ import {
5757 */
5858async function withGroupWrite < T extends { stoppedRuns : StoppedRun [ ] } > (
5959 context : ScimUseCaseContext ,
60- work : ( tx : DbTransaction ) => Promise < T >
60+ work : ( tx : DbTransaction , settings : ScimConnectionSettings ) => Promise < T >
6161) : Promise < Omit < T , 'stoppedRuns' > > {
6262 const { stoppedRuns, ...result } = await db . transaction ( async ( tx ) => {
6363 await acquireOrganizationMutationLock ( tx , context . organizationId )
64- return work ( tx )
64+ const [ connection ] = await tx
65+ . select ( { status : scimConnection . status , settings : scimConnection . settings } )
66+ . from ( scimConnection )
67+ . where (
68+ and (
69+ eq ( scimConnection . id , context . connection . id ) ,
70+ eq ( scimConnection . organizationId , context . organizationId )
71+ )
72+ )
73+ . limit ( 1 )
74+ if ( ! connection || connection . status !== 'active' ) {
75+ throw new ScimError ( 401 , undefined , 'Invalid SCIM token' , {
76+ 'WWW-Authenticate' : 'Bearer realm="SCIM"' ,
77+ } )
78+ }
79+ return work ( tx , connection . settings )
6580 } )
6681 deliverRunStops ( stoppedRuns )
6782 return result
@@ -185,7 +200,7 @@ export const createScimGroup = defineAuthorizedScimUseCase({
185200 context,
186201 } : ScimUseCaseArgs < CreateScimGroupInput > ) : Promise < ScimGroupWriteResult > {
187202 const { group } = input
188- return withGroupWrite ( context , async ( tx ) => {
203+ return withGroupWrite ( context , async ( tx , settings ) => {
189204 await assertDisplayNameAvailable ( tx , {
190205 connectionId : context . connection . id ,
191206 displayName : group . displayName ,
@@ -202,7 +217,7 @@ export const createScimGroup = defineAuthorizedScimUseCase({
202217 }
203218 await assertMemberCount ( tx , created . id )
204219
205- const mapped = context . connection . settings . autoMapPermissionGroupsByName
220+ const mapped = settings . autoMapPermissionGroupsByName
206221 ? await autoMapPermissionGroupByName ( tx , {
207222 organizationId : context . organizationId ,
208223 scimGroupId : created . id ,
@@ -253,7 +268,7 @@ export const replaceScimGroup = defineAuthorizedScimUseCase({
253268 input,
254269 context,
255270 } : ScimUseCaseArgs < ReplaceScimGroupInput > ) : Promise < ScimGroupWriteResult > {
256- return withGroupWrite ( context , async ( tx ) => {
271+ return withGroupWrite ( context , async ( tx , settings ) => {
257272 const current = await findScimGroupById ( tx , context . connection . id , input . groupId )
258273 if ( ! current ) throw notFound ( 'SCIM Group not found' )
259274
@@ -277,7 +292,7 @@ export const replaceScimGroup = defineAuthorizedScimUseCase({
277292 } )
278293 }
279294 let adopted = false
280- if ( renamed && context . connection . settings . autoMapPermissionGroupsByName ) {
295+ if ( renamed && settings . autoMapPermissionGroupsByName ) {
281296 const mapped = await autoMapPermissionGroupByName ( tx , {
282297 organizationId : context . organizationId ,
283298 scimGroupId : current . id ,
@@ -358,7 +373,7 @@ export const patchScimGroup = defineAuthorizedScimUseCase({
358373 } : ScimUseCaseArgs < PatchScimGroupInput > ) : Promise < PatchScimGroupResult > {
359374 const patch = parseGroupPatch ( input . operations )
360375
361- return withGroupWrite ( context , async ( tx ) => {
376+ return withGroupWrite ( context , async ( tx , settings ) => {
362377 const current = await findScimGroupById ( tx , context . connection . id , input . groupId )
363378 if ( ! current ) throw notFound ( 'SCIM Group not found' )
364379
@@ -402,11 +417,7 @@ export const patchScimGroup = defineAuthorizedScimUseCase({
402417 ...( externalIdChanged ? { externalId : patch . externalId } : { } ) ,
403418 } )
404419 }
405- if (
406- renamed &&
407- patch . displayName &&
408- context . connection . settings . autoMapPermissionGroupsByName
409- ) {
420+ if ( renamed && patch . displayName && settings . autoMapPermissionGroupsByName ) {
410421 const mapped = await autoMapPermissionGroupByName ( tx , {
411422 organizationId : context . organizationId ,
412423 scimGroupId : current . id ,
0 commit comments