Files
browser-cli/n8n-nodes-browser-cli/credentials/BrowserCliApi.credentials.ts
T
daniel156161 cea8a7e994 feat: add n8n serve node and harden remote access
- Add the n8n community node package with credentials, command mapping, direct serve TCP client, and browser-cli protocol crypto helpers.

- Cover Ed25519 signing, canonical JSON, PQ transport encryption, request mapping, and security behavior with unit tests.

- Harden serve-http with per-address rate limiting, an 8 MB request body cap, and clear warnings when binding plain HTTP beyond loopback.

- Stop one-shot --key overrides from being persisted automatically; document explicit remote trust and keep key-management behind the keys policy tier.

- Make HTML-to-Markdown conversion safer by bounding tree depth and dropping unsafe link/image URL schemes.

- Bump package and extension release metadata to 0.16.3.
2026-06-19 10:00:23 +02:00

86 lines
3.2 KiB
TypeScript

import type { ICredentialType, INodeProperties } from 'n8n-workflow';
/**
* Credentials for a raw `browser-cli serve` endpoint.
*
* browser-cli cannot be installed inside n8n, so the node talks directly to a
* `serve` instance running on the machine that drives the browser. Start it
* there and trust this client's key:
*
* browser-cli auth keygen # on the n8n side, prints a PEM
* browser-cli auth trust <pubkey> --allow-control # on the serve side
* browser-cli serve --host 0.0.0.0 --port 8765 --authorized-keys ~/.browser_cli/authorized_keys
*
* The connection is authenticated with the Ed25519 private key below and the
* request/response bodies are encrypted with an ML-KEM-768 (post-quantum) key
* exchange, so it is safe to expose over an untrusted network without TLS.
* Leave the key empty only for a loopback `serve --no-auth` instance.
*/
export class BrowserCliApi implements ICredentialType {
name = 'browserCliApi';
displayName = 'Browser CLI API';
documentationUrl = 'https://chromewebstore.google.com/detail/browser-cli/hekaebjhbhhdbmakimmaklbblbmccahp';
// The serve protocol is raw TCP, not HTTP, so the declarative HTTP test does
// not apply — testing is done by the node method of this name, which runs a
// real authenticated handshake against the endpoint.
testedBy = 'browserCliApiTest';
properties: INodeProperties[] = [
{
displayName: 'Host',
name: 'host',
type: 'string',
default: '127.0.0.1',
placeholder: 'browser-host.example',
required: true,
description: 'Host of the remote `browser-cli serve` endpoint',
},
{
displayName: 'Port',
name: 'port',
type: 'number',
default: 8765,
required: true,
description: 'TCP port the `serve` endpoint listens on',
},
{
displayName: 'Ed25519 Private Key',
name: 'privateKey',
type: 'string',
typeOptions: { password: true, rows: 4 },
default: '',
placeholder: '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----',
description:
'PKCS8 PEM Ed25519 private key (from `browser-cli auth keygen`) whose public key is trusted by the serve endpoint. Leave empty only for a loopback `serve --no-auth` instance.',
},
{
displayName: 'Browser Alias',
name: 'browser',
type: 'string',
default: '',
placeholder: 'main',
description:
'Optional browser alias to route to (the serve `_route` target). Required when the serve endpoint exposes multiple browser instances; leave empty for a single-browser serve.',
},
{
displayName: 'Use TLS',
name: 'tls',
type: 'boolean',
default: false,
description:
'Whether to wrap the connection in TLS. Only needed when `serve` sits behind a TLS-terminating proxy; the protocol is already end-to-end encrypted via post-quantum key exchange.',
},
{
displayName: 'Ignore SSL Issues',
name: 'allowUnauthorizedCerts',
type: 'boolean',
default: false,
displayOptions: { show: { tls: [true] } },
description: 'Whether to connect even when the TLS certificate cannot be verified (e.g. a self-signed proxy)',
},
];
}