@fieldwangai/agentflow 0.1.45 → 0.1.46

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/bin/lib/auth.mjs CHANGED
@@ -97,8 +97,11 @@ function normalizeUserAllowlistInput(value) {
97
97
  return [];
98
98
  }
99
99
 
100
- export function readUserAllowlist() {
101
- const fromEnv = normalizeUserAllowlistInput(process.env.AGENTFLOW_USER_WHITELIST || process.env.AGENTFLOW_ALLOWED_USERS || "");
100
+ function readUserAllowlistEnvUsers() {
101
+ return normalizeUserAllowlistInput(process.env.AGENTFLOW_USER_WHITELIST || process.env.AGENTFLOW_ALLOWED_USERS || "");
102
+ }
103
+
104
+ function readUserAllowlistFileUsers() {
102
105
  let fromFile = [];
103
106
  try {
104
107
  const p = userAllowlistPath();
@@ -109,8 +112,32 @@ export function readUserAllowlist() {
109
112
  } catch {
110
113
  fromFile = [];
111
114
  }
115
+ return fromFile;
116
+ }
117
+
118
+ export function readUserAllowlist() {
119
+ const fromEnv = readUserAllowlistEnvUsers();
120
+ const fromFile = readUserAllowlistFileUsers();
112
121
  const users = Array.from(new Set([...fromFile, ...fromEnv].map((item) => String(item || "").trim()).filter(Boolean)));
113
- return { enabled: users.length > 0, users, path: userAllowlistPath() };
122
+ return { enabled: users.length > 0, users, fileUsers: fromFile, envUsers: fromEnv, path: userAllowlistPath() };
123
+ }
124
+
125
+ export function writeUserAllowlist(users) {
126
+ const normalized = [];
127
+ const seen = new Set();
128
+ for (const item of normalizeUserAllowlistInput(users)) {
129
+ const user = String(item || "").trim();
130
+ const safe = sanitizeAgentflowUserId(user);
131
+ if (!safe) {
132
+ throw new Error(`invalid username: ${user}`);
133
+ }
134
+ const key = safe.toLowerCase();
135
+ if (seen.has(key)) continue;
136
+ seen.add(key);
137
+ normalized.push(user);
138
+ }
139
+ writeJsonObject(userAllowlistPath(), { users: normalized, updatedAt: new Date().toISOString() });
140
+ return readUserAllowlist();
114
141
  }
115
142
 
116
143
  function userAllowlistMatchSet(users) {
@@ -96,6 +96,7 @@ import {
96
96
  loginOrCreateUser,
97
97
  logoutRequest,
98
98
  readUserAllowlist,
99
+ writeUserAllowlist,
99
100
  } from "./auth.mjs";
100
101
  import { readGlobalEnvRows, readMergedEnvObject, readUserEnvRows, writeGlobalEnvRows, writeUserEnvRows } from "./user-env.mjs";
101
102
  import {
@@ -3204,6 +3205,33 @@ export function startUiServer({
3204
3205
  }
3205
3206
  }
3206
3207
 
3208
+ if (url.pathname === "/api/admin/user-allowlist") {
3209
+ if (!authUser?.isAdmin) {
3210
+ json(res, 403, { error: "Admin permission required" });
3211
+ return;
3212
+ }
3213
+ if (req.method === "GET") {
3214
+ json(res, 200, { allowlist: readUserAllowlist() });
3215
+ return;
3216
+ }
3217
+ if (req.method === "POST") {
3218
+ let payload;
3219
+ try {
3220
+ payload = JSON.parse(await readBody(req));
3221
+ } catch {
3222
+ json(res, 400, { error: "Invalid JSON body" });
3223
+ return;
3224
+ }
3225
+ try {
3226
+ const allowlist = writeUserAllowlist(payload?.users || payload?.fileUsers || []);
3227
+ json(res, 200, { ok: true, allowlist });
3228
+ } catch (e) {
3229
+ json(res, 400, { error: (e && e.message) || String(e) });
3230
+ }
3231
+ return;
3232
+ }
3233
+ }
3234
+
3207
3235
  if (url.pathname === "/api/flows") {
3208
3236
  if (req.method === "GET") {
3209
3237
  try {