n8n-nodes-deep-ocr 1.3.2 โ†’ 1.4.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.
package/README.md CHANGED
@@ -61,6 +61,48 @@ npm install n8n-nodes-deep-ocr
61
61
  | `handwriting` | Full transcription with unclear-word markers, confidence rating, language |
62
62
  | `generic` | Flexible extraction for any document โ€” adapts structure to the content |
63
63
 
64
+ ## ๐Ÿ“ค Output Examples
65
+
66
+ ### Invoice
67
+ ```json
68
+ {
69
+ "vendor": { "name": "ACME GmbH", "address": "Musterstr. 1, 10115 Berlin", "vat_id": "DE123456789" },
70
+ "invoice_number": "RE-2024-00842",
71
+ "invoice_date": "2024-03-15",
72
+ "due_date": "2024-04-14",
73
+ "line_items": [
74
+ { "description": "Consulting Services", "quantity": 8, "unit_price": 150.00, "total": 1200.00 }
75
+ ],
76
+ "subtotal": 1200.00,
77
+ "tax_rate": 19,
78
+ "tax_amount": 228.00,
79
+ "total": 1428.00,
80
+ "iban": "DE89 3704 0044 0532 0130 00",
81
+ "filename": "invoice.pdf",
82
+ "document_type": "invoice",
83
+ "metadata": { "pages": 1 }
84
+ }
85
+ ```
86
+
87
+ ### Receipt
88
+ ```json
89
+ {
90
+ "merchant": { "name": "REWE City", "address": "Friedrichstr. 12, 10117 Berlin" },
91
+ "date": "2024-03-22",
92
+ "items": [
93
+ { "description": "Bioland ร„pfel 1kg", "quantity": 1, "price": 2.49 },
94
+ { "description": "Mineralwasser 6x1.5L", "quantity": 1, "price": 3.99 }
95
+ ],
96
+ "subtotal": 6.48,
97
+ "tax_breakdown": [{ "rate": 7, "amount": 0.42 }],
98
+ "total": 6.90,
99
+ "payment_method": "EC-Karte",
100
+ "filename": "receipt.jpg",
101
+ "document_type": "receipt",
102
+ "metadata": { "pages": 1 }
103
+ }
104
+ ```
105
+
64
106
  ## ๐Ÿ“‹ Example Workflow
65
107
 
