@@ -8,7 +8,7 @@ import { env } from "@sourcebot/shared";
88import { processGitHubPullRequest , processGitLabMergeRequest } from "@/features/agents/review-agent/app" ;
99import { throttling , type ThrottlingOptions } from "@octokit/plugin-throttling" ;
1010import fs from "fs" ;
11- import { GitHubPullRequest , GitLabMergeRequestPayload , GitLabNotePayload } from "@/features/agents/review-agent/types" ;
11+ import { GitHubPullRequest , gitLabMergeRequestPayloadSchema , gitLabNotePayloadSchema } from "@/features/agents/review-agent/types" ;
1212import { createLogger } from "@sourcebot/shared" ;
1313
1414const logger = createLogger ( 'webhook' ) ;
@@ -96,24 +96,24 @@ function isIssueCommentEvent(eventHeader: string, payload: unknown): payload is
9696 return eventHeader === "issue_comment" && typeof payload === "object" && payload !== null && "action" in payload && typeof payload . action === "string" && payload . action === "created" ;
9797}
9898
99- function isGitLabMergeRequestEvent ( eventHeader : string , payload : unknown ) : payload is GitLabMergeRequestPayload {
99+ function isGitLabMergeRequestEvent ( eventHeader : string , payload : unknown ) : boolean {
100100 return (
101101 eventHeader === "Merge Request Hook" &&
102102 typeof payload === "object" &&
103103 payload !== null &&
104104 "object_attributes" in payload &&
105- typeof ( payload as GitLabMergeRequestPayload ) . object_attributes ?. action === "string" &&
106- [ "open" , "update" , "reopen" ] . includes ( ( payload as GitLabMergeRequestPayload ) . object_attributes . action )
105+ typeof ( payload as Record < string , unknown > & { object_attributes : { action ?: unknown } } ) . object_attributes ?. action === "string" &&
106+ [ "open" , "update" , "reopen" ] . includes ( ( payload as Record < string , unknown > & { object_attributes : { action : string } } ) . object_attributes . action )
107107 ) ;
108108}
109109
110- function isGitLabNoteEvent ( eventHeader : string , payload : unknown ) : payload is GitLabNotePayload {
110+ function isGitLabNoteEvent ( eventHeader : string , payload : unknown ) : boolean {
111111 return (
112112 eventHeader === "Note Hook" &&
113113 typeof payload === "object" &&
114114 payload !== null &&
115115 "object_attributes" in payload &&
116- ( payload as GitLabNotePayload ) . object_attributes ?. noteable_type === "MergeRequest"
116+ ( payload as Record < string , unknown > & { object_attributes : { noteable_type ?: unknown } } ) . object_attributes ?. noteable_type === "MergeRequest"
117117 ) ;
118118}
119119
@@ -217,45 +217,57 @@ export const POST = async (request: NextRequest) => {
217217 return Response . json ( { status : 'ok' } ) ;
218218 }
219219
220+ const parsed = gitLabMergeRequestPayloadSchema . safeParse ( body ) ;
221+ if ( ! parsed . success ) {
222+ logger . warn ( `GitLab MR webhook payload failed validation: ${ parsed . error . message } ` ) ;
223+ return Response . json ( { status : 'ok' } ) ;
224+ }
225+
220226 try {
221227 await processGitLabMergeRequest (
222228 gitlabClient ,
223- body . project . id ,
224- body ,
229+ parsed . data . project . id ,
230+ parsed . data ,
225231 env . GITLAB_REVIEW_AGENT_HOST ,
226232 ) ;
227233 } catch ( error ) {
228- logger . error ( `Error in processGitLabMergeRequest for project ${ body . project . id } (${ gitlabEvent } ):` , error ) ;
234+ logger . error ( `Error in processGitLabMergeRequest for project ${ parsed . data . project . id } (${ gitlabEvent } ):` , error ) ;
229235 }
230236 }
231237
232238 if ( isGitLabNoteEvent ( gitlabEvent , body ) ) {
233- const noteBody = body . object_attributes ?. note ;
239+ const parsed = gitLabNotePayloadSchema . safeParse ( body ) ;
240+ if ( ! parsed . success ) {
241+ logger . warn ( `GitLab Note webhook payload failed validation: ${ parsed . error . message } ` ) ;
242+ return Response . json ( { status : 'ok' } ) ;
243+ }
244+
245+ const noteBody = parsed . data . object_attributes . note ;
234246 if ( noteBody === `/${ env . REVIEW_AGENT_REVIEW_COMMAND } ` ) {
235247 logger . info ( 'Review agent review command received on GitLab MR, processing' ) ;
236248
237- const mrPayload : GitLabMergeRequestPayload = {
249+ const mrPayload = {
238250 object_kind : "merge_request" ,
239251 object_attributes : {
240- iid : body . merge_request . iid ,
241- title : body . merge_request . title ,
242- description : body . merge_request . description ,
252+ iid : parsed . data . merge_request . iid ,
253+ title : parsed . data . merge_request . title ,
254+ description : parsed . data . merge_request . description ,
243255 action : "update" ,
244- last_commit : body . merge_request . last_commit ,
245- diff_refs : body . merge_request . diff_refs ,
256+ last_commit : parsed . data . merge_request . last_commit ,
257+ diff_refs : parsed . data . merge_request . diff_refs ,
246258 } ,
247- project : body . project ,
259+ project : parsed . data . project ,
248260 } ;
249261
250262 try {
251263 await processGitLabMergeRequest (
252264 gitlabClient ,
253- body . project . id ,
265+ parsed . data . project . id ,
254266 mrPayload ,
255267 env . GITLAB_REVIEW_AGENT_HOST ,
256268 ) ;
257269 } catch ( error ) {
258- logger . error ( `Error in processGitLabMergeRequest for project ${ body . project . id } (${ gitlabEvent } ):` , error ) ;
270+ logger . error ( `Error in processGitLabMergeRequest for project ${ parsed . data . project . id } (${ gitlabEvent } ):` , error ) ;
259271 }
260272 }
261273 }
0 commit comments