@textbee/n8n-nodes-textbee 1.0.0 → 1.2.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 +39 -11
- package/dist/credentials/TextbeeApi.credentials.js +2 -2
- package/dist/credentials/TextbeeApi.credentials.js.map +1 -1
- package/dist/nodes/Textbee/resources/message/send.js +35 -3
- package/dist/nodes/Textbee/resources/message/send.js.map +1 -1
- package/dist/nodes/Textbee/resources/message/sendBulk.js +30 -8
- package/dist/nodes/Textbee/resources/message/sendBulk.js.map +1 -1
- package/dist/nodes/Textbee/shared/bulk.d.ts +2 -0
- package/dist/nodes/Textbee/shared/bulk.js +4 -0
- package/dist/nodes/Textbee/shared/bulk.js.map +1 -1
- package/dist/nodes/Textbee/shared/descriptions.d.ts +1 -0
- package/dist/nodes/Textbee/shared/descriptions.js +2 -1
- package/dist/nodes/Textbee/shared/descriptions.js.map +1 -1
- package/dist/nodes/Textbee/shared/signature.d.ts +3 -0
- package/dist/nodes/Textbee/shared/signature.js +40 -3
- package/dist/nodes/Textbee/shared/signature.js.map +1 -1
- package/dist/nodes/Textbee/shared/subscription.d.ts +3 -0
- package/dist/nodes/Textbee/shared/subscription.js +26 -0
- package/dist/nodes/Textbee/shared/subscription.js.map +1 -1
- package/dist/nodes/TextbeeTrigger/TextbeeTrigger.node.js +45 -18
- package/dist/nodes/TextbeeTrigger/TextbeeTrigger.node.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,12 +20,14 @@ The textbee node can also be used as a tool by the n8n AI Agent.
|
|
|
20
20
|
3. Enter `@textbee/n8n-nodes-textbee`.
|
|
21
21
|
4. Agree to the risks and install.
|
|
22
22
|
|
|
23
|
-
Or
|
|
23
|
+
Or install it from the environment when n8n starts. The value is a JSON array:
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
|
-
N8N_COMMUNITY_PACKAGES
|
|
26
|
+
N8N_COMMUNITY_PACKAGES='[{"name":"@textbee/n8n-nodes-textbee"}]'
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
+
Restart n8n after you set it. See [installing with environment variables](https://docs.n8n.io/integrations/community-nodes/installation-and-management/environment-variable-installation/) in the n8n docs.
|
|
30
|
+
|
|
29
31
|
### n8n Cloud
|
|
30
32
|
|
|
31
33
|
The nodes are in review for n8n verification. After approval you can add them from the nodes panel in n8n Cloud.
|
|
@@ -34,11 +36,11 @@ The nodes are in review for n8n verification. After approval you can add them fr
|
|
|
34
36
|
|
|
35
37
|
Create a **Textbee API** credential:
|
|
36
38
|
|
|
37
|
-
| Field | Required
|
|
38
|
-
| -------------------------- |
|
|
39
|
-
| **API Key** | Yes
|
|
40
|
-
| **Base URL** | No
|
|
41
|
-
| **Webhook Signing Secret** | Trigger
|
|
39
|
+
| Field | Required | Description |
|
|
40
|
+
| -------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
41
|
+
| **API Key** | Yes | From the [textbee dashboard](https://app.textbee.dev/dashboard). See [API keys](https://textbee.dev/docs/getting-started/api-keys). |
|
|
42
|
+
| **Base URL** | No | Defaults to `https://api.textbee.dev`. Change it for [self-hosted](https://textbee.dev/docs/self-hosting) instances. The `/api/v1` suffix is added automatically. |
|
|
43
|
+
| **Webhook Signing Secret** | No | Leave it empty: the textbee Trigger creates a separate secret for each workflow. Set it (at least 20 characters) only if you need the same secret across workflows. If set, it is always used. |
|
|
42
44
|
|
|
43
45
|
## Operations
|
|
44
46
|
|
|
@@ -55,9 +57,30 @@ Create a **Textbee API** credential:
|
|
|
55
57
|
|
|
56
58
|
Starts a workflow on these events: `MESSAGE_RECEIVED`, `MESSAGE_SENT`, `MESSAGE_DELIVERED`, `MESSAGE_FAILED`, `UNKNOWN_STATE`.
|
|
57
59
|
|
|
58
|
-
When you
|
|
60
|
+
No setup in the textbee dashboard is needed. When you publish the workflow, the trigger creates a webhook subscription in textbee that points at the n8n production webhook URL. When you unpublish it, the trigger deletes the subscription. If the URL, the events, or the signing secret change, the trigger updates the existing subscription instead of creating a new one. If events stop arriving, publish the workflow again.
|
|
61
|
+
|
|
62
|
+
The subscription is named `n8n: <workflow name> (<n8n host>)`, so you can see in the textbee dashboard which n8n instance owns it.
|
|
63
|
+
|
|
64
|
+
A textbee account can have 5 webhook subscriptions by default. The limit depends on your plan. Each published workflow with a textbee Trigger uses one.
|
|
65
|
+
|
|
66
|
+
#### Signing secret
|
|
67
|
+
|
|
68
|
+
When the credential **Webhook Signing Secret** is empty, the trigger creates a random secret for each workflow and keeps it in the workflow's static data in n8n. Each workflow then has its own secret, and the secret never appears in node output. When the credential secret is set, every trigger on that credential uses it, and the trigger also checks that each delivery belongs to its own subscription.
|
|
69
|
+
|
|
70
|
+
#### Signature checks and replay protection
|
|
59
71
|
|
|
60
|
-
|
|
72
|
+
textbee signs every delivery. Requests with a missing or wrong signature get HTTP 401.
|
|
73
|
+
|
|
74
|
+
- `X-Textbee-Signature: t=<unix seconds>,v1=<hex>`: `v1` is the HMAC-SHA256 of `<t>.<raw body>`. The trigger rejects a timestamp more than 5 minutes away from the current time, so a captured request cannot be replayed later. `X-Textbee-Timestamp` carries the same timestamp.
|
|
75
|
+
- `X-Signature`: the HMAC-SHA256 of the raw body, without a timestamp. textbee still sends it for older integrations.
|
|
76
|
+
|
|
77
|
+
When the textbee API reports timestamped signatures for the subscription, the trigger requires a valid `X-Textbee-Signature` and rejects requests that only carry `X-Signature`. Older and self-hosted textbee versions that do not send the timestamped header are still accepted with `X-Signature`.
|
|
78
|
+
|
|
79
|
+
Notes:
|
|
80
|
+
|
|
81
|
+
- After you upgrade this package, publish your textbee Trigger workflows again (or restart n8n). The trigger learns that the API supports timestamped signatures when the workflow is published.
|
|
82
|
+
- The n8n server clock must be correct (use NTP). A clock that is more than 5 minutes off makes every delivery fail.
|
|
83
|
+
- If you change the credential signing secret, publish the workflows again so textbee uses the new secret.
|
|
61
84
|
|
|
62
85
|
## Usage
|
|
63
86
|
|
|
@@ -65,8 +88,13 @@ Every request is checked against the `X-Signature` header (HMAC-SHA256 of the ra
|
|
|
65
88
|
|
|
66
89
|
1. Add a **textbee** node.
|
|
67
90
|
2. Set Resource to **Message** and Operation to **Send**.
|
|
68
|
-
3. Enter the **Message** and the **Recipients** (
|
|
91
|
+
3. Enter the **Message** and the **Recipients** (phone numbers or short codes, comma-separated). International format, for example `+15555550123`, reaches any country. Local numbers and short codes reach recipients in the sending phone's country.
|
|
69
92
|
4. Optionally pick a **Device**. Without one, textbee uses your default device.
|
|
93
|
+
5. Optionally pick a **SIM**. **SIM 1** and **SIM 2** are the slots in the phone. **Default (Phone Decides)** sends no SIM choice, so the phone uses its default SIM. An expression that returns `0` (SIM 1) or `1` (SIM 2) also works.
|
|
94
|
+
|
|
95
|
+
If the slot has no active SIM, the message fails with the error code `SIM_SLOT_EMPTY`. textbee never sends it from another SIM. The older **SIM Subscription ID (Older)** field still works, but Android can change that ID after a SIM swap. When you set both, the **SIM** option wins.
|
|
96
|
+
|
|
97
|
+
In **Send Bulk**, each message entry has its own **SIM** field.
|
|
70
98
|
|
|
71
99
|
A successful response means textbee accepted and queued the message. It is not a delivery confirmation. To follow the status, use **Get Many** with the `smsBatchId` filter, or a **textbee Trigger** on **Message Delivered** and **Message Failed**.
|
|
72
100
|
|
|
@@ -75,7 +103,7 @@ A successful response means textbee accepted and queued the message. It is not a
|
|
|
75
103
|
1. In the textbee Android app, turn on **Receive SMS**.
|
|
76
104
|
2. Add a **textbee Trigger** and select **Message Received**.
|
|
77
105
|
3. Connect a **textbee** node with Operation **Send**. Set Recipients to `{{ $json.sender }}` and write the reply in Message.
|
|
78
|
-
4.
|
|
106
|
+
4. Publish the workflow. The production webhook URL must be public, because textbee does not deliver to localhost or private addresses. In development, use a tunnel.
|
|
79
107
|
|
|
80
108
|
textbee retries failed deliveries. Use the `idempotencyKey` field of the payload to skip duplicates.
|
|
81
109
|
|
|
@@ -32,8 +32,8 @@ class TextbeeApi {
|
|
|
32
32
|
type: 'string',
|
|
33
33
|
typeOptions: { password: true },
|
|
34
34
|
default: '',
|
|
35
|
-
description: '
|
|
36
|
-
hint: '
|
|
35
|
+
description: 'Optional. Leave empty and the textbee Trigger creates a separate secret for each workflow. Set it only if you need the same secret across workflows.',
|
|
36
|
+
hint: 'If set, use at least 20 characters',
|
|
37
37
|
},
|
|
38
38
|
];
|
|
39
39
|
this.authenticate = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextbeeApi.credentials.js","sourceRoot":"","sources":["../../credentials/TextbeeApi.credentials.ts"],"names":[],"mappings":";;;AAQA,6DAAoE;AAEpE,MAAa,UAAU;IAAvB;QACC,SAAI,GAAG,YAAY,CAAC;QAEpB,gBAAW,GAAG,aAAa,CAAC;QAE5B,SAAI,GAAS,EAAE,KAAK,EAAE,2BAA2B,EAAE,IAAI,EAAE,gCAAgC,EAAE,CAAC;QAE5F,qBAAgB,GAAG,mDAAmD,CAAC;QAEvE,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,oCAAoC;aACjD;YACD;gBACC,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,yBAAyB;gBAClC,WAAW,EAAE,yBAAyB;gBACtC,WAAW,EACV,+IAA+I;aAChJ;YACD;gBACC,WAAW,EAAE,wBAAwB;gBACrC,IAAI,EAAE,sBAAsB;gBAC5B,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,WAAW,EACV,
|
|
1
|
+
{"version":3,"file":"TextbeeApi.credentials.js","sourceRoot":"","sources":["../../credentials/TextbeeApi.credentials.ts"],"names":[],"mappings":";;;AAQA,6DAAoE;AAEpE,MAAa,UAAU;IAAvB;QACC,SAAI,GAAG,YAAY,CAAC;QAEpB,gBAAW,GAAG,aAAa,CAAC;QAE5B,SAAI,GAAS,EAAE,KAAK,EAAE,2BAA2B,EAAE,IAAI,EAAE,gCAAgC,EAAE,CAAC;QAE5F,qBAAgB,GAAG,mDAAmD,CAAC;QAEvE,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,oCAAoC;aACjD;YACD;gBACC,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,yBAAyB;gBAClC,WAAW,EAAE,yBAAyB;gBACtC,WAAW,EACV,+IAA+I;aAChJ;YACD;gBACC,WAAW,EAAE,wBAAwB;gBACrC,IAAI,EAAE,sBAAsB;gBAC5B,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,WAAW,EACV,sJAAsJ;gBACvJ,IAAI,EAAE,oCAAoC;aAC1C;SACD,CAAC;QAEF,iBAAY,GAAyB;YACpC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACX,OAAO,EAAE;oBACR,WAAW,EAAE,0BAA0B;iBACvC;aACD;SACD,CAAC;QAEF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,2BAAiB;gBAC1B,GAAG,EAAE,gBAAgB;gBACrB,MAAM,EAAE,KAAK;aACb;SACD,CAAC;IACH,CAAC;CAAA;AAxDD,gCAwDC"}
|
|
@@ -35,7 +35,7 @@ exports.messageSendDescription = [
|
|
|
35
35
|
default: '',
|
|
36
36
|
required: true,
|
|
37
37
|
placeholder: '+12015550123, +12015550124',
|
|
38
|
-
description: 'Phone numbers
|
|
38
|
+
description: 'Phone numbers or short codes. International format, for example +15555550123, reaches any country. Local numbers and short codes reach recipients in the same country as the sending phone. Separate multiple recipients with commas. Each recipient counts as one message against your plan.',
|
|
39
39
|
displayOptions: {
|
|
40
40
|
show: showOnlyForMessageSend,
|
|
41
41
|
},
|
|
@@ -60,6 +60,38 @@ exports.messageSendDescription = [
|
|
|
60
60
|
},
|
|
61
61
|
},
|
|
62
62
|
},
|
|
63
|
+
{
|
|
64
|
+
displayName: 'SIM',
|
|
65
|
+
name: 'simSlotIndex',
|
|
66
|
+
type: 'options',
|
|
67
|
+
options: [
|
|
68
|
+
{
|
|
69
|
+
name: 'Default (Phone Decides)',
|
|
70
|
+
value: '',
|
|
71
|
+
description: 'Do not choose a SIM. The phone uses its default SIM.',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: 'SIM 1',
|
|
75
|
+
value: 0,
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'SIM 2',
|
|
79
|
+
value: 1,
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
default: '',
|
|
83
|
+
description: 'Which SIM sends the message, by its slot in the phone. Default lets the phone decide. If the slot has no active SIM, the message fails and is never sent from another SIM. You can also switch to Expression and return 0 for SIM 1 or 1 for SIM 2.',
|
|
84
|
+
displayOptions: {
|
|
85
|
+
show: showOnlyForMessageSend,
|
|
86
|
+
},
|
|
87
|
+
routing: {
|
|
88
|
+
send: {
|
|
89
|
+
type: 'body',
|
|
90
|
+
property: 'simSlotIndex',
|
|
91
|
+
value: `={{ ${descriptions_1.simSlotExpressionBody} }}`,
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
},
|
|
63
95
|
{
|
|
64
96
|
displayName: 'Additional Fields',
|
|
65
97
|
name: 'additionalFields',
|
|
@@ -71,11 +103,11 @@ exports.messageSendDescription = [
|
|
|
71
103
|
},
|
|
72
104
|
options: [
|
|
73
105
|
{
|
|
74
|
-
displayName: 'SIM Subscription ID',
|
|
106
|
+
displayName: 'SIM Subscription ID (Older)',
|
|
75
107
|
name: 'simSubscriptionId',
|
|
76
108
|
type: 'number',
|
|
77
109
|
default: 0,
|
|
78
|
-
description: '
|
|
110
|
+
description: 'Older way to choose a SIM, by its Android subscription ID. The ID can change after a SIM swap. The SIM option is preferred and wins when both are set.',
|
|
79
111
|
routing: {
|
|
80
112
|
send: {
|
|
81
113
|
type: 'body',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send.js","sourceRoot":"","sources":["../../../../../nodes/Textbee/resources/message/send.ts"],"names":[],"mappings":";;;AAEA,wDAA2D;AAC3D,
|
|
1
|
+
{"version":3,"file":"send.js","sourceRoot":"","sources":["../../../../../nodes/Textbee/resources/message/send.ts"],"names":[],"mappings":"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"}
|
|
@@ -45,14 +45,7 @@ exports.messageSendBulkDescription = [
|
|
|
45
45
|
default: '',
|
|
46
46
|
required: true,
|
|
47
47
|
placeholder: '+12015550123',
|
|
48
|
-
description: '
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
displayName: 'SIM Subscription ID',
|
|
52
|
-
name: 'simSubscriptionId',
|
|
53
|
-
type: 'number',
|
|
54
|
-
default: 0,
|
|
55
|
-
description: 'SIM subscription ID for this entry. Leave at 0 to use the device default SIM.',
|
|
48
|
+
description: 'Phone numbers or short codes, comma-separated. International format, for example +15555550123, reaches any country.',
|
|
56
49
|
},
|
|
57
50
|
{
|
|
58
51
|
displayName: 'Scheduled At',
|
|
@@ -61,6 +54,35 @@ exports.messageSendBulkDescription = [
|
|
|
61
54
|
default: '',
|
|
62
55
|
description: 'Optional ISO schedule time (up to 72 hours ahead)',
|
|
63
56
|
},
|
|
57
|
+
{
|
|
58
|
+
displayName: 'SIM',
|
|
59
|
+
name: 'simSlotIndex',
|
|
60
|
+
type: 'options',
|
|
61
|
+
options: [
|
|
62
|
+
{
|
|
63
|
+
name: 'Default (Phone Decides)',
|
|
64
|
+
value: '',
|
|
65
|
+
description: 'Do not choose a SIM. The phone uses its default SIM.',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'SIM 1',
|
|
69
|
+
value: 0,
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: 'SIM 2',
|
|
73
|
+
value: 1,
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
default: '',
|
|
77
|
+
description: 'Which SIM sends the message, by its slot in the phone. Default lets the phone decide. If the slot has no active SIM, the message fails and is never sent from another SIM. You can also switch to Expression and return 0 for SIM 1 or 1 for SIM 2.',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
displayName: 'SIM Subscription ID (Older)',
|
|
81
|
+
name: 'simSubscriptionId',
|
|
82
|
+
type: 'number',
|
|
83
|
+
default: 0,
|
|
84
|
+
description: 'Older way to choose a SIM, by its Android subscription ID. Leave at 0 to skip it. The SIM option is preferred and wins when both are set.',
|
|
85
|
+
},
|
|
64
86
|
],
|
|
65
87
|
},
|
|
66
88
|
],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sendBulk.js","sourceRoot":"","sources":["../../../../../nodes/Textbee/resources/message/sendBulk.ts"],"names":[],"mappings":";;;AAEA,4CAAwD;AACxD,wDAA2D;AAC3D,4DAAoF;AAEpF,MAAM,0BAA0B,GAAG;IAClC,SAAS,EAAE,CAAC,UAAU,CAAC;IACvB,QAAQ,EAAE,CAAC,SAAS,CAAC;CACrB,CAAC;AAEW,QAAA,0BAA0B,GAAsB;IAC5D;QACC,WAAW,EAAE,UAAU;QACvB,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE;YACZ,cAAc,EAAE,IAAI;SACpB;QACD,WAAW,EAAE,aAAa;QAC1B,OAAO,EAAE,EAAE;QACX,QAAQ,EAAE,IAAI;QACd,cAAc,EAAE;YACf,IAAI,EAAE,0BAA0B;SAChC;QACD,OAAO,EAAE;YACR;gBACC,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE;oBACP;wBACC,WAAW,EAAE,SAAS;wBACtB,IAAI,EAAE,SAAS;wBACf,IAAI,EAAE,QAAQ;wBACd,WAAW,EAAE;4BACZ,IAAI,EAAE,CAAC;yBACP;wBACD,OAAO,EAAE,EAAE;wBACX,QAAQ,EAAE,IAAI;wBACd,WAAW,EAAE,wBAAwB;qBACrC;oBACD;wBACC,WAAW,EAAE,YAAY;wBACzB,IAAI,EAAE,YAAY;wBAClB,IAAI,EAAE,QAAQ;wBACd,OAAO,EAAE,EAAE;wBACX,QAAQ,EAAE,IAAI;wBACd,WAAW,EAAE,cAAc;wBAC3B,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"sendBulk.js","sourceRoot":"","sources":["../../../../../nodes/Textbee/resources/message/sendBulk.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,12 +2,14 @@ import { type IExecuteSingleFunctions, type IHttpRequestOptions } from 'n8n-work
|
|
|
2
2
|
export type BulkMessageInput = {
|
|
3
3
|
message?: string;
|
|
4
4
|
recipients?: string;
|
|
5
|
+
simSlotIndex?: number | string;
|
|
5
6
|
simSubscriptionId?: number;
|
|
6
7
|
scheduledAt?: string;
|
|
7
8
|
};
|
|
8
9
|
export type BulkMessage = {
|
|
9
10
|
message: string;
|
|
10
11
|
recipients: string[];
|
|
12
|
+
simSlotIndex?: number | string;
|
|
11
13
|
simSubscriptionId?: number;
|
|
12
14
|
scheduledAt?: string;
|
|
13
15
|
};
|
|
@@ -25,6 +25,10 @@ function buildBulkMessages(entries) {
|
|
|
25
25
|
message: (_a = entry.message) !== null && _a !== void 0 ? _a : '',
|
|
26
26
|
recipients: splitRecipients(entry.recipients),
|
|
27
27
|
};
|
|
28
|
+
if (entry.simSlotIndex !== undefined && entry.simSlotIndex !== null && entry.simSlotIndex !== '') {
|
|
29
|
+
const slot = typeof entry.simSlotIndex === 'string' && entry.simSlotIndex.trim() === '' ? NaN : Number(entry.simSlotIndex);
|
|
30
|
+
message.simSlotIndex = Number.isInteger(slot) ? slot : entry.simSlotIndex;
|
|
31
|
+
}
|
|
28
32
|
if (entry.simSubscriptionId)
|
|
29
33
|
message.simSubscriptionId = entry.simSubscriptionId;
|
|
30
34
|
if (entry.scheduledAt) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bulk.js","sourceRoot":"","sources":["../../../../nodes/Textbee/shared/bulk.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"bulk.js","sourceRoot":"","sources":["../../../../nodes/Textbee/shared/bulk.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,3 +6,4 @@ export declare const unwrapDataPostReceive: {
|
|
|
6
6
|
property: string;
|
|
7
7
|
};
|
|
8
8
|
}[];
|
|
9
|
+
export declare const simSlotExpressionBody = "$value === '' || $value === undefined || $value === null ? undefined : (Number.isInteger(typeof $value === 'string' && $value.trim() === '' ? NaN : Number($value)) ? Number($value) : $value)";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.unwrapDataPostReceive = exports.deviceIdProperty = void 0;
|
|
3
|
+
exports.simSlotExpressionBody = exports.unwrapDataPostReceive = exports.deviceIdProperty = void 0;
|
|
4
4
|
exports.deviceIdProperty = {
|
|
5
5
|
displayName: 'Device',
|
|
6
6
|
name: 'deviceId',
|
|
@@ -43,4 +43,5 @@ exports.unwrapDataPostReceive = [
|
|
|
43
43
|
},
|
|
44
44
|
},
|
|
45
45
|
];
|
|
46
|
+
exports.simSlotExpressionBody = "$value === '' || $value === undefined || $value === null ? undefined : (Number.isInteger(typeof $value === 'string' && $value.trim() === '' ? NaN : Number($value)) ? Number($value) : $value)";
|
|
46
47
|
//# sourceMappingURL=descriptions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"descriptions.js","sourceRoot":"","sources":["../../../../nodes/Textbee/shared/descriptions.ts"],"names":[],"mappings":";;;AAEa,QAAA,gBAAgB,GAAoB;IAChD,WAAW,EAAE,QAAQ;IACrB,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,iBAAiB;IACvB,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE;IACpC,WAAW,EACV,4HAA4H;IAC7H,KAAK,EAAE;QACN;YACC,WAAW,EAAE,WAAW;YACxB,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,MAAM;YACZ,WAAW,EAAE,kBAAkB;YAC/B,WAAW,EAAE;gBACZ,gBAAgB,EAAE,eAAe;gBACjC,UAAU,EAAE,IAAI;aAChB;SACD;QACD;YACC,WAAW,EAAE,IAAI;YACjB,IAAI,EAAE,IAAI;YACV,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,0BAA0B;YACvC,UAAU,EAAE;gBACX;oBACC,IAAI,EAAE,OAAO;oBACb,UAAU,EAAE;wBACX,KAAK,EAAE,mBAAmB;wBAC1B,YAAY,EAAE,+BAA+B;qBAC7C;iBACD;aACD;SACD;KACD;CACD,CAAC;AAEW,QAAA,qBAAqB,GAAG;IACpC;QACC,IAAI,EAAE,cAAuB;QAC7B,UAAU,EAAE;YACX,QAAQ,EAAE,MAAM;SAChB;KACD;CACD,CAAC"}
|
|
1
|
+
{"version":3,"file":"descriptions.js","sourceRoot":"","sources":["../../../../nodes/Textbee/shared/descriptions.ts"],"names":[],"mappings":";;;AAEa,QAAA,gBAAgB,GAAoB;IAChD,WAAW,EAAE,QAAQ;IACrB,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,iBAAiB;IACvB,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE;IACpC,WAAW,EACV,4HAA4H;IAC7H,KAAK,EAAE;QACN;YACC,WAAW,EAAE,WAAW;YACxB,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,MAAM;YACZ,WAAW,EAAE,kBAAkB;YAC/B,WAAW,EAAE;gBACZ,gBAAgB,EAAE,eAAe;gBACjC,UAAU,EAAE,IAAI;aAChB;SACD;QACD;YACC,WAAW,EAAE,IAAI;YACjB,IAAI,EAAE,IAAI;YACV,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,0BAA0B;YACvC,UAAU,EAAE;gBACX;oBACC,IAAI,EAAE,OAAO;oBACb,UAAU,EAAE;wBACX,KAAK,EAAE,mBAAmB;wBAC1B,YAAY,EAAE,+BAA+B;qBAC7C;iBACD;aACD;SACD;KACD;CACD,CAAC;AAEW,QAAA,qBAAqB,GAAG;IACpC;QACC,IAAI,EAAE,cAAuB;QAC7B,UAAU,EAAE;YACX,QAAQ,EAAE,MAAM;SAChB;KACD;CACD,CAAC;AAQW,QAAA,qBAAqB,GACjC,gMAAgM,CAAC"}
|
|
@@ -1,2 +1,5 @@
|
|
|
1
1
|
export declare function computeSignature(body: Buffer | string, secret: string): string;
|
|
2
2
|
export declare function verifySignature(body: Buffer | string, header: string | undefined, secret: string | undefined): boolean;
|
|
3
|
+
export declare const SIGNATURE_TOLERANCE_SECONDS = 300;
|
|
4
|
+
export declare function verifyTimestampedSignature(body: Buffer | string, header: string | undefined, secret: string | undefined, nowSeconds: number, toleranceSeconds?: number): boolean;
|
|
5
|
+
export declare function generateSigningSecret(): string;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SIGNATURE_TOLERANCE_SECONDS = void 0;
|
|
3
4
|
exports.computeSignature = computeSignature;
|
|
4
5
|
exports.verifySignature = verifySignature;
|
|
6
|
+
exports.verifyTimestampedSignature = verifyTimestampedSignature;
|
|
7
|
+
exports.generateSigningSecret = generateSigningSecret;
|
|
5
8
|
const crypto_1 = require("crypto");
|
|
6
9
|
function computeSignature(body, secret) {
|
|
7
10
|
return (0, crypto_1.createHmac)('sha256', secret).update(body).digest('hex');
|
|
@@ -9,8 +12,42 @@ function computeSignature(body, secret) {
|
|
|
9
12
|
function verifySignature(body, header, secret) {
|
|
10
13
|
if (!secret || !header)
|
|
11
14
|
return false;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
return safeEqualHex(computeSignature(body, secret), header);
|
|
16
|
+
}
|
|
17
|
+
exports.SIGNATURE_TOLERANCE_SECONDS = 300;
|
|
18
|
+
function verifyTimestampedSignature(body, header, secret, nowSeconds, toleranceSeconds = exports.SIGNATURE_TOLERANCE_SECONDS) {
|
|
19
|
+
if (!secret || !header)
|
|
20
|
+
return false;
|
|
21
|
+
let timestamp;
|
|
22
|
+
const signatures = [];
|
|
23
|
+
for (const part of header.split(',')) {
|
|
24
|
+
const index = part.indexOf('=');
|
|
25
|
+
if (index < 0)
|
|
26
|
+
continue;
|
|
27
|
+
const key = part.slice(0, index).trim();
|
|
28
|
+
const value = part.slice(index + 1).trim();
|
|
29
|
+
if (key === 't') {
|
|
30
|
+
if (timestamp !== undefined)
|
|
31
|
+
return false;
|
|
32
|
+
timestamp = value;
|
|
33
|
+
}
|
|
34
|
+
else if (key === 'v1') {
|
|
35
|
+
signatures.push(value);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (!timestamp || !/^\d{1,12}$/.test(timestamp) || signatures.length === 0)
|
|
39
|
+
return false;
|
|
40
|
+
if (Math.abs(nowSeconds - Number(timestamp)) > toleranceSeconds)
|
|
41
|
+
return false;
|
|
42
|
+
const expected = (0, crypto_1.createHmac)('sha256', secret).update(`${timestamp}.`).update(body).digest('hex');
|
|
43
|
+
return signatures.some((signature) => safeEqualHex(expected, signature));
|
|
44
|
+
}
|
|
45
|
+
function safeEqualHex(expected, provided) {
|
|
46
|
+
const a = Buffer.from(expected, 'utf8');
|
|
47
|
+
const b = Buffer.from(provided.trim().toLowerCase(), 'utf8');
|
|
48
|
+
return a.length === b.length && (0, crypto_1.timingSafeEqual)(a, b);
|
|
49
|
+
}
|
|
50
|
+
function generateSigningSecret() {
|
|
51
|
+
return (0, crypto_1.randomBytes)(32).toString('hex');
|
|
15
52
|
}
|
|
16
53
|
//# sourceMappingURL=signature.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signature.js","sourceRoot":"","sources":["../../../../nodes/Textbee/shared/signature.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"signature.js","sourceRoot":"","sources":["../../../../nodes/Textbee/shared/signature.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ export type WebhookSubscription = {
|
|
|
4
4
|
events?: string[];
|
|
5
5
|
isActive?: boolean;
|
|
6
6
|
signingSecret?: string;
|
|
7
|
+
signatureVersion?: number;
|
|
7
8
|
};
|
|
8
9
|
export type DesiredSubscription = {
|
|
9
10
|
deliveryUrl: string;
|
|
@@ -12,4 +13,6 @@ export type DesiredSubscription = {
|
|
|
12
13
|
};
|
|
13
14
|
export type SubscriptionPlan = 'keep' | 'update';
|
|
14
15
|
export declare function planSubscription(existing: WebhookSubscription, desired: DesiredSubscription): SubscriptionPlan;
|
|
16
|
+
export declare function subscriptionName(workflowName: string, deliveryUrl: string): string;
|
|
17
|
+
export declare function resolveSigningSecret(credentialSecret: unknown, storedSecret: unknown): string | undefined;
|
|
15
18
|
export declare function isNotFoundError(error: unknown): boolean;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.planSubscription = planSubscription;
|
|
4
|
+
exports.subscriptionName = subscriptionName;
|
|
5
|
+
exports.resolveSigningSecret = resolveSigningSecret;
|
|
4
6
|
exports.isNotFoundError = isNotFoundError;
|
|
5
7
|
function sameEvents(a, b) {
|
|
6
8
|
return [...a].sort().join(',') === [...b].sort().join(',');
|
|
@@ -13,6 +15,30 @@ function planSubscription(existing, desired) {
|
|
|
13
15
|
existing.signingSecret === desired.signingSecret;
|
|
14
16
|
return matches ? 'keep' : 'update';
|
|
15
17
|
}
|
|
18
|
+
const MAX_NAME_LENGTH = 64;
|
|
19
|
+
function subscriptionName(workflowName, deliveryUrl) {
|
|
20
|
+
const prefix = 'n8n: ';
|
|
21
|
+
let host = '';
|
|
22
|
+
try {
|
|
23
|
+
host = new URL(deliveryUrl).host;
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
}
|
|
27
|
+
if (!host)
|
|
28
|
+
return `${prefix}${workflowName}`.slice(0, MAX_NAME_LENGTH).trimEnd();
|
|
29
|
+
const suffix = ` (${host})`;
|
|
30
|
+
const room = MAX_NAME_LENGTH - prefix.length - suffix.length;
|
|
31
|
+
if (room < 1)
|
|
32
|
+
return `${prefix}${workflowName}${suffix}`.slice(0, MAX_NAME_LENGTH);
|
|
33
|
+
return `${prefix}${workflowName.slice(0, room).trimEnd()}${suffix}`;
|
|
34
|
+
}
|
|
35
|
+
function resolveSigningSecret(credentialSecret, storedSecret) {
|
|
36
|
+
if (typeof credentialSecret === 'string' && credentialSecret !== '')
|
|
37
|
+
return credentialSecret;
|
|
38
|
+
if (typeof storedSecret === 'string' && storedSecret !== '')
|
|
39
|
+
return storedSecret;
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
16
42
|
function isNotFoundError(error) {
|
|
17
43
|
var _a, _b, _c, _d;
|
|
18
44
|
if (typeof error !== 'object' || error === null)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subscription.js","sourceRoot":"","sources":["../../../../nodes/Textbee/shared/subscription.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"subscription.js","sourceRoot":"","sources":["../../../../nodes/Textbee/shared/subscription.ts"],"names":[],"mappings":";;AA2BA,4CAWC;AASD,4CAcC;AAMD,oDAOC;AAGD,0CAgBC;AA3ED,SAAS,UAAU,CAAC,CAAW,EAAE,CAAW;IAC3C,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC5D,CAAC;AAOD,SAAgB,gBAAgB,CAC/B,QAA6B,EAC7B,OAA4B;;IAE5B,MAAM,OAAO,GACZ,QAAQ,CAAC,QAAQ,KAAK,IAAI;QAC1B,QAAQ,CAAC,WAAW,KAAK,OAAO,CAAC,WAAW;QAC5C,UAAU,CAAC,MAAA,QAAQ,CAAC,MAAM,mCAAI,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC;QACjD,QAAQ,CAAC,aAAa,KAAK,OAAO,CAAC,aAAa,CAAC;IAElD,OAAO,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;AACpC,CAAC;AAGD,MAAM,eAAe,GAAG,EAAE,CAAC;AAM3B,SAAgB,gBAAgB,CAAC,YAAoB,EAAE,WAAmB;IACzE,MAAM,MAAM,GAAG,OAAO,CAAC;IACvB,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,CAAC;QACJ,IAAI,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;IAET,CAAC;IACD,IAAI,CAAC,IAAI;QAAE,OAAO,GAAG,MAAM,GAAG,YAAY,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,OAAO,EAAE,CAAC;IAEjF,MAAM,MAAM,GAAG,KAAK,IAAI,GAAG,CAAC;IAC5B,MAAM,IAAI,GAAG,eAAe,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7D,IAAI,IAAI,GAAG,CAAC;QAAE,OAAO,GAAG,MAAM,GAAG,YAAY,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC;IACnF,OAAO,GAAG,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,OAAO,EAAE,GAAG,MAAM,EAAE,CAAC;AACrE,CAAC;AAMD,SAAgB,oBAAoB,CACnC,gBAAyB,EACzB,YAAqB;IAErB,IAAI,OAAO,gBAAgB,KAAK,QAAQ,IAAI,gBAAgB,KAAK,EAAE;QAAE,OAAO,gBAAgB,CAAC;IAC7F,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,KAAK,EAAE;QAAE,OAAO,YAAY,CAAC;IACjF,OAAO,SAAS,CAAC;AAClB,CAAC;AAGD,SAAgB,eAAe,CAAC,KAAc;;IAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,CAAC,GAAG,KAKT,CAAC;IACF,MAAM,KAAK,GAAG;QACb,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,UAAU;QACZ,MAAA,CAAC,CAAC,QAAQ,0CAAE,MAAM;QAClB,MAAA,MAAA,CAAC,CAAC,KAAK,0CAAE,QAAQ,0CAAE,MAAM;QACzB,MAAA,CAAC,CAAC,KAAK,0CAAE,MAAM;KACf,CAAC;IACF,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -40,12 +40,20 @@ function webhookPath(webhookId) {
|
|
|
40
40
|
}
|
|
41
41
|
return `/webhooks/${webhookId}`;
|
|
42
42
|
}
|
|
43
|
-
async function desiredSubscription() {
|
|
43
|
+
async function desiredSubscription(generate) {
|
|
44
44
|
var _a;
|
|
45
45
|
const credentials = await this.getCredentials('textbeeApi');
|
|
46
|
-
const
|
|
47
|
-
if (
|
|
48
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `
|
|
46
|
+
const sharedSecret = String((_a = credentials.webhookSigningSecret) !== null && _a !== void 0 ? _a : '');
|
|
47
|
+
if (sharedSecret !== '' && sharedSecret.length < MIN_SECRET_LENGTH) {
|
|
48
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The Webhook Signing Secret on the textbee API credential must be at least ${MIN_SECRET_LENGTH} characters. Leave it empty to let the trigger create one.`);
|
|
49
|
+
}
|
|
50
|
+
const webhookData = this.getWorkflowStaticData('node');
|
|
51
|
+
let signingSecret = (0, subscription_1.resolveSigningSecret)(sharedSecret, webhookData.signingSecret);
|
|
52
|
+
if (!signingSecret) {
|
|
53
|
+
if (!generate)
|
|
54
|
+
return undefined;
|
|
55
|
+
signingSecret = (0, signature_1.generateSigningSecret)();
|
|
56
|
+
webhookData.signingSecret = signingSecret;
|
|
49
57
|
}
|
|
50
58
|
return {
|
|
51
59
|
deliveryUrl: this.getNodeWebhookUrl('default'),
|
|
@@ -53,19 +61,27 @@ async function desiredSubscription() {
|
|
|
53
61
|
signingSecret,
|
|
54
62
|
};
|
|
55
63
|
}
|
|
56
|
-
function
|
|
64
|
+
function storeSignatureVersion(webhookData, subscription) {
|
|
65
|
+
var _a;
|
|
66
|
+
if (Number((_a = subscription === null || subscription === void 0 ? void 0 : subscription.signatureVersion) !== null && _a !== void 0 ? _a : 0) >= 2)
|
|
67
|
+
webhookData.signatureVersion = 2;
|
|
68
|
+
else
|
|
69
|
+
delete webhookData.signatureVersion;
|
|
70
|
+
}
|
|
71
|
+
function nameFor(desired) {
|
|
57
72
|
var _a;
|
|
58
|
-
return
|
|
73
|
+
return (0, subscription_1.subscriptionName)((_a = this.getWorkflow().name) !== null && _a !== void 0 ? _a : 'workflow', desired.deliveryUrl);
|
|
59
74
|
}
|
|
60
75
|
async function updateSubscription(webhookId, desired) {
|
|
61
76
|
try {
|
|
62
|
-
await transport_1.textbeeApiRequest.call(this, 'PATCH', webhookPath.call(this, webhookId), {
|
|
63
|
-
name:
|
|
77
|
+
const response = (await transport_1.textbeeApiRequest.call(this, 'PATCH', webhookPath.call(this, webhookId), {
|
|
78
|
+
name: nameFor.call(this, desired),
|
|
64
79
|
deliveryUrl: desired.deliveryUrl,
|
|
65
80
|
events: desired.events,
|
|
66
81
|
signingSecret: desired.signingSecret,
|
|
67
82
|
isActive: true,
|
|
68
|
-
});
|
|
83
|
+
}));
|
|
84
|
+
storeSignatureVersion(this.getWorkflowStaticData('node'), response === null || response === void 0 ? void 0 : response.data);
|
|
69
85
|
return true;
|
|
70
86
|
}
|
|
71
87
|
catch (error) {
|
|
@@ -114,7 +130,7 @@ class TextbeeTrigger {
|
|
|
114
130
|
description: 'The textbee events that start this workflow',
|
|
115
131
|
},
|
|
116
132
|
{
|
|
117
|
-
displayName: '
|
|
133
|
+
displayName: 'Publishing this workflow creates the webhook in textbee for you. You do not need to add a webhook in the textbee dashboard. textbee only delivers to public URLs, so a localhost n8n needs a tunnel. For Message Received, turn on Receive SMS in the textbee Android app. If events stop arriving, publish the workflow again.',
|
|
118
134
|
name: 'triggerNotice',
|
|
119
135
|
type: 'notice',
|
|
120
136
|
default: '',
|
|
@@ -141,13 +157,14 @@ class TextbeeTrigger {
|
|
|
141
157
|
delete webhookData.webhookId;
|
|
142
158
|
return false;
|
|
143
159
|
}
|
|
144
|
-
|
|
145
|
-
|
|
160
|
+
storeSignatureVersion(webhookData, subscription);
|
|
161
|
+
const desired = await desiredSubscription.call(this, false);
|
|
162
|
+
return desired !== undefined && (0, subscription_1.planSubscription)(subscription, desired) === 'keep';
|
|
146
163
|
},
|
|
147
164
|
async create() {
|
|
148
165
|
var _a;
|
|
149
166
|
const webhookData = this.getWorkflowStaticData('node');
|
|
150
|
-
const desired = await desiredSubscription.call(this);
|
|
167
|
+
const desired = (await desiredSubscription.call(this, true));
|
|
151
168
|
const storedId = webhookData.webhookId;
|
|
152
169
|
if (storedId && (await updateSubscription.call(this, storedId, desired))) {
|
|
153
170
|
return true;
|
|
@@ -160,12 +177,13 @@ class TextbeeTrigger {
|
|
|
160
177
|
return true;
|
|
161
178
|
}
|
|
162
179
|
const response = (await transport_1.textbeeApiRequest.call(this, 'POST', '/webhooks', {
|
|
163
|
-
name:
|
|
180
|
+
name: nameFor.call(this, desired),
|
|
164
181
|
deliveryUrl: desired.deliveryUrl,
|
|
165
182
|
signingSecret: desired.signingSecret,
|
|
166
183
|
events: desired.events,
|
|
167
184
|
}));
|
|
168
185
|
webhookData.webhookId = response.data._id;
|
|
186
|
+
storeSignatureVersion(webhookData, response.data);
|
|
169
187
|
return true;
|
|
170
188
|
},
|
|
171
189
|
async delete() {
|
|
@@ -181,26 +199,35 @@ class TextbeeTrigger {
|
|
|
181
199
|
throw (0, transport_1.toNodeApiError)(this.getNode(), error);
|
|
182
200
|
}
|
|
183
201
|
delete webhookData.webhookId;
|
|
202
|
+
delete webhookData.signingSecret;
|
|
203
|
+
delete webhookData.signatureVersion;
|
|
184
204
|
return true;
|
|
185
205
|
},
|
|
186
206
|
},
|
|
187
207
|
};
|
|
188
208
|
}
|
|
189
209
|
async webhook() {
|
|
210
|
+
var _a;
|
|
190
211
|
const credentials = await this.getCredentials('textbeeApi');
|
|
191
|
-
const
|
|
212
|
+
const webhookData = this.getWorkflowStaticData('node');
|
|
213
|
+
const signingSecret = (0, subscription_1.resolveSigningSecret)(credentials.webhookSigningSecret, webhookData.signingSecret);
|
|
192
214
|
const headerData = this.getHeaderData();
|
|
193
|
-
const
|
|
215
|
+
const legacyHeader = headerData['x-signature'];
|
|
216
|
+
const timestampedHeader = headerData['x-textbee-signature'];
|
|
194
217
|
const rawBody = this.getRequestObject().rawBody;
|
|
195
218
|
const bodyBuffer = Buffer.isBuffer(rawBody)
|
|
196
219
|
? rawBody
|
|
197
220
|
: Buffer.from(typeof rawBody === 'string' ? rawBody : JSON.stringify(this.getBodyData()));
|
|
198
|
-
|
|
221
|
+
const requireTimestamped = Number((_a = webhookData.signatureVersion) !== null && _a !== void 0 ? _a : 0) >= 2;
|
|
222
|
+
const valid = requireTimestamped || timestampedHeader !== undefined
|
|
223
|
+
? (0, signature_1.verifyTimestampedSignature)(bodyBuffer, timestampedHeader, signingSecret, Math.floor(Date.now() / 1000))
|
|
224
|
+
: (0, signature_1.verifySignature)(bodyBuffer, legacyHeader, signingSecret);
|
|
225
|
+
if (!valid) {
|
|
199
226
|
this.getResponseObject().status(401).json({ error: 'Invalid signature' });
|
|
200
227
|
return { noWebhookResponse: true };
|
|
201
228
|
}
|
|
202
229
|
const bodyData = this.getBodyData();
|
|
203
|
-
const ownId =
|
|
230
|
+
const ownId = webhookData.webhookId;
|
|
204
231
|
const deliveredFor = bodyData.webhookSubscriptionId;
|
|
205
232
|
if (ownId && deliveredFor && String(deliveredFor) !== String(ownId)) {
|
|
206
233
|
this.getResponseObject().status(401).json({ error: 'Unknown subscription' });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextbeeTrigger.node.js","sourceRoot":"","sources":["../../../nodes/TextbeeTrigger/TextbeeTrigger.node.ts"],"names":[],"mappings":";;;AAAA,+CASsB;AAEtB,
|
|
1
|
+
{"version":3,"file":"TextbeeTrigger.node.js","sourceRoot":"","sources":["../../../nodes/TextbeeTrigger/TextbeeTrigger.node.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED