@lifeaitools/clauth 0.7.5 → 1.1.0

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.
@@ -119,12 +119,27 @@ async function handleEnable(sb: any, body: any, mh: string) {
119
119
  }
120
120
 
121
121
  async function handleAdd(sb: any, body: any, mh: string) {
122
- const { name, label, key_type, description } = body;
122
+ const { name, label, key_type, description, project } = body;
123
123
  if (!name || !label || !key_type) return { error: "name, label, key_type required" };
124
- const { error } = await sb.from("clauth_services").insert({ name, label, key_type, description: description || null });
124
+ const row: any = { name, label, key_type, description: description || null };
125
+ if (project) row.project = project;
126
+ const { error } = await sb.from("clauth_services").insert(row);
125
127
  if (error) return { error: error.message };
126
128
  await auditLog(sb, mh, name, "add", "success");
127
- return { success: true, name, label, key_type };
129
+ return { success: true, name, label, key_type, project: project || null };
130
+ }
131
+
132
+ async function handleUpdate(sb: any, body: any, mh: string) {
133
+ const { service, project, label, description } = body;
134
+ if (!service) return { error: "service required" };
135
+ const updates: any = { updated_at: new Date().toISOString() };
136
+ if (project !== undefined) updates.project = project || null; // empty string clears project
137
+ if (label !== undefined) updates.label = label;
138
+ if (description !== undefined) updates.description = description || null;
139
+ const { error } = await sb.from("clauth_services").update(updates).eq("name", service);
140
+ if (error) return { error: error.message };
141
+ await auditLog(sb, mh, service, "update", "success", `fields: ${Object.keys(updates).join(", ")}`);
142
+ return { success: true, service, ...updates };
128
143
  }
129
144
 
130
145
  async function handleRemove(sb: any, body: any, mh: string) {
@@ -152,9 +167,13 @@ async function handleRevoke(sb: any, body: any, mh: string) {
152
167
  return { success: true, service };
153
168
  }
154
169
 
155
- async function handleStatus(sb: any, mh: string) {
156
- const { data: services } = await sb.from("clauth_services")
157
- .select("name, label, key_type, enabled, vault_key, last_retrieved, last_rotated, created_at").order("name");
170
+ async function handleStatus(sb: any, body: any, mh: string) {
171
+ let q = sb.from("clauth_services")
172
+ .select("name, label, key_type, enabled, vault_key, last_retrieved, last_rotated, created_at, project")
173
+ .order("project", { ascending: true, nullsFirst: true })
174
+ .order("name");
175
+ if (body.project) q = q.eq("project", body.project);
176
+ const { data: services } = await q;
158
177
  await auditLog(sb, mh, "all", "status", "success");
159
178
  return { services: services || [] };
160
179
  }
@@ -225,9 +244,10 @@ Deno.serve(async (req: Request) => {
225
244
  case "write": return Response.json(await handleWrite(sb, body, mh));
226
245
  case "enable": return Response.json(await handleEnable(sb, body, mh));
227
246
  case "add": return Response.json(await handleAdd(sb, body, mh));
247
+ case "update": return Response.json(await handleUpdate(sb, body, mh));
228
248
  case "remove": return Response.json(await handleRemove(sb, body, mh));
229
249
  case "revoke": return Response.json(await handleRevoke(sb, body, mh));
230
- case "status": return Response.json(await handleStatus(sb, mh));
250
+ case "status": return Response.json(await handleStatus(sb, body, mh));
231
251
  case "change-password": return Response.json(await handleChangePassword(sb, body, mh));
232
252
  case "test": return Response.json({ valid: true, machine_hash: mh, timestamp: body.timestamp, ip });
233
253
  default: return Response.json({ error: "unknown_route", route }, { status: 404 });
@@ -0,0 +1,13 @@
1
+ -- clauth_config: key/value store for daemon configuration
2
+ -- Used to persist tunnel hostname and other daemon settings
3
+ CREATE TABLE IF NOT EXISTS clauth_config (
4
+ key text PRIMARY KEY,
5
+ value jsonb NOT NULL,
6
+ updated_at timestamptz DEFAULT now()
7
+ );
8
+
9
+ -- RLS: only service role can access (same pattern as other clauth tables)
10
+ ALTER TABLE clauth_config ENABLE ROW LEVEL SECURITY;
11
+
12
+ -- Seed: no tunnel by default (user must run clauth tunnel setup)
13
+ -- INSERT INTO clauth_config (key, value) VALUES ('tunnel_hostname', 'null');