fix(n8n): AList user/update requires username; hooks -> container-local; deploy script
- w1/w3-body: disable calls now send username + assert code===200
(v3.63 validator rejects {id,disabled} with 400 -> silent no-disable)
- regenerated W1/W3 json, deployed live via REST API, activeVersionId re-aligned
- NocoDB hooks repointed to http://n8n:5678 (old auto.hoelee.com chain loses
events on VPS stalls; W2 hook path was also 404 since creation)
- deploy_w1_w3.mjs: reusable PUT deploy via n8n API key from SECRETS.md
- PROJECT_STATE: e2e verification results + updated next steps
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,28 @@
|
||||
// Deploy regenerated W1..W4 workflows to live n8n via public API.
|
||||
// Usage: N8N_API_KEY=<key> N8N_BASE=http://192.168.137.2:5678 node deploy_w1_w3.mjs
|
||||
// Key lives in repo-root SECRETS.md (never hardcode here).
|
||||
import { readFile } from "node:fs/promises";
|
||||
|
||||
const N8N = process.env.N8N_BASE || "http://192.168.137.2:5678";
|
||||
const KEY = process.env.N8N_API_KEY;
|
||||
if (!KEY) { console.error("N8N_API_KEY env required (see SECRETS.md)"); process.exit(1); }
|
||||
const H = { "X-N8N-API-KEY": KEY, "Content-Type": "application/json" };
|
||||
|
||||
const TARGETS = [
|
||||
{ file: "W1-customer-provision.json", id: "gU2ee9Eg5w1KzB5p" },
|
||||
{ file: "W3-expiry-sync.json", id: "zlEfjj5eK5IfILtk" },
|
||||
];
|
||||
|
||||
for (const t of TARGETS) {
|
||||
const wf = JSON.parse(await readFile(t.file, "utf-8"));
|
||||
delete wf.pinData;
|
||||
delete wf.active;
|
||||
delete wf.id;
|
||||
const r = await fetch(`${N8N}/api/v1/workflows/${t.id}`, {
|
||||
method: "PUT", headers: H, body: JSON.stringify(wf),
|
||||
});
|
||||
const txt = await r.text();
|
||||
console.log(t.file, "PUT", r.status, txt.slice(0, 120));
|
||||
if (r.status !== 200) process.exit(1);
|
||||
}
|
||||
console.log("DEPLOY OK — remember to recheck workflow_entity.activeVersionId alignment");
|
||||
+4
-1
@@ -153,7 +153,10 @@ if (status !== 'active') {
|
||||
}
|
||||
const actions = [];
|
||||
if (alistUserId) {
|
||||
await alistReq(ctx, 'POST', '/api/admin/user/update', { id: alistUserId, disabled: true }, token);
|
||||
// AList v3.63 /user/update REQUIRES username (validation: Username required).
|
||||
// Sending {id,disabled} alone -> 400 -> silent no-disable (found live 2026-08-25).
|
||||
const disRes = await alistReq(ctx, 'POST', '/api/admin/user/update', { id: alistUserId, username, disabled: true }, token);
|
||||
if (!disRes || disRes.code !== 200) throw new Error('AList disable failed: ' + JSON.stringify(disRes));
|
||||
actions.push('disable_user');
|
||||
}
|
||||
if (alistRoleId) {
|
||||
|
||||
+5
-2
@@ -56,8 +56,11 @@ for (const cust of customers) {
|
||||
applied.push('role_scopes');
|
||||
}
|
||||
if (shouldDisable) {
|
||||
if (!DRY_RUN && cust.alist_user_id)
|
||||
await alistReq(ctx, 'POST', '/api/admin/user/update', { id: cust.alist_user_id, disabled: true }, token);
|
||||
// AList v3.63 /user/update REQUIRES username — {id,disabled} alone = 400 silent no-op (2026-08-25).
|
||||
if (!DRY_RUN && cust.alist_user_id) {
|
||||
const disRes = await alistReq(ctx, 'POST', '/api/admin/user/update', { id: cust.alist_user_id, username: cust.username, disabled: true }, token);
|
||||
if (!disRes || disRes.code !== 200) throw new Error('AList disable failed: ' + JSON.stringify(disRes));
|
||||
}
|
||||
applied.push('disable');
|
||||
}
|
||||
if (applied.length) {
|
||||
|
||||
Reference in New Issue
Block a user