@@ -75,39 +75,67 @@ async function deletePlaneWebhook(
7575 throw new Error ( `Plane webhook deletion failed (HTTP ${ response . status } )` )
7676}
7777
78+ function previousPlaneDeliveryConfig (
79+ providerConfig : Record < string , unknown > ,
80+ payload : unknown
81+ ) : Record < string , unknown > | undefined {
82+ const previous = toRecord ( providerConfig . previousSubscription )
83+ const config = toRecord ( previous . providerConfig )
84+ return previous . provider === 'plane' &&
85+ typeof config . externalId === 'string' &&
86+ toRecord ( payload ) . webhook_id === config . externalId
87+ ? config
88+ : undefined
89+ }
90+
91+ const verifyPlaneSignature = createHmacVerifier ( {
92+ configKey : 'webhookSecret' ,
93+ headerName : 'X-Plane-Signature' ,
94+ providerLabel : 'Plane' ,
95+ requireSecret : true ,
96+ validateFn : ( secret , signature , rawBody ) =>
97+ typeof secret === 'string' &&
98+ secret . length > 0 &&
99+ / ^ [ a - f 0 - 9 ] { 64 } $ / . test ( signature ) &&
100+ safeCompare ( hmacSha256Hex ( rawBody , secret ) , signature ) ,
101+ } )
102+
78103export const planeHandler : WebhookProviderHandler = {
79- verifyAuth : createHmacVerifier ( {
80- configKey : 'webhookSecret' ,
81- headerName : 'X-Plane-Signature' ,
82- providerLabel : 'Plane' ,
83- requireSecret : true ,
84- validateFn : ( secret , signature , rawBody ) =>
85- typeof secret === 'string' &&
86- secret . length > 0 &&
87- / ^ [ a - f 0 - 9 ] { 64 } $ / . test ( signature ) &&
88- safeCompare ( hmacSha256Hex ( rawBody , secret ) , signature ) ,
89- } ) ,
104+ verifyAuth ( ctx ) {
105+ let providerConfig = ctx . providerConfig
106+ if ( providerConfig . previousSubscription ) {
107+ try {
108+ const payload : unknown = JSON . parse ( ctx . rawBody )
109+ providerConfig = previousPlaneDeliveryConfig ( providerConfig , payload ) ?? providerConfig
110+ } catch { }
111+ }
112+ return verifyPlaneSignature ( { ...ctx , providerConfig } )
113+ } ,
90114
91115 async matchEvent ( { body, providerConfig } ) {
92116 const { planeEventName, PLANE_TRIGGER_EVENTS } = await import ( '@/triggers/plane/utils' )
93117 const payload = toRecord ( body )
118+ const matchConfig =
119+ ( providerConfig . subscriptionActivationPending === true
120+ ? previousPlaneDeliveryConfig ( providerConfig , payload )
121+ : undefined ) ?? providerConfig
94122 const eventName = planeEventName ( body )
95123 if ( ! eventName ) return false
96- const triggerId = providerConfig . triggerId
124+ const triggerId = matchConfig . triggerId
97125 if (
98126 typeof triggerId === 'string' &&
99127 triggerId !== 'plane_webhook' &&
100128 PLANE_TRIGGER_EVENTS [ triggerId ] !== eventName
101129 )
102130 return false
103- const workspaceId = providerConfig . workspaceId
131+ const workspaceId = matchConfig . workspaceId
104132 if (
105133 typeof workspaceId === 'string' &&
106134 workspaceId . trim ( ) &&
107135 workspaceId . trim ( ) !== payload . workspace_id
108136 )
109137 return false
110- const projectId = providerConfig . projectId
138+ const projectId = matchConfig . projectId
111139 if ( typeof projectId === 'string' && projectId . trim ( ) ) {
112140 const records = Array . isArray ( payload . data )
113141 ? payload . data
0 commit comments