@@ -18,14 +18,14 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
1818const {
1919 mockMergeSubblockStateWithValues,
2020 mockMergeSubBlockValues,
21- mockValidateAuthToken ,
21+ mockReadDeploymentAuthToken ,
2222 mockSetDeploymentAuthCookie,
2323 mockIsEmailAllowed,
2424 mockCheckRateLimitDirect,
2525} = vi . hoisted ( ( ) => ( {
2626 mockMergeSubblockStateWithValues : vi . fn ( ) . mockReturnValue ( { } ) ,
2727 mockMergeSubBlockValues : vi . fn ( ) . mockReturnValue ( { } ) ,
28- mockValidateAuthToken : vi . fn ( ) . mockReturnValue ( false ) ,
28+ mockReadDeploymentAuthToken : vi . fn ( ) . mockResolvedValue ( null ) ,
2929 mockSetDeploymentAuthCookie : vi . fn ( ) ,
3030 mockIsEmailAllowed : vi . fn ( ) ,
3131 mockCheckRateLimitDirect : vi . fn ( ) . mockResolvedValue ( { allowed : true } ) ,
@@ -57,7 +57,7 @@ vi.mock('@sim/workflow-persistence/subblocks', () => ({
5757vi . mock ( '@/lib/core/security/encryption' , ( ) => encryptionMock )
5858
5959vi . mock ( '@/lib/core/security/deployment' , ( ) => ( {
60- validateAuthToken : mockValidateAuthToken ,
60+ readDeploymentAuthToken : mockReadDeploymentAuthToken ,
6161 setDeploymentAuthCookie : mockSetDeploymentAuthCookie ,
6262 isEmailAllowed : mockIsEmailAllowed ,
6363 deploymentAuthCookieName : ( prefix : string , id : string ) => `${ prefix } _auth_${ id } ` ,
@@ -84,52 +84,65 @@ describe('Chat API Utils', () => {
8484
8585 describe ( 'Auth token utils' , ( ) => {
8686 it ( 'should accept valid auth cookie via validateChatAuth' , async ( ) => {
87- mockValidateAuthToken . mockReturnValue ( true )
87+ mockReadDeploymentAuthToken . mockResolvedValue ( { } )
8888
8989 const deployment = {
9090 id : 'chat-id' ,
9191 authType : 'password' ,
9292 password : 'encrypted-password' ,
9393 }
9494
95- const mockRequest = {
96- method : 'POST' ,
97- cookies : {
98- get : vi . fn ( ) . mockReturnValue ( { value : 'valid-token' } ) ,
99- } ,
100- } as any
95+ const mockRequest = createMockRequest ( 'POST' , undefined , {
96+ cookie : 'chat_auth_chat-id=valid-token' ,
97+ } )
10198
10299 const result = await validateChatAuth ( 'request-id' , deployment , mockRequest )
103- expect ( mockValidateAuthToken ) . toHaveBeenCalledWith ( {
100+ expect ( mockReadDeploymentAuthToken ) . toHaveBeenCalledWith ( {
104101 token : 'valid-token' ,
105102 resource : deployment ,
106103 } )
107104 expect ( result . authorized ) . toBe ( true )
108105 } )
109106
110107 it ( 'should reject invalid auth cookie via validateChatAuth' , async ( ) => {
111- mockValidateAuthToken . mockReturnValue ( false )
108+ mockReadDeploymentAuthToken . mockResolvedValue ( null )
112109
113110 const deployment = {
114111 id : 'chat-id' ,
115112 authType : 'password' ,
116113 password : 'encrypted-password' ,
117114 }
118115
119- const mockRequest = {
120- method : 'GET' ,
121- cookies : {
122- get : vi . fn ( ) . mockReturnValue ( { value : 'invalid-token' } ) ,
123- } ,
124- } as any
116+ const mockRequest = createMockRequest ( 'GET' , undefined , {
117+ cookie : 'chat_auth_chat-id=invalid-token' ,
118+ } )
125119
126120 const result = await validateChatAuth ( 'request-id' , deployment , mockRequest )
127121 expect ( result . authorized ) . toBe ( false )
128122 } )
123+
124+ it ( 'returns the authenticated email carried by a valid email-auth cookie' , async ( ) => {
125+ mockReadDeploymentAuthToken . mockResolvedValue ( {
126+ authenticatedEmail : 'person@example.com' ,
127+ } )
128+
129+ const deployment = {
130+ id : 'chat-id' ,
131+ authType : 'email' ,
132+ }
133+ const mockRequest = createMockRequest ( 'POST' , undefined , {
134+ cookie : 'chat_auth_chat-id=valid-token' ,
135+ } )
136+
137+ await expect ( validateChatAuth ( 'request-id' , deployment , mockRequest ) ) . resolves . toEqual ( {
138+ authorized : true ,
139+ authenticatedEmail : 'person@example.com' ,
140+ } )
141+ } )
129142 } )
130143
131144 describe ( 'Cookie handling' , ( ) => {
132- it ( 'should delegate to setDeploymentAuthCookie' , ( ) => {
145+ it ( 'should delegate to setDeploymentAuthCookie' , async ( ) => {
133146 const mockResponse = {
134147 cookies : { set : vi . fn ( ) } ,
135148 } as unknown as NextResponse
@@ -139,7 +152,7 @@ describe('Chat API Utils', () => {
139152 authType : 'password' ,
140153 password : 'encrypted-password' ,
141154 }
142- setChatAuthCookie ( mockResponse , deployment )
155+ await setChatAuthCookie ( mockResponse , deployment )
143156
144157 expect ( mockSetDeploymentAuthCookie ) . toHaveBeenCalledWith ( {
145158 response : mockResponse ,
@@ -148,6 +161,26 @@ describe('Chat API Utils', () => {
148161 verifiedEmail : undefined ,
149162 } )
150163 } )
164+
165+ it ( 'forwards an authenticated email into the signed deployment cookie' , async ( ) => {
166+ const mockResponse = {
167+ cookies : { set : vi . fn ( ) } ,
168+ } as unknown as NextResponse
169+
170+ const deployment = {
171+ id : 'test-chat-id' ,
172+ authType : 'email' ,
173+ allowedEmails : [ 'person@example.com' ] ,
174+ }
175+ await setChatAuthCookie ( mockResponse , deployment , 'person@example.com' )
176+
177+ expect ( mockSetDeploymentAuthCookie ) . toHaveBeenCalledWith ( {
178+ response : mockResponse ,
179+ cookiePrefix : 'chat' ,
180+ resource : deployment ,
181+ verifiedEmail : 'person@example.com' ,
182+ } )
183+ } )
151184 } )
152185
153186 describe ( 'Chat auth validation' , ( ) => {
@@ -429,14 +462,17 @@ describe('Chat API Utils', () => {
429462 } )
430463
431464 it ( 'authorizes execution when session email is allowlisted' , async ( ) => {
432- mockGetSession . mockResolvedValue ( { user : { email : 'user@example .com' } } )
465+ mockGetSession . mockResolvedValue ( { user : { email : 'User@Example .com' } } )
433466 mockIsEmailAllowed . mockReturnValue ( true )
434467
435468 const result = await validateChatAuth ( 'request-id' , ssoDeployment , postRequest , {
436469 input : 'hello' ,
437470 } )
438471
439- expect ( result . authorized ) . toBe ( true )
472+ expect ( result ) . toEqual ( {
473+ authorized : true ,
474+ authenticatedEmail : 'user@example.com' ,
475+ } )
440476 } )
441477
442478 it ( 'rejects execution when session email is not allowlisted' , async ( ) => {
0 commit comments