@@ -27,6 +27,16 @@ export interface WorkflowAccessOptions {
2727async function getValidatedWorkflow ( workflowId : string ) : Promise < ValidationResult > {
2828 const activeWorkflow = await getActiveWorkflowRecord ( workflowId )
2929 if ( activeWorkflow ) {
30+ if ( ! activeWorkflow . workspaceId ) {
31+ return {
32+ error : {
33+ message :
34+ 'This workflow is not attached to a workspace. Personal workflows are deprecated and cannot be accessed.' ,
35+ status : 403 ,
36+ } ,
37+ }
38+ }
39+
3040 return { workflow : activeWorkflow }
3141 }
3242
@@ -71,39 +81,20 @@ export async function validateWorkflowAccess(
7181 const allowInternalSecret = normalizedOptions . allowInternalSecret ?? false
7282
7383 if ( ! requireDeployment ) {
74- const auth = await checkHybridAuth ( request , { requireWorkflowId : false } )
75- if ( ! auth . success || ! auth . userId ) {
76- return {
77- error : {
78- message : auth . error || 'Unauthorized' ,
79- status : 401 ,
80- } ,
81- }
82- }
83-
8484 const workflowResult = await getValidatedWorkflow ( workflowId )
8585 if ( workflowResult . error || ! workflowResult . workflow ) {
8686 return workflowResult
8787 }
8888 const workflow = workflowResult . workflow
89+ const apiKeyHeader = request . headers . get ( 'x-api-key' )
8990
90- if ( auth . authType === AuthType . API_KEY ) {
91- const apiKeyHeader = request . headers . get ( 'x-api-key' )
92- if ( ! apiKeyHeader ) {
93- return {
94- error : {
95- message : 'Unauthorized: Invalid API key' ,
96- status : 401 ,
97- } ,
98- }
99- }
100-
91+ if ( apiKeyHeader ) {
10192 const scopedApiKeyResult = await authenticateApiKeyFromHeader ( apiKeyHeader , {
10293 workspaceId : workflow . workspaceId as string ,
10394 keyTypes : [ 'workspace' , 'personal' ] ,
10495 } )
10596
106- if ( ! scopedApiKeyResult . success ) {
97+ if ( ! scopedApiKeyResult . success || ! scopedApiKeyResult . userId ) {
10798 return {
10899 error : {
109100 message : 'Unauthorized: Invalid API key' ,
@@ -112,7 +103,11 @@ export async function validateWorkflowAccess(
112103 }
113104 }
114105
115- if ( ! scopedApiKeyResult . userId ) {
106+ if ( scopedApiKeyResult . keyId ) {
107+ await updateApiKeyLastUsed ( scopedApiKeyResult . keyId )
108+ }
109+
110+ if ( ! scopedApiKeyResult . workspaceId ) {
116111 return {
117112 error : {
118113 message : 'Unauthorized: Invalid API key' ,
@@ -121,26 +116,40 @@ export async function validateWorkflowAccess(
121116 }
122117 }
123118
124- if ( scopedApiKeyResult . keyId ) {
125- await updateApiKeyLastUsed ( scopedApiKeyResult . keyId )
119+ const auth : AuthResult = {
120+ success : true ,
121+ userId : scopedApiKeyResult . userId ,
122+ workspaceId : scopedApiKeyResult . workspaceId ,
123+ userName : scopedApiKeyResult . userName ,
124+ userEmail : scopedApiKeyResult . userEmail ,
125+ authType : AuthType . API_KEY ,
126+ apiKeyType : scopedApiKeyResult . keyType ,
126127 }
127128
128- auth . workspaceId = scopedApiKeyResult . workspaceId
129- auth . userId = scopedApiKeyResult . userId
130- auth . userName = scopedApiKeyResult . userName
131- auth . userEmail = scopedApiKeyResult . userEmail
132- auth . apiKeyType = scopedApiKeyResult . keyType
129+ const authorization = await authorizeWorkflowByWorkspacePermission ( {
130+ workflowId,
131+ userId : scopedApiKeyResult . userId ,
132+ action,
133+ workflow,
134+ } )
135+ if ( ! authorization . allowed ) {
136+ return {
137+ error : {
138+ message : authorization . message || 'Access denied' ,
139+ status : authorization . status ,
140+ } ,
141+ }
142+ }
143+
144+ return { workflow, auth }
133145 }
134146
135- if (
136- auth . authType === AuthType . API_KEY &&
137- auth . apiKeyType === 'workspace' &&
138- auth . workspaceId !== workflow . workspaceId
139- ) {
147+ const auth = await checkHybridAuth ( request , { requireWorkflowId : false } )
148+ if ( ! auth . success || ! auth . userId ) {
140149 return {
141150 error : {
142- message : 'Workflow not found ',
143- status : 404 ,
151+ message : auth . error || 'Unauthorized ',
152+ status : 401 ,
144153 } ,
145154 }
146155 }
0 commit comments