1+ import { describe , it , beforeEach , vi , expect } from "vitest" ;
2+
3+ import { DelegationCredentialRepository } from "@calcom/features/delegation-credentials/repositories/DelegationCredentialRepository" ;
4+
5+ import { toggleDelegationCredentialEnabled } from "./toggleEnabled.handler" ;
6+
7+ // Mock the repository
8+ vi . mock ( "@calcom/features/delegation-credentials/repositories/DelegationCredentialRepository" , ( ) => ( {
9+ DelegationCredentialRepository : {
10+ findById : vi . fn ( ) ,
11+ updateById : vi . fn ( ) ,
12+ findByIdIncludeSensitiveServiceAccountKey : vi . fn ( ) ,
13+ } ,
14+ } ) ) ;
15+
16+ // Mock other dependencies
17+ vi . mock ( "@calcom/app-store/delegationCredential" , ( ) => ( {
18+ checkIfSuccessfullyConfiguredInWorkspace : vi . fn ( ) . mockResolvedValue ( true ) ,
19+ } ) ) ;
20+
21+ vi . mock ( "@calcom/emails/integration-email-service" , ( ) => ( {
22+ sendDelegationCredentialDisabledEmail : vi . fn ( ) ,
23+ } ) ) ;
24+
25+ vi . mock ( "./getAffectedMembersForDisable.handler" , ( ) => ( {
26+ getAffectedMembersForDisable : vi . fn ( ) . mockResolvedValue ( [ ] ) ,
27+ } ) ) ;
28+
29+ vi . mock ( "./utils" , ( ) => ( {
30+ ensureNoServiceAccountKey : vi . fn ( ( credential ) => credential ) ,
31+ } ) ) ;
32+
33+ describe ( "toggleDelegationCredentialEnabled - Security Fix" , ( ) => {
34+ beforeEach ( ( ) => {
35+ vi . clearAllMocks ( ) ;
36+ } ) ;
37+
38+ it ( "should prevent users without organizationId from accessing any credentials" , async ( ) => {
39+ const userWithoutOrg = {
40+ id : 1 ,
41+ email : "user@example.com" ,
42+ organizationId : null ,
43+ } ;
44+
45+ const input = {
46+ id : "any-credential" ,
47+ enabled : true ,
48+ } ;
49+
50+ const mockCredential = {
51+ id : "any-credential" ,
52+ organizationId : 1 ,
53+ enabled : false ,
54+ workspacePlatform : { slug : "google" } ,
55+ } ;
56+
57+ vi . mocked ( DelegationCredentialRepository . findById ) . mockResolvedValue ( mockCredential ) ;
58+
59+ await expect (
60+ toggleDelegationCredentialEnabled ( userWithoutOrg , input )
61+ ) . rejects . toThrow ( "You must be part of an organization to toggle a delegation credential" ) ;
62+
63+ expect ( DelegationCredentialRepository . updateById ) . not . toHaveBeenCalled ( ) ;
64+ } ) ;
65+
66+ it ( "should prevent cross-organization access" , async ( ) => {
67+ const userFromOrg1 = {
68+ id : 1 ,
69+ email : "user@org1.com" ,
70+ organizationId : 1 ,
71+ } ;
72+
73+ const input = {
74+ id : "org2-credential" ,
75+ enabled : false ,
76+ } ;
77+
78+ const org2Credential = {
79+ id : "org2-credential" ,
80+ organizationId : 2 , // Different organization
81+ enabled : true ,
82+ workspacePlatform : { slug : "google" } ,
83+ } ;
84+
85+ vi . mocked ( DelegationCredentialRepository . findById ) . mockResolvedValue ( org2Credential ) ;
86+
87+ await expect (
88+ toggleDelegationCredentialEnabled ( userFromOrg1 , input )
89+ ) . rejects . toThrow ( "Delegation credential not found" ) ;
90+
91+ expect ( DelegationCredentialRepository . updateById ) . not . toHaveBeenCalled ( ) ;
92+ } ) ;
93+
94+ it ( "should allow same-organization access" , async ( ) => {
95+ const userFromOrg1 = {
96+ id : 1 ,
97+ email : "admin@org1.com" ,
98+ organizationId : 1 ,
99+ } ;
100+
101+ const input = {
102+ id : "org1-credential" ,
103+ enabled : false ,
104+ } ;
105+
106+ const org1Credential = {
107+ id : "org1-credential" ,
108+ organizationId : 1 , // Same organization
109+ enabled : true ,
110+ workspacePlatform : { slug : "google" } ,
111+ } ;
112+
113+ const updatedCredential = {
114+ ...org1Credential ,
115+ enabled : false ,
116+ lastDisabledAt : new Date ( ) ,
117+ } ;
118+
119+ vi . mocked ( DelegationCredentialRepository . findById ) . mockResolvedValue ( org1Credential ) ;
120+ vi . mocked ( DelegationCredentialRepository . updateById ) . mockResolvedValue ( updatedCredential ) ;
121+
122+ const result = await toggleDelegationCredentialEnabled ( userFromOrg1 , input ) ;
123+
124+ expect ( result ) . toEqual ( updatedCredential ) ;
125+ expect ( DelegationCredentialRepository . updateById ) . toHaveBeenCalledWith ( {
126+ id : "org1-credential" ,
127+ data : {
128+ enabled : false ,
129+ lastEnabledAt : undefined ,
130+ lastDisabledAt : expect . any ( Date ) ,
131+ } ,
132+ } ) ;
133+ } ) ;
134+
135+ it ( "should handle nonexistent credentials" , async ( ) => {
136+ const user = {
137+ id : 1 ,
138+ email : "user@org1.com" ,
139+ organizationId : 1 ,
140+ } ;
141+
142+ const input = {
143+ id : "nonexistent-credential" ,
144+ enabled : true ,
145+ } ;
146+
147+ vi . mocked ( DelegationCredentialRepository . findById ) . mockResolvedValue ( null ) ;
148+
149+ await expect (
150+ toggleDelegationCredentialEnabled ( user , input )
151+ ) . rejects . toThrow ( "Delegation credential not found" ) ;
152+ } ) ;
153+ } ) ;
0 commit comments