Files
nextcloud-nodered-ocs-api/docs/ARCHITECTURE.md
T

82 lines
3.1 KiB
Markdown
Raw Normal View History

# Architecture
## Two components
### 1. `nextcloud-node-red` (Docker + nodes)
A thin wrapper around the official [`nodered/node-red`](https://hub.docker.com/r/nodered/node-red) image:
1. **Build time:** `nodes/nextcloud-ocs/` is copied to `/opt/nextcloud-nodes/node-red-contrib-nextcloud-ocs`.
2. **Run time:** `entrypoint.sh` runs as container `ENTRYPOINT`, copies that tree into `/data/node_modules/node-red-contrib-nextcloud-ocs`, then starts `node-red --userDir /data`.
Node-RED discovers contrib nodes from `{userDir}/node_modules/*/package.json``node-red.nodes` map.
### 2. `nodered-embed` (Nextcloud app)
PHP app registered as `nodered_embed`:
- **Navigation** entry opens a full-page iframe to the configured Node-RED URL.
- **CSPListener** relaxes Content-Security-Policy so Nextcloud may embed Node-RED (`frame-src`) and Node-RED may embed Nextcloud pages if needed (`frame-ancestors`).
- **Admin settings** store `nodered_url`, optional Docker container name, and a Docker-management flag (UI only for now).
## Node implementation pattern
Each functional node follows the same structure:
```
collectives.js → OPERATIONS hash (operationId → method, path, body fields)
collectives.html → Editor UI, dropdown of operations, config node picker
nextcloud-config.js → Credential node (baseUrl, username, password)
```
On input:
1. Resolve `msg.operation` or the configured default operation.
2. Substitute path placeholders (`{id}`, `{collectiveId}`, …) from config + `msg.*`.
3. Build query string and JSON body from configured fields + `msg` overrides.
4. HTTP request with `OCS-APIRequest: true`, `Accept: application/json`, Basic Auth.
5. Parse JSON into `msg.payload`, set `msg.statusCode`, `node.send(msg)`.
**ocs-api** is the escape hatch: you supply any OCS path and method without adding a new operation to the hash.
## Data persistence
| Path | Contents |
|------|----------|
| `/data/flows.json` | Flows (Docker volume `node-red-data`) |
| `/data/flows_cred.json` | Encrypted credentials |
| `/data/node_modules/node-red-contrib-nextcloud-ocs/` | Copy of custom nodes (refreshed on each start) |
The named volume **masks** anything copied into `/data` at image build time. That is why the entrypoint always re-copies from `/opt`.
## Network
```
Node-RED container (--network host)
→ https://cloud.example.com (same host or LAN)
```
On Ubuntu, a bridge network often breaks `localhost` / hostname resolution (`127.0.1.1` in `/etc/hosts`). Host networking avoids that for co-located Nextcloud + Node-RED.
## Authentication flow
```
Editor: nextcloud-config node
→ stored in flows_cred.json (encrypted)
Runtime: each API node
→ RED.nodes.getNode(config.nextcloud)
→ credentials.username + credentials.password
→ Authorization: Basic base64(user:app-password)
```
Use **app passwords**, not the account login password.
## Versioning
Package version in `nodes/nextcloud-ocs/package.json` (e.g. `0.8.0`) should be bumped when adding nodes or breaking operation ids. After deploy, verify inside the container:
```bash
docker exec nextcloud-node-red cat /data/node_modules/node-red-contrib-nextcloud-ocs/package.json
```