66
108
  ```json
@@ -94,6 +136,30 @@ npm install n8n-nodes-deep-ocr
94
136
  | JPG/JPEG | image/jpeg | 10MB |
95
137
  | WebP | image/webp | 10MB |
96
138
 
139
+ ## ๐Ÿ”ง Troubleshooting
140
+
141
+ ### "Unsupported file type" error
142
+ The node only accepts PDF, PNG, JPG, JPEG, and WebP files. Make sure the upstream node sets the correct MIME type. If you're using **HTTP Request** to download a file, check that the response has a proper `Content-Type` header.
143
+
144
+ ### "File size exceeds maximum allowed size"
145
+ The Deep-OCR API accepts files up to **10MB**. For larger PDFs, consider compressing them first or splitting them into individual pages.
146
+
147
+ ### "Connection tested successfully" but processing fails
148
+ Your API key is valid, but the key may not have enough quota remaining. Check your usage in the [Deep-OCR Dashboard](https://deep-ocr.com).
149
+
150
+ ### Node not appearing in n8n's node picker
151
+ In n8n 2.x, unverified community nodes are hidden from the picker search. Install the node via **Settings โ†’ Community Nodes**, then add it to your workflow by importing the following JSON snippet:
152
+
153
+ ```json
154
+ {
155
+ "type": "n8n-nodes-deep-ocr.deepOcr",
156
+ "parameters": { "binaryPropertyName": "data", "documentType": "invoice" }
157
+ }
158
+ ```
159
+
160
+ ### Binary property not found
161
+ The **Binary Property** field must match the property name set by the previous node. The default is `data` (used by Read Binary File, HTTP Request, etc.). Check the output of the previous node to confirm the property name.
162
+
97
163
  ## ๐Ÿ› ๏ธ Development
98
164
 
99
165
  ### Prerequisites
@@ -1 +1 @@
1
- {"version":3,"file":"DeepOcr.node.d.ts","sourceRoot":"","sources":["../../../src/nodes/DeepOcr/DeepOcr.node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,SAAS,EACT,oBAAoB,EAGrB,MAAM,cAAc,CAAC;AAoCtB;;;;;GAKG;AACH,qBAAa,OAAQ,YAAW,SAAS;IACvC,WAAW,EAAE,oBAAoB,CA8F/B;IAEI,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;CAiHxE"}
1
+ {"version":3,"file":"DeepOcr.node.d.ts","sourceRoot":"","sources":["../../../src/nodes/DeepOcr/DeepOcr.node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,SAAS,EACT,oBAAoB,EAGrB,MAAM,cAAc,CAAC;AA0CtB;;;;;GAKG;AACH,qBAAa,OAAQ,YAAW,SAAS;IACvC,WAAW,EAAE,oBAAoB,CA+F/B;IAEI,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;CA4GxE"}
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DeepOcr = void 0;
4
4
  const n8n_workflow_1 = require("n8n-workflow");
5
5
  const errors_1 = require("../../utils/errors");
6
+ /** Deep-OCR API endpoint */
7
+ const API_ENDPOINT = 'https://api.deep-ocr.com/v1/ocr';
6
8
  const ALLOWED_DOCUMENT_TYPES = [
7
9
  'auto',
8
10
  'bank_statement',
@@ -51,6 +53,7 @@ class DeepOcr {
51
53
  default: 'data',
52
54
  required: true,
53
55
  description: 'Name of the binary property containing the document to process',
56
+ placeholder: "e.g. 'data', 'file', 'document'",
54
57
  },
55
58
  {
56
59
  displayName: 'Document Type',
@@ -131,13 +134,19 @@ class DeepOcr {
131
134
  }
132
135
  // Get binary data
133
136
  const binaryData = this.helpers.assertBinaryData(itemIndex, binaryPropertyName);
134
- // Validate MIME type โ€” reject undefined/empty to prevent silent bypass
137
+ // Validate MIME type โ€” case-insensitive; reject undefined/empty to prevent silent bypass
135
138
  if (!(0, errors_1.isValidMimeType)(binaryData.mimeType)) {
136
139
  throw (0, errors_1.createFileTypeError)(this.getNode(), binaryData.mimeType ?? 'unknown', itemIndex);
137
140
  }
138
- // Early size check from metadata before loading the full buffer into memory (DoS prevention)
139
- const metaSize = parseInt(binaryData.fileSize ?? '0', 10);
140
- if (metaSize > 0 && !(0, errors_1.isValidFileSize)(metaSize)) {
141
+ // Early size check from metadata before loading the full buffer into memory (DoS prevention).
142
+ // Only accepts strict digit strings โ€” parseInt would partially parse "123abc" โ†’ 123 or "1e9" โ†’ 1,
143
+ // which could let oversized files bypass this guard. Non-matching values fall through to the
144
+ // authoritative buffer-length check below.
145
+ const rawFileSize = binaryData.fileSize;
146
+ const metaSize = typeof rawFileSize === 'string' && /^[0-9]+$/.test(rawFileSize)
147
+ ? Number(rawFileSize)
148
+ : 0;
149
+ if (metaSize > 0 && Number.isFinite(metaSize) && !(0, errors_1.isValidFileSize)(metaSize)) {
141
150
  throw (0, errors_1.createFileSizeError)(this.getNode(), metaSize, itemIndex);
142
151
  }
143
152
  // Load buffer
@@ -146,21 +155,18 @@ class DeepOcr {
146
155
  if (!(0, errors_1.isValidFileSize)(buffer.length)) {
147
156
  throw (0, errors_1.createFileSizeError)(this.getNode(), buffer.length, itemIndex);
148
157
  }
149
- // Sanitize filename to prevent path traversal sequences in multipart headers
150
- const rawFilename = binaryData.fileName ?? 'document';
151
- const safeFilename = rawFilename
152
- .replace(/\.\./g, '')
153
- .replace(/[/\\]/g, '_')
154
- .replace(/[<>:"|?*\x00-\x1f]/g, '')
155
- .substring(0, 255) || 'document';
158
+ // Sanitize filename to prevent path traversal and homograph attacks in multipart headers
159
+ const safeFilename = (0, errors_1.sanitizeFilename)(binaryData.fileName ?? 'document');
156
160
  // Make API request โ€” document_type as query param, file as multipart.
157
161
  // When documentType is 'auto', omit the parameter entirely so the API
158
162
  // classifies the document automatically.
159
163
  const form = new FormData();
160
164
  form.append('file', new Blob([buffer], { type: binaryData.mimeType }), safeFilename);
165
+ // n8n's httpRequestWithAuthentication accepts FormData at runtime even though
166
+ // the TypeScript type expects IDataObject โ€” the double-cast is intentional.
161
167
  const rawResponse = await this.helpers.httpRequestWithAuthentication.call(this, 'deepOcrApi', {
162
168
  method: 'POST',
163
- url: 'https://api.deep-ocr.com/v1/ocr',
169
+ url: API_ENDPOINT,
164
170
  qs: documentType !== 'auto' ? { document_type: documentType } : {},
165
171
  body: form,
166
172
  });
@@ -184,10 +190,8 @@ class DeepOcr {
184
190
  catch (error) {
185
191
  if (this.continueOnFail()) {
186
192
  const raw = error instanceof Error ? error.message : 'Unknown error occurred';
187
- // Truncate to prevent verbose API errors from leaking document content into workflow logs
188
- const errorMessage = raw.length > 200 ? raw.substring(0, 200) + 'โ€ฆ' : raw;
189
193
  returnData.push({
190
- json: { error: errorMessage },
194
+ json: { error: (0, errors_1.truncateErrorMessage)(raw) },
191
195
  pairedItem: { item: itemIndex },
192
196
  });
193
197
  continue;
@@ -195,13 +199,7 @@ class DeepOcr {
195
199
  if (error instanceof n8n_workflow_1.NodeApiError || error instanceof n8n_workflow_1.NodeOperationError) {
196
200
  throw error;
197
201
  }
198
- const errorObject = {
199
- message: error instanceof Error ? error.message : 'Unknown error',
200
- };
201
- throw new n8n_workflow_1.NodeApiError(this.getNode(), errorObject, {
202
- message: 'Failed to process document with Deep-OCR API',
203
- itemIndex,
204
- });
202
+ throw (0, errors_1.wrapUnknownError)(this.getNode(), error, itemIndex);
205
203
  }
206
204
  }
207
205
  return [returnData];
@@ -1 +1 @@
1
- {"version":3,"file":"DeepOcr.node.js","sourceRoot":"","sources":["../../../src/nodes/DeepOcr/DeepOcr.node.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DeepOcr.node.js","sourceRoot":"","sources":["../../../src/nodes/DeepOcr/DeepOcr.node.ts"],"names":[],"mappings":"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"}
@@ -1,22 +1,15 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
2
- <defs>
3
- <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
4
- <stop offset="0%" style="stop-color:#4A90D9;stop-opacity:1" />
5
- <stop offset="100%" style="stop-color:#2E5C8A;stop-opacity:1" />
6
- </linearGradient>
7
- </defs>
8
- <!-- Document background -->
9
- <rect x="8" y="4" width="40" height="52" rx="3" ry="3" fill="#ffffff" stroke="#2E5C8A" stroke-width="2"/>
10
- <!-- Document fold -->
11
- <polygon points="38,4 48,14 38,14" fill="#E8F0F8" stroke="#2E5C8A" stroke-width="1"/>
12
- <!-- Text lines -->
13
- <rect x="14" y="20" width="28" height="3" fill="#4A90D9" rx="1"/>
14
- <rect x="14" y="27" width="24" height="3" fill="#4A90D9" rx="1"/>
15
- <rect x="14" y="34" width="26" height="3" fill="#4A90D9" rx="1"/>
16
- <rect x="14" y="41" width="20" height="3" fill="#4A90D9" rx="1"/>
17
- <!-- OCR scanning effect -->
18
- <rect x="12" y="18" width="32" height="28" fill="none" stroke="url(#grad1)" stroke-width="2" stroke-dasharray="4,2" rx="2"/>
19
- <!-- AI/Deep learning symbol -->
20
- <circle cx="50" cy="46" r="12" fill="url(#grad1)"/>
21
- <text x="50" y="51" font-family="Arial, sans-serif" font-size="12" font-weight="bold" fill="white" text-anchor="middle">AI</text>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="none">
2
+ <rect width="32" height="32" rx="8" fill="#1A1A1A"/>
3
+ <!-- Document outline -->
4
+ <rect x="8" y="6" width="14" height="18" rx="2" stroke="#B9FF00" stroke-width="1.5" fill="none"/>
5
+ <!-- Folded corner -->
6
+ <path d="M18 6 L22 10" stroke="#B9FF00" stroke-width="1.5" stroke-linecap="round"/>
7
+ <path d="M18 6 L18 10 L22 10" stroke="#B9FF00" stroke-width="1.5" fill="none" stroke-linejoin="round"/>
8
+ <!-- Scan lines -->
9
+ <line x1="11" y1="13" x2="19" y2="13" stroke="#B9FF00" stroke-width="1.5" stroke-linecap="round"/>
10
+ <line x1="11" y1="16" x2="19" y2="16" stroke="#B9FF00" stroke-width="1.5" stroke-linecap="round"/>
11
+ <line x1="11" y1="19" x2="16" y2="19" stroke="#B9FF00" stroke-width="1.5" stroke-linecap="round"/>
12
+ <!-- Scan line indicator -->
13
+ <line x1="24" y1="12" x2="24" y2="22" stroke="#B9FF00" stroke-width="1.5" stroke-linecap="round" opacity="0.6"/>
14
+ <line x1="22" y1="17" x2="26" y2="17" stroke="#B9FF00" stroke-width="2" stroke-linecap="round"/>
22
15
  </svg>
@@ -1,19 +1,13 @@
1
1
  import { NodeApiError, NodeOperationError } from 'n8n-workflow';
2
- import type { INode, JsonObject } from 'n8n-workflow';
3
- /**
4
- * Error codes for Deep-OCR operations
5
- */
6
- export declare enum DeepOcrErrorCode {
7
- INVALID_FILE_TYPE = "INVALID_FILE_TYPE",
8
- FILE_TOO_LARGE = "FILE_TOO_LARGE",
9
- MISSING_BINARY_DATA = "MISSING_BINARY_DATA",
10
- API_ERROR = "API_ERROR",
11
- AUTH_ERROR = "AUTH_ERROR"
12
- }
2
+ import type { INode } from 'n8n-workflow';
13
3
  /**
14
4
  * Maximum file size in bytes (10MB)
15
5
  */
16
6
  export declare const MAX_FILE_SIZE: number;
7
+ /**
8
+ * Maximum safe filename length in characters (enforced on UTF-16 code units, not bytes)
9
+ */
10
+ export declare const MAX_FILENAME_LENGTH = 255;
17
11
  /**
18
12
  * Allowed MIME types for document processing
19
13
  */
@@ -27,15 +21,30 @@ export declare function createFileTypeError(node: INode, mimeType: string, itemI
27
21
  */
28
22
  export declare function createFileSizeError(node: INode, sizeBytes: number, itemIndex?: number): NodeOperationError;
29
23
  /**
30
- * Creates a NodeApiError for API failures
31
- */
32
- export declare function createApiError(node: INode, error: Error | JsonObject, itemIndex?: number): NodeApiError;
33
- /**
34
- * Validates MIME type against allowed types
24
+ * Validates MIME type against allowed types โ€” case-insensitive to handle
25
+ * non-standard capitalisation from HTTP clients (e.g. image/JPEG).
26
+ * Rejects undefined/empty to prevent silent bypass.
35
27
  */
36
28
  export declare function isValidMimeType(mimeType: string | undefined): boolean;
37
29
  /**
38
30
  * Validates file size against maximum limit
39
31
  */
40
32
  export declare function isValidFileSize(sizeBytes: number): boolean;
33
+ /**
34
+ * Sanitizes a filename to prevent path traversal and header injection.
35
+ * Applies NFKD Unicode normalization first to neutralize homograph attacks,
36
+ * then strips traversal sequences, path separators, and control characters.
37
+ * Falls back to 'document' if the result is empty.
38
+ */
39
+ export declare function sanitizeFilename(filename: string): string;
40
+ /**
41
+ * Truncates an error message to prevent verbose API errors from leaking
42
+ * document content into workflow logs.
43
+ */
44
+ export declare function truncateErrorMessage(message: string, maxLength?: number): string;
45
+ /**
46
+ * Wraps an unknown caught value into a NodeApiError for n8n.
47
+ * Used for unexpected errors that are neither NodeApiError nor NodeOperationError.
48
+ */
49
+ export declare function wrapUnknownError(node: INode, error: unknown, itemIndex?: number): NodeApiError;
41
50
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEtD;;GAEG;AACH,oBAAY,gBAAgB;IAC1B,iBAAiB,sBAAsB;IACvC,cAAc,mBAAmB;IACjC,mBAAmB,wBAAwB;IAC3C,SAAS,cAAc;IACvB,UAAU,eAAe;CAC1B;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,QAAmB,CAAC;AAE9C;;GAEG;AACH,eAAO,MAAM,kBAAkB,UAM9B,CAAC;AAEF;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,KAAK,EACX,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB,kBAAkB,CASpB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,KAAK,EACX,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACjB,kBAAkB,CAUpB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,KAAK,EACX,KAAK,EAAE,KAAK,GAAG,UAAU,EACzB,SAAS,CAAC,EAAE,MAAM,GACjB,YAAY,CAKd;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAKrE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE1D"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE1C;;GAEG;AACH,eAAO,MAAM,aAAa,QAAmB,CAAC;AAE9C;;GAEG;AACH,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC;;GAEG;AACH,eAAO,MAAM,kBAAkB,UAM9B,CAAC;AAEF;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,KAAK,EACX,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB,kBAAkB,CASpB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,KAAK,EACX,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACjB,kBAAkB,CAUpB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAKrE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CASzD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,SAAM,GAAG,MAAM,CAK7E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY,CAM9F"}
@@ -1,27 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ALLOWED_MIME_TYPES = exports.MAX_FILE_SIZE = exports.DeepOcrErrorCode = void 0;
3
+ exports.ALLOWED_MIME_TYPES = exports.MAX_FILENAME_LENGTH = exports.MAX_FILE_SIZE = void 0;
4
4
  exports.createFileTypeError = createFileTypeError;
5
5
  exports.createFileSizeError = createFileSizeError;
6
- exports.createApiError = createApiError;
7
6
  exports.isValidMimeType = isValidMimeType;
8
7
  exports.isValidFileSize = isValidFileSize;
8
+ exports.sanitizeFilename = sanitizeFilename;
9
+ exports.truncateErrorMessage = truncateErrorMessage;
10
+ exports.wrapUnknownError = wrapUnknownError;
9
11
  const n8n_workflow_1 = require("n8n-workflow");
10
- /**
11
- * Error codes for Deep-OCR operations
12
- */
13
- var DeepOcrErrorCode;
14
- (function (DeepOcrErrorCode) {
15
- DeepOcrErrorCode["INVALID_FILE_TYPE"] = "INVALID_FILE_TYPE";
16
- DeepOcrErrorCode["FILE_TOO_LARGE"] = "FILE_TOO_LARGE";
17
- DeepOcrErrorCode["MISSING_BINARY_DATA"] = "MISSING_BINARY_DATA";
18
- DeepOcrErrorCode["API_ERROR"] = "API_ERROR";
19
- DeepOcrErrorCode["AUTH_ERROR"] = "AUTH_ERROR";
20
- })(DeepOcrErrorCode || (exports.DeepOcrErrorCode = DeepOcrErrorCode = {}));
21
12
  /**
22
13
  * Maximum file size in bytes (10MB)
23
14
  */
24
15
  exports.MAX_FILE_SIZE = 10 * 1024 * 1024;
16
+ /**
17
+ * Maximum safe filename length in characters (enforced on UTF-16 code units, not bytes)
18
+ */
19
+ exports.MAX_FILENAME_LENGTH = 255;
25
20
  /**
26
21
  * Allowed MIME types for document processing
27
22
  */
@@ -52,22 +47,15 @@ function createFileSizeError(node, sizeBytes, itemIndex) {
52
47
  });
53
48
  }
54
49
  /**
55
- * Creates a NodeApiError for API failures
56
- */
57
- function createApiError(node, error, itemIndex) {
58
- return new n8n_workflow_1.NodeApiError(node, error, {
59
- message: 'Failed to process document with Deep-OCR API',
60
- itemIndex,
61
- });
62
- }
63
- /**
64
- * Validates MIME type against allowed types
50
+ * Validates MIME type against allowed types โ€” case-insensitive to handle
51
+ * non-standard capitalisation from HTTP clients (e.g. image/JPEG).
52
+ * Rejects undefined/empty to prevent silent bypass.
65
53
  */
66
54
  function isValidMimeType(mimeType) {
67
55
  if (mimeType === undefined || mimeType.trim() === '') {
68
- return false; // Reject files with no declared MIME type
56
+ return false;
69
57
  }
70
- return exports.ALLOWED_MIME_TYPES.includes(mimeType);
58
+ return exports.ALLOWED_MIME_TYPES.includes(mimeType.toLowerCase());
71
59
  }
72
60
  /**
73
61
  * Validates file size against maximum limit
@@ -75,4 +63,42 @@ function isValidMimeType(mimeType) {
75
63
  function isValidFileSize(sizeBytes) {
76
64
  return sizeBytes <= exports.MAX_FILE_SIZE;
77
65
  }
66
+ /**
67
+ * Sanitizes a filename to prevent path traversal and header injection.
68
+ * Applies NFKD Unicode normalization first to neutralize homograph attacks,
69
+ * then strips traversal sequences, path separators, and control characters.
70
+ * Falls back to 'document' if the result is empty.
71
+ */
72
+ function sanitizeFilename(filename) {
73
+ return (filename
74
+ .normalize('NFKD')
75
+ .replace(/\.\./g, '')
76
+ .replace(/[/\\]/g, '_')
77
+ .replace(/[<>:"|?*\x00-\x1f]/g, '')
78
+ .substring(0, exports.MAX_FILENAME_LENGTH) || 'document');
79
+ }
80
+ /**
81
+ * Truncates an error message to prevent verbose API errors from leaking
82
+ * document content into workflow logs.
83
+ */
84
+ function truncateErrorMessage(message, maxLength = 200) {
85
+ if (message.length <= maxLength)
86
+ return message;
87
+ if (maxLength <= 0)
88
+ return '';
89
+ if (maxLength === 1)
90
+ return 'โ€ฆ';
91
+ return message.substring(0, maxLength - 1) + 'โ€ฆ';
92
+ }
93
+ /**
94
+ * Wraps an unknown caught value into a NodeApiError for n8n.
95
+ * Used for unexpected errors that are neither NodeApiError nor NodeOperationError.
96
+ */
97
+ function wrapUnknownError(node, error, itemIndex) {
98
+ const message = error instanceof Error ? error.message : 'Unknown error';
99
+ return new n8n_workflow_1.NodeApiError(node, { message }, {
100
+ message: 'Failed to process document with Deep-OCR API',
101
+ itemIndex,
102
+ });
103
+ }
78
104
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":";;;AAiCA,kDAaC;AAKD,kDAcC;AAKD,wCASC;AAKD,0CAKC;AAKD,0CAEC;AAhGD,+CAAgE;AAGhE;;GAEG;AACH,IAAY,gBAMX;AAND,WAAY,gBAAgB;IAC1B,2DAAuC,CAAA;IACvC,qDAAiC,CAAA;IACjC,+DAA2C,CAAA;IAC3C,2CAAuB,CAAA;IACvB,6CAAyB,CAAA;AAC3B,CAAC,EANW,gBAAgB,gCAAhB,gBAAgB,QAM3B;AAED;;GAEG;AACU,QAAA,aAAa,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAE9C;;GAEG;AACU,QAAA,kBAAkB,GAAG;IAChC,iBAAiB;IACjB,WAAW;IACX,YAAY;IACZ,WAAW;IACX,YAAY;CACb,CAAC;AAEF;;GAEG;AACH,SAAgB,mBAAmB,CACjC,IAAW,EACX,QAAgB,EAChB,SAAkB;IAElB,OAAO,IAAI,iCAAkB,CAC3B,IAAI,EACJ,0BAA0B,QAAQ,8CAA8C,EAChF;QACE,SAAS;QACT,WAAW,EAAE,2BAA2B,QAAQ,+CAA+C;KAChG,CACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,mBAAmB,CACjC,IAAW,EACX,SAAiB,EACjB,SAAkB;IAElB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC;IACnD,OAAO,IAAI,iCAAkB,CAC3B,IAAI,EACJ,cAAc,MAAM,0CAA0C,EAC9D;QACE,SAAS;QACT,WAAW,EAAE,wDAAwD;KACtE,CACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc,CAC5B,IAAW,EACX,KAAyB,EACzB,SAAkB;IAElB,OAAO,IAAI,2BAAY,CAAC,IAAI,EAAE,KAAmB,EAAE;QACjD,OAAO,EAAE,8CAA8C;QACvD,SAAS;KACV,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,QAA4B;IAC1D,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrD,OAAO,KAAK,CAAC,CAAC,0CAA0C;IAC1D,CAAC;IACD,OAAO,0BAAkB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC/C,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,SAAiB;IAC/C,OAAO,SAAS,IAAI,qBAAa,CAAC;AACpC,CAAC"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":";;;AA2BA,kDAaC;AAKD,kDAcC;AAOD,0CAKC;AAKD,0CAEC;AAQD,4CASC;AAMD,oDAKC;AAMD,4CAMC;AAtHD,+CAAgE;AAGhE;;GAEG;AACU,QAAA,aAAa,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAE9C;;GAEG;AACU,QAAA,mBAAmB,GAAG,GAAG,CAAC;AAEvC;;GAEG;AACU,QAAA,kBAAkB,GAAG;IAChC,iBAAiB;IACjB,WAAW;IACX,YAAY;IACZ,WAAW;IACX,YAAY;CACb,CAAC;AAEF;;GAEG;AACH,SAAgB,mBAAmB,CACjC,IAAW,EACX,QAAgB,EAChB,SAAkB;IAElB,OAAO,IAAI,iCAAkB,CAC3B,IAAI,EACJ,0BAA0B,QAAQ,8CAA8C,EAChF;QACE,SAAS;QACT,WAAW,EAAE,2BAA2B,QAAQ,+CAA+C;KAChG,CACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,mBAAmB,CACjC,IAAW,EACX,SAAiB,EACjB,SAAkB;IAElB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC;IACnD,OAAO,IAAI,iCAAkB,CAC3B,IAAI,EACJ,cAAc,MAAM,0CAA0C,EAC9D;QACE,SAAS;QACT,WAAW,EAAE,wDAAwD;KACtE,CACF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAgB,eAAe,CAAC,QAA4B;IAC1D,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,0BAAkB,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,SAAiB;IAC/C,OAAO,SAAS,IAAI,qBAAa,CAAC;AACpC,CAAC;AAED;;;;;GAKG;AACH,SAAgB,gBAAgB,CAAC,QAAgB;IAC/C,OAAO,CACL,QAAQ;SACL,SAAS,CAAC,MAAM,CAAC;SACjB,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;SACpB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,qBAAqB,EAAE,EAAE,CAAC;SAClC,SAAS,CAAC,CAAC,EAAE,2BAAmB,CAAC,IAAI,UAAU,CACnD,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAgB,oBAAoB,CAAC,OAAe,EAAE,SAAS,GAAG,GAAG;IACnE,IAAI,OAAO,CAAC,MAAM,IAAI,SAAS;QAAE,OAAO,OAAO,CAAC;IAChD,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAC9B,IAAI,SAAS,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IAChC,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;AACnD,CAAC;AAED;;;GAGG;AACH,SAAgB,gBAAgB,CAAC,IAAW,EAAE,KAAc,EAAE,SAAkB;IAC9E,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;IACzE,OAAO,IAAI,2BAAY,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE;QACzC,OAAO,EAAE,8CAA8C;QACvD,SAAS;KACV,CAAC,CAAC;AACL,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-deep-ocr",
3
- "version": "1.3.2",
3
+ "version": "1.4.2",
4
4
  "description": "n8n community node for Deep-OCR document processing API",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",
@@ -14,7 +14,8 @@
14
14
  "license": "MIT",
15
15
  "homepage": "https://github.com/Heey-Global/deep-ocr-n8n",
16
16
  "author": {
17
- "name": "Heey"
17
+ "name": "Heey",
18
+ "email": "hello@deep-ocr.com"
18
19
  },
19
20
  "repository": {
20
21
  "type": "git",
@@ -39,10 +40,10 @@
39
40
  ]
40
41
  },
41
42
  "devDependencies": {
42
- "@n8n/eslint-plugin-community-nodes": "^0.10.0",
43
43
  "@eslint/eslintrc": "^3.3.5",
44
+ "@n8n/eslint-plugin-community-nodes": "^0.10.0",
44
45
  "@types/jest": "^30.0.0",
45
- "@types/node": "^22.0.0",
46
+ "@types/node": "^24.0.0",
46
47
  "@typescript-eslint/eslint-plugin": "^8.57.0",
47
48
  "@typescript-eslint/parser": "^8.57.0",
48
49
  "eslint": "^9.39.0",
@@ -55,7 +56,7 @@
55
56
  "n8n-workflow": "^2.14.0",
56
57
  "prettier": "^3.8.0",
57
58
  "ts-jest": "^29.4.0",
58
- "typescript": "^5.9.0"
59
+ "typescript": "^6.0.2"
59
60
  },
60
61
  "peerDependencies": {
61
62
  "n8n-workflow": "^1.0.0 || ^2.0.0"