n8n-nodes-formbase 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,6 +8,7 @@ Community node for [n8n](https://n8n.io) that starts workflows when a [formbase]
8
8
  - Trigger on abandoned submissions when partial submission tracking is enabled.
9
9
  - Load forms dynamically from every workspace available to the credential.
10
10
  - Register and remove formbase webhook subscriptions with the n8n workflow lifecycle.
11
+ - Verify every webhook with HMAC-SHA256 and reject stale or forged requests.
11
12
  - Connect through workspace-scoped OAuth 2.1 with PKCE and automatic refresh-token rotation.
12
13
 
13
14
  ## Install
@@ -42,6 +43,12 @@ Self-hosted n8n must use configured HTTPS public URL for OAuth callback. Loopbac
42
43
 
43
44
  n8n webhook URL must be publicly reachable over HTTPS. For reverse-proxy or tunnel deployments, configure n8n's `WEBHOOK_URL` so generated webhook URLs use public origin.
44
45
 
46
+ n8n generates a separate 256-bit signing secret for each registration. Incoming requests must contain a valid `X-formbase-Signature` header with a timestamp no more than five minutes old. Missing, stale, or invalid signatures receive `401 Unauthorized` and do not start the workflow.
47
+
48
+ ## Example workflow
49
+
50
+ Import [`examples/formbase-submission.json`](examples/formbase-submission.json), connect formbase credential, select form, then activate workflow. Example maps event ID, submission ID, respondent email, and form name into stable output fields.
51
+
45
52
  ## Output
46
53
 
47
54
  Each webhook produces one n8n item containing formbase payload:
@@ -7,7 +7,10 @@ class FormbaseOAuth2Api {
7
7
  this.name = constants_1.FORMBASE_OAUTH2_CREDENTIAL_NAME;
8
8
  this.extends = ['oAuth2Api'];
9
9
  this.displayName = 'formbase OAuth2 API';
10
- this.icon = { light: 'file:../nodes/Formbase/formbase.svg', dark: 'file:../nodes/Formbase/formbase.dark.svg' };
10
+ this.icon = {
11
+ light: 'file:../nodes/Formbase/formbase-logo.svg',
12
+ dark: 'file:../nodes/Formbase/formbase-logo.dark.svg',
13
+ };
11
14
  this.documentationUrl = 'https://github.com/formbaseso/n8n-nodes-formbase#configure-credentials';
12
15
  this.properties = [
13
16
  {
@@ -1 +1 @@
1
- {"version":3,"file":"FormbaseOAuth2Api.credentials.js","sourceRoot":"","sources":["../../credentials/FormbaseOAuth2Api.credentials.ts"],"names":[],"mappings":";;;AAEA,2DAAwG;AAExG,MAAa,iBAAiB;IAA9B;QACE,SAAI,GAAG,2CAA+B,CAAA;QAEtC,YAAO,GAAG,CAAC,WAAW,CAAC,CAAA;QAGvB,gBAAW,GAAG,qBAAqB,CAAA;QAEnC,SAAI,GAAS,EAAE,KAAK,EAAE,qCAAqC,EAAE,IAAI,EAAE,0CAA0C,EAAE,CAAA;QAE/G,qBAAgB,GAAG,wEAAwE,CAAA;QAE3F,eAAU,GAAsB;YAC9B;gBACE,WAAW,EAAE,iCAAiC;gBAC9C,IAAI,EAAE,8BAA8B;gBACpC,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,IAAI;aACd;YACD;gBACE,WAAW,EAAE,YAAY;gBACzB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,qCAAyB;gBAClC,QAAQ,EAAE,IAAI;aACf;SACF,CAAA;QAED,SAAI,GAA2B;YAC7B,OAAO,EAAE;gBACP,GAAG,EAAE,6BAA6B;gBAClC,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE;oBACJ,MAAM,EAAE,QAAQ;oBAChB,MAAM,EAAE,EAAE;iBACX;aACF;SACF,CAAA;IACH,CAAC;CAAA;AAtCD,8CAsCC"}
1
+ {"version":3,"file":"FormbaseOAuth2Api.credentials.js","sourceRoot":"","sources":["../../credentials/FormbaseOAuth2Api.credentials.ts"],"names":[],"mappings":";;;AAEA,2DAAwG;AAExG,MAAa,iBAAiB;IAA9B;QACE,SAAI,GAAG,2CAA+B,CAAA;QAEtC,YAAO,GAAG,CAAC,WAAW,CAAC,CAAA;QAGvB,gBAAW,GAAG,qBAAqB,CAAA;QAEnC,SAAI,GAAS;YACX,KAAK,EAAE,0CAA0C;YACjD,IAAI,EAAE,+CAA+C;SACtD,CAAA;QAED,qBAAgB,GAAG,wEAAwE,CAAA;QAE3F,eAAU,GAAsB;YAC9B;gBACE,WAAW,EAAE,iCAAiC;gBAC9C,IAAI,EAAE,8BAA8B;gBACpC,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,IAAI;aACd;YACD;gBACE,WAAW,EAAE,YAAY;gBACzB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,qCAAyB;gBAClC,QAAQ,EAAE,IAAI;aACf;SACF,CAAA;QAED,SAAI,GAA2B;YAC7B,OAAO,EAAE;gBACP,GAAG,EAAE,6BAA6B;gBAClC,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE;oBACJ,MAAM,EAAE,QAAQ;oBAChB,MAAM,EAAE,EAAE;iBACX;aACF;SACF,CAAA;IACH,CAAC;CAAA;AAzCD,8CAyCC"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FormbaseTrigger = void 0;
4
4
  const n8n_workflow_1 = require("n8n-workflow");
5
5
  const constants_1 = require("./constants");
6
+ const FormbaseWebhookSignature_1 = require("./FormbaseWebhookSignature");
6
7
  const GenericFunctions_1 = require("./GenericFunctions");
7
8
  const FORMS_PAGE_SIZE = 100;
8
9
  async function listWorkspaceForms(context, workspace) {
@@ -27,17 +28,20 @@ async function listWorkspaceForms(context, workspace) {
27
28
  function findWebhookSubscription(subscriptions, targetUrl, eventType) {
28
29
  return subscriptions.find((subscription) => subscription.targetUrl === targetUrl && subscription.provider === 'n8n' && subscription.eventType === eventType);
29
30
  }
31
+ function clearWebhookRegistration(webhookData) {
32
+ delete webhookData.subscriptionId;
33
+ delete webhookData.webhookSecret;
34
+ }
30
35
  class FormbaseTrigger {
31
36
  constructor() {
32
37
  this.description = {
33
38
  displayName: 'formbase Trigger',
34
39
  name: 'formbaseTrigger',
35
- icon: { light: 'file:formbase.svg', dark: 'file:formbase.dark.svg' },
40
+ icon: { light: 'file:formbase-logo.svg', dark: 'file:formbase-logo.dark.svg' },
36
41
  group: ['trigger'],
37
42
  version: 1,
38
- subtitle: '={{$parameter["event"]}}',
43
+ subtitle: '={{ $parameter["event"] === "submission_created" ? "On submission created" : "On submission abandoned" }}',
39
44
  description: 'Starts the workflow when a formbase form receives a submission',
40
- usableAsTool: true,
41
45
  defaults: {
42
46
  name: 'formbase Trigger',
43
47
  },
@@ -85,10 +89,14 @@ class FormbaseTrigger {
85
89
  {
86
90
  name: 'Submission Abandoned',
87
91
  value: constants_1.FORMBASE_WEBHOOK_EVENTS.submissionAbandoned,
92
+ action: 'On submission abandoned',
93
+ description: 'Runs when a respondent leaves the selected form before submitting it; requires partial submission tracking',
88
94
  },
89
95
  {
90
96
  name: 'Submission Created',
91
97
  value: constants_1.FORMBASE_WEBHOOK_EVENTS.submissionCreated,
98
+ action: 'On submission created',
99
+ description: 'Runs when a respondent submits the selected form',
92
100
  },
93
101
  ],
94
102
  default: 'submission_created',
@@ -127,10 +135,17 @@ class FormbaseTrigger {
127
135
  formId,
128
136
  }));
129
137
  const match = findWebhookSubscription(result.items, webhookUrl, eventType);
130
- if (match) {
131
- webhookData.subscriptionId = match.subscriptionId;
132
- return true;
138
+ if (!match) {
139
+ clearWebhookRegistration(webhookData);
140
+ return false;
133
141
  }
142
+ const registrationMatchesStaticData = webhookData.subscriptionId === match.subscriptionId && typeof webhookData.webhookSecret === 'string';
143
+ if (registrationMatchesStaticData)
144
+ return true;
145
+ await GenericFunctions_1.formbaseApiRequest.call(this, 'webhooks.delete', {
146
+ subscriptionId: match.subscriptionId,
147
+ });
148
+ clearWebhookRegistration(webhookData);
134
149
  return false;
135
150
  },
136
151
  async create() {
@@ -139,21 +154,26 @@ class FormbaseTrigger {
139
154
  return false;
140
155
  const formId = this.getNodeParameter('formId');
141
156
  const eventType = this.getNodeParameter('event');
157
+ const webhookSecret = (0, FormbaseWebhookSignature_1.createFormbaseWebhookSecret)();
142
158
  const created = (await GenericFunctions_1.formbaseApiRequest.call(this, 'webhooks.create', {
143
159
  formId,
144
160
  targetUrl: webhookUrl,
145
161
  provider: 'n8n',
146
162
  eventType,
163
+ signingSecret: webhookSecret,
147
164
  }));
148
165
  const webhookData = this.getWorkflowStaticData('node');
149
166
  webhookData.subscriptionId = created.subscriptionId;
167
+ webhookData.webhookSecret = webhookSecret;
150
168
  return true;
151
169
  },
152
170
  async delete() {
153
171
  const webhookData = this.getWorkflowStaticData('node');
154
172
  const subscriptionId = webhookData.subscriptionId;
155
- if (typeof subscriptionId !== 'string')
173
+ if (typeof subscriptionId !== 'string') {
174
+ clearWebhookRegistration(webhookData);
156
175
  return true;
176
+ }
157
177
  try {
158
178
  await GenericFunctions_1.formbaseApiRequest.call(this, 'webhooks.delete', {
159
179
  subscriptionId,
@@ -164,13 +184,17 @@ class FormbaseTrigger {
164
184
  return false;
165
185
  }
166
186
  }
167
- delete webhookData.subscriptionId;
187
+ clearWebhookRegistration(webhookData);
168
188
  return true;
169
189
  },
170
190
  },
171
191
  };
172
192
  }
173
193
  async webhook() {
194
+ if (!(0, FormbaseWebhookSignature_1.verifyFormbaseWebhookSignature)(this)) {
195
+ this.getResponseObject().status(401).send('Unauthorized').end();
196
+ return { noWebhookResponse: true };
197
+ }
174
198
  const body = this.getBodyData();
175
199
  return {
176
200
  workflowData: [this.helpers.returnJsonArray(body)],
@@ -1 +1 @@
1
- {"version":3,"file":"FormbaseTrigger.node.js","sourceRoot":"","sources":["../../../nodes/Formbase/FormbaseTrigger.node.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FormbaseTrigger.node.js","sourceRoot":"","sources":["../../../nodes/Formbase/FormbaseTrigger.node.ts"],"names":[],"mappings":";;;AAUA,+CAAgE;AAEhE,2CAAiH;AACjH,yEAAwG;AACxG,yDAAuD;AA8BvD,MAAM,eAAe,GAAG,GAAG,CAAA;AAE3B,KAAK,UAAU,kBAAkB,CAAC,OAA8B,EAAE,SAA2B;IAC3F,MAAM,KAAK,GAAkB,EAAE,CAAA;IAC/B,IAAI,MAA0B,CAAA;IAE9B,GAAG,CAAC;QACF,MAAM,MAAM,GAAG,CAAC,MAAM,qCAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE;YACnE,WAAW,EAAE,SAAS,CAAC,EAAE;YACzB,KAAK,EAAE,eAAe;YACtB,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9B,CAAC,CAA8B,CAAA;QAEhC,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;QAC3B,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,MAAK;QAC1B,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YACvB,MAAM,IAAI,2BAAY,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,4CAA4C,EAAE,CAAC,CAAA;QACtG,CAAC;QACD,MAAM,GAAG,MAAM,CAAC,UAAU,CAAA;IAC5B,CAAC,QAAQ,MAAM,EAAC;IAEhB,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,uBAAuB,CAC9B,aAAoC,EACpC,SAAiB,EACjB,SAA+B;IAE/B,OAAO,aAAa,CAAC,IAAI,CACvB,CAAC,YAAY,EAAE,EAAE,CACf,YAAY,CAAC,SAAS,KAAK,SAAS,IAAI,YAAY,CAAC,QAAQ,KAAK,KAAK,IAAI,YAAY,CAAC,SAAS,KAAK,SAAS,CAClH,CAAA;AACH,CAAC;AAED,SAAS,wBAAwB,CAAC,WAAwB;IACxD,OAAO,WAAW,CAAC,cAAc,CAAA;IACjC,OAAO,WAAW,CAAC,aAAa,CAAA;AAClC,CAAC;AAGD,MAAa,eAAe;IAA5B;QACE,gBAAW,GAAyB;YAClC,WAAW,EAAE,kBAAkB;YAC/B,IAAI,EAAE,iBAAiB;YACvB,IAAI,EAAE,EAAE,KAAK,EAAE,wBAAwB,EAAE,IAAI,EAAE,6BAA6B,EAAE;YAC9E,KAAK,EAAE,CAAC,SAAS,CAAC;YAClB,OAAO,EAAE,CAAC;YACV,QAAQ,EACN,2GAA2G;YAC7G,WAAW,EAAE,gEAAgE;YAC7E,QAAQ,EAAE;gBACR,IAAI,EAAE,kBAAkB;aACzB;YACD,MAAM,EAAE,EAAE;YACV,OAAO,EAAE,CAAC,kCAAmB,CAAC,IAAI,CAAC;YACnC,WAAW,EAAE;gBACX;oBACE,IAAI,EAAE,2CAA+B;oBACrC,QAAQ,EAAE,IAAI;iBACf;aACF;YACD,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,SAAS;oBACf,UAAU,EAAE,MAAM;oBAClB,YAAY,EAAE,YAAY;oBAC1B,IAAI,EAAE,UAAU;iBACjB;aACF;YACD,YAAY,EAAE;gBACZ,MAAM,EAAE,oCAAoC;gBAC5C,cAAc,EAAE;oBACd,QAAQ,EACN,kKAAkK;oBACpK,MAAM,EACJ,0HAA0H;iBAC7H;gBACD,cAAc,EAAE,uFAAuF;aACxG;YACD,UAAU,EAAE;gBACV;oBACE,WAAW,EAAE,iBAAiB;oBAC9B,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,SAAS;oBACf,WAAW,EAAE;wBACX,iBAAiB,EAAE,UAAU;qBAC9B;oBACD,OAAO,EAAE,EAAE;oBACX,QAAQ,EAAE,IAAI;oBACd,WAAW,EAAE,gHAAgH;iBAC9H;gBACD;oBACE,WAAW,EAAE,OAAO;oBACpB,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,SAAS;oBACf,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,sBAAsB;4BAC5B,KAAK,EAAE,mCAAuB,CAAC,mBAAmB;4BAClD,MAAM,EAAE,yBAAyB;4BACjC,WAAW,EACT,4GAA4G;yBAC/G;wBACD;4BACE,IAAI,EAAE,oBAAoB;4BAC1B,KAAK,EAAE,mCAAuB,CAAC,iBAAiB;4BAChD,MAAM,EAAE,uBAAuB;4BAC/B,WAAW,EAAE,kDAAkD;yBAChE;qBACF;oBACD,OAAO,EAAE,oBAAoB;oBAC7B,WAAW,EAAE,mFAAmF;iBACjG;aACF;SACF,CAAA;QAED,YAAO,GAAG;YACR,WAAW,EAAE;gBACX,KAAK,CAAC,QAAQ;oBACZ,MAAM,eAAe,GAAG,CAAC,MAAM,qCAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,EAAE,EAAE,CAAC,CAAmC,CAAA;oBACtH,MAAM,gBAAgB,GAAG,MAAM,OAAO,CAAC,GAAG,CACxC,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;wBAC9C,SAAS;wBACT,KAAK,EAAE,MAAM,kBAAkB,CAAC,IAAI,EAAE,SAAS,CAAC;qBACjD,CAAC,CAAC,CACJ,CAAA;oBACD,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAA;oBAErD,OAAO,gBAAgB,CAAC,OAAO,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,CACvD,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;wBACnB,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI;wBACxE,KAAK,EAAE,IAAI,CAAC,EAAE;qBACf,CAAC,CAAC,CACJ,CAAA;gBACH,CAAC;aACF;SACF,CAAA;QAED,mBAAc,GAAG;YACf,OAAO,EAAE;gBACP,KAAK,CAAC,WAAW;oBACf,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAA;oBACpD,IAAI,CAAC,UAAU;wBAAE,OAAO,KAAK,CAAA;oBAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAW,CAAA;oBACxD,IAAI,CAAC,MAAM;wBAAE,OAAO,KAAK,CAAA;oBACzB,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAyB,CAAA;oBAExE,MAAM,WAAW,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAA;oBACtD,MAAM,MAAM,GAAG,CAAC,MAAM,qCAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,eAAe,EAAE;wBACnE,MAAM;qBACP,CAAC,CAAsC,CAAA;oBAExC,MAAM,KAAK,GAAG,uBAAuB,CAAC,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,CAAC,CAAA;oBAC1E,IAAI,CAAC,KAAK,EAAE,CAAC;wBACX,wBAAwB,CAAC,WAAW,CAAC,CAAA;wBACrC,OAAO,KAAK,CAAA;oBACd,CAAC;oBAED,MAAM,6BAA6B,GACjC,WAAW,CAAC,cAAc,KAAK,KAAK,CAAC,cAAc,IAAI,OAAO,WAAW,CAAC,aAAa,KAAK,QAAQ,CAAA;oBACtG,IAAI,6BAA6B;wBAAE,OAAO,IAAI,CAAA;oBAI9C,MAAM,qCAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,EAAE;wBACrD,cAAc,EAAE,KAAK,CAAC,cAAc;qBACrC,CAAC,CAAA;oBACF,wBAAwB,CAAC,WAAW,CAAC,CAAA;oBACrC,OAAO,KAAK,CAAA;gBACd,CAAC;gBAED,KAAK,CAAC,MAAM;oBACV,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAA;oBACpD,IAAI,CAAC,UAAU;wBAAE,OAAO,KAAK,CAAA;oBAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAW,CAAA;oBACxD,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAyB,CAAA;oBACxE,MAAM,aAAa,GAAG,IAAA,sDAA2B,GAAE,CAAA;oBAEnD,MAAM,OAAO,GAAG,CAAC,MAAM,qCAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,EAAE;wBACtE,MAAM;wBACN,SAAS,EAAE,UAAU;wBACrB,QAAQ,EAAE,KAAK;wBACf,SAAS;wBACT,aAAa,EAAE,aAAa;qBAC7B,CAAC,CAA0B,CAAA;oBAE5B,MAAM,WAAW,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAA;oBACtD,WAAW,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAA;oBACnD,WAAW,CAAC,aAAa,GAAG,aAAa,CAAA;oBACzC,OAAO,IAAI,CAAA;gBACb,CAAC;gBAED,KAAK,CAAC,MAAM;oBACV,MAAM,WAAW,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAA;oBACtD,MAAM,cAAc,GAAG,WAAW,CAAC,cAAc,CAAA;oBACjD,IAAI,OAAO,cAAc,KAAK,QAAQ,EAAE,CAAC;wBACvC,wBAAwB,CAAC,WAAW,CAAC,CAAA;wBACrC,OAAO,IAAI,CAAA;oBACb,CAAC;oBAED,IAAI,CAAC;wBACH,MAAM,qCAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,EAAE;4BACrD,cAAc;yBACf,CAAC,CAAA;oBACJ,CAAC;oBAAC,OAAO,KAAc,EAAE,CAAC;wBACxB,IAAI,CAAC,CAAC,KAAK,YAAY,2BAAY,CAAC,IAAI,KAAK,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;4BACjE,OAAO,KAAK,CAAA;wBACd,CAAC;oBACH,CAAC;oBACD,wBAAwB,CAAC,WAAW,CAAC,CAAA;oBACrC,OAAO,IAAI,CAAA;gBACb,CAAC;aACF;SACF,CAAA;IAaH,CAAC;IAXC,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,IAAA,yDAA8B,EAAC,IAAI,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC,iBAAiB,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,GAAG,EAAE,CAAA;YAC/D,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAA;QACpC,CAAC;QAED,MAAM,IAAI,GAAgB,IAAI,CAAC,WAAW,EAAE,CAAA;QAC5C,OAAO;YACL,YAAY,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;SACnD,CAAA;IACH,CAAC;CACF;AA1LD,0CA0LC"}
@@ -0,0 +1,18 @@
1
+ {
2
+ "node": "n8n-nodes-formbase",
3
+ "nodeVersion": "1.0",
4
+ "codexVersion": "1.0",
5
+ "categories": ["Marketing & Content", "Productivity"],
6
+ "resources": {
7
+ "credentialDocumentation": [
8
+ {
9
+ "url": "https://github.com/formbaseso/n8n-nodes-formbase#configure-credentials"
10
+ }
11
+ ],
12
+ "primaryDocumentation": [
13
+ {
14
+ "url": "https://github.com/formbaseso/n8n-nodes-formbase"
15
+ }
16
+ ]
17
+ }
18
+ }
@@ -0,0 +1,3 @@
1
+ import type { IWebhookFunctions } from 'n8n-workflow';
2
+ export declare function createFormbaseWebhookSecret(): string;
3
+ export declare function verifyFormbaseWebhookSignature(context: IWebhookFunctions): boolean;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createFormbaseWebhookSecret = createFormbaseWebhookSecret;
4
+ exports.verifyFormbaseWebhookSignature = verifyFormbaseWebhookSignature;
5
+ const node_crypto_1 = require("node:crypto");
6
+ const SIGNATURE_HEADER_PATTERN = /^t=(\d+),sha256=([a-f0-9]{64})$/;
7
+ const SIGNATURE_MAX_AGE_SECONDS = 5 * 60;
8
+ function getRawBody(request) {
9
+ if (!('rawBody' in request))
10
+ return undefined;
11
+ const rawBody = request.rawBody;
12
+ if (Buffer.isBuffer(rawBody))
13
+ return rawBody;
14
+ if (typeof rawBody === 'string')
15
+ return Buffer.from(rawBody);
16
+ return undefined;
17
+ }
18
+ function createFormbaseWebhookSecret() {
19
+ return `whsec_${(0, node_crypto_1.randomBytes)(32).toString('hex')}`;
20
+ }
21
+ function verifyFormbaseWebhookSignature(context) {
22
+ const webhookData = context.getWorkflowStaticData('node');
23
+ const secret = webhookData.webhookSecret;
24
+ if (typeof secret !== 'string' || secret.length === 0)
25
+ return false;
26
+ const signatureHeader = context.getHeaderData()['x-formbase-signature'];
27
+ if (typeof signatureHeader !== 'string')
28
+ return false;
29
+ const match = SIGNATURE_HEADER_PATTERN.exec(signatureHeader);
30
+ if (!match)
31
+ return false;
32
+ const [, timestamp, signatureHex] = match;
33
+ const timestampSeconds = Number(timestamp);
34
+ if (!Number.isSafeInteger(timestampSeconds))
35
+ return false;
36
+ const currentTimestampSeconds = Math.floor(Date.now() / 1000);
37
+ if (Math.abs(currentTimestampSeconds - timestampSeconds) > SIGNATURE_MAX_AGE_SECONDS)
38
+ return false;
39
+ const rawBody = getRawBody(context.getRequestObject());
40
+ if (!rawBody)
41
+ return false;
42
+ const expectedSignature = (0, node_crypto_1.createHmac)('sha256', secret).update(timestamp).update('.').update(rawBody).digest();
43
+ const receivedSignature = Buffer.from(signatureHex, 'hex');
44
+ return expectedSignature.length === receivedSignature.length && (0, node_crypto_1.timingSafeEqual)(expectedSignature, receivedSignature);
45
+ }
46
+ //# sourceMappingURL=FormbaseWebhookSignature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FormbaseWebhookSignature.js","sourceRoot":"","sources":["../../../nodes/Formbase/FormbaseWebhookSignature.ts"],"names":[],"mappings":";;AAgBA,kEAEC;AAED,wEAyBC;AA7CD,6CAAsE;AAItE,MAAM,wBAAwB,GAAG,iCAAiC,CAAA;AAClE,MAAM,yBAAyB,GAAG,CAAC,GAAG,EAAE,CAAA;AAExC,SAAS,UAAU,CAAC,OAA0D;IAC5E,IAAI,CAAC,CAAC,SAAS,IAAI,OAAO,CAAC;QAAE,OAAO,SAAS,CAAA;IAE7C,MAAM,OAAO,GAAY,OAAO,CAAC,OAAO,CAAA;IACxC,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAA;IAC5C,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAC5D,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAgB,2BAA2B;IACzC,OAAO,SAAS,IAAA,yBAAW,EAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAA;AACnD,CAAC;AAED,SAAgB,8BAA8B,CAAC,OAA0B;IACvE,MAAM,WAAW,GAAG,OAAO,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAA;IACzD,MAAM,MAAM,GAAG,WAAW,CAAC,aAAa,CAAA;IACxC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IAEnE,MAAM,eAAe,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,sBAAsB,CAAC,CAAA;IACvE,IAAI,OAAO,eAAe,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAErD,MAAM,KAAK,GAAG,wBAAwB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;IAC5D,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAA;IAExB,MAAM,CAAC,EAAE,SAAS,EAAE,YAAY,CAAC,GAAG,KAAK,CAAA;IACzC,MAAM,gBAAgB,GAAG,MAAM,CAAC,SAAS,CAAC,CAAA;IAC1C,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,gBAAgB,CAAC;QAAE,OAAO,KAAK,CAAA;IAEzD,MAAM,uBAAuB,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;IAC7D,IAAI,IAAI,CAAC,GAAG,CAAC,uBAAuB,GAAG,gBAAgB,CAAC,GAAG,yBAAyB;QAAE,OAAO,KAAK,CAAA;IAElG,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAA;IACtD,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAA;IAE1B,MAAM,iBAAiB,GAAG,IAAA,wBAAU,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAA;IAC7G,MAAM,iBAAiB,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,CAAA;IAE1D,OAAO,iBAAiB,CAAC,MAAM,KAAK,iBAAiB,CAAC,MAAM,IAAI,IAAA,6BAAe,EAAC,iBAAiB,EAAE,iBAAiB,CAAC,CAAA;AACvH,CAAC"}
@@ -0,0 +1,6 @@
1
+ <svg viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="32" height="32" rx="10" fill="#FFFFFF" fill-opacity="0.04"/>
3
+ <rect x="8" y="8" width="6" height="16" rx="2.5" fill="#F7F7F7"/>
4
+ <rect x="16" y="8" width="8" height="6" rx="2.5" fill="#F7F7F7" fill-opacity="0.8"/>
5
+ <rect x="16" y="16" width="6" height="5" rx="2.5" fill="#F7F7F7" fill-opacity="0.7"/>
6
+ </svg>
@@ -0,0 +1,6 @@
1
+ <svg viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="32" height="32" rx="10" fill="#000000" fill-opacity="0.04"/>
3
+ <rect x="8" y="8" width="6" height="16" rx="2.5" fill="#2F2F2F"/>
4
+ <rect x="16" y="8" width="8" height="6" rx="2.5" fill="#2F2F2F" fill-opacity="0.8"/>
5
+ <rect x="16" y="16" width="6" height="5" rx="2.5" fill="#2F2F2F" fill-opacity="0.7"/>
6
+ </svg>
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-formbase",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "n8n community node for formbase — trigger workflows from form submissions.",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",
@@ -32,7 +32,8 @@
32
32
  "prepublishOnly": "npm test && npm run build && npm run lint"
33
33
  },
34
34
  "files": [
35
- "dist"
35
+ "dist",
36
+ "examples"
36
37
  ],
37
38
  "engines": {
38
39
  "node": ">=22"
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "Handle formbase submission",
3
+ "nodes": [
4
+ {
5
+ "parameters": {
6
+ "formId": "",
7
+ "event": "submission_created"
8
+ },
9
+ "type": "n8n-nodes-formbase.formbaseTrigger",
10
+ "typeVersion": 1,
11
+ "position": [0, 0],
12
+ "id": "16e911f0-6385-4acc-8286-1afb15eb035c",
13
+ "name": "formbase Trigger"
14
+ },
15
+ {
16
+ "parameters": {
17
+ "assignments": {
18
+ "assignments": [
19
+ {
20
+ "id": "cdcb57d7-377e-45e2-8da9-63e52f4690b4",
21
+ "name": "eventId",
22
+ "value": "={{ $json.eventId }}",
23
+ "type": "string"
24
+ },
25
+ {
26
+ "id": "b27b42be-fc5d-491f-a93b-02a7fa4e63f8",
27
+ "name": "submissionId",
28
+ "value": "={{ $json.submission.id }}",
29
+ "type": "string"
30
+ },
31
+ {
32
+ "id": "2b171786-cb32-4e73-96e5-d60f39060fe1",
33
+ "name": "respondentEmail",
34
+ "value": "={{ $json.submission.respondentEmail }}",
35
+ "type": "string"
36
+ },
37
+ {
38
+ "id": "a6366cdf-c3b9-4bdc-be3c-723d2bfab7a4",
39
+ "name": "formName",
40
+ "value": "={{ $json.form.name }}",
41
+ "type": "string"
42
+ }
43
+ ]
44
+ },
45
+ "options": {}
46
+ },
47
+ "type": "n8n-nodes-base.set",
48
+ "typeVersion": 3.4,
49
+ "position": [240, 0],
50
+ "id": "27abc7e3-21e9-4654-9078-b12b60420f6d",
51
+ "name": "Prepare submission"
52
+ }
53
+ ],
54
+ "pinData": {},
55
+ "connections": {
56
+ "formbase Trigger": {
57
+ "main": [
58
+ [
59
+ {
60
+ "node": "Prepare submission",
61
+ "type": "main",
62
+ "index": 0
63
+ }
64
+ ]
65
+ ]
66
+ }
67
+ },
68
+ "active": false,
69
+ "settings": {
70
+ "executionOrder": "v1"
71
+ },
72
+ "versionId": "0f0cc0ea-543e-43ac-bf55-9256b1ee5f85",
73
+ "meta": {
74
+ "templateCredsSetupCompleted": false
75
+ },
76
+ "tags": []
77
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-formbase",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "n8n community node for formbase — trigger workflows from form submissions.",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",
@@ -32,7 +32,8 @@
32
32
  "prepublishOnly": "npm test && npm run build && npm run lint"
33
33
  },
34
34
  "files": [
35
- "dist"
35
+ "dist",
36
+ "examples"
36
37
  ],
37
38
  "engines": {
38
39
  "node": ">=22"
@@ -1,4 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60" width="60" height="60">
2
- <circle cx="30" cy="30" r="28" fill="#818CF8"/>
3
- <text x="30" y="40" font-family="Inter, system-ui, sans-serif" font-size="32" font-weight="700" text-anchor="middle" fill="#ffffff">F</text>
4
- </svg>
@@ -1,4 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60" width="60" height="60">
2
- <circle cx="30" cy="30" r="28" fill="#6366F1"/>
3
- <text x="30" y="40" font-family="Inter, system-ui, sans-serif" font-size="32" font-weight="700" text-anchor="middle" fill="#ffffff">F</text>
4
- </svg>