11import { beforeEach , describe , expect , it , vi } from "vitest" ;
22
33const mocks = vi . hoisted ( ( ) => ( {
4+ authenticateRequest : vi . fn < ( ...args : any [ ] ) => Promise < any > > ( ) ,
5+ verifyUserActorToken : vi . fn < ( ...args : any [ ] ) => Promise < any > > ( ) ,
6+ isUserActorToken : vi . fn < ( value : string ) => boolean > ( ) ,
47 authenticateUatOrApiRequest : vi . fn < ( ...args : any [ ] ) => Promise < any > > ( ) ,
58 authorizePatEnvironmentAccess : vi . fn < ( ...args : any [ ] ) => Promise < any > > ( ) ,
69} ) ) ;
710
8- vi . mock ( "~/services/uatRoutePreamble.server" , ( ) => ( {
9- authenticateUatOrApiRequest : mocks . authenticateUatOrApiRequest ,
11+ vi . mock ( "@trigger.dev/rbac" , async ( importOriginal ) => ( {
12+ ...( await importOriginal < Record < string , unknown > > ( ) ) ,
13+ isUserActorToken : mocks . isUserActorToken ,
14+ verifyUserActorToken : mocks . verifyUserActorToken ,
1015} ) ) ;
1116vi . mock ( "~/services/environmentVariableApiAccess.server" , ( ) => ( {
1217 authorizePatEnvironmentAccess : mocks . authorizePatEnvironmentAccess ,
1318} ) ) ;
1419vi . mock ( "~/services/apiAuth.server" , ( ) => ( {
1520 authenticatedEnvironmentForAuthentication : vi . fn ( async ( ) => environment ) ,
1621 branchNameFromRequest : ( ) => undefined ,
22+ authenticateRequest : mocks . authenticateRequest ,
1723} ) ) ;
1824vi . mock ( "~/services/logger.server" , ( ) => ( {
19- logger : { debug : vi . fn ( ) , error : vi . fn ( ) , warn : vi . fn ( ) } ,
25+ logger : { debug : vi . fn ( ) , error : vi . fn ( ) , warn : vi . fn ( ) , info : vi . fn ( ) } ,
2026} ) ) ;
27+ vi . mock ( "~/env.server" , ( ) => ( { env : { SESSION_SECRET : "test-session-secret" } } ) ) ;
28+ vi . mock ( "~/db.server" , ( ) => ( { prisma : { } , $replica : { } } ) ) ;
2129
2230import { validateJWT } from "@trigger.dev/core/v3/jwt" ;
2331import { action } from "~/routes/api.v1.projects.$projectRef.$env.jwt" ;
@@ -32,10 +40,10 @@ const environment = {
3240
3341const params = { projectRef : "proj_abc" , env : "prod" } ;
3442
35- function request ( body : unknown = { } ) {
43+ function request ( body : unknown = { } , bearer = "tr_pat_test" ) {
3644 return new Request ( "https://example.com/api/v1/projects/proj_abc/prod/jwt" , {
3745 method : "POST" ,
38- headers : { "Content-Type" : "application/json" } ,
46+ headers : { "Content-Type" : "application/json" , Authorization : `Bearer ${ bearer } ` } ,
3947 body : JSON . stringify ( body ) ,
4048 } ) ;
4149}
@@ -50,14 +58,18 @@ async function mintedClaims(body?: unknown) {
5058
5159describe ( "env JWT exchange — act claim" , ( ) => {
5260 beforeEach ( ( ) => {
53- mocks . authenticateUatOrApiRequest . mockReset ( ) ;
61+ mocks . authenticateRequest . mockReset ( ) ;
62+ mocks . verifyUserActorToken . mockReset ( ) ;
63+ mocks . isUserActorToken . mockReset ( ) ;
64+ mocks . isUserActorToken . mockReturnValue ( false ) ;
5465 mocks . authorizePatEnvironmentAccess . mockReset ( ) ;
5566 mocks . authorizePatEnvironmentAccess . mockResolvedValue ( undefined ) ;
5667 } ) ;
5768
5869 it ( "stamps the PAT's user with the personal-access-token client" , async ( ) => {
59- mocks . authenticateUatOrApiRequest . mockResolvedValue ( {
60- authenticationResult : { type : "personalAccessToken" , result : { userId : "usr_42" } } ,
70+ mocks . authenticateRequest . mockResolvedValue ( {
71+ type : "personalAccessToken" ,
72+ result : { userId : "usr_42" } ,
6173 } ) ;
6274
6375 const claims = await mintedClaims ( ) ;
@@ -67,9 +79,13 @@ describe("env JWT exchange — act claim", () => {
6779 } ) ;
6880
6981 it ( "passes through a user-actor token's own client" , async ( ) => {
70- mocks . authenticateUatOrApiRequest . mockResolvedValue ( {
71- authenticationResult : { type : "personalAccessToken" , result : { userId : "usr_7" } } ,
72- userActor : { userId : "usr_7" , client : "dashboard-agent" , cap : [ "read:runs" ] } ,
82+ mocks . isUserActorToken . mockReturnValue ( true ) ;
83+ mocks . verifyUserActorToken . mockResolvedValue ( {
84+ userId : "usr_7" ,
85+ client : "dashboard-agent" ,
86+ // An agent token always carries the environment it was minted for.
87+ environmentId : environment . id ,
88+ cap : [ "read:runs" ] ,
7389 } ) ;
7490
7591 const claims = await mintedClaims ( { claims : { scopes : [ "read:runs" ] } } ) ;
@@ -79,11 +95,9 @@ describe("env JWT exchange — act claim", () => {
7995 } ) ;
8096
8197 it ( "omits act for an org access token (no user)" , async ( ) => {
82- mocks . authenticateUatOrApiRequest . mockResolvedValue ( {
83- authenticationResult : {
84- type : "organizationAccessToken" ,
85- result : { organizationId : "org_1" } ,
86- } ,
98+ mocks . authenticateRequest . mockResolvedValue ( {
99+ type : "organizationAccessToken" ,
100+ result : { organizationId : "org_1" } ,
87101 } ) ;
88102
89103 const claims = await mintedClaims ( ) ;
@@ -93,7 +107,7 @@ describe("env JWT exchange — act claim", () => {
93107 } ) ;
94108
95109 it ( "401s without a token" , async ( ) => {
96- mocks . authenticateUatOrApiRequest . mockResolvedValue ( undefined ) ;
110+ mocks . authenticateRequest . mockResolvedValue ( undefined ) ;
97111
98112 const response = await action ( { request : request ( ) , params, context : { } as any } ) ;
99113
0 commit comments