@t0mer/n8n-nodes-ssllabs 2026.9.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.
Files changed (62) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +234 -0
  3. package/dist/assets/demo/ssllabs-demo.png +0 -0
  4. package/dist/credentials/SslLabsApi.credentials.d.ts +10 -0
  5. package/dist/credentials/SslLabsApi.credentials.js +46 -0
  6. package/dist/credentials/SslLabsApi.credentials.js.map +1 -0
  7. package/dist/credentials/sslLabs.dark.svg +9 -0
  8. package/dist/credentials/sslLabs.svg +9 -0
  9. package/dist/nodes/SslLabs/SslLabs.node.d.ts +5 -0
  10. package/dist/nodes/SslLabs/SslLabs.node.js +91 -0
  11. package/dist/nodes/SslLabs/SslLabs.node.js.map +1 -0
  12. package/dist/nodes/SslLabs/SslLabs.node.json +18 -0
  13. package/dist/nodes/SslLabs/resources/assessment.d.ts +11 -0
  14. package/dist/nodes/SslLabs/resources/assessment.js +258 -0
  15. package/dist/nodes/SslLabs/resources/assessment.js.map +1 -0
  16. package/dist/nodes/SslLabs/resources/endpoint.d.ts +2 -0
  17. package/dist/nodes/SslLabs/resources/endpoint.js +77 -0
  18. package/dist/nodes/SslLabs/resources/endpoint.js.map +1 -0
  19. package/dist/nodes/SslLabs/resources/registration.d.ts +2 -0
  20. package/dist/nodes/SslLabs/resources/registration.js +71 -0
  21. package/dist/nodes/SslLabs/resources/registration.js.map +1 -0
  22. package/dist/nodes/SslLabs/resources/service.d.ts +3 -0
  23. package/dist/nodes/SslLabs/resources/service.js +86 -0
  24. package/dist/nodes/SslLabs/resources/service.js.map +1 -0
  25. package/dist/nodes/SslLabs/shared.d.ts +11 -0
  26. package/dist/nodes/SslLabs/shared.js +26 -0
  27. package/dist/nodes/SslLabs/shared.js.map +1 -0
  28. package/dist/nodes/SslLabs/sslLabs.dark.svg +9 -0
  29. package/dist/nodes/SslLabs/sslLabs.svg +9 -0
  30. package/dist/nodes/SslLabsTrigger/SslLabsTrigger.node.d.ts +5 -0
  31. package/dist/nodes/SslLabsTrigger/SslLabsTrigger.node.js +237 -0
  32. package/dist/nodes/SslLabsTrigger/SslLabsTrigger.node.js.map +1 -0
  33. package/dist/nodes/SslLabsTrigger/SslLabsTrigger.node.json +18 -0
  34. package/dist/nodes/SslLabsTrigger/sslLabs.dark.svg +9 -0
  35. package/dist/nodes/SslLabsTrigger/sslLabs.svg +9 -0
  36. package/dist/nodes/SslLabsTrigger/state.d.ts +35 -0
  37. package/dist/nodes/SslLabsTrigger/state.js +122 -0
  38. package/dist/nodes/SslLabsTrigger/state.js.map +1 -0
  39. package/dist/package.json +73 -0
  40. package/dist/shared/batch.d.ts +24 -0
  41. package/dist/shared/batch.js +66 -0
  42. package/dist/shared/batch.js.map +1 -0
  43. package/dist/shared/grades.d.ts +8 -0
  44. package/dist/shared/grades.js +38 -0
  45. package/dist/shared/grades.js.map +1 -0
  46. package/dist/shared/host.d.ts +2 -0
  47. package/dist/shared/host.js +38 -0
  48. package/dist/shared/host.js.map +1 -0
  49. package/dist/shared/poll.d.ts +29 -0
  50. package/dist/shared/poll.js +81 -0
  51. package/dist/shared/poll.js.map +1 -0
  52. package/dist/shared/summary.d.ts +8 -0
  53. package/dist/shared/summary.js +87 -0
  54. package/dist/shared/summary.js.map +1 -0
  55. package/dist/shared/transport.d.ts +37 -0
  56. package/dist/shared/transport.js +161 -0
  57. package/dist/shared/transport.js.map +1 -0
  58. package/dist/shared/types.d.ts +88 -0
  59. package/dist/shared/types.js +3 -0
  60. package/dist/shared/types.js.map +1 -0
  61. package/dist/tsconfig.tsbuildinfo +1 -0
  62. package/package.json +73 -0
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GRADE_ORDER = void 0;
4
+ exports.isGrade = isGrade;
5
+ exports.gradeRank = gradeRank;
6
+ exports.compareGrades = compareGrades;
7
+ exports.worstGrade = worstGrade;
8
+ exports.bestGrade = bestGrade;
9
+ exports.isWorseThan = isWorseThan;
10
+ exports.GRADE_ORDER = ['A+', 'A', 'A-', 'B', 'C', 'D', 'E', 'F', 'T', 'M'];
11
+ function isGrade(value) {
12
+ return typeof value === 'string' && exports.GRADE_ORDER.includes(value);
13
+ }
14
+ function gradeRank(grade) {
15
+ return isGrade(grade) ? exports.GRADE_ORDER.indexOf(grade) : undefined;
16
+ }
17
+ function compareGrades(a, b) {
18
+ var _a, _b;
19
+ const ra = (_a = gradeRank(a)) !== null && _a !== void 0 ? _a : exports.GRADE_ORDER.length;
20
+ const rb = (_b = gradeRank(b)) !== null && _b !== void 0 ? _b : exports.GRADE_ORDER.length;
21
+ return ra - rb;
22
+ }
23
+ function pick(grades, worst) {
24
+ const known = grades.filter(isGrade);
25
+ if (!known.length)
26
+ return null;
27
+ return known.reduce((acc, g) => (worst ? compareGrades(g, acc) > 0 : compareGrades(g, acc) < 0) ? g : acc);
28
+ }
29
+ function worstGrade(grades) {
30
+ return pick(grades, true);
31
+ }
32
+ function bestGrade(grades) {
33
+ return pick(grades, false);
34
+ }
35
+ function isWorseThan(grade, threshold) {
36
+ return isGrade(grade) && compareGrades(grade, threshold) > 0;
37
+ }
38
+ //# sourceMappingURL=grades.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grades.js","sourceRoot":"","sources":["../../shared/grades.ts"],"names":[],"mappings":";;;AAKA,0BAEC;AAGD,8BAEC;AAGD,sCAIC;AAWD,gCAEC;AAGD,8BAEC;AAGD,kCAEC;AAzCY,QAAA,WAAW,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAU,CAAC;AAIzF,SAAgB,OAAO,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAK,mBAAiC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACxF,CAAC;AAGD,SAAgB,SAAS,CAAC,KAAc;IACvC,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,mBAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAChE,CAAC;AAGD,SAAgB,aAAa,CAAC,CAAU,EAAE,CAAU;;IACnD,MAAM,EAAE,GAAG,MAAA,SAAS,CAAC,CAAC,CAAC,mCAAI,mBAAW,CAAC,MAAM,CAAC;IAC9C,MAAM,EAAE,GAAG,MAAA,SAAS,CAAC,CAAC,CAAC,mCAAI,mBAAW,CAAC,MAAM,CAAC;IAC9C,OAAO,EAAE,GAAG,EAAE,CAAC;AAChB,CAAC;AAED,SAAS,IAAI,CAAC,MAAiB,EAAE,KAAc;IAC9C,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACrC,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAC/B,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAC9B,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CACzE,CAAC;AACH,CAAC;AAGD,SAAgB,UAAU,CAAC,MAAiB;IAC3C,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAC3B,CAAC;AAGD,SAAgB,SAAS,CAAC,MAAiB;IAC1C,OAAO,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAC5B,CAAC;AAGD,SAAgB,WAAW,CAAC,KAAc,EAAE,SAAgB;IAC3D,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,aAAa,CAAC,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { INode } from 'n8n-workflow';
2
+ export declare function normalizeHost(input: unknown, node: INode, itemIndex?: number): string;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeHost = normalizeHost;
4
+ const n8n_workflow_1 = require("n8n-workflow");
5
+ const LABEL = /^(?!-)[a-z0-9-]{1,63}(?<!-)$/;
6
+ const IPV4 = /^(25[0-5]|2[0-4]\d|1?\d?\d)(\.(25[0-5]|2[0-4]\d|1?\d?\d)){3}$/;
7
+ function isHostname(value) {
8
+ if (value.length > 253)
9
+ return false;
10
+ const labels = value.split('.');
11
+ return labels.length >= 2 && labels.every((label) => LABEL.test(label));
12
+ }
13
+ function isIpv6(value) {
14
+ return value.includes(':') && /^[0-9a-f:.]+$/.test(value) && value.split('::').length <= 2;
15
+ }
16
+ function normalizeHost(input, node, itemIndex) {
17
+ var _a;
18
+ let value = typeof input === 'string' ? input.trim().toLowerCase() : '';
19
+ value = value.replace(/^[a-z][a-z0-9+.-]*:\/\//, '');
20
+ value = value.replace(/[/?#].*$/, '');
21
+ value = value.replace(/^.*@/, '');
22
+ const bracketed = /^\[([^\]]+)\](?::\d+)?$/.exec(value);
23
+ if (bracketed) {
24
+ value = bracketed[1];
25
+ }
26
+ else if (((_a = value.match(/:/g)) !== null && _a !== void 0 ? _a : []).length === 1) {
27
+ value = value.replace(/:\d*$/, '');
28
+ }
29
+ value = value.replace(/\.$/, '');
30
+ if (value && (IPV4.test(value) || isIpv6(value) || isHostname(value))) {
31
+ return value;
32
+ }
33
+ throw new n8n_workflow_1.NodeOperationError(node, `"${typeof input === 'string' ? input : String(input)}" is not a valid hostname`, {
34
+ itemIndex,
35
+ description: 'Enter a public hostname such as example.com. URLs are accepted and reduced to their host.',
36
+ });
37
+ }
38
+ //# sourceMappingURL=host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.js","sourceRoot":"","sources":["../../shared/host.ts"],"names":[],"mappings":";;AAoBA,sCA0BC;AA7CD,+CAAkD;AAElD,MAAM,KAAK,GAAG,8BAA8B,CAAC;AAC7C,MAAM,IAAI,GAAG,+DAA+D,CAAC;AAE7E,SAAS,UAAU,CAAC,KAAa;IAChC,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG;QAAE,OAAO,KAAK,CAAC;IACrC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChC,OAAO,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,MAAM,CAAC,KAAa;IAC5B,OAAO,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;AAC5F,CAAC;AAMD,SAAgB,aAAa,CAAC,KAAc,EAAE,IAAW,EAAE,SAAkB;;IAC5E,IAAI,KAAK,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxE,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,yBAAyB,EAAE,EAAE,CAAC,CAAC;IACrD,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACtC,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAElC,MAAM,SAAS,GAAG,yBAAyB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxD,IAAI,SAAS,EAAE,CAAC;QACf,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IACtB,CAAC;SAAM,IAAI,CAAC,MAAA,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,mCAAI,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnD,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACpC,CAAC;IACD,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAEjC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACvE,OAAO,KAAK,CAAC;IACd,CAAC;IACD,MAAM,IAAI,iCAAkB,CAC3B,IAAI,EACJ,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,EAChF;QACC,SAAS;QACT,WAAW,EACV,2FAA2F;KAC5F,CACD,CAAC;AACH,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type { IDataObject } from 'n8n-workflow';
2
+ import { type RetryPolicy, type SslLabsContext } from './transport';
3
+ import type { Host } from './types';
4
+ export interface AnalyzeParams {
5
+ host: string;
6
+ startNew?: boolean;
7
+ fromCache?: boolean;
8
+ maxAge?: number;
9
+ publish?: boolean;
10
+ ignoreMismatch?: boolean;
11
+ all?: 'on' | 'done';
12
+ }
13
+ export interface AnalyzeCallOptions {
14
+ abortSignal?: AbortSignal;
15
+ itemIndex?: number;
16
+ retry?: Partial<RetryPolicy> | false;
17
+ }
18
+ export declare function buildAnalyzeQs(ctx: SslLabsContext, params: AnalyzeParams, firstCall: boolean, itemIndex?: number): IDataObject;
19
+ export declare function analyze(ctx: SslLabsContext, params: AnalyzeParams, firstCall: boolean, options?: AnalyzeCallOptions): Promise<Host>;
20
+ export declare function isFinished(host: Host): boolean;
21
+ export interface WaitOptions extends AnalyzeCallOptions {
22
+ initialIntervalMs?: number;
23
+ intervalMs?: number;
24
+ timeoutMs?: number;
25
+ sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
26
+ now?: () => number;
27
+ beforeStart?: () => Promise<void>;
28
+ }
29
+ export declare function waitForAssessment(ctx: SslLabsContext, params: AnalyzeParams, options?: WaitOptions): Promise<Host>;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildAnalyzeQs = buildAnalyzeQs;
4
+ exports.analyze = analyze;
5
+ exports.isFinished = isFinished;
6
+ exports.waitForAssessment = waitForAssessment;
7
+ const n8n_workflow_1 = require("n8n-workflow");
8
+ const transport_1 = require("./transport");
9
+ function buildAnalyzeQs(ctx, params, firstCall, itemIndex) {
10
+ var _a;
11
+ if (params.startNew && params.fromCache) {
12
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), '"Force New Scan" and "Use Cache" cannot both be on', {
13
+ itemIndex,
14
+ description: 'SSL Labs rejects startNew together with fromCache. Turn one of them off.',
15
+ });
16
+ }
17
+ const qs = { host: params.host, all: (_a = params.all) !== null && _a !== void 0 ? _a : 'done' };
18
+ if (params.publish)
19
+ qs.publish = 'on';
20
+ if (params.ignoreMismatch)
21
+ qs.ignoreMismatch = 'on';
22
+ if (params.fromCache) {
23
+ qs.fromCache = 'on';
24
+ if (params.maxAge !== undefined && params.maxAge > 0)
25
+ qs.maxAge = Math.ceil(params.maxAge);
26
+ }
27
+ else if (params.startNew && firstCall) {
28
+ qs.startNew = 'on';
29
+ }
30
+ return qs;
31
+ }
32
+ async function analyze(ctx, params, firstCall, options = {}) {
33
+ const qs = buildAnalyzeQs(ctx, params, firstCall, options.itemIndex);
34
+ const retry = options.retry === false || !qs.startNew
35
+ ? options.retry
36
+ : { ...options.retry, serverErrorRetries: 0 };
37
+ const { body } = await (0, transport_1.sslLabsRequest)(ctx, {
38
+ path: 'analyze',
39
+ qs,
40
+ abortSignal: options.abortSignal,
41
+ itemIndex: options.itemIndex,
42
+ retry,
43
+ });
44
+ return body;
45
+ }
46
+ function isFinished(host) {
47
+ return host.status === 'READY' || host.status === 'ERROR';
48
+ }
49
+ async function waitForAssessment(ctx, params, options = {}) {
50
+ var _a, _b, _c, _d, _e, _f, _g;
51
+ const initialIntervalMs = (_a = options.initialIntervalMs) !== null && _a !== void 0 ? _a : 5000;
52
+ const intervalMs = (_b = options.intervalMs) !== null && _b !== void 0 ? _b : 10000;
53
+ const timeoutMs = (_c = options.timeoutMs) !== null && _c !== void 0 ? _c : 15 * 60000;
54
+ const wait = (_d = options.sleep) !== null && _d !== void 0 ? _d : n8n_workflow_1.sleep;
55
+ const now = (_e = options.now) !== null && _e !== void 0 ? _e : Date.now;
56
+ const deadline = now() + timeoutMs;
57
+ const callOptions = {
58
+ ...options,
59
+ retry: options.retry === false ? false : { ...options.retry, deadline: Date.now() + timeoutMs },
60
+ };
61
+ await ((_f = options.beforeStart) === null || _f === void 0 ? void 0 : _f.call(options));
62
+ let host = await analyze(ctx, params, true, callOptions);
63
+ while (!isFinished(host)) {
64
+ const delay = host.status === 'IN_PROGRESS' ? intervalMs : initialIntervalMs;
65
+ if (now() + delay > deadline) {
66
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), `Assessment of ${params.host} did not finish within ${Math.round(timeoutMs / 60000)} minutes (last status: ${host.status})`, {
67
+ itemIndex: options.itemIndex,
68
+ description: 'Assessments usually take 1–5 minutes per IP address. Increase "Timeout (Minutes)", or use the "Start Only" mode and read the result later with "Get Status".',
69
+ });
70
+ }
71
+ if ((_g = options.abortSignal) === null || _g === void 0 ? void 0 : _g.aborted) {
72
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'Execution was cancelled', {
73
+ itemIndex: options.itemIndex,
74
+ });
75
+ }
76
+ await wait(delay, options.abortSignal);
77
+ host = await analyze(ctx, params, false, callOptions);
78
+ }
79
+ return host;
80
+ }
81
+ //# sourceMappingURL=poll.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poll.js","sourceRoot":"","sources":["../../shared/poll.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { Cert, Host, Summary, SummaryCertificate } from './types';
2
+ export declare function toEpochMs(value: unknown): number | null;
3
+ export declare function toIso(value: unknown): string | null;
4
+ export declare function reportUrl(host: string): string;
5
+ export declare function leafCert(host: Host): Cert | null;
6
+ export declare function certKey(cert: Cert | null): string | null;
7
+ export declare function summarizeCert(cert: Cert | null, now: number): SummaryCertificate | null;
8
+ export declare function toSummary(host: Host, now?: number): Summary;
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toEpochMs = toEpochMs;
4
+ exports.toIso = toIso;
5
+ exports.reportUrl = reportUrl;
6
+ exports.leafCert = leafCert;
7
+ exports.certKey = certKey;
8
+ exports.summarizeCert = summarizeCert;
9
+ exports.toSummary = toSummary;
10
+ const grades_1 = require("./grades");
11
+ const DAY_MS = 86400000;
12
+ function toEpochMs(value) {
13
+ if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0)
14
+ return null;
15
+ return value < 1e12 ? value * 1000 : value;
16
+ }
17
+ function toIso(value) {
18
+ const ms = toEpochMs(value);
19
+ return ms === null ? null : new Date(ms).toISOString();
20
+ }
21
+ function reportUrl(host) {
22
+ return `https://www.ssllabs.com/ssltest/analyze.html?d=${encodeURIComponent(host)}`;
23
+ }
24
+ function leafCert(host) {
25
+ var _a, _b, _c, _d, _e, _f, _g;
26
+ const certs = (_a = host.certs) !== null && _a !== void 0 ? _a : [];
27
+ for (const endpoint of (_b = host.endpoints) !== null && _b !== void 0 ? _b : []) {
28
+ const leafId = (_f = (_e = (_d = (_c = endpoint.details) === null || _c === void 0 ? void 0 : _c.certChains) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.certIds) === null || _f === void 0 ? void 0 : _f[0];
29
+ const match = leafId ? certs.find((c) => c.id === leafId) : undefined;
30
+ if (match)
31
+ return match;
32
+ }
33
+ return (_g = certs[0]) !== null && _g !== void 0 ? _g : null;
34
+ }
35
+ function certKey(cert) {
36
+ if (!cert)
37
+ return null;
38
+ return cert.sha256Hash || cert.sha1Hash || cert.serialNumber || cert.id || null;
39
+ }
40
+ function summarizeCert(cert, now) {
41
+ var _a, _b, _c;
42
+ if (!cert)
43
+ return null;
44
+ const notAfterMs = toEpochMs(cert.notAfter);
45
+ return {
46
+ subject: (_a = cert.subject) !== null && _a !== void 0 ? _a : null,
47
+ issuer: (_b = cert.issuerSubject) !== null && _b !== void 0 ? _b : null,
48
+ notBefore: toIso(cert.notBefore),
49
+ notAfter: toIso(cert.notAfter),
50
+ daysUntilExpiry: notAfterMs === null ? null : Math.floor((notAfterMs - now) / DAY_MS),
51
+ serialNumber: (_c = cert.serialNumber) !== null && _c !== void 0 ? _c : null,
52
+ fingerprint: certKey(cert),
53
+ };
54
+ }
55
+ function toSummary(host, now = Date.now()) {
56
+ var _a, _b, _c, _d;
57
+ const endpoints = (_a = host.endpoints) !== null && _a !== void 0 ? _a : [];
58
+ const grades = endpoints.map((e) => e.grade);
59
+ const worst = (0, grades_1.worstGrade)(grades);
60
+ return {
61
+ host: host.host,
62
+ status: host.status,
63
+ statusMessage: (_b = host.statusMessage) !== null && _b !== void 0 ? _b : null,
64
+ grade: worst,
65
+ worstGrade: worst,
66
+ bestGrade: (0, grades_1.bestGrade)(grades),
67
+ hasWarnings: endpoints.some((e) => e.hasWarnings === true),
68
+ endpoints: endpoints.map((e) => {
69
+ var _a, _b, _c, _d, _e;
70
+ return ({
71
+ ipAddress: (_a = e.ipAddress) !== null && _a !== void 0 ? _a : null,
72
+ serverName: (_b = e.serverName) !== null && _b !== void 0 ? _b : null,
73
+ grade: (_c = e.grade) !== null && _c !== void 0 ? _c : null,
74
+ gradeTrustIgnored: (_d = e.gradeTrustIgnored) !== null && _d !== void 0 ? _d : null,
75
+ hasWarnings: e.hasWarnings === true,
76
+ isExceptional: e.isExceptional === true,
77
+ statusMessage: (_e = e.statusMessage) !== null && _e !== void 0 ? _e : null,
78
+ });
79
+ }),
80
+ certificate: summarizeCert(leafCert(host), now),
81
+ testTime: toIso(host.testTime),
82
+ engineVersion: (_c = host.engineVersion) !== null && _c !== void 0 ? _c : null,
83
+ criteriaVersion: (_d = host.criteriaVersion) !== null && _d !== void 0 ? _d : null,
84
+ reportUrl: reportUrl(host.host),
85
+ };
86
+ }
87
+ //# sourceMappingURL=summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary.js","sourceRoot":"","sources":["../../shared/summary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { IDataObject, IExecuteFunctions, IHttpRequestMethods, IPollFunctions } from 'n8n-workflow';
2
+ import { NodeApiError } from 'n8n-workflow';
3
+ export declare const DEFAULT_BASE_URL = "https://api.ssllabs.com/api/v4";
4
+ export declare const CREDENTIAL_TYPE = "sslLabsApi";
5
+ export declare const UNREGISTERED_EMAIL_MESSAGE = "Email is not registered with SSL Labs v4 \u2014 use the Register operation first";
6
+ export type SslLabsContext = IExecuteFunctions | IPollFunctions;
7
+ export interface SslLabsRequest {
8
+ path: string;
9
+ method?: IHttpRequestMethods;
10
+ qs?: IDataObject;
11
+ body?: IDataObject;
12
+ authenticate?: boolean;
13
+ abortSignal?: AbortSignal;
14
+ itemIndex?: number;
15
+ retry?: Partial<RetryPolicy> | false;
16
+ }
17
+ export interface RetryPolicy {
18
+ rateLimitRetries: number;
19
+ rateLimitWaitMs: number;
20
+ unavailableRetries: number;
21
+ unavailableWaitMs: number;
22
+ serverErrorRetries: number;
23
+ serverErrorWaitMs: number;
24
+ sleep: (ms: number, signal?: AbortSignal) => Promise<void>;
25
+ deadline?: number;
26
+ }
27
+ export declare const DEFAULT_RETRY_POLICY: RetryPolicy;
28
+ export declare const BUSY_STATUSES: number[];
29
+ export declare function isBusyError(error: unknown): boolean;
30
+ export interface SslLabsResponse<T> {
31
+ body: T;
32
+ headers: IDataObject;
33
+ }
34
+ export declare function normalizeBaseUrl(url: unknown): string;
35
+ export declare function isUnregisteredEmail(statusCode: number, body: unknown): boolean;
36
+ export declare function toApiError(ctx: SslLabsContext, statusCode: number, body: unknown, itemIndex?: number, authenticated?: boolean): NodeApiError;
37
+ export declare function sslLabsRequest<T = unknown>(ctx: SslLabsContext, request: SslLabsRequest): Promise<SslLabsResponse<T>>;
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BUSY_STATUSES = exports.DEFAULT_RETRY_POLICY = exports.UNREGISTERED_EMAIL_MESSAGE = exports.CREDENTIAL_TYPE = exports.DEFAULT_BASE_URL = void 0;
4
+ exports.isBusyError = isBusyError;
5
+ exports.normalizeBaseUrl = normalizeBaseUrl;
6
+ exports.isUnregisteredEmail = isUnregisteredEmail;
7
+ exports.toApiError = toApiError;
8
+ exports.sslLabsRequest = sslLabsRequest;
9
+ const n8n_workflow_1 = require("n8n-workflow");
10
+ exports.DEFAULT_BASE_URL = 'https://api.ssllabs.com/api/v4';
11
+ exports.CREDENTIAL_TYPE = 'sslLabsApi';
12
+ exports.UNREGISTERED_EMAIL_MESSAGE = 'Email is not registered with SSL Labs v4 — use the Register operation first';
13
+ exports.DEFAULT_RETRY_POLICY = {
14
+ rateLimitRetries: 3,
15
+ rateLimitWaitMs: 15000,
16
+ unavailableRetries: 2,
17
+ unavailableWaitMs: 60000,
18
+ serverErrorRetries: 1,
19
+ serverErrorWaitMs: 5000,
20
+ sleep: n8n_workflow_1.sleep,
21
+ };
22
+ exports.BUSY_STATUSES = [429, 503, 529];
23
+ function isBusyError(error) {
24
+ var _a;
25
+ return (error instanceof n8n_workflow_1.NodeApiError && exports.BUSY_STATUSES.includes(Number((_a = error.httpCode) !== null && _a !== void 0 ? _a : Number.NaN)));
26
+ }
27
+ function retryPlan(policy, statusCode) {
28
+ if (statusCode === 429)
29
+ return { retries: policy.rateLimitRetries, waitMs: policy.rateLimitWaitMs };
30
+ if (statusCode === 503 || statusCode === 529) {
31
+ return { retries: policy.unavailableRetries, waitMs: policy.unavailableWaitMs };
32
+ }
33
+ if (statusCode === 500)
34
+ return { retries: policy.serverErrorRetries, waitMs: policy.serverErrorWaitMs };
35
+ return { retries: 0, waitMs: 0 };
36
+ }
37
+ function normalizeBaseUrl(url) {
38
+ const value = typeof url === 'string' ? url.trim() : '';
39
+ return (value || exports.DEFAULT_BASE_URL).replace(/\/+$/, '');
40
+ }
41
+ function isHttpsUrl(url) {
42
+ return /^https:\/\/[^/\s]+/i.test(url);
43
+ }
44
+ async function resolveBaseUrl(ctx, required) {
45
+ if (required) {
46
+ const credentials = await ctx.getCredentials(exports.CREDENTIAL_TYPE);
47
+ return normalizeBaseUrl(credentials.baseUrl);
48
+ }
49
+ try {
50
+ const credentials = await ctx.getCredentials(exports.CREDENTIAL_TYPE);
51
+ return normalizeBaseUrl(credentials.baseUrl);
52
+ }
53
+ catch {
54
+ return exports.DEFAULT_BASE_URL;
55
+ }
56
+ }
57
+ function parseBody(body) {
58
+ if (typeof body !== 'string')
59
+ return body;
60
+ try {
61
+ return JSON.parse(body);
62
+ }
63
+ catch {
64
+ return body;
65
+ }
66
+ }
67
+ function apiErrors(body) {
68
+ if (body && typeof body === 'object' && Array.isArray(body.errors)) {
69
+ return body.errors;
70
+ }
71
+ return [];
72
+ }
73
+ function describeApiErrors(body) {
74
+ const errors = apiErrors(body);
75
+ if (errors.length) {
76
+ return errors
77
+ .map((e) => { var _a, _b; return (e.field ? `${e.field}: ${(_a = e.message) !== null && _a !== void 0 ? _a : ''}` : ((_b = e.message) !== null && _b !== void 0 ? _b : '')); })
78
+ .join('; ');
79
+ }
80
+ if (body && typeof body === 'object' && typeof body.message === 'string') {
81
+ return body.message;
82
+ }
83
+ return typeof body === 'string' ? body.slice(0, 500) : '';
84
+ }
85
+ function isUnregisteredEmail(statusCode, body) {
86
+ if (statusCode === 441)
87
+ return true;
88
+ if (statusCode !== 400)
89
+ return false;
90
+ return apiErrors(body).some((e) => { var _a; return e.field === 'email' || /not\s+(yet\s+)?register/i.test((_a = e.message) !== null && _a !== void 0 ? _a : ''); });
91
+ }
92
+ const STATUS_MESSAGES = {
93
+ 400: 'SSL Labs rejected the request parameters',
94
+ 429: 'SSL Labs rate limit reached (too many concurrent or new assessments). Lower the batch concurrency or try again later',
95
+ 500: 'SSL Labs internal server error. Try again later',
96
+ 503: 'SSL Labs is unavailable (maintenance). Try again in 15–30 minutes',
97
+ 529: 'SSL Labs is overloaded. Try again in 15–30 minutes',
98
+ };
99
+ function toApiError(ctx, statusCode, body, itemIndex, authenticated = true) {
100
+ var _a;
101
+ const detail = describeApiErrors(body);
102
+ const errorResponse = (body && typeof body === 'object' ? body : { message: detail || String(statusCode) });
103
+ if (authenticated && isUnregisteredEmail(statusCode, body)) {
104
+ return new n8n_workflow_1.NodeApiError(ctx.getNode(), errorResponse, {
105
+ message: exports.UNREGISTERED_EMAIL_MESSAGE,
106
+ description: detail || undefined,
107
+ httpCode: String(statusCode),
108
+ itemIndex,
109
+ });
110
+ }
111
+ const base = (_a = STATUS_MESSAGES[statusCode]) !== null && _a !== void 0 ? _a : `SSL Labs request failed with HTTP ${statusCode}`;
112
+ return new n8n_workflow_1.NodeApiError(ctx.getNode(), errorResponse, {
113
+ message: detail ? `${base}: ${detail}` : base,
114
+ description: detail || undefined,
115
+ httpCode: String(statusCode),
116
+ itemIndex,
117
+ });
118
+ }
119
+ async function sslLabsRequest(ctx, request) {
120
+ var _a, _b, _c;
121
+ const authenticate = (_a = request.authenticate) !== null && _a !== void 0 ? _a : true;
122
+ const baseUrl = await resolveBaseUrl(ctx, authenticate);
123
+ if (!isHttpsUrl(baseUrl)) {
124
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), `Base URL must start with https:// (got "${baseUrl}")`, {
125
+ itemIndex: request.itemIndex,
126
+ description: `Fix the SSL Labs API credential. The default is ${exports.DEFAULT_BASE_URL}.`,
127
+ });
128
+ }
129
+ const policy = request.retry === false ? null : { ...exports.DEFAULT_RETRY_POLICY, ...request.retry };
130
+ const options = {
131
+ method: (_b = request.method) !== null && _b !== void 0 ? _b : 'GET',
132
+ url: `${baseUrl}/${request.path.replace(/^\/+/, '')}`,
133
+ qs: request.qs,
134
+ returnFullResponse: true,
135
+ ignoreHttpStatusErrors: true,
136
+ abortSignal: request.abortSignal,
137
+ };
138
+ if (request.body) {
139
+ options.body = request.body;
140
+ options.json = true;
141
+ }
142
+ for (let attempt = 0;; attempt++) {
143
+ const response = (authenticate
144
+ ? await ctx.helpers.httpRequestWithAuthentication.call(ctx, exports.CREDENTIAL_TYPE, options)
145
+ : await ctx.helpers.httpRequest(options));
146
+ const body = parseBody(response.body);
147
+ if (response.statusCode >= 200 && response.statusCode < 300) {
148
+ return { body: body, headers: (_c = response.headers) !== null && _c !== void 0 ? _c : {} };
149
+ }
150
+ const plan = policy ? retryPlan(policy, response.statusCode) : { retries: 0, waitMs: 0 };
151
+ if (!policy || attempt >= plan.retries) {
152
+ throw toApiError(ctx, response.statusCode, body, request.itemIndex, authenticate);
153
+ }
154
+ const waitMs = Math.round(plan.waitMs * (attempt + 1) * (0.75 + Math.random() * 0.5));
155
+ if (policy.deadline !== undefined && Date.now() + waitMs > policy.deadline) {
156
+ throw toApiError(ctx, response.statusCode, body, request.itemIndex, authenticate);
157
+ }
158
+ await policy.sleep(waitMs, request.abortSignal);
159
+ }
160
+ }
161
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../shared/transport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ export type HostStatus = 'DNS' | 'IN_PROGRESS' | 'READY' | 'ERROR';
2
+ export interface Cert {
3
+ id?: string;
4
+ subject?: string;
5
+ issuerSubject?: string;
6
+ serialNumber?: string;
7
+ notBefore?: number;
8
+ notAfter?: number;
9
+ sha1Hash?: string;
10
+ sha256Hash?: string;
11
+ [key: string]: unknown;
12
+ }
13
+ export interface CertChain {
14
+ id?: string;
15
+ certIds?: string[];
16
+ [key: string]: unknown;
17
+ }
18
+ export interface Endpoint {
19
+ ipAddress?: string;
20
+ serverName?: string;
21
+ statusMessage?: string;
22
+ grade?: string;
23
+ gradeTrustIgnored?: string;
24
+ hasWarnings?: boolean;
25
+ isExceptional?: boolean;
26
+ progress?: number;
27
+ details?: {
28
+ certChains?: CertChain[];
29
+ [key: string]: unknown;
30
+ };
31
+ [key: string]: unknown;
32
+ }
33
+ export interface Host {
34
+ host: string;
35
+ port?: number;
36
+ protocol?: string;
37
+ status: HostStatus;
38
+ statusMessage?: string;
39
+ startTime?: number;
40
+ testTime?: number;
41
+ engineVersion?: string;
42
+ criteriaVersion?: string;
43
+ endpoints?: Endpoint[];
44
+ certs?: Cert[];
45
+ [key: string]: unknown;
46
+ }
47
+ export interface Info {
48
+ engineVersion?: string;
49
+ criteriaVersion?: string;
50
+ maxAssessments?: number;
51
+ currentAssessments?: number;
52
+ newAssessmentCoolOff?: number;
53
+ messages?: string[];
54
+ [key: string]: unknown;
55
+ }
56
+ export interface SummaryEndpoint {
57
+ ipAddress: string | null;
58
+ serverName: string | null;
59
+ grade: string | null;
60
+ gradeTrustIgnored: string | null;
61
+ hasWarnings: boolean;
62
+ isExceptional: boolean;
63
+ statusMessage: string | null;
64
+ }
65
+ export interface SummaryCertificate {
66
+ subject: string | null;
67
+ issuer: string | null;
68
+ notBefore: string | null;
69
+ notAfter: string | null;
70
+ daysUntilExpiry: number | null;
71
+ serialNumber: string | null;
72
+ fingerprint: string | null;
73
+ }
74
+ export interface Summary {
75
+ host: string;
76
+ status: HostStatus;
77
+ statusMessage: string | null;
78
+ grade: string | null;
79
+ worstGrade: string | null;
80
+ bestGrade: string | null;
81
+ hasWarnings: boolean;
82
+ endpoints: SummaryEndpoint[];
83
+ certificate: SummaryCertificate | null;
84
+ testTime: string | null;
85
+ engineVersion: string | null;
86
+ criteriaVersion: string | null;
87
+ reportUrl: string;
88
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../shared/types.ts"],"names":[],"mappings":""}