@com55/node-red-ai-access 0.2.0-beta.2 → 0.2.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +61 -1
- package/README.md +100 -75
- package/ai-access.html +1 -1
- package/dist/plugin.cjs +957 -650
- package/dist/plugin.d.cts +9 -2
- package/docs/README.md +2 -2
- package/docs/api/openapi.yaml +5 -5
- package/docs/errors.md +2 -2
- package/docs/mcp-clients.md +16 -15
- package/docs/mcp-tools.md +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,7 +6,67 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
6
6
|
and this project adheres to
|
|
7
7
|
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## [0.2.0-beta.3] - 2026-10-28
|
|
10
|
+
|
|
11
|
+
### Breaking
|
|
12
|
+
|
|
13
|
+
- **Dashboard moved from `<httpAdminRoot>/mcp` to `<httpAdminRoot>/ai-access`.**
|
|
14
|
+
Browser `GET /mcp` (anything that is not an MCP `text/event-stream` request)
|
|
15
|
+
now answers `302` → `/ai-access`; MCP traffic on `/mcp` and `/mcp/rpc` (OAuth
|
|
16
|
+
resource, ChatGPT/Claude) is unchanged. Proposal `reviewPath` / `reviewUrl`,
|
|
17
|
+
`accessLinksUrl`, settings `mcpPageUrl`, error hints and docs now point at
|
|
18
|
+
`/ai-access` (`#proposal=<id>`, `#links`). Old dashboard URLs and bookmarks
|
|
19
|
+
(`<httpAdminRoot>/mcp`, including `#proposal=<id>` / `#links` fragments) keep
|
|
20
|
+
working through the redirect (browsers carry the fragment across a `302`), but
|
|
21
|
+
update bookmarks to `/ai-access`: the redirect is only for browsers and `/mcp`
|
|
22
|
+
is the MCP endpoint.
|
|
23
|
+
- **Settings moved out of the editor sidebar.** The sidebar now holds only the
|
|
24
|
+
Enable AI Access toggle (or the local-only opt-in without adminAuth), the
|
|
25
|
+
Enable MCP OAuth toggle, the OAuth route-conflict warning (with reveal links,
|
|
26
|
+
shown only when conflicts exist) and an "Open AI Access dashboard" button.
|
|
27
|
+
Public URL + check, CORS, rate limits, trust proxy, default deploy type,
|
|
28
|
+
default token expiry, max active tokens, OAuth lifetimes / max clients,
|
|
29
|
+
registered OAuth clients + revoke and the pending-proposal counter moved to
|
|
30
|
+
the dashboard. Permission checks are unchanged (writes need `*`).
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
|
|
34
|
+
- Dashboard redesign: top tabs Overview, Settings, Access tokens, OAuth,
|
|
35
|
+
Proposals, Audit log; card layout, number + unit inputs on one line, prominent
|
|
36
|
+
Public URL check result, responsive, dark-mode aware (`prefers-color-scheme`),
|
|
37
|
+
no external assets. Hash aliases `#overview`, `#tokens`, plus `#settings` and
|
|
38
|
+
`#oauth`.
|
|
39
|
+
- OAuth tab collision list links `http in` nodes to the editor
|
|
40
|
+
(`<httpAdminRoot>/#node/<id>`, falling back to `#flow/<tabId>`); collision
|
|
41
|
+
details now include `flowId`.
|
|
42
|
+
|
|
43
|
+
### Fixed
|
|
44
|
+
|
|
45
|
+
- MCP OAuth with ChatGPT: "Authentication succeeded, action discovery failed".
|
|
46
|
+
The OAuth protected resource (and the URL users add in ChatGPT/Claude) is
|
|
47
|
+
`<Public URL>/mcp`, but MCP was only served at `/mcp/rpc`, so the
|
|
48
|
+
authenticated `POST /mcp` returned 404. `/mcp` now also serves MCP Streamable
|
|
49
|
+
HTTP (POST; SSE `GET`/`DELETE` answer 405 like `/mcp/rpc`, and the same 401 +
|
|
50
|
+
`resource_metadata` challenge). Browsers opening `/mcp` still get the
|
|
51
|
+
dashboard.
|
|
52
|
+
|
|
53
|
+
- Editor sidebar: Revoke for registered OAuth clients appeared to do nothing
|
|
54
|
+
because its confirm dialog rendered at the top of the scrolled settings panel
|
|
55
|
+
(out of view). The dialog now overlays the whole tab.
|
|
56
|
+
|
|
57
|
+
### Changed
|
|
58
|
+
|
|
59
|
+
- Default "Maximum registered OAuth clients" (`oauth.dcrMaxClients`) is now 5
|
|
60
|
+
(was 20). Upgrading with more than 5 approved clients removes none of them:
|
|
61
|
+
existing clients keep working, but new registrations get `400` (Maximum active
|
|
62
|
+
OAuth clients reached) until clients are revoked below the limit or the limit
|
|
63
|
+
is raised.
|
|
64
|
+
- At most 25 OAuth clients may await consent at once (was 100).
|
|
65
|
+
- AI-facing CORS policy now also covers `/mcp`.
|
|
66
|
+
- Redesigned OAuth consent page: branded card, redirect host first, permission
|
|
67
|
+
list with descriptions, signed-in user, prominent Allow / secondary Deny,
|
|
68
|
+
responsive and dark-mode friendly, no external assets. When signed out with
|
|
69
|
+
credentials login, the page shows an inline sign-in form in the same style.
|
|
10
70
|
|
|
11
71
|
## [0.2.0-beta.2] - 2026-10-28
|
|
12
72
|
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
Temporary, owner-approved Node-RED access for AI clients. Ships as a **Node-RED
|
|
9
9
|
4.x+ plugin** with:
|
|
10
10
|
|
|
11
|
-
- an admin
|
|
11
|
+
- an admin dashboard at `/ai-access` (browser `GET /mcp` redirects there)
|
|
12
12
|
- a versioned REST API under `/mcp/api/v1`
|
|
13
13
|
- an MCP JSON-RPC endpoint at `/mcp/rpc` (Streamable HTTP) over the same
|
|
14
14
|
services
|
|
@@ -37,21 +37,24 @@ Configuration).
|
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
2. Restart Node-RED.
|
|
40
|
-
3. Log in to the editor, then open **`/
|
|
41
|
-
`http://localhost:1880/
|
|
42
|
-
set)
|
|
40
|
+
3. Log in to the editor, then open **`/ai-access`** on the admin root (for
|
|
41
|
+
example `http://localhost:1880/ai-access`, or `{httpAdminRoot}/ai-access`
|
|
42
|
+
when `httpAdminRoot` is set), or click **Open AI Access dashboard** in the
|
|
43
|
+
editor sidebar. Opening `/mcp` in a browser redirects to the dashboard (MCP
|
|
44
|
+
clients keep using `/mcp`).
|
|
43
45
|
|
|
44
|
-
The `/
|
|
46
|
+
The `/ai-access` HTML shell is served without adminAuth so the page can read the
|
|
45
47
|
editor token from browser `localStorage` (Node-RED does not use cookies) and
|
|
46
48
|
call APIs with `Authorization: Bearer`. If no valid token is present, the page
|
|
47
49
|
redirects to the editor login. All data and actions stay behind permission
|
|
48
50
|
checks.
|
|
49
51
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
The dashboard has tabs for **Overview** (status and diagnostics), **Settings**,
|
|
53
|
+
**Access tokens**, **OAuth**, **Proposals** and **Audit log**. You can create
|
|
54
|
+
access tokens, review proposals (with a readable node/property diff against the
|
|
55
|
+
live flow), approve or reject changes, and read a human-readable audit log.
|
|
56
|
+
Users with `read` (including guest, if configured) get a read-only view; only
|
|
57
|
+
users with `*` can create/revoke links and approve/reject proposals.
|
|
55
58
|
|
|
56
59
|
## Configuration
|
|
57
60
|
|
|
@@ -86,7 +89,7 @@ module.exports = {
|
|
|
86
89
|
// enabled: true,
|
|
87
90
|
// accessTokenTtlSec: 3600,
|
|
88
91
|
// refreshIdleTtlSec: 2592000,
|
|
89
|
-
// dcrMaxClients:
|
|
92
|
+
// dcrMaxClients: 5,
|
|
90
93
|
// },
|
|
91
94
|
},
|
|
92
95
|
};
|
|
@@ -143,8 +146,8 @@ are rejected. Exposed headers include `Mcp-Session-Id`, `WWW-Authenticate`,
|
|
|
143
146
|
Effective values are resolved **without restart** in this order (highest wins):
|
|
144
147
|
|
|
145
148
|
1. **`settings.js`** — keys present in the `aiAccess` block are locked
|
|
146
|
-
2. **Disk** — `<userDir>/.ai-access/config.json` (
|
|
147
|
-
|
|
149
|
+
2. **Disk** — `<userDir>/.ai-access/config.json` (dashboard **Settings** /
|
|
150
|
+
**OAuth** tabs, editor sidebar toggles, or `PUT /mcp/api/v1/settings`)
|
|
148
151
|
3. **Built-in defaults** — as documented above
|
|
149
152
|
|
|
150
153
|
This is a breaking precedence change in 0.2.0: settings.js now wins over disk.
|
|
@@ -154,21 +157,23 @@ PUT ignores locked keys while applying unlocked ones; GET and PUT return
|
|
|
154
157
|
per-field `sources` (`settings.js`, `disk`, or `default`) and the precedence
|
|
155
158
|
order.
|
|
156
159
|
|
|
157
|
-
The editor right-hand sidebar tab (**AI Access
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
160
|
+
The editor right-hand sidebar tab (**AI Access**) holds only: the **Enable AI
|
|
161
|
+
Access features** toggle (the `allowWithoutAdminAuth` local-only opt-in when
|
|
162
|
+
`adminAuth` is off), the **Enable MCP OAuth** toggle, an OAuth route-conflict
|
|
163
|
+
warning with links that reveal the conflicting node (only when conflicts exist),
|
|
164
|
+
and an **Open AI Access dashboard** button.
|
|
165
|
+
|
|
166
|
+
Everything else is on the dashboard. The **Settings** tab lets `*` admins change
|
|
167
|
+
default deploy type, access-token TTL, maximum active tokens, Public URL (with a
|
|
168
|
+
reachability **Check**), CORS origins, and the three rate limits, and shows
|
|
169
|
+
Express's effective `trust proxy` setting. The **OAuth** tab configures token
|
|
170
|
+
lifetimes and the client limit, lists registered clients with revoke buttons,
|
|
171
|
+
and reports route collisions (linking `http in` nodes to the editor) and the
|
|
172
|
+
`httpNodeRoot: false` metadata fallback. `read` users see the same values
|
|
173
|
+
read-only; writes need `*`, exactly as before. Changes apply immediately;
|
|
174
|
+
changing limits starts fresh rate-limit buckets. Enabling OAuth with no Public
|
|
175
|
+
URL or an HTTP non-loopback URL shows a warning confirmation; it does not block
|
|
176
|
+
the change. Fields set in `settings.js` are locked.
|
|
172
177
|
|
|
173
178
|
### MCP OAuth
|
|
174
179
|
|
|
@@ -180,9 +185,9 @@ at `/.well-known/oauth-authorization-server` and protected resource metadata at
|
|
|
180
185
|
`/.well-known/oauth-protected-resource/mcp` and
|
|
181
186
|
`/.well-known/oauth-protected-resource`. The issuer is `publicBaseUrl` and the
|
|
182
187
|
resource indicator is `{publicBaseUrl}/mcp`. When `httpNodeRoot` is false,
|
|
183
|
-
metadata is available under the admin `/mcp` path instead; the
|
|
184
|
-
this fallback. Route collisions disable the affected OAuth
|
|
185
|
-
in the sidebar.
|
|
188
|
+
metadata is available under the admin `/mcp` path instead; the dashboard OAuth
|
|
189
|
+
tab displays this fallback. Route collisions disable the affected OAuth
|
|
190
|
+
endpoints and appear in the sidebar and on the OAuth tab.
|
|
186
191
|
|
|
187
192
|
Clients use authorization code with PKCE S256 and can request `read` or
|
|
188
193
|
`propose`. Consent uses the Node-RED editor login. Access tokens last one hour
|
|
@@ -191,6 +196,23 @@ use. Reusing a rotated refresh token revokes its token family. Tokens are stored
|
|
|
191
196
|
as SHA-256 hashes in `<userDir>/.ai-access/oauth.json`. Access-link `aia_`
|
|
192
197
|
bearer tokens continue to work. See [MCP client setup](docs/mcp-clients.md).
|
|
193
198
|
|
|
199
|
+
Add `{publicBaseUrl}/mcp` as the server URL in ChatGPT, Claude and other MCP
|
|
200
|
+
clients; `/mcp` and `/mcp/rpc` serve the same MCP endpoint (browsers opening
|
|
201
|
+
`/mcp` are redirected to `/ai-access`). At most `oauth.dcrMaxClients`
|
|
202
|
+
(default 5) approved clients are kept: lowering the limit removes none, but new
|
|
203
|
+
registrations are refused with `400` until clients are revoked.
|
|
204
|
+
|
|
205
|
+
When you are signed out and Node-RED uses `credentials` login, the consent page
|
|
206
|
+
shows its own sign-in form. It calls Node-RED's `/auth/token` endpoint and
|
|
207
|
+
stores the resulting editor token in `localStorage` under the editor's key, so
|
|
208
|
+
this also signs you in to the Node-RED editor in that browser.
|
|
209
|
+
|
|
210
|
+
> **Exposing Node-RED publicly:** Node-RED's own `/auth/token` login endpoint is
|
|
211
|
+
> not rate limited (neither by Node-RED nor by this plugin). Before exposing
|
|
212
|
+
> Node-RED to the internet for OAuth, put it behind a reverse proxy or other
|
|
213
|
+
> limiter that throttles `POST {httpAdminRoot}/auth/token` (and preferably the
|
|
214
|
+
> whole admin path), and use strong passwords.
|
|
215
|
+
|
|
194
216
|
Public URL **Check** uses `POST /mcp/api/v1/settings/check-public-url` and
|
|
195
217
|
requires `*` permission because it performs an outbound request. It validates
|
|
196
218
|
the form URL, fetches only `{publicBaseUrl}{httpAdminRoot}/mcp/api/v1`
|
|
@@ -229,30 +251,32 @@ OpenAPI: **`GET /mcp/api/v1/openapi.yaml`** or
|
|
|
229
251
|
**`GET /mcp/api/v1/openapi.json`** (also in
|
|
230
252
|
[`docs/api/openapi.yaml`](docs/api/openapi.yaml)).
|
|
231
253
|
|
|
232
|
-
| Path | Purpose
|
|
233
|
-
| ---------------------------------------- |
|
|
234
|
-
| `GET /
|
|
235
|
-
| `GET /mcp
|
|
236
|
-
| `GET /mcp/a/<token
|
|
237
|
-
| `
|
|
238
|
-
| `
|
|
239
|
-
| `
|
|
240
|
-
| `GET /mcp/api/v1
|
|
241
|
-
| `GET /mcp/api/v1/
|
|
242
|
-
| `GET /mcp/api/v1/
|
|
243
|
-
| `
|
|
244
|
-
| `GET /mcp/api/v1/
|
|
245
|
-
| `
|
|
246
|
-
| `
|
|
247
|
-
| `
|
|
248
|
-
| `
|
|
249
|
-
| `
|
|
250
|
-
| `GET /mcp/api/v1/
|
|
251
|
-
| `
|
|
252
|
-
| `GET /mcp/api/v1/proposals
|
|
253
|
-
| `
|
|
254
|
-
| `
|
|
255
|
-
| `
|
|
254
|
+
| Path | Purpose |
|
|
255
|
+
| ---------------------------------------- | --------------------------------------------------------- |
|
|
256
|
+
| `GET /ai-access` | Admin dashboard (overview, settings, tokens, OAuth, …) |
|
|
257
|
+
| `GET /mcp` (browser) | `302` redirect to `/ai-access` |
|
|
258
|
+
| `GET /mcp/a/<token>` | Self-contained GET link (markdown docs) |
|
|
259
|
+
| `GET /mcp/a/<token>/…` | Token-scoped GET status/flows/propose/drafts |
|
|
260
|
+
| `POST /mcp/rpc` | MCP Streamable HTTP (access-link Bearer; tools) |
|
|
261
|
+
| `POST /mcp` | Same MCP endpoint (OAuth resource URL for ChatGPT/Claude) |
|
|
262
|
+
| `GET /mcp/api/v1` | Discovery index (no auth; endpoints + auth hint) |
|
|
263
|
+
| `GET /mcp/api/v1/openapi.yaml` | OpenAPI 3.1 specification (YAML) |
|
|
264
|
+
| `GET /mcp/api/v1/openapi.json` | OpenAPI 3.1 specification (JSON) |
|
|
265
|
+
| `GET /mcp/api/v1/status` | Plugin status JSON (admin or access link) |
|
|
266
|
+
| `GET /mcp/api/v1/settings` | Effective AI Access settings (admin `read`) |
|
|
267
|
+
| `PUT /mcp/api/v1/settings` | Update settings (`*`; persists to disk, hot) |
|
|
268
|
+
| `GET /mcp/api/v1/links` | List active access links (`*` only) |
|
|
269
|
+
| `POST /mcp/api/v1/links` | Create access link (`*` only; token once) |
|
|
270
|
+
| `DELETE /mcp/api/v1/links/:id` | Revoke access link (`*` only) |
|
|
271
|
+
| `GET /mcp/api/v1/flows` | List flows + rev (admin `read` or access link) |
|
|
272
|
+
| `GET /mcp/api/v1/flows/:id` | Get one flow + rev (admin `read` or access link) |
|
|
273
|
+
| `POST /mcp/api/v1/proposals` | Create proposal (access-link Bearer only) |
|
|
274
|
+
| `GET /mcp/api/v1/proposals` | List proposals (admin: all; link: own) |
|
|
275
|
+
| `GET /mcp/api/v1/proposals/:id` | Get proposal (admin: any; link: own) |
|
|
276
|
+
| `GET /mcp/api/v1/proposals/:id/diff` | Diff proposal vs current flow (admin `read`/own) |
|
|
277
|
+
| `POST /mcp/api/v1/proposals/:id/approve` | Approve + deploy (`*`; optional deploymentType) |
|
|
278
|
+
| `POST /mcp/api/v1/proposals/:id/reject` | Reject with reason (`*`; no flow mutate) |
|
|
279
|
+
| `GET /mcp/api/v1/logs` | Append-only audit log (admin `read`) |
|
|
256
280
|
|
|
257
281
|
### MCP JSON-RPC (`POST /mcp/rpc`)
|
|
258
282
|
|
|
@@ -268,22 +292,23 @@ use them. Proposal create/list/get responses include `title`, `displayName`
|
|
|
268
292
|
(`title ·` **server-local** datetime with explicit offset, e.g.
|
|
269
293
|
`16 Oct 01:35 +00:00`), `reviewUrl` (absolute URL using the request
|
|
270
294
|
Host/protocol — `X-Forwarded-*` only when Express `trust proxy` is set), and
|
|
271
|
-
`reviewPath` (relative `/
|
|
272
|
-
`/
|
|
273
|
-
refer to proposals by `displayName` + `reviewUrl`,
|
|
274
|
-
access-link callers, `get_status` reports `permission: null`
|
|
275
|
-
`caller.kind: "access-link"` (expected — AI tokens are not admin sessions).
|
|
276
|
-
|
|
277
|
-
Approve, reject, and access-link management stay human-only on the `/
|
|
278
|
-
page (and the corresponding REST routes). Rate limits, payload size
|
|
279
|
-
audit logging match REST. Missing tokens return **401**
|
|
280
|
-
known-expired tokens return **401** `token_expired`;
|
|
281
|
-
tokens return **401** `access_link_invalid` (all with
|
|
282
|
-
telling the AI to ask the user for a new access link. Every
|
|
283
|
-
a `code`. `token_expired` also includes `expiredAt` and
|
|
284
|
-
`/
|
|
285
|
-
`minutesRemaining` (rounded up), and
|
|
286
|
-
|
|
295
|
+
`reviewPath` (relative `/ai-access#proposal=<id>`). `createdAt` remains
|
|
296
|
+
ISO-8601. The `/ai-access` dashboard renders times in the browser's local
|
|
297
|
+
timezone. AI clients should refer to proposals by `displayName` + `reviewUrl`,
|
|
298
|
+
not the raw id. For access-link callers, `get_status` reports `permission: null`
|
|
299
|
+
and `caller.kind: "access-link"` (expected — AI tokens are not admin sessions).
|
|
300
|
+
|
|
301
|
+
Approve, reject, and access-link management stay human-only on the `/ai-access`
|
|
302
|
+
admin page (and the corresponding REST routes). Rate limits, payload size
|
|
303
|
+
limits, and audit logging match REST. Missing tokens return **401**
|
|
304
|
+
`access_link_missing`; known-expired tokens return **401** `token_expired`;
|
|
305
|
+
other invalid/revoked tokens return **401** `access_link_invalid` (all with
|
|
306
|
+
`WWW-Authenticate`) telling the AI to ask the user for a new access link. Every
|
|
307
|
+
error JSON includes a `code`. `token_expired` also includes `expiredAt` and
|
|
308
|
+
`accessLinksUrl` (the `/ai-access` dashboard's Access tokens tab). Access-link
|
|
309
|
+
`/status` includes `expiresAt`, `minutesRemaining` (rounded up), and
|
|
310
|
+
`secondsRemaining`. See `docs/errors.md` (generated from
|
|
311
|
+
`src/plugin/error-registry.ts`).
|
|
287
312
|
|
|
288
313
|
Access links are **in memory** (default TTL **4h**, max 10). Caps: **get_link ≤
|
|
289
314
|
24h**, **rest/mcp ≤ 30d**. Creating a link returns the raw `token` plus a
|
|
@@ -311,8 +336,8 @@ errors mark it **failed**. Reject never mutates flows.
|
|
|
311
336
|
|
|
312
337
|
### Self-contained GET link (chat AIs that can only HTTP GET)
|
|
313
338
|
|
|
314
|
-
1. An owner with `*` opens `/
|
|
315
|
-
(default TTL **4 hours**, max **24 hours**). Copy the full URL
|
|
339
|
+
1. An owner with `*` opens `/ai-access` → **Access tokens** → create a **GET
|
|
340
|
+
link** (default TTL **4 hours**, max **24 hours**). Copy the full URL
|
|
316
341
|
`http(s)://<host><httpAdminRoot>/mcp/a/<token>` (or **Copy link for AI**).
|
|
317
342
|
2. The AI opens that URL for markdown docs, then uses GET-only routes under the
|
|
318
343
|
same path (`/status`, `/flows`, `/flows/<id>`, `/proposals`, `/propose` with
|
|
@@ -337,7 +362,7 @@ errors mark it **failed**. Reject never mutates flows.
|
|
|
337
362
|
HTML adds a restrictive `Content-Security-Policy`. REST and MCP endpoints are
|
|
338
363
|
not affected.
|
|
339
364
|
|
|
340
|
-
3. Changes become **pending proposals**; a human approves on `/
|
|
365
|
+
3. Changes become **pending proposals**; a human approves on `/ai-access`. JSON
|
|
341
366
|
responses use `Cache-Control: no-store`.
|
|
342
367
|
|
|
343
368
|
### Bearer REST / MCP
|
|
@@ -355,7 +380,7 @@ errors mark it **failed**. Reject never mutates flows.
|
|
|
355
380
|
`list_proposals` / alias `list_my_proposals` (same access-link auth and
|
|
356
381
|
limits)
|
|
357
382
|
|
|
358
|
-
3. The owner reviews the proposal on `/
|
|
383
|
+
3. The owner reviews the proposal on `/ai-access` and approves or rejects it.
|
|
359
384
|
4. If the token is invalid, expired, revoked, or cleared by a restart, the API
|
|
360
385
|
returns **401** telling the AI to **ask the user for a new access link**.
|
|
361
386
|
|
package/ai-access.html
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
}
|
|
15
15
|
window.__com55AiAccessSidebarLoading = true;
|
|
16
16
|
|
|
17
|
-
var EDITOR_SIDEBAR_ASSET_VERSION = '0.2.0-beta.
|
|
17
|
+
var EDITOR_SIDEBAR_ASSET_VERSION = '0.2.0-beta.3';
|
|
18
18
|
var root = (RED.settings.httpAdminRoot || '/').replace(/\/$/, '');
|
|
19
19
|
var src =
|
|
20
20
|
(root || '') +
|