@@ -10,6 +10,8 @@ describe('OAuth Token API Routes', () => {
1010 const mockGetUserId = vi . fn ( )
1111 const mockGetCredential = vi . fn ( )
1212 const mockRefreshTokenIfNeeded = vi . fn ( )
13+ const mockAuthorizeCredentialUse = vi . fn ( )
14+ const mockCheckHybridAuth = vi . fn ( )
1315
1416 const mockLogger = {
1517 info : vi . fn ( ) ,
@@ -37,6 +39,14 @@ describe('OAuth Token API Routes', () => {
3739 vi . doMock ( '@/lib/logs/console/logger' , ( ) => ( {
3840 createLogger : vi . fn ( ) . mockReturnValue ( mockLogger ) ,
3941 } ) )
42+
43+ vi . doMock ( '@/lib/auth/credential-access' , ( ) => ( {
44+ authorizeCredentialUse : mockAuthorizeCredentialUse ,
45+ } ) )
46+
47+ vi . doMock ( '@/lib/auth/hybrid' , ( ) => ( {
48+ checkHybridAuth : mockCheckHybridAuth ,
49+ } ) )
4050 } )
4151
4252 afterEach ( ( ) => {
@@ -48,7 +58,12 @@ describe('OAuth Token API Routes', () => {
4858 */
4959 describe ( 'POST handler' , ( ) => {
5060 it ( 'should return access token successfully' , async ( ) => {
51- mockGetUserId . mockResolvedValueOnce ( 'test-user-id' )
61+ mockAuthorizeCredentialUse . mockResolvedValueOnce ( {
62+ ok : true ,
63+ authType : 'session' ,
64+ requesterUserId : 'test-user-id' ,
65+ credentialOwnerUserId : 'owner-user-id' ,
66+ } )
5267 mockGetCredential . mockResolvedValueOnce ( {
5368 id : 'credential-id' ,
5469 accessToken : 'test-token' ,
@@ -78,14 +93,18 @@ describe('OAuth Token API Routes', () => {
7893 expect ( data ) . toHaveProperty ( 'accessToken' , 'fresh-token' )
7994
8095 // Verify mocks were called correctly
81- // POST no longer calls getUserId; token resolution uses credential owner.
82- expect ( mockGetUserId ) . not . toHaveBeenCalled ( )
96+ expect ( mockAuthorizeCredentialUse ) . toHaveBeenCalled ( )
8397 expect ( mockGetCredential ) . toHaveBeenCalled ( )
8498 expect ( mockRefreshTokenIfNeeded ) . toHaveBeenCalled ( )
8599 } )
86100
87101 it ( 'should handle workflowId for server-side authentication' , async ( ) => {
88- mockGetUserId . mockResolvedValueOnce ( 'workflow-owner-id' )
102+ mockAuthorizeCredentialUse . mockResolvedValueOnce ( {
103+ ok : true ,
104+ authType : 'internal_jwt' ,
105+ requesterUserId : 'workflow-owner-id' ,
106+ credentialOwnerUserId : 'workflow-owner-id' ,
107+ } )
89108 mockGetCredential . mockResolvedValueOnce ( {
90109 id : 'credential-id' ,
91110 accessToken : 'test-token' ,
@@ -111,8 +130,7 @@ describe('OAuth Token API Routes', () => {
111130 expect ( response . status ) . toBe ( 200 )
112131 expect ( data ) . toHaveProperty ( 'accessToken' , 'fresh-token' )
113132
114- // POST no longer calls getUserId; still refreshes successfully
115- expect ( mockGetUserId ) . not . toHaveBeenCalled ( )
133+ expect ( mockAuthorizeCredentialUse ) . toHaveBeenCalled ( )
116134 expect ( mockGetCredential ) . toHaveBeenCalled ( )
117135 } )
118136
@@ -130,8 +148,10 @@ describe('OAuth Token API Routes', () => {
130148 } )
131149
132150 it ( 'should handle authentication failure' , async ( ) => {
133- // Authentication failure no longer applies to POST path; treat as refresh failure via missing owner
134- mockGetUserId . mockResolvedValueOnce ( undefined )
151+ mockAuthorizeCredentialUse . mockResolvedValueOnce ( {
152+ ok : false ,
153+ error : 'Authentication required' ,
154+ } )
135155
136156 const req = createMockRequest ( 'POST' , {
137157 credentialId : 'credential-id' ,
@@ -142,12 +162,12 @@ describe('OAuth Token API Routes', () => {
142162 const response = await POST ( req )
143163 const data = await response . json ( )
144164
145- expect ( [ 401 , 404 ] ) . toContain ( response . status )
165+ expect ( response . status ) . toBe ( 403 )
146166 expect ( data ) . toHaveProperty ( 'error' )
147167 } )
148168
149169 it ( 'should handle workflow not found' , async ( ) => {
150- mockGetUserId . mockResolvedValueOnce ( undefined )
170+ mockAuthorizeCredentialUse . mockResolvedValueOnce ( { ok : false , error : 'Workflow not found' } )
151171
152172 const req = createMockRequest ( 'POST' , {
153173 credentialId : 'credential-id' ,
@@ -159,13 +179,16 @@ describe('OAuth Token API Routes', () => {
159179 const response = await POST ( req )
160180 const data = await response . json ( )
161181
162- // With owner-based resolution, missing workflowId no longer matters.
163- // If credential not found via owner lookup, returns 404 accordingly
164- expect ( [ 401 , 404 ] ) . toContain ( response . status )
182+ expect ( response . status ) . toBe ( 403 )
165183 } )
166184
167185 it ( 'should handle credential not found' , async ( ) => {
168- mockGetUserId . mockResolvedValueOnce ( 'test-user-id' )
186+ mockAuthorizeCredentialUse . mockResolvedValueOnce ( {
187+ ok : true ,
188+ authType : 'session' ,
189+ requesterUserId : 'test-user-id' ,
190+ credentialOwnerUserId : 'owner-user-id' ,
191+ } )
169192 mockGetCredential . mockResolvedValueOnce ( undefined )
170193
171194 const req = createMockRequest ( 'POST' , {
@@ -177,12 +200,17 @@ describe('OAuth Token API Routes', () => {
177200 const response = await POST ( req )
178201 const data = await response . json ( )
179202
180- expect ( [ 401 , 404 ] ) . toContain ( response . status )
203+ expect ( response . status ) . toBe ( 401 )
181204 expect ( data ) . toHaveProperty ( 'error' )
182205 } )
183206
184207 it ( 'should handle token refresh failure' , async ( ) => {
185- mockGetUserId . mockResolvedValueOnce ( 'test-user-id' )
208+ mockAuthorizeCredentialUse . mockResolvedValueOnce ( {
209+ ok : true ,
210+ authType : 'session' ,
211+ requesterUserId : 'test-user-id' ,
212+ credentialOwnerUserId : 'owner-user-id' ,
213+ } )
186214 mockGetCredential . mockResolvedValueOnce ( {
187215 id : 'credential-id' ,
188216 accessToken : 'test-token' ,
@@ -211,7 +239,11 @@ describe('OAuth Token API Routes', () => {
211239 */
212240 describe ( 'GET handler' , ( ) => {
213241 it ( 'should return access token successfully' , async ( ) => {
214- mockGetUserId . mockResolvedValueOnce ( 'test-user-id' )
242+ mockCheckHybridAuth . mockResolvedValueOnce ( {
243+ success : true ,
244+ authType : 'session' ,
245+ userId : 'test-user-id' ,
246+ } )
215247 mockGetCredential . mockResolvedValueOnce ( {
216248 id : 'credential-id' ,
217249 accessToken : 'test-token' ,
@@ -236,7 +268,7 @@ describe('OAuth Token API Routes', () => {
236268 expect ( response . status ) . toBe ( 200 )
237269 expect ( data ) . toHaveProperty ( 'accessToken' , 'fresh-token' )
238270
239- expect ( mockGetUserId ) . toHaveBeenCalledWith ( mockRequestId )
271+ expect ( mockCheckHybridAuth ) . toHaveBeenCalled ( )
240272 expect ( mockGetCredential ) . toHaveBeenCalledWith ( mockRequestId , 'credential-id' , 'test-user-id' )
241273 expect ( mockRefreshTokenIfNeeded ) . toHaveBeenCalled ( )
242274 } )
@@ -255,7 +287,10 @@ describe('OAuth Token API Routes', () => {
255287 } )
256288
257289 it ( 'should handle authentication failure' , async ( ) => {
258- mockGetUserId . mockResolvedValueOnce ( undefined )
290+ mockCheckHybridAuth . mockResolvedValueOnce ( {
291+ success : false ,
292+ error : 'Authentication required' ,
293+ } )
259294
260295 const req = new Request (
261296 'http://localhost:3000/api/auth/oauth/token?credentialId=credential-id'
@@ -266,12 +301,16 @@ describe('OAuth Token API Routes', () => {
266301 const response = await GET ( req as any )
267302 const data = await response . json ( )
268303
269- expect ( [ 401 , 404 ] ) . toContain ( response . status )
304+ expect ( response . status ) . toBe ( 401 )
270305 expect ( data ) . toHaveProperty ( 'error' )
271306 } )
272307
273308 it ( 'should handle credential not found' , async ( ) => {
274- mockGetUserId . mockResolvedValueOnce ( 'test-user-id' )
309+ mockCheckHybridAuth . mockResolvedValueOnce ( {
310+ success : true ,
311+ authType : 'session' ,
312+ userId : 'test-user-id' ,
313+ } )
275314 mockGetCredential . mockResolvedValueOnce ( undefined )
276315
277316 const req = new Request (
@@ -283,12 +322,16 @@ describe('OAuth Token API Routes', () => {
283322 const response = await GET ( req as any )
284323 const data = await response . json ( )
285324
286- expect ( [ 401 , 404 ] ) . toContain ( response . status )
325+ expect ( response . status ) . toBe ( 404 )
287326 expect ( data ) . toHaveProperty ( 'error' )
288327 } )
289328
290329 it ( 'should handle missing access token' , async ( ) => {
291- mockGetUserId . mockResolvedValueOnce ( 'test-user-id' )
330+ mockCheckHybridAuth . mockResolvedValueOnce ( {
331+ success : true ,
332+ authType : 'session' ,
333+ userId : 'test-user-id' ,
334+ } )
292335 mockGetCredential . mockResolvedValueOnce ( {
293336 id : 'credential-id' ,
294337 accessToken : null ,
@@ -305,12 +348,16 @@ describe('OAuth Token API Routes', () => {
305348 const response = await GET ( req as any )
306349 const data = await response . json ( )
307350
308- expect ( [ 400 , 401 ] ) . toContain ( response . status )
351+ expect ( response . status ) . toBe ( 400 )
309352 expect ( data ) . toHaveProperty ( 'error' )
310353 } )
311354
312355 it ( 'should handle token refresh failure' , async ( ) => {
313- mockGetUserId . mockResolvedValueOnce ( 'test-user-id' )
356+ mockCheckHybridAuth . mockResolvedValueOnce ( {
357+ success : true ,
358+ authType : 'session' ,
359+ userId : 'test-user-id' ,
360+ } )
314361 mockGetCredential . mockResolvedValueOnce ( {
315362 id : 'credential-id' ,
316363 accessToken : 'test-token' ,
@@ -329,7 +376,7 @@ describe('OAuth Token API Routes', () => {
329376 const response = await GET ( req as any )
330377 const data = await response . json ( )
331378
332- expect ( [ 401 , 404 ] ) . toContain ( response . status )
379+ expect ( response . status ) . toBe ( 401 )
333380 expect ( data ) . toHaveProperty ( 'error' )
334381 } )
335382 } )
0 commit comments