@ixiam/n8n-nodes-civicrm 3.2.0 → 3.2.2
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.
|
@@ -116,7 +116,6 @@ async function civicrmApiRequest(method, path, body, runtimeBearerToken) {
|
|
|
116
116
|
useJwt = true;
|
|
117
117
|
}
|
|
118
118
|
else {
|
|
119
|
-
console.warn('[CiviCRM] JWT generation returned no token, falling back to API key');
|
|
120
119
|
this.addExecutionHints({
|
|
121
120
|
message: 'JWT authentication could not be obtained (no token returned by CiviCRM). Falling back to API Key authentication.',
|
|
122
121
|
type: 'warning',
|
|
@@ -126,7 +125,6 @@ async function civicrmApiRequest(method, path, body, runtimeBearerToken) {
|
|
|
126
125
|
}
|
|
127
126
|
catch (error) {
|
|
128
127
|
const errorMsg = getHttpErrorDetails(error);
|
|
129
|
-
console.warn(`[CiviCRM] JWT generation failed: ${errorMsg}. Falling back to API key.`);
|
|
130
128
|
this.addExecutionHints({
|
|
131
129
|
message: `JWT authentication failed (${errorMsg}). Falling back to API Key authentication.`,
|
|
132
130
|
type: 'warning',
|
|
@@ -154,7 +152,6 @@ async function civicrmApiRequest(method, path, body, runtimeBearerToken) {
|
|
|
154
152
|
return response;
|
|
155
153
|
}
|
|
156
154
|
else {
|
|
157
|
-
console.warn('[CiviCRM] JWT returned empty response. Retrying with API key (JWT may have limited permissions).');
|
|
158
155
|
this.addExecutionHints({
|
|
159
156
|
message: 'The JWT-authenticated request returned no data (JWT may have limited permissions). Retrying with API Key authentication.',
|
|
160
157
|
type: 'warning',
|
|
@@ -165,7 +162,6 @@ async function civicrmApiRequest(method, path, body, runtimeBearerToken) {
|
|
|
165
162
|
}
|
|
166
163
|
catch (error) {
|
|
167
164
|
const errorMsg = getHttpErrorDetails(error);
|
|
168
|
-
console.warn('[CiviCRM] JWT request failed. Retrying with API key.');
|
|
169
165
|
this.addExecutionHints({
|
|
170
166
|
message: `The JWT-authenticated request failed (${errorMsg}). Retrying with API Key authentication.`,
|
|
171
167
|
type: 'warning',
|
|
@@ -186,11 +182,7 @@ async function civicrmApiRequest(method, path, body, runtimeBearerToken) {
|
|
|
186
182
|
json: true,
|
|
187
183
|
};
|
|
188
184
|
try {
|
|
189
|
-
|
|
190
|
-
if (useJwt && jwtToken) {
|
|
191
|
-
console.log('[CiviCRM] API key request successful (JWT was insufficient, using API key as fallback)');
|
|
192
|
-
}
|
|
193
|
-
return response;
|
|
185
|
+
return await this.helpers.httpRequest.call(this, apiKeyOptions);
|
|
194
186
|
}
|
|
195
187
|
catch (error) {
|
|
196
188
|
throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
|
|
@@ -8,28 +8,6 @@ const contactIdCache = {}; // Cache resolved contact IDs
|
|
|
8
8
|
function isJwtAuthEnabled(credentials) {
|
|
9
9
|
return (credentials === null || credentials === void 0 ? void 0 : credentials.enableJwtAuth) === true;
|
|
10
10
|
}
|
|
11
|
-
/**
|
|
12
|
-
* Extracts a readable message from an HTTP error, including the response body
|
|
13
|
-
* (e.g. CiviCRM's "Login not permitted. Must satisfy guard (perm, site_key)."),
|
|
14
|
-
* which the bare `error.message` (e.g. "Request failed with status code 401")
|
|
15
|
-
* does not include.
|
|
16
|
-
*/
|
|
17
|
-
function getErrorDetails(error) {
|
|
18
|
-
var _a, _b, _c;
|
|
19
|
-
const errorObj = error;
|
|
20
|
-
const status = (_a = errorObj === null || errorObj === void 0 ? void 0 : errorObj.response) === null || _a === void 0 ? void 0 : _a.status;
|
|
21
|
-
const data = (_b = errorObj === null || errorObj === void 0 ? void 0 : errorObj.response) === null || _b === void 0 ? void 0 : _b.data;
|
|
22
|
-
const message = (_c = errorObj === null || errorObj === void 0 ? void 0 : errorObj.message) !== null && _c !== void 0 ? _c : String(error);
|
|
23
|
-
const body = typeof data === 'string' && data.trim()
|
|
24
|
-
? data
|
|
25
|
-
: data && typeof data === 'object'
|
|
26
|
-
? JSON.stringify(data)
|
|
27
|
-
: undefined;
|
|
28
|
-
if (body) {
|
|
29
|
-
return status ? `${message} | HTTP ${status} body: ${body}` : `${message} | body: ${body}`;
|
|
30
|
-
}
|
|
31
|
-
return status ? `${message} | HTTP ${status}` : message;
|
|
32
|
-
}
|
|
33
11
|
/**
|
|
34
12
|
* Resolve the current authenticated user's contact ID from Contact/get.
|
|
35
13
|
* Finds the contact that owns the given api_key.
|
|
@@ -60,16 +38,13 @@ async function resolveContactId(context, baseUrl, apiToken) {
|
|
|
60
38
|
});
|
|
61
39
|
const contacts = (response === null || response === void 0 ? void 0 : response.values) || [];
|
|
62
40
|
if (contacts.length === 0) {
|
|
63
|
-
console.warn('[CiviCRM] Contact/get found no contact with this api_key - JWT auto-resolve will be skipped');
|
|
64
41
|
return undefined;
|
|
65
42
|
}
|
|
66
43
|
const contactId = contacts[0].id;
|
|
67
44
|
contactIdCache[cacheKey] = contactId;
|
|
68
45
|
return contactId;
|
|
69
46
|
}
|
|
70
|
-
catch
|
|
71
|
-
const errorMsg = getErrorDetails(error);
|
|
72
|
-
console.warn(`[CiviCRM] Failed to auto-resolve contact ID: ${errorMsg}. Will attempt API key fallback.`);
|
|
47
|
+
catch {
|
|
73
48
|
return undefined;
|
|
74
49
|
}
|
|
75
50
|
}
|
|
@@ -116,26 +91,15 @@ async function getServerIssuedJwt(context, baseUrl, apiToken, contactId = 0, ttl
|
|
|
116
91
|
});
|
|
117
92
|
const cred = ((_b = (_a = response === null || response === void 0 ? void 0 : response.values) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.cred) || '';
|
|
118
93
|
if (!cred.startsWith('Bearer ')) {
|
|
119
|
-
console.warn('[CiviCRM] Invalid JWT response: missing Bearer token');
|
|
120
94
|
return undefined;
|
|
121
95
|
}
|
|
122
96
|
const token = cred.substring(7); // Remove "Bearer " prefix
|
|
123
97
|
serverIssuedCache[cacheKey] = { token, expiresAt: now + ttl * 1000 };
|
|
124
98
|
return token;
|
|
125
99
|
}
|
|
126
|
-
catch
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
errorMsg.includes('403') ||
|
|
130
|
-
errorMsg.includes('Permission denied') ||
|
|
131
|
-
errorMsg.includes('Login not permitted') ||
|
|
132
|
-
errorMsg.includes('Must satisfy guard');
|
|
133
|
-
if (isPermissionDenied) {
|
|
134
|
-
// User lacks permissions for JWT. Fall back to API key auth.
|
|
135
|
-
console.warn(`[CiviCRM JWT] User lacks permissions for AuthxCredential/create (${errorMsg}). Will use API key authentication instead.`);
|
|
136
|
-
return undefined;
|
|
137
|
-
}
|
|
138
|
-
console.warn(`[CiviCRM JWT] Failed to obtain JWT: ${errorMsg}. Falling back to API key.`);
|
|
100
|
+
catch {
|
|
101
|
+
// Any failure here (permission denied, network error, malformed response) falls
|
|
102
|
+
// back to API key auth in the caller -- see GenericFunctions.civicrmApiRequest.
|
|
139
103
|
return undefined;
|
|
140
104
|
}
|
|
141
105
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ixiam/n8n-nodes-civicrm",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.2",
|
|
4
4
|
"description": "Full-featured CiviCRM API v4 integration for n8n",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -52,7 +52,6 @@
|
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@n8n/node-cli": "^0.23.1",
|
|
54
54
|
"@types/jest": "^30.0.0",
|
|
55
|
-
"@types/jsonwebtoken": "^9.0.10",
|
|
56
55
|
"@types/node": "^20.11.30",
|
|
57
56
|
"eslint": "9.32.0",
|
|
58
57
|
"jest": "^30.5.1",
|
|
@@ -61,9 +60,7 @@
|
|
|
61
60
|
"ts-jest": "^29.4.12",
|
|
62
61
|
"typescript": "5.9.2"
|
|
63
62
|
},
|
|
64
|
-
"dependencies": {
|
|
65
|
-
"jsonwebtoken": "^9.0.3"
|
|
66
|
-
},
|
|
63
|
+
"dependencies": {},
|
|
67
64
|
"peerDependencies": {
|
|
68
65
|
"n8n-workflow": "*"
|
|
69
66
|
},
|