1945 lines
68 KiB
Markdown
1945 lines
68 KiB
Markdown
# P2NS Admin Backend API
|
|
|
|
The P2NS (Peer-to-Peer Name System) admin backend API, hosted at `https://p2ns.admin`, provides endpoints for managing the decentralized DNS system programmatically. These endpoints, implemented in `admin.js`, allow interaction with domains, Holesail servers and clients, local DNS records, certificates, virtual interfaces, logs, settings, and system status. All endpoints are accessible via HTTP/HTTPS and do not require authentication (since the domain is local). Responses are typically JSON or plain text, with errors returned as plain text messages. Real-time updates are broadcast via WebSocket at `wss://p2ns.admin/ws`.
|
|
|
|
## Base URL
|
|
`https://p2ns.admin`
|
|
|
|
## WebSocket Endpoint
|
|
- **URL**: `wss://p2ns.admin/ws`
|
|
- **Description**: Establishes a WebSocket connection for real-time updates from the server.
|
|
- **Client → server messages**:
|
|
- `subscribe-stats` / `unsubscribe-stats` / `request-stats-snapshot` — Stats tab live data.
|
|
- `subscribe-log` — `{ "type": "subscribe-log", "channel": "core", "lines": 1000 }` (channels: `core`, `proxy`, `httpProxy`, `dns`, `plugins`, `holesail`).
|
|
- `unsubscribe-log` — Stop log tail.
|
|
- `request-domains` — Refresh domains list (server replies with `domains-list`).
|
|
|
|
- **Server → client messages**:
|
|
- `stats-snapshot` — Full stats page payload (`stats`, `historical`, `health`, `status`, `minutes`). Includes `stats.core` (invite RPC diagnostics) and `stats.pluginRpc` / `stats.peerChannels` (plugin RPC metrics).
|
|
- `update-stats` — Notifies stats subscribers to apply their latest snapshot (does not embed metrics itself).
|
|
- `update-health` — Health payload for Diagnostics tab subscribers.
|
|
- `file-log` — `{ "type": "file-log", "channel": "dns", "level": "info", "message": "<line>" }` (live log tail).
|
|
- `log-snapshot` — Initial tail after `subscribe-log`: `{ "type": "log-snapshot", "channel": "core", "lines": ["..."] }`.
|
|
- `log` — **Legacy**; may still map to core. Prefer `file-log` + `subscribe-log`.
|
|
- `holesail-log` — Holesail child process logs (`id`, `level`, `message`).
|
|
- `plugin-log` — Per-plugin logs (`domain`, `level`, `component`, `message`).
|
|
- `domains-list` — Resolved domains array.
|
|
- `update-database`, `update-peers`, `update-certs`, `update-interfaces`, `update-local-dns`, `update-holesail`, `update-holesail-clients`, `update-settings`, `update-plugins`, `update-plugin-settings` — Tab refresh hints.
|
|
- `system-reset` — Client should reload.
|
|
|
|
- **Example (`file-log`)**:
|
|
```json
|
|
{
|
|
"type": "file-log",
|
|
"channel": "core",
|
|
"level": "info",
|
|
"message": "2026-05-28T12:00:00.000Z [INFO] [Main] Starting..."
|
|
}
|
|
```
|
|
|
|
## Endpoints
|
|
|
|
### 1. GET /
|
|
- **Description**: Serves the admin panel HTML (`includes/admin/admin-frontend/index.html`).
|
|
- **Response**: HTML content.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to load admin panel.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/
|
|
```
|
|
|
|
### 2. GET /styles.css
|
|
- **Description**: Serves the admin panel stylesheet (`includes/admin/admin-frontend/styles.css`).
|
|
- **Response**: CSS content.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to load styles.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/styles.css
|
|
```
|
|
|
|
### 3. GET /admin.js
|
|
- **Description**: Serves the admin panel JavaScript (`includes/admin/admin-frontend/admin.js`).
|
|
- **Response**: JavaScript content.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to load script.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/admin.js
|
|
```
|
|
|
|
### 4. GET /api/resolved-domains
|
|
- **Description**: Retrieves a list of resolved domains with their hashes, local status, ownership, consensus information, and available services.
|
|
- **Response**: JSON array of objects with:
|
|
- `domain` (string): Domain name
|
|
- `hash` (string): Holesail hash or `"internal"` for internal domains
|
|
- `isLocal` (boolean): Whether the local writer has a claim for this domain
|
|
- `isOwner` (boolean): Whether the local writer is the resolved claimant (owner) of this domain
|
|
- `consensusState` (object): Detailed consensus information including status, vote counts, quorum status, etc.
|
|
- `consensusStatus` (string): Simplified status that may include `"conflict"` for domains where local peer has a claim but another claimant won
|
|
- `services` (array): Array of service objects with `serviceName`, `key`, `port`, and `protocol` fields
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to fetch domains.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/resolved-domains
|
|
```
|
|
```json
|
|
[
|
|
{
|
|
"domain": "example.tld",
|
|
"hash": "hs://s00084bf...",
|
|
"isLocal": true,
|
|
"isOwner": true,
|
|
"consensusState": {
|
|
"status": "resolved",
|
|
"hash": "hs://s00084bf...",
|
|
"resolvedClaimant": "a6a6d7ebcc1df8f33410067bf96ad2cc30d5276516f758bb0f34195e914c451f",
|
|
"voteCounts": {
|
|
"a6a6d7ebcc1df8f33410067bf96ad2cc30d5276516f758bb0f34195e914c451f": 8
|
|
},
|
|
"activePeers": 5,
|
|
"quorumMet": true,
|
|
"minVotes": 2,
|
|
"totalVotes": 8,
|
|
"lastResolution": 1766780982538
|
|
},
|
|
"consensusStatus": "resolved",
|
|
"services": [
|
|
{
|
|
"serviceName": "web",
|
|
"key": "hs://s00084bf...",
|
|
"port": 8080,
|
|
"protocol": "tcp"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"domain": "bm.git",
|
|
"hash": "hs://s000f44fb5cfe3fa7f37e9070ea14975a8dbf1e2156689638bc92458118df7a4987b",
|
|
"isLocal": true,
|
|
"isOwner": false,
|
|
"consensusState": {
|
|
"status": "resolved",
|
|
"hash": "hs://s000f44fb5cfe3fa7f37e9070ea14975a8dbf1e2156689638bc92458118df7a4987b",
|
|
"resolvedClaimant": "acbb3b69ee810f4fbe54927a5742530e4cf76b7b462a4c37ddfe27ba5c3060b6",
|
|
"voteCounts": {
|
|
"a6a6d7ebcc1df8f33410067bf96ad2cc30d5276516f758bb0f34195e914c451f": 1,
|
|
"acbb3b69ee810f4fbe54927a5742530e4cf76b7b462a4c37ddfe27ba5c3060b6": 7
|
|
},
|
|
"activePeers": 5,
|
|
"quorumMet": true,
|
|
"minVotes": 2,
|
|
"totalVotes": 8,
|
|
"lastResolution": 1766780982538
|
|
},
|
|
"consensusStatus": "conflict",
|
|
"services": []
|
|
},
|
|
{
|
|
"domain": "peer.directory",
|
|
"hash": "internal",
|
|
"isLocal": true,
|
|
"isOwner": true,
|
|
"consensusStatus": "internal",
|
|
"services": []
|
|
}
|
|
]
|
|
```
|
|
|
|
### 5. GET /api/entries
|
|
- **Description**: Retrieves all Autopass ledger entries (claims and votes).
|
|
- **Response**: JSON array of objects with `key` (string) and `value` (string).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to fetch entries.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/entries
|
|
```
|
|
```json
|
|
[
|
|
{ "key": "claim:example.tld:abc123", "value": "hs://s00084bf..." },
|
|
{ "key": "vote:example.tld:abc123:def456", "value": "1" }
|
|
]
|
|
```
|
|
|
|
### 6. GET /api/peers
|
|
- **Description**: Lists connected peers (public keys).
|
|
- **Response**: JSON array of peer public keys (strings).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to fetch peers.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/peers
|
|
```
|
|
```json
|
|
["def456", "ghi789"]
|
|
```
|
|
|
|
### 7. GET /api/certs
|
|
- **Description**: Lists domains with generated certificates.
|
|
- **Response**: JSON array of domain names (strings).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to fetch certs.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/certs
|
|
```
|
|
```json
|
|
["example.tld", "peer.directory"]
|
|
```
|
|
|
|
### 8. GET /api/cert-details?domain=<domain>
|
|
- **Description**: Retrieves the certificate content for a specified domain.
|
|
- **Query Parameters**:
|
|
- `domain`: The domain name (e.g., `example.tld`).
|
|
- **Response**: Plain text certificate content (PEM format).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to fetch cert details.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/cert-details?domain=example.tld
|
|
```
|
|
```text
|
|
-----BEGIN CERTIFICATE-----
|
|
MIID...
|
|
-----END CERTIFICATE-----
|
|
```
|
|
|
|
### 9. GET /api/interfaces
|
|
- **Description**: Lists virtual interfaces with domain-to-IP mappings.
|
|
- **Response**: JSON array of objects with `domain` (string) and `ip` (string).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to fetch interfaces.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/interfaces
|
|
```
|
|
```json
|
|
[
|
|
{ "domain": "example.tld", "ip": "192.168.3.2" },
|
|
{ "domain": "peer.directory", "ip": "192.168.3.3" }
|
|
]
|
|
```
|
|
|
|
### 10. GET /api/local-dns
|
|
- **Description**: Retrieves custom local DNS records and conflicting domains (domains with both P2P and public records).
|
|
- **Response**: JSON object with:
|
|
- `records`: Array of DNS records with `index` (number), `name` (string), `type` (string), `ttl` (number), `class` (string, usually "IN"), and type-specific fields (e.g., `data` for A, `preference` and `exchange` for MX).
|
|
- `conflicts`: Array of objects with `domain` (string), `version` (p2p/public), and `publicIP` (string).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to fetch local DNS and conflicts.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/local-dns
|
|
```
|
|
```json
|
|
{
|
|
"records": [
|
|
{ "index": 0, "name": "local.example", "type": "A", "class": "IN", "ttl": 3600, "data": "192.168.1.100" },
|
|
{ "index": 1, "name": "mail.example", "type": "MX", "class": "IN", "ttl": 3600, "preference": 10, "exchange": "mx.example.com" },
|
|
{ "index": 2, "name": "_service._tcp.example", "type": "SRV", "class": "IN", "ttl": 3600, "priority": 0, "weight": 5, "port": 8080, "target": "server.example.com" }
|
|
],
|
|
"conflicts": [
|
|
{ "domain": "myspace.com", "version": "public", "publicIP": "151.101.1.195" },
|
|
{ "domain": "example.com", "version": "p2p", "publicIP": "93.184.216.34" }
|
|
]
|
|
}
|
|
```
|
|
|
|
### 11. GET /api/selector-cache
|
|
- **Description**: Retrieves DNS version preferences for domains with both P2P and public records.
|
|
- **Response**: JSON object mapping domains to `p2p` or `public`.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to fetch selector cache.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/selector-cache
|
|
```
|
|
```json
|
|
{
|
|
"myspace.com": "public",
|
|
"example.com": "p2p"
|
|
}
|
|
```
|
|
|
|
### 12. GET /api/status
|
|
- **Description**: Retrieves system status, including master/joiner mode and peer count.
|
|
- **Response**: JSON object with `isMaster` (boolean), `isConnected` (boolean), and `peersCount` (number).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to fetch status.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/status
|
|
```
|
|
```json
|
|
{
|
|
"isMaster": true,
|
|
"isConnected": true,
|
|
"peersCount": 5
|
|
}
|
|
```
|
|
|
|
### 13. GET /api/holesail-servers
|
|
- **Description**: Lists all Holesail servers with their configurations and status.
|
|
- **Response**: JSON array of objects with `id` (string), `opts` (configuration object), and `info` (object including `state`: running/stopped).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to fetch Holesail servers.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/holesail-servers
|
|
```
|
|
```json
|
|
[
|
|
{
|
|
"id": "abc123",
|
|
"opts": { "name": "server1", "port": 8080, "host": "0.0.0.0", "secure": true, "log": 1 },
|
|
"info": { "state": "running", "url": "hs://s00084bf..." }
|
|
}
|
|
]
|
|
```
|
|
|
|
### 14. GET /api/holesail-clients
|
|
- **Description**: Lists all Holesail clients with their configurations and status.
|
|
- **Response**: JSON array of objects with `id` (string), `opts` (configuration object), and `info` (object including `state`: running/starting/stopped/error).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to fetch Holesail clients.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/holesail-clients
|
|
```
|
|
```json
|
|
[
|
|
{
|
|
"id": "def456",
|
|
"opts": { "domain": "example.tld", "key": "hs://s00084bf...", "port": 8080, "protocol": "tcp" },
|
|
"info": { "state": "running" }
|
|
}
|
|
]
|
|
```
|
|
|
|
### 15. GET /api/settings
|
|
- **Description**: Retrieves environment settings (whitelisted variables). Note: `SUBNETS`, `SUBNET_BASE`, and `INITIAL_IP_INDEX` are managed separately via the subnet configurator (see `/api/subnets`).
|
|
- **Response**: JSON object with `settings` (object mapping whitelisted keys to values) and `metadata` (object with setting metadata including types, descriptions, and categories).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to fetch settings.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/settings
|
|
```
|
|
```json
|
|
{
|
|
"settings": {
|
|
"LOG_LEVEL": "1",
|
|
"INTERNAL_DOMAINS": "Note: Internal domains are now automatically discovered from plugin-sites/{domain}/config.json files"
|
|
},
|
|
"metadata": {
|
|
"LOG_LEVEL": {
|
|
"type": "number",
|
|
"category": "Logging & Debugging",
|
|
"label": "Log Level",
|
|
"description": "...",
|
|
"default": "0"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### 16. POST /api/add-domain
|
|
- **Description**: Adds a domain with its Holesail hash to the P2P network and `domains.json`. Assigns an IP if needed and triggers auto-voting. **Note: Internal domains (automatically discovered from `plugin-sites/{domain}/config.json` files, including `p2ns.admin`) cannot be claimed and will return an error.**
|
|
- **Request Body**: JSON with `domain` (string), `hash` (string, e.g., `hs://<hash>`), and optionally `ssl` (boolean). The `ssl` field indicates if the Holesail connection uses SSL/TLS. When `true`, proxy connections will use HTTPS/WSS instead of HTTP/WS. Defaults to `false` if not provided.
|
|
- **Response**: Plain text `OK` on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to add domain.
|
|
- **WebSocket Broadcast**: `update-database`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"domain":"example.tld","hash":"hs://s00084bf...","ssl":true}' \
|
|
https://p2ns.admin/api/add-domain
|
|
```
|
|
```text
|
|
OK
|
|
```
|
|
|
|
### 17. POST /api/remove-domain
|
|
- **Description**: Removes a domain. Behavior depends on consensus status:
|
|
- **Resolved Claimant**: Performs full cleanup removing all claims and votes for the domain, broadcasts `consensus.removeDomain` RPC to trigger other peers to clean up
|
|
- **Conflict Claim**: Removes only your own claim and votes, broadcasts `removeConflictDomainClaim:` notification (other peers preserve their claims)
|
|
- **Request Body**: JSON with `domain` (string).
|
|
- **Response**: Plain text `OK` on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `403`: No claim found for domain or peer not initialized.
|
|
- `500`: Failed to remove domain.
|
|
- **WebSocket Broadcast**: `update-database`, `update-holesail-clients`, `update-local-dns`.
|
|
- **Note**: Only the peer that created a claim can remove it. Ownership is strictly validated before removal.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"domain":"example.tld"}' \
|
|
https://p2ns.admin/api/remove-domain
|
|
```
|
|
```text
|
|
OK
|
|
```
|
|
|
|
### 18. POST /api/regenerate-ca
|
|
- **Description**: Regenerates the root CA certificate.
|
|
- **Request Body**: None.
|
|
- **Response**: Plain text `OK` on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to regenerate CA.
|
|
- **WebSocket Broadcast**: `update-certs`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
https://p2ns.admin/api/regenerate-ca
|
|
```
|
|
```text
|
|
OK
|
|
```
|
|
|
|
### 19. POST /api/install-ca
|
|
- **Description**: Installs the root CA to the system trust store.
|
|
- **Request Body**: None.
|
|
- **Response**: Plain text `OK` on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to install CA.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
https://p2ns.admin/api/install-ca
|
|
```
|
|
```text
|
|
OK
|
|
```
|
|
|
|
### 20. POST /api/generate-cert
|
|
- **Description**: Generates a certificate for a specified domain, assigning an IP if needed.
|
|
- **Request Body**: JSON with `domain` (string).
|
|
- **Response**: Plain text `OK` on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to generate cert.
|
|
- **WebSocket Broadcast**: `update-certs`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"domain":"example.tld"}' \
|
|
https://p2ns.admin/api/generate-cert
|
|
```
|
|
```text
|
|
OK
|
|
```
|
|
|
|
### 21. POST /api/delete-cert
|
|
- **Description**: Deletes the certificate for a specified domain.
|
|
- **Request Body**: JSON with `domain` (string).
|
|
- **Response**: Plain text `OK` on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to delete cert.
|
|
- **WebSocket Broadcast**: `update-certs`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"domain":"example.tld"}' \
|
|
https://p2ns.admin/api/delete-cert
|
|
```
|
|
```text
|
|
OK
|
|
```
|
|
|
|
### 22. POST /api/regenerate-cert
|
|
- **Description**: Regenerates the certificate for a specified domain, assigning an IP if needed.
|
|
- **Request Body**: JSON with `domain` (string).
|
|
- **Response**: Plain text `OK` on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to regenerate cert.
|
|
- **WebSocket Broadcast**: `update-certs`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"domain":"example.tld"}' \
|
|
https://p2ns.admin/api/regenerate-cert
|
|
```
|
|
```text
|
|
OK
|
|
```
|
|
|
|
### 23. POST /api/cleanup-interfaces
|
|
- **Description**: Cleans up unused virtual interfaces.
|
|
- **Note**: This endpoint is available via the API but is not exposed in the admin UI interface.
|
|
- **Request Body**: None.
|
|
- **Response**: Plain text `OK` on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to cleanup interfaces.
|
|
- **WebSocket Broadcast**: `update-interfaces`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
https://p2ns.admin/api/cleanup-interfaces
|
|
```
|
|
```text
|
|
OK
|
|
```
|
|
|
|
### 24. POST /api/add-local-dns
|
|
- **Description**: Adds a custom DNS record to `local_dns.json`. Supports all DNS record types (e.g., A, AAAA, CNAME, MX, TXT, SRV, SOA, CAA, NS, PTR, OTHER) with flexible fields.
|
|
- **Request Body**: JSON object with `name` (string), `type` (string), `ttl` (number), `class` (string, optional, defaults to "IN"), and type-specific fields (e.g., `data` for A, `preference` and `exchange` for MX).
|
|
- **Response**: Plain text `OK` on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to add local DNS record.
|
|
- **WebSocket Broadcast**: `update-local-dns`.
|
|
- **Example** (A record):
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"name":"local.example","type":"A","ttl":3600,"data":"192.168.1.100"}' \
|
|
https://p2ns.admin/api/add-local-dns
|
|
```
|
|
```text
|
|
OK
|
|
```
|
|
- **Example** (SRV record):
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"name":"_service._tcp.example","type":"SRV","ttl":3600,"priority":0,"weight":5,"port":8080,"target":"server.example.com"}' \
|
|
https://p2ns.admin/api/add-local-dns
|
|
```
|
|
```text
|
|
OK
|
|
```
|
|
|
|
### 25. POST /api/update-local-dns
|
|
- **Description**: Updates an existing custom DNS record in `local_dns.json` by index. Supports all DNS record types.
|
|
- **Request Body**: JSON object with `index` (number) and `record` (object with `name`, `type`, `ttl`, `class` (optional), and type-specific fields).
|
|
- **Response**: Plain text `OK` on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `400`: Invalid index.
|
|
- `500`: Failed to update local DNS record.
|
|
- **WebSocket Broadcast**: `update-local-dns`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"index":0,"record":{"name":"local.example","type":"A","ttl":7200,"data":"192.168.1.101"}}' \
|
|
https://p2ns.admin/api/update-local-dns
|
|
```
|
|
```text
|
|
OK
|
|
```
|
|
|
|
### 26. POST /api/delete-local-dns
|
|
- **Description**: Deletes a custom DNS record from `local_dns.json` by index.
|
|
- **Request Body**: JSON with `index` (number).
|
|
- **Response**: Plain text `OK` on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `400`: Invalid index.
|
|
- `500`: Failed to delete local DNS record.
|
|
- **WebSocket Broadcast**: `update-local-dns`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"index":0}' \
|
|
https://p2ns.admin/api/delete-local-dns
|
|
```
|
|
```text
|
|
OK
|
|
```
|
|
|
|
### 27. POST /api/update-version-preference
|
|
- **Description**: Updates the DNS version preference (p2p or public) for a domain with both P2P and public records, stored in `selector_cache.json`.
|
|
- **Request Body**: JSON with `domain` (string) and `version` (string: `p2p` or `public`).
|
|
- **Response**: Plain text `OK` on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `400`: Invalid version.
|
|
- `500`: Failed to update version preference.
|
|
- **WebSocket Broadcast**: `update-local-dns`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"domain":"myspace.com","version":"public"}' \
|
|
https://p2ns.admin/api/update-version-preference
|
|
```
|
|
```text
|
|
OK
|
|
```
|
|
|
|
### 28. GET /api/p2p-domain-conflicts
|
|
- **Description**: Retrieves domains with P2P consensus conflicts where the user has a local claim but another claimant won consensus. Used for the P2P Domain Conflicts management interface.
|
|
- **Response**: JSON object with `conflicts` array containing objects with:
|
|
- `domain` (string): Domain name
|
|
- `localHash` (string): User's local claim hash
|
|
- `resolvedHash` (string): Consensus-resolved hash
|
|
- `resolvedClaimant` (string): Public key of consensus winner
|
|
- `localClaimant` (string): User's public key
|
|
- `consensusStatus` (string): Current consensus status
|
|
- `hashPreference` (string): User's hash preference ('local' or 'resolved')
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to fetch P2P domain conflicts.
|
|
- **WebSocket Broadcast**: None.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/p2p-domain-conflicts
|
|
```
|
|
```json
|
|
{
|
|
"conflicts": [
|
|
{
|
|
"domain": "example.com",
|
|
"localHash": "hs://s0001abc...",
|
|
"resolvedHash": "hs://s0001def...",
|
|
"resolvedClaimant": "abc123...",
|
|
"localClaimant": "def456...",
|
|
"consensusStatus": "resolved",
|
|
"hashPreference": "resolved"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### 29. POST /api/update-hash-preference
|
|
- **Description**: Updates the hash preference ('local' or 'resolved') for a domain with P2P consensus conflicts, stored in `selector_cache.json`. When changed, automatically restarts any active Holesail clients for the domain to use the new hash.
|
|
- **Request Body**: JSON with `domain` (string) and `preference` (string: `local` or `resolved`).
|
|
- **Response**: Plain text `OK` on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `400`: Invalid preference.
|
|
- `500`: Failed to update hash preference.
|
|
- **WebSocket Broadcast**: `update-local-dns`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"domain":"example.com","preference":"local"}' \
|
|
https://p2ns.admin/api/update-hash-preference
|
|
```
|
|
```text
|
|
OK
|
|
```
|
|
|
|
### 30. POST /api/clear-dns-cache
|
|
- **Description**: Clears DNS resolution cache entries for a specific domain to force fresh hash resolution on next DNS query.
|
|
- **Request Body**: JSON with `domain` (string).
|
|
- **Response**: Plain text `OK` on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to clear DNS cache.
|
|
- **WebSocket Broadcast**: None.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"domain":"example.com"}' \
|
|
https://p2ns.admin/api/clear-dns-cache
|
|
```
|
|
```text
|
|
OK
|
|
```
|
|
|
|
### 31. POST /api/restart-holesail-clients-for-domain
|
|
- **Description**: Restarts all Holesail clients (both admin-managed and DNS-triggered) for a specific domain to use updated hash preferences. Closes existing connections and creates new ones with correct hashes. Ensures IP assignment exists before creating clients.
|
|
- **Request Body**: JSON with `domain` (string).
|
|
- **Response**: Plain text `OK` on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to restart clients or resolve hash.
|
|
- `500`: Failed to restart Holesail clients.
|
|
- **WebSocket Broadcast**: `update-holesail-clients`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"domain":"example.com"}' \
|
|
https://p2ns.admin/api/restart-holesail-clients-for-domain
|
|
```
|
|
```text
|
|
OK
|
|
```
|
|
|
|
### 32. POST /api/holesail-create
|
|
- **Description**: Creates a new Holesail server, optionally assigning it to a domain. Persists to `holesail_servers.json`.
|
|
- **Request Body**: JSON with `name` (string, optional), `port` (number), `host` (string, optional), `key` (string, optional), `domain` (string, optional), `secure` (boolean), `udp` (boolean), `log` (number).
|
|
- **Response**: JSON with `id` (string) on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to create Holesail server.
|
|
- **WebSocket Broadcast**: `update-holesail`, `update-database` (if domain assigned).
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"name":"server1","port":8080,"host":"0.0.0.0","secure":true,"udp":false,"log":1,"domain":"example.tld"}' \
|
|
https://p2ns.admin/api/holesail-create
|
|
```
|
|
```json
|
|
{"id":"abc123"}
|
|
```
|
|
|
|
### 33. POST /api/holesail-delete
|
|
- **Description**: Deletes a Holesail server by ID and removes it from `holesail_servers.json`.
|
|
- **Request Body**: JSON with `id` (string).
|
|
- **Response**: Plain text `OK` on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to delete Holesail server.
|
|
- **WebSocket Broadcast**: `update-holesail`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"id":"abc123"}' \
|
|
https://p2ns.admin/api/holesail-delete
|
|
```
|
|
```text
|
|
OK
|
|
```
|
|
|
|
### 34. POST /api/holesail-restart
|
|
- **Description**: Restarts a Holesail server by ID, optionally reassigning its domain. Persists to `holesail_servers.json`.
|
|
- **Request Body**: JSON with `id` (string).
|
|
- **Response**: Plain text `OK` on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to restart Holesail server.
|
|
- **WebSocket Broadcast**: `update-holesail`, `update-database` (if domain assigned).
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"id":"abc123"}' \
|
|
https://p2ns.admin/api/holesail-restart
|
|
```
|
|
```text
|
|
OK
|
|
```
|
|
|
|
### 35. POST /api/holesail-client-create
|
|
- **Description**: Creates a new Holesail client for a domain and port. Persists to `holesail_clients.json`. If `serviceName` is provided, the client ID will be `domain_servicename`; otherwise, a generated ID is used. The client is also added to the domain's claim record `clients` array.
|
|
- **Request Body**: JSON with:
|
|
- `domain` (string, required): Domain name (must be owned by local writer)
|
|
- `key` (string, required): Holesail connection hash (e.g., `hs://s00084bf...`)
|
|
- `port` (number, required): Port number
|
|
- `serviceName` (string, optional): Service name for naming the client (format: `domain_servicename`)
|
|
- `protocol` (string, optional): Protocol type (`tcp` or `udp`, default: `tcp`)
|
|
- **Response**: JSON with `id` (string) on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `400`: Invalid request (missing required fields or domain not owned).
|
|
- `500`: Failed to create Holesail client.
|
|
- **WebSocket Broadcast**: `update-holesail-clients`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"domain":"example.tld","key":"hs://s00084bf...","port":8080,"serviceName":"web","protocol":"tcp"}' \
|
|
https://p2ns.admin/api/holesail-client-create
|
|
```
|
|
```json
|
|
{"id":"example.tld_web"}
|
|
```
|
|
|
|
### 36. POST /api/holesail-client-delete
|
|
- **Description**: Deletes a Holesail client by ID, closing connections and removing it from `holesail_clients.json`.
|
|
- **Request Body**: JSON with `id` (string).
|
|
- **Response**: Plain text `OK` on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to delete Holesail client.
|
|
- **WebSocket Broadcast**: `update-holesail-clients`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"id":"def456"}' \
|
|
https://p2ns.admin/api/holesail-client-delete
|
|
```
|
|
```text
|
|
OK
|
|
```
|
|
|
|
### 37. POST /api/holesail-client-restart
|
|
- **Description**: Restarts a Holesail client by ID, ensuring the port is free and connections are closed.
|
|
- **Request Body**: JSON with `id` (string).
|
|
- **Response**: Plain text `OK` on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to restart Holesail client.
|
|
- **WebSocket Broadcast**: `update-holesail-clients`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"id":"def456"}' \
|
|
https://p2ns.admin/api/holesail-client-restart
|
|
```
|
|
```text
|
|
OK
|
|
```
|
|
|
|
### 38. POST /api/update-settings
|
|
- **Description**: Updates environment settings (whitelisted variables) and persists them to `.env`. Note: `SUBNETS` can be updated here, but it's recommended to use `/api/subnets` for subnet management. `SUBNET_BASE` and `INITIAL_IP_INDEX` are deprecated in favor of the subnet configurator.
|
|
- **Request Body**: JSON with `settings` (object mapping whitelisted keys to values). For `SUBNETS`, provide a JSON array string.
|
|
- **Response**: JSON object with `message` (string), `restartRequired` (boolean), and optionally `restartRequiredSettings` (array of strings).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `400`: Validation failed (includes `errors` array).
|
|
- `500`: Failed to update settings.
|
|
- **WebSocket Broadcast**: `update-settings`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"settings":{"LOG_LEVEL":"1"}}' \
|
|
https://p2ns.admin/api/update-settings
|
|
```
|
|
```json
|
|
{
|
|
"message": "Settings saved and applied successfully.",
|
|
"restartRequired": false
|
|
}
|
|
```
|
|
|
|
### 39. GET /api/network-interfaces
|
|
- **Description**: Retrieves a list of available network interfaces on the system. Used by the admin interface to populate the Subnet Interface Name dropdown setting.
|
|
- **Response**: JSON object with `interfaces` (array of interface objects). Each interface object contains:
|
|
- `value` (string): Interface name (e.g., "lo0", "lo", "eth0")
|
|
- `label` (string): Display label for the interface (may include "(default)" for OS default)
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to fetch network interfaces.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/network-interfaces
|
|
```
|
|
```json
|
|
{
|
|
"interfaces": [
|
|
{ "value": "lo0", "label": "lo0" },
|
|
{ "value": "en0", "label": "en0" },
|
|
{ "value": "eth0", "label": "eth0" }
|
|
]
|
|
}
|
|
```
|
|
- **Note**: Interfaces are sorted with loopback interfaces (lo, lo0) and OS-specific defaults (lo0 on macOS, lo on Linux, Loopback Pseudo-Interface 1 on Windows) prioritized first.
|
|
|
|
### 40. GET /api/subnets
|
|
- **Description**: Retrieves all configured subnets with capacity information. Returns default subnet from `SUBNET_BASE` if no subnets are configured.
|
|
- **Response**: JSON object with `subnets` (array of subnet objects). Each subnet object contains:
|
|
- `base` (string): Network base IP address (e.g., "192.168.3.0")
|
|
- `cidr` (number): CIDR notation (1-32, e.g., 24)
|
|
- `startIndex` (number): First usable IP index (1-254)
|
|
- `name` (string): Subnet name/description
|
|
- `index` (number): Subnet index in array
|
|
- `available` (number): Total available IPs in subnet
|
|
- `used` (number): Currently used IPs
|
|
- `remaining` (number): Remaining available IPs
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to fetch subnets.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/subnets
|
|
```
|
|
```json
|
|
{
|
|
"subnets": [
|
|
{
|
|
"base": "192.168.3.0",
|
|
"cidr": 24,
|
|
"startIndex": 2,
|
|
"name": "Primary Subnet",
|
|
"index": 0,
|
|
"available": 253,
|
|
"used": 5,
|
|
"remaining": 248
|
|
},
|
|
{
|
|
"base": "10.0.0.0",
|
|
"cidr": 24,
|
|
"startIndex": 2,
|
|
"name": "Secondary Subnet",
|
|
"index": 1,
|
|
"available": 253,
|
|
"used": 0,
|
|
"remaining": 253
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### 41. POST /api/subnets
|
|
- **Description**: Updates subnet configuration. Replaces all existing subnets with the provided array. Changes require a system restart to fully take effect.
|
|
- **Request Body**: JSON object with `subnets` (array of subnet objects). Each subnet object must contain:
|
|
- `base` (string, required): Network base IP address (e.g., "192.168.3.0")
|
|
- `cidr` (number, required): CIDR notation (1-32, typically 24)
|
|
- `startIndex` (number, required): First usable IP index (1-254, typically 2)
|
|
- `name` (string, optional): Subnet name/description (defaults to "Subnet N" if not provided)
|
|
- **Response**: JSON object with `message` (string) and `restartRequired` (boolean, always true).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `400`: Validation failed (includes `error` string and `errors` array).
|
|
- `500`: Failed to update subnets.
|
|
- **WebSocket Broadcast**: `update-settings`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"subnets":[{"base":"192.168.3.0","cidr":24,"startIndex":2,"name":"Primary Subnet"},{"base":"10.0.0.0","cidr":24,"startIndex":2,"name":"Secondary Subnet"}]}' \
|
|
https://p2ns.admin/api/subnets
|
|
```
|
|
```json
|
|
{
|
|
"message": "Subnets updated. Restart required to fully apply changes.",
|
|
"restartRequired": true
|
|
}
|
|
```
|
|
- **Validation Rules**:
|
|
- `base` must be a valid IPv4 address (e.g., "192.168.3.0")
|
|
- `cidr` must be between 1 and 32
|
|
- `startIndex` must be between 1 and 254 (or up to subnet size - 2)
|
|
- Subnets must not overlap with each other
|
|
|
|
### 42. GET /api/health
|
|
- **Description**: Health check endpoint supporting liveness and readiness probes.
|
|
- **Query Parameters**:
|
|
- `probe`: Type of health probe (`liveness` or `readiness`, default: `liveness`).
|
|
- **Response**: JSON object with `status` (healthy/degraded/not_ready), `timestamp`, `uptime`, `probe`, `services` (object with DNS, proxy, swarm status), and `dependencies` (object with corestore, hyperswarm status).
|
|
- **Status Codes**:
|
|
- `200`: System is healthy.
|
|
- `503`: System is degraded or not ready.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/health
|
|
```
|
|
```json
|
|
{
|
|
"status": "healthy",
|
|
"timestamp": "2024-01-01T00:00:00.000Z",
|
|
"uptime": 3600000,
|
|
"probe": "liveness",
|
|
"services": {
|
|
"dns": { "enabled": true, "healthy": true, "initialized": true },
|
|
"proxy": { "enabled": true, "healthy": true },
|
|
"swarm": { "healthy": true }
|
|
},
|
|
"dependencies": {
|
|
"corestore": { "healthy": true },
|
|
"hyperswarm": { "healthy": true }
|
|
}
|
|
}
|
|
```
|
|
|
|
### 43. GET /api/stats
|
|
- **Description**: Retrieves a one-shot system metrics snapshot (same data shape as `stats-snapshot` over WebSocket). The admin UI loads this once, then uses `subscribe-stats` for live updates.
|
|
- **Response**: JSON object including:
|
|
- Request statistics (total, success rate, average response time, failed requests)
|
|
- Holesail children (servers, clients, P2P domain connections) with status, PID, uptime, CPU/memory usage
|
|
- `core` — Core control-plane / invite RPC diagnostics (`diagnoseInviteIssues`)
|
|
- `pluginRpc` and `peerChannels` — Per-plugin protomux-rpc protocol stats (`transport: 'rpc'`, methods, `rpcOpen` counts)
|
|
- HyperDB / Hyperdrive sections when available
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to fetch stats.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/stats
|
|
```
|
|
```json
|
|
{
|
|
"requests": {
|
|
"total": 1000,
|
|
"successful": 950,
|
|
"failed": 50,
|
|
"successRate": 0.95,
|
|
"avgResponseTime": 45
|
|
},
|
|
"holesailChildren": [
|
|
{
|
|
"id": "abc123",
|
|
"type": "server",
|
|
"status": "running",
|
|
"pid": 12345,
|
|
"uptime": 3600000,
|
|
"cpuUsage": { "percentage": 2.5 },
|
|
"memoryUsage": { "rss": 52428800 }
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### 44. GET /api/logs
|
|
- **Description**: Lists available split log channels written under `LOG_DIR` (default `./logs/`).
|
|
- **Response**: `{ "channels": [ { "id": "core", "label": "Core", "file": "core.log" }, ... ] }`
|
|
- **Status Codes**: `200`, `500`
|
|
- **Example**:
|
|
```bash
|
|
curl -k https://p2ns.admin/api/logs
|
|
```
|
|
|
|
### 45. GET /api/logs/:channel
|
|
- **Description**: Returns the tail of a log file (in-memory buffer with file fallback).
|
|
- **Path**: `channel` — `core`, `proxy`, `httpProxy`, `dns`, `plugins`, or `holesail`
|
|
- **Query**: `lines` — max lines (default `500`, max `5000`)
|
|
- **Response**: `{ "channel": "dns", "lines": ["..."] }`
|
|
- **Example**:
|
|
```bash
|
|
curl -k "https://p2ns.admin/api/logs/dns?lines=200"
|
|
```
|
|
|
|
### 46. GET /api/stats/historical
|
|
- **Description**: Retrieves historical metrics data for a specified time range.
|
|
- **Query Parameters**:
|
|
- `minutes`: Time range in minutes (1-1440, default: 60).
|
|
- **Response**: JSON object with historical metrics data including request trends, connection statistics, and system performance over time.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to fetch historical data.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
"https://p2ns.admin/api/stats/historical?minutes=1440"
|
|
```
|
|
|
|
### 47. GET /api/backups
|
|
- **Description**: Lists all available backups with metadata including name, timestamp, size, and file count.
|
|
- **Response**: JSON array of backup objects with `name`, `timestamp`, `size`, `sizeFormatted`, and `fileCount`.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to list backups.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/backups
|
|
```
|
|
```json
|
|
[
|
|
{
|
|
"name": "backup-20240101-000000",
|
|
"timestamp": "2024-01-01T00:00:00.000Z",
|
|
"size": 1048576,
|
|
"sizeFormatted": "1.00 MB",
|
|
"fileCount": 15
|
|
}
|
|
]
|
|
```
|
|
|
|
### 48. POST /api/backups/create
|
|
- **Description**: Creates a manual backup of configuration files, certificates, and cache data. Automatic cleanup of old backups is performed before creation.
|
|
- **Request Body**: None.
|
|
- **Response**: JSON object with `success` (boolean) and `path` (string, backup file path).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to create backup.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
https://p2ns.admin/api/backups/create
|
|
```
|
|
```json
|
|
{
|
|
"success": true,
|
|
"path": "./backups/backup-20240101-000000.tar.gz"
|
|
}
|
|
```
|
|
|
|
### 49. POST /api/backups/restore
|
|
- **Description**: Restores system configuration from a backup. Replaces current configuration files and certificates.
|
|
- **Request Body**: JSON with `backupName` (string, backup name to restore).
|
|
- **Response**: JSON object with `success` (boolean) and `message` (string).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `400`: Invalid request (missing backupName).
|
|
- `500`: Failed to restore backup.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"backupName":"backup-20240101-000000"}' \
|
|
https://p2ns.admin/api/backups/restore
|
|
```
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Backup restored successfully"
|
|
}
|
|
```
|
|
|
|
### 50. DELETE /api/backups/:id
|
|
- **Description**: Deletes a backup by name. Supports both directory and tar.gz formats.
|
|
- **Path Parameters**:
|
|
- `id`: Backup name (e.g., `backup-20240101-000000` or `backup-20240101-000000.tar.gz`).
|
|
- **Response**: JSON object with `success` (boolean) and `message` (string).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `400`: Invalid backup name.
|
|
- `500`: Failed to delete backup.
|
|
- **Example**:
|
|
```bash
|
|
curl -X DELETE \
|
|
https://p2ns.admin/api/backups/backup-20240101-000000
|
|
```
|
|
|
|
### 51. GET /api/backups/:id/metadata
|
|
- **Description**: Retrieves detailed metadata for a backup including file list, sizes, and timestamps.
|
|
- **Path Parameters**:
|
|
- `id`: Backup name.
|
|
- **Response**: JSON object with backup metadata including `timestamp`, `files` (array with name, size, sizeFormatted, modified), and other metadata.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `404`: Backup not found.
|
|
- `500`: Failed to get backup metadata.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/backups/backup-20240101-000000/metadata
|
|
```
|
|
|
|
### 52. POST /api/diagnostics/dns-lookup
|
|
- **Description**: Performs DNS lookup for a domain with specified record type.
|
|
- **Request Body**: JSON with `domain` (string, required) and `type` (string, optional, default: `A`). Supported types: A, AAAA, MX, TXT, NS, CNAME, SRV, PTR, SOA.
|
|
- **Response**: JSON object with `success` (boolean), `domain`, `type`, `results` (array), and `responseTime` (number).
|
|
- **Status Codes**:
|
|
- `200`: Success (includes both successful and failed lookups).
|
|
- `400`: Invalid request (missing domain).
|
|
- `500`: Server error.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"domain":"example.com","type":"A"}' \
|
|
https://p2ns.admin/api/diagnostics/dns-lookup
|
|
```
|
|
```json
|
|
{
|
|
"success": true,
|
|
"domain": "example.com",
|
|
"type": "A",
|
|
"results": ["93.184.216.34"],
|
|
"responseTime": 25
|
|
}
|
|
```
|
|
|
|
### 53. POST /api/diagnostics/ping
|
|
- **Description**: Tests network connectivity using ping. Supports both streaming and non-streaming modes.
|
|
- **Request Body**: JSON with `target` (string, required), `count` (number, optional, default: 4), and `stream` (boolean, optional, default: false).
|
|
- **Response**:
|
|
- **Non-streaming**: JSON object with `success`, `target`, `count`, `output`, `error`, and `responseTime`.
|
|
- **Streaming**: NDJSON stream with `type` (output/error/complete), `data`, `timestamp`, and completion status.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `400`: Invalid request (missing target).
|
|
- `500`: Server error.
|
|
- **Example** (non-streaming):
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"target":"8.8.8.8","count":4}' \
|
|
https://p2ns.admin/api/diagnostics/ping
|
|
```
|
|
- **Example** (streaming):
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"target":"8.8.8.8","count":4,"stream":true}' \
|
|
https://p2ns.admin/api/diagnostics/ping
|
|
```
|
|
|
|
### 54. POST /api/diagnostics/traceroute
|
|
- **Description**: Traces network path to a target. Supports both streaming and non-streaming modes.
|
|
- **Request Body**: JSON with `target` (string, required) and `stream` (boolean, optional, default: false).
|
|
- **Response**:
|
|
- **Non-streaming**: JSON object with `success`, `target`, `output`, `error`, and `responseTime`.
|
|
- **Streaming**: NDJSON stream with `type` (output/error/complete), `data`, `timestamp`, and completion status.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `400`: Invalid request (missing target).
|
|
- `500`: Server error.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"target":"8.8.8.8","stream":true}' \
|
|
https://p2ns.admin/api/diagnostics/traceroute
|
|
```
|
|
|
|
### 55. POST /api/diagnostics/connection-test
|
|
- **Description**: Tests TCP connectivity to a domain and port combination.
|
|
- **Request Body**: JSON with `domain` (string, required) and `port` (number, required).
|
|
- **Response**: JSON object with `success` (boolean), `domain`, `ip` (resolved IP), `port`, `latency` (if successful), `error` (if failed), and `responseTime`.
|
|
- **Status Codes**:
|
|
- `200`: Success (includes both successful and failed tests).
|
|
- `400`: Invalid request (missing domain or port).
|
|
- `500`: Server error.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"domain":"example.com","port":443}' \
|
|
https://p2ns.admin/api/diagnostics/connection-test
|
|
```
|
|
```json
|
|
{
|
|
"success": true,
|
|
"domain": "example.com",
|
|
"ip": "93.184.216.34",
|
|
"port": 443,
|
|
"latency": 45,
|
|
"responseTime": 50
|
|
}
|
|
```
|
|
|
|
### 56. GET /api/diagnostics/bandwidth
|
|
- **Description**: Network interface information and configuration. Real-time throughput stats are not available via Node.js; response is interface layout only.
|
|
- **Response**: JSON with `interfaces`, optional `note`, `responseTime`.
|
|
- **Status Codes**: `200`, `500`
|
|
- **Example**:
|
|
```bash
|
|
curl -k https://p2ns.admin/api/diagnostics/bandwidth
|
|
```
|
|
|
|
### 57. GET /api/diagnostics/invites
|
|
- **Description**: Core invite / control-plane diagnostics over `p2ns.core-request-rpc` (`invite.request`, `invite.deliver`, `invite.ack`, `core.status`). Used by the Stats **Core** section and Invite Diagnostics UI.
|
|
- **Response**: JSON with `summary` (dnsPass, rpcOpen, requestChannelOpen, failed peers, …), `peers`, `recommendations`, `connectionIssues`, etc.
|
|
- **Status Codes**: `200`, `503` (still initializing), `500`
|
|
- **Example**:
|
|
```bash
|
|
curl -k https://p2ns.admin/api/diagnostics/invites
|
|
```
|
|
|
|
### 58. GET /<tab>
|
|
- **Description**: Redirects to the admin panel with the specified tab (e.g., `/domains`, `/host`, `/local-dns`) open.
|
|
- **Path Parameters**:
|
|
- `tab`: One of `domains`, `host`, `local-dns`, `entries`, `peers`, `certs`, `interfaces`, `logs`, `settings`.
|
|
- **Response**: HTTP redirect to `/#<tab>`.
|
|
- **Status Codes**:
|
|
- `302`: Redirect.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
-L \
|
|
https://p2ns.admin/domains
|
|
```
|
|
|
|
### 59. GET /favicon.ico
|
|
- **Description**: Returns a 404 response (favicon not implemented).
|
|
- **Response**: Plain text `Not Found`.
|
|
- **Status Codes**:
|
|
- `404`: Not found.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/favicon.ico
|
|
```
|
|
```text
|
|
Not Found
|
|
```
|
|
|
|
## Consensus Endpoints
|
|
|
|
### 60. GET /api/consensus/:domain
|
|
- **Description**: Retrieves the consensus state for a specific domain, including vote counts, quorum status, and resolution information.
|
|
- **Path Parameters**:
|
|
- `domain`: The domain name (e.g., `example.tld`).
|
|
- **Response**: JSON object with:
|
|
- `status` (string): Consensus status (`resolved`, `insufficient_quorum`, `tie`, `no_claims`, `error`).
|
|
- `hash` (string|null): Resolved Holesail hash if status is `resolved`, otherwise `null`.
|
|
- `resolvedClaimant` (string|null): Public key of the winning claimant if resolved, otherwise `null`.
|
|
- `voteCounts` (object): Mapping of claimant public keys to their vote counts.
|
|
- `activePeers` (number): Number of active peers in the network (including local node).
|
|
- `quorumMet` (boolean): Whether the quorum threshold has been met.
|
|
- `minVotes` (number): Minimum votes required to meet quorum.
|
|
- `totalVotes` (number): Total number of votes cast for all claimants.
|
|
- `lastResolution` (number|null): Timestamp of last resolution, or `null` if never resolved.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to get consensus state.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/consensus/example.tld
|
|
```
|
|
```json
|
|
{
|
|
"status": "resolved",
|
|
"hash": "hs://s00084bf87dfa89a3048fb081c0e6207eb5a",
|
|
"resolvedClaimant": "abc123def456...",
|
|
"voteCounts": {
|
|
"abc123def456...": 3,
|
|
"ghi789jkl012...": 1
|
|
},
|
|
"activePeers": 5,
|
|
"quorumMet": true,
|
|
"minVotes": 3,
|
|
"totalVotes": 4,
|
|
"lastResolution": 1704067200000
|
|
}
|
|
```
|
|
|
|
### GET /api/consensus/status
|
|
- **Description**: Returns health and progress of the consensus Autobase sidecar (the sole read path for `getConsensusState`).
|
|
- **Response**: JSON object with:
|
|
- `open` (boolean): Whether the sidecar Autobase instance is open.
|
|
- `ready` (boolean): Whether the sidecar has completed opening.
|
|
- `writable` (boolean): Whether this node can append sidecar events.
|
|
- `bootstrapComplete` (boolean): Whether bootstrap or hydration from dnsPass has finished.
|
|
- `eventCount` (number): Total events applied to the in-memory view.
|
|
- `domainCount` (number): Domains present in the apply view.
|
|
- `lastApplyAt` (number|null): Timestamp of the last applied event.
|
|
- `indexedLength` (number): Autobase indexed length.
|
|
- `length` (number): Autobase length.
|
|
- `key` (string|null): Sidecar public key (hex).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to get consensus status.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/consensus/status
|
|
```
|
|
```json
|
|
{
|
|
"open": true,
|
|
"ready": true,
|
|
"writable": true,
|
|
"bootstrapComplete": true,
|
|
"eventCount": 142,
|
|
"domainCount": 12,
|
|
"lastApplyAt": 1704067200000,
|
|
"indexedLength": 142,
|
|
"length": 142,
|
|
"key": "a1b2c3..."
|
|
}
|
|
```
|
|
|
|
### 61. GET /api/consensus/metrics
|
|
- **Description**: Retrieves overall consensus metrics including resolution statistics, quorum failures, ties, validation failures, and sidecar health.
|
|
- **Response**: JSON object with:
|
|
- `resolutions` (number): Total number of successful domain resolutions.
|
|
- `quorumFailures` (number): Number of times quorum was not met.
|
|
- `ties` (number): Number of ties that required tie-breaking.
|
|
- `validationFailures` (number): Number of invalid votes that were rejected.
|
|
- `totalVotes` (number): Total number of votes cast across all domains.
|
|
- `avgVotesPerDomain` (number): Average number of votes per domain.
|
|
- `domainResolutions` (array): Per-domain resolution statistics with `domain`, `resolved` count, and `failed` count.
|
|
- `sidecar` (object): Same fields as `GET /api/consensus/status`.
|
|
- `bootstrapComplete` (boolean): Whether sidecar bootstrap/hydration is complete.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to get consensus metrics.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/consensus/metrics
|
|
```
|
|
```json
|
|
{
|
|
"resolutions": 42,
|
|
"quorumFailures": 3,
|
|
"ties": 2,
|
|
"validationFailures": 1,
|
|
"totalVotes": 156,
|
|
"avgVotesPerDomain": 3.71,
|
|
"domainResolutions": [
|
|
{
|
|
"domain": "example.tld",
|
|
"resolved": 5,
|
|
"failed": 0
|
|
},
|
|
{
|
|
"domain": "another.tld",
|
|
"resolved": 3,
|
|
"failed": 1
|
|
}
|
|
],
|
|
"sidecar": {
|
|
"open": true,
|
|
"ready": true,
|
|
"writable": true,
|
|
"bootstrapComplete": true,
|
|
"eventCount": 142,
|
|
"domainCount": 12,
|
|
"lastApplyAt": 1704067200000,
|
|
"indexedLength": 142,
|
|
"length": 142,
|
|
"key": "a1b2c3..."
|
|
},
|
|
"bootstrapComplete": true
|
|
}
|
|
```
|
|
|
|
### 62. POST /api/consensus/recalculate
|
|
- **Description**: Forces a consensus recalculation for all domains. Invalidates the consensus cache and triggers auto-voting checks.
|
|
- **Request Body**: None.
|
|
- **Response**: JSON object with `success` (boolean) and `message` (string).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to recalculate consensus.
|
|
- **WebSocket Broadcast**: `update-database` (triggers refresh of domains and entries).
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
https://p2ns.admin/api/consensus/recalculate
|
|
```
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Consensus recalculation triggered"
|
|
}
|
|
```
|
|
|
|
### 63. POST /api/consensus/recalculate/:domain
|
|
- **Description**: Forces a consensus recalculation for a specific domain. Invalidates the consensus cache for that domain and triggers auto-voting.
|
|
- **Path Parameters**:
|
|
- `domain`: The domain name (e.g., `example.tld`).
|
|
- **Request Body**: None.
|
|
- **Response**: JSON object with `success` (boolean) and `message` (string).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to recalculate consensus for domain.
|
|
- **WebSocket Broadcast**: `update-database` (triggers refresh of domains and entries).
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
https://p2ns.admin/api/consensus/recalculate/example.tld
|
|
```
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Consensus recalculation triggered for example.tld"
|
|
}
|
|
```
|
|
|
|
## Service Subscription Endpoints
|
|
|
|
### 64. GET /api/domain-services
|
|
- **Description**: Retrieves all services configured for a specific domain from its claim record.
|
|
- **Query Parameters**:
|
|
- `domain` (string, required): The domain name to query services for.
|
|
- **Response**: JSON array of service objects, each containing:
|
|
- `serviceName` (string): Service identifier
|
|
- `key` (string): Holesail connection hash
|
|
- `port` (number): Port number
|
|
- `protocol` (string): Protocol type (`tcp` or `udp`)
|
|
- **Status Codes**:
|
|
- `200`: Success (returns empty array if domain has no services or is not resolved).
|
|
- `400`: Missing domain parameter.
|
|
- `500`: Failed to fetch domain services.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
"https://p2ns.admin/api/domain-services?domain=example.tld"
|
|
```
|
|
```json
|
|
[
|
|
{
|
|
"serviceName": "web",
|
|
"key": "hs://s00084bf87dfa89a3048fb081c0e6207eb5a",
|
|
"port": 8080,
|
|
"protocol": "tcp"
|
|
},
|
|
{
|
|
"serviceName": "api",
|
|
"key": "hs://s000bcc379b38f6d3a5cb4cfde23fa52392d",
|
|
"port": 9090,
|
|
"protocol": "tcp"
|
|
}
|
|
]
|
|
```
|
|
|
|
### 65. GET /api/service-subscriptions
|
|
- **Description**: Lists all service subscriptions configured on this node.
|
|
- **Response**: JSON array of subscription objects, each containing:
|
|
- `domain` (string): Domain name
|
|
- `serviceName` (string): Service identifier
|
|
- `key` (string): Holesail connection hash
|
|
- `port` (number): Port number
|
|
- `protocol` (string): Protocol type (`tcp` or `udp`)
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to fetch subscriptions.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/service-subscriptions
|
|
```
|
|
```json
|
|
[
|
|
{
|
|
"domain": "example.tld",
|
|
"serviceName": "web",
|
|
"key": "hs://s00084bf87dfa89a3048fb081c0e6207eb5a",
|
|
"port": 8080,
|
|
"protocol": "tcp"
|
|
}
|
|
]
|
|
```
|
|
|
|
### 66. GET /api/subscribe-all-domains
|
|
- **Description**: Lists all domains for which "subscribe all" is enabled. When enabled, the system automatically subscribes to all services for that domain, including newly added services.
|
|
- **Response**: JSON array of domain names (strings).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to fetch subscribe-all domains.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/subscribe-all-domains
|
|
```
|
|
```json
|
|
["example.tld", "another.tld"]
|
|
```
|
|
|
|
### 67. POST /api/service-subscribe
|
|
- **Description**: Subscribes to a specific service from a domain. Creates a Holesail client automatically with ID `domain_servicename` and persists the subscription to `subscriptions.json`.
|
|
- **Request Body**: JSON with:
|
|
- `domain` (string, required): Domain name
|
|
- `serviceName` (string, required): Service identifier
|
|
- `key` (string, required): Holesail connection hash
|
|
- `port` (number, required): Port number
|
|
- `protocol` (string, optional): Protocol type (`tcp` or `udp`, default: `tcp`)
|
|
- **Response**: JSON with `success` (boolean) on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `400`: Missing required fields.
|
|
- `409`: Already subscribed to this service.
|
|
- `500`: Failed to subscribe.
|
|
- **WebSocket Broadcast**: `update-holesail-clients`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"domain":"example.tld","serviceName":"web","key":"hs://s00084bf...","port":8080,"protocol":"tcp"}' \
|
|
https://p2ns.admin/api/service-subscribe
|
|
```
|
|
```json
|
|
{"success": true}
|
|
```
|
|
|
|
### 68. POST /api/service-unsubscribe
|
|
- **Description**: Unsubscribes from a specific service. Deletes the associated Holesail client and removes the subscription from `subscriptions.json`.
|
|
- **Request Body**: JSON with:
|
|
- `domain` (string, required): Domain name
|
|
- `serviceName` (string, required): Service identifier
|
|
- **Response**: JSON with `success` (boolean) on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `400`: Missing required fields.
|
|
- `404`: Subscription not found.
|
|
- `500`: Failed to unsubscribe.
|
|
- **WebSocket Broadcast**: `update-holesail-clients`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"domain":"example.tld","serviceName":"web"}' \
|
|
https://p2ns.admin/api/service-unsubscribe
|
|
```
|
|
```json
|
|
{"success": true}
|
|
```
|
|
|
|
### 69. POST /api/subscribe-all
|
|
- **Description**: Enables "subscribe all" for a domain. This automatically subscribes to all current services for that domain and will automatically subscribe to any new services added in the future. Creates Holesail clients for all existing services.
|
|
- **Request Body**: JSON with:
|
|
- `domain` (string, required): Domain name
|
|
- **Response**: JSON with `success` (boolean) on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `400`: Missing domain field.
|
|
- `500`: Failed to set subscribe-all.
|
|
- **WebSocket Broadcast**: `update-holesail-clients`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"domain":"example.tld"}' \
|
|
https://p2ns.admin/api/subscribe-all
|
|
```
|
|
```json
|
|
{"success": true}
|
|
```
|
|
|
|
### 70. POST /api/unsubscribe-all
|
|
- **Description**: Disables "subscribe all" for a domain and unsubscribes from all services for that domain. Deletes all associated Holesail clients.
|
|
- **Request Body**: JSON with:
|
|
- `domain` (string, required): Domain name
|
|
- **Response**: JSON with `success` (boolean) on success, error message on failure.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `400`: Missing domain field.
|
|
- `500`: Failed to clear subscribe-all.
|
|
- **WebSocket Broadcast**: `update-holesail-clients`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"domain":"example.tld"}' \
|
|
https://p2ns.admin/api/unsubscribe-all
|
|
```
|
|
```json
|
|
{"success": true}
|
|
```
|
|
|
|
## Plugin Management Endpoints
|
|
|
|
**Note:** For detailed information about the plugin system, see [plugins/README.md](plugins/README.md) and [plugins/PLUGIN_SDK.md](plugins/PLUGIN_SDK.md).
|
|
|
|
### 71. GET /api/plugins
|
|
- **Description**: Lists all plugins with their information, status, actions, and settings. Includes both loaded and stopped plugins.
|
|
- **Response**: JSON object with `plugins` (array of plugin objects). Each plugin object contains:
|
|
- `domain` (string): Plugin domain name
|
|
- `name` (string): Plugin name from config.json
|
|
- `version` (string): Plugin version
|
|
- `description` (string): Plugin description
|
|
- `author` (string): Plugin author
|
|
- `homepage` (string): Plugin homepage URL
|
|
- `license` (string): Plugin license
|
|
- `status` (string): Plugin status (`loaded`, `stopped`, or `static`)
|
|
- `hasHandler` (boolean): Whether plugin has a handler function
|
|
- `hasWww` (boolean): Whether plugin has a www directory
|
|
- `hasDatabase` (boolean): Whether plugin has HyperDB configured
|
|
- `actions` (array): Array of registered action objects
|
|
- `settings` (object): Map of registered settings with their current values
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to list plugins.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/plugins
|
|
```
|
|
```json
|
|
{
|
|
"plugins": [
|
|
{
|
|
"domain": "example.plugin",
|
|
"name": "Example Plugin",
|
|
"version": "1.0.0",
|
|
"description": "A template plugin",
|
|
"author": "P2NS",
|
|
"homepage": "https://example.com",
|
|
"license": "MIT",
|
|
"status": "loaded",
|
|
"hasHandler": true,
|
|
"hasWww": true,
|
|
"hasDatabase": false,
|
|
"actions": [
|
|
{
|
|
"name": "testAction",
|
|
"label": "Test Action",
|
|
"description": "A test action",
|
|
"icon": "🧪"
|
|
}
|
|
],
|
|
"settings": {
|
|
"maxItems": {
|
|
"type": "number",
|
|
"label": "Maximum Items",
|
|
"description": "Maximum number of items",
|
|
"default": 100,
|
|
"value": 100
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### 72. GET /api/plugins/:domain
|
|
- **Description**: Retrieves detailed information for a specific plugin.
|
|
- **Path Parameters**:
|
|
- `domain`: The plugin domain name (e.g., `example.plugin`).
|
|
- **Response**: JSON object with plugin information (same structure as plugin object in GET /api/plugins).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `404`: Plugin not found.
|
|
- `500`: Failed to get plugin info.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://p2ns.admin/api/plugins/example.plugin
|
|
```
|
|
|
|
### 73. POST /api/plugins/:domain/start
|
|
- **Description**: Starts a stopped plugin. Loads the plugin handler and initializes resources.
|
|
- **Path Parameters**:
|
|
- `domain`: The plugin domain name (e.g., `example.plugin`).
|
|
- **Request Body**: None.
|
|
- **Response**: JSON object with `success` (boolean), `message` (string), and `domain` (string).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `400`: Invalid domain parameter.
|
|
- `500`: Failed to start plugin.
|
|
- **WebSocket Broadcast**: `update-plugins`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
https://p2ns.admin/api/plugins/example.plugin/start
|
|
```
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Plugin example.plugin started successfully",
|
|
"domain": "example.plugin"
|
|
}
|
|
```
|
|
|
|
### 74. POST /api/plugins/:domain/stop
|
|
- **Description**: Stops a running plugin. Unloads the plugin handler and cleans up resources.
|
|
- **Path Parameters**:
|
|
- `domain`: The plugin domain name (e.g., `example.plugin`).
|
|
- **Request Body**: None.
|
|
- **Response**: JSON object with `success` (boolean), `message` (string), and `domain` (string).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `400`: Invalid domain parameter.
|
|
- `500`: Failed to stop plugin.
|
|
- **WebSocket Broadcast**: `update-plugins`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
https://p2ns.admin/api/plugins/example.plugin/stop
|
|
```
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Plugin example.plugin stopped successfully",
|
|
"domain": "example.plugin"
|
|
}
|
|
```
|
|
|
|
### 75. POST /api/plugins/:domain/reload
|
|
- **Description**: Reloads a plugin. Stops the plugin, clears the module cache, and starts it again. Useful for applying code changes without restarting P2NS.
|
|
- **Path Parameters**:
|
|
- `domain`: The plugin domain name (e.g., `example.plugin`).
|
|
- **Request Body**: None.
|
|
- **Response**: JSON object with `success` (boolean), `message` (string), and `domain` (string).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `400`: Invalid domain parameter.
|
|
- `500`: Failed to reload plugin.
|
|
- **WebSocket Broadcast**: `update-plugins`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
https://p2ns.admin/api/plugins/example.plugin/reload
|
|
```
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Plugin example.plugin reloaded successfully",
|
|
"domain": "example.plugin"
|
|
}
|
|
```
|
|
|
|
### 76. POST /api/plugins/:domain/actions/:actionName
|
|
- **Description**: Executes a registered plugin action. The action handler is called with the provided parameters.
|
|
- **Path Parameters**:
|
|
- `domain`: The plugin domain name (e.g., `example.plugin`).
|
|
- `actionName`: The action name (e.g., `testAction`).
|
|
- **Request Body**: JSON object with action parameters (optional).
|
|
- **Response**: JSON object with `success` (boolean) and `result` (any) containing the action handler's return value.
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `400`: Invalid request path.
|
|
- `404`: Plugin or action not found.
|
|
- `500`: Action execution failed.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"value": 10}' \
|
|
https://p2ns.admin/api/plugins/example.plugin/actions/testAction
|
|
```
|
|
```json
|
|
{
|
|
"success": true,
|
|
"result": {
|
|
"success": true,
|
|
"message": "Test action executed successfully!",
|
|
"timestamp": "2025-12-12T10:00:00.000Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
### 77. POST /api/plugins/:domain/settings
|
|
- **Description**: Updates plugin settings. Saves settings to `cache/plugin-settings/{domain}.json` and persists them across plugin restarts.
|
|
- **Path Parameters**:
|
|
- `domain`: The plugin domain name (e.g., `example.plugin`).
|
|
- **Request Body**: JSON object mapping setting keys to values.
|
|
- **Response**: JSON object with `success` (boolean) and `message` (string).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `400`: Invalid domain parameter.
|
|
- `500`: Failed to update settings.
|
|
- **WebSocket Broadcast**: `update-plugin-settings`.
|
|
- **Example**:
|
|
```bash
|
|
curl -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"maxItems": 200, "enableFeature": true}' \
|
|
https://p2ns.admin/api/plugins/example.plugin/settings
|
|
```
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Settings updated for plugin example.plugin"
|
|
}
|
|
```
|
|
|
|
### 78. GET /api/token
|
|
- **Description**: Generates a signed Ed25519 authentication token for plugin authentication. Available to all plugins globally.
|
|
- **Request Headers**: None required.
|
|
- **Response**: JSON object with `token` (string), `expiresAt` (number), and `peerId` (string).
|
|
- **Status Codes**:
|
|
- `200`: Success.
|
|
- `500`: Failed to generate token.
|
|
- **Example**:
|
|
```bash
|
|
curl -X GET \
|
|
https://global.profile/api/token
|
|
```
|
|
```json
|
|
{
|
|
"token": "eyJwZWVySWQiOiIxMjM0NTY3ODkwYWJjZGVmZ2hpamsuLi4iLCJ0aW1lc3RhbXAiOjE2ODk...",
|
|
"expiresAt": 1689123456789,
|
|
"peerId": "1234567890abcdef..."
|
|
}
|
|
```
|
|
- **Notes**:
|
|
- Tokens expire after 1 hour (3600 seconds) by default.
|
|
- Tokens are signed with Ed25519 using the local peer's private key.
|
|
- Use the token in the `Authorization: Bearer <token>` header for authenticated requests.
|
|
- The `X-Auth-Token` header is also supported as an alternative.
|
|
|
|
## Authentication
|
|
|
|
Plugin write operations (POST, PUT, DELETE, PATCH) require authentication using Ed25519-signed tokens.
|
|
|
|
### Authentication Headers
|
|
|
|
**Authorization Header (Preferred):**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Alternative Header:**
|
|
```
|
|
X-Auth-Token: <token>
|
|
```
|
|
|
|
### Error Responses
|
|
|
|
**401 Unauthorized:**
|
|
```json
|
|
{
|
|
"error": "Authentication required",
|
|
"message": "Invalid or missing authentication token"
|
|
}
|
|
```
|
|
|
|
**403 Forbidden:**
|
|
```json
|
|
{
|
|
"error": "Forbidden",
|
|
"message": "Only the local peer can perform this operation"
|
|
}
|
|
```
|
|
|
|
### Token Format
|
|
|
|
Tokens are base64-encoded JSON objects containing:
|
|
- `peerId`: The public key (hex string) of the authenticated peer
|
|
- `timestamp`: Token creation timestamp (milliseconds)
|
|
- `expiresAt`: Token expiration timestamp (milliseconds)
|
|
- `signature`: Ed25519 signature (hex string) of the token payload
|
|
|
|
### Frontend Integration
|
|
|
|
Include the authentication utilities script:
|
|
```html
|
|
<script src="/auth-utils.js"></script>
|
|
```
|
|
|
|
Use `authenticatedFetch()` for write operations:
|
|
```javascript
|
|
const response = await authenticatedFetch('/api/data', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({ data: 'value' })
|
|
});
|
|
```
|
|
|
|
See [plugins/PLUGIN_SDK.md](plugins/PLUGIN_SDK.md#authentication-and-authorization) for complete authentication API documentation.
|
|
|
|
## Security Notes
|
|
- **Plugin Authentication**: Write operations in plugins require Ed25519-signed tokens. See [Authentication](#authentication) section above.
|
|
- **No Authentication**: Admin endpoints are unauthenticated, so restrict access to trusted networks or users in production.
|
|
- **HTTPS**: Use HTTPS to protect data in transit.
|
|
- **Input Validation**: Ensure inputs (e.g., domain names, DNS record fields) are sanitized to prevent injection attacks.
|
|
- **Permissions**: `selector_cache.json`, `domains.json`, `local_dns.json`, `holesail_servers.json`, `holesail_clients.json`, and `subscriptions.json` should have restricted permissions to prevent unauthorized modifications.
|
|
|
|
## Testing
|
|
- Use tools like `curl` or Postman to test endpoints.
|
|
- Verify WebSocket updates using a WebSocket client (e.g., `wscat`).
|
|
- Test DNS record creation with various types (e.g., SRV, SOA) and check `local_dns.json`.
|
|
- Monitor logs in the admin **Logs** tab (`subscribe-log` per channel) or `GET /api/logs/:channel`; plugin logs use `plugin-log` WebSocket messages. |