@synoikia/core 0.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.
Files changed (209) hide show
  1. package/LICENSE +21 -0
  2. package/dist/app.d.ts +79 -0
  3. package/dist/app.js +155 -0
  4. package/dist/app.js.map +1 -0
  5. package/dist/approvals/links.d.ts +23 -0
  6. package/dist/approvals/links.js +49 -0
  7. package/dist/approvals/links.js.map +1 -0
  8. package/dist/approvals/service.d.ts +110 -0
  9. package/dist/approvals/service.js +182 -0
  10. package/dist/approvals/service.js.map +1 -0
  11. package/dist/audit-query.d.ts +52 -0
  12. package/dist/audit-query.js +116 -0
  13. package/dist/audit-query.js.map +1 -0
  14. package/dist/audit.d.ts +5 -0
  15. package/dist/audit.js +8 -0
  16. package/dist/audit.js.map +1 -0
  17. package/dist/auth/mcp-auth.d.ts +50 -0
  18. package/dist/auth/mcp-auth.js +160 -0
  19. package/dist/auth/mcp-auth.js.map +1 -0
  20. package/dist/auth/mcp-tokens.d.ts +57 -0
  21. package/dist/auth/mcp-tokens.js +143 -0
  22. package/dist/auth/mcp-tokens.js.map +1 -0
  23. package/dist/auth/oauth.d.ts +188 -0
  24. package/dist/auth/oauth.js +470 -0
  25. package/dist/auth/oauth.js.map +1 -0
  26. package/dist/auth/oidc.d.ts +110 -0
  27. package/dist/auth/oidc.js +221 -0
  28. package/dist/auth/oidc.js.map +1 -0
  29. package/dist/auth/sessions.d.ts +34 -0
  30. package/dist/auth/sessions.js +83 -0
  31. package/dist/auth/sessions.js.map +1 -0
  32. package/dist/auth/throttle.d.ts +31 -0
  33. package/dist/auth/throttle.js +52 -0
  34. package/dist/auth/throttle.js.map +1 -0
  35. package/dist/auth/tokens.d.ts +7 -0
  36. package/dist/auth/tokens.js +40 -0
  37. package/dist/auth/tokens.js.map +1 -0
  38. package/dist/auth/totp.d.ts +14 -0
  39. package/dist/auth/totp.js +81 -0
  40. package/dist/auth/totp.js.map +1 -0
  41. package/dist/auth/users.d.ts +70 -0
  42. package/dist/auth/users.js +296 -0
  43. package/dist/auth/users.js.map +1 -0
  44. package/dist/catalog/groups.d.ts +102 -0
  45. package/dist/catalog/groups.js +363 -0
  46. package/dist/catalog/groups.js.map +1 -0
  47. package/dist/catalog/registry.d.ts +25 -0
  48. package/dist/catalog/registry.js +80 -0
  49. package/dist/catalog/registry.js.map +1 -0
  50. package/dist/catalog/rules.d.ts +128 -0
  51. package/dist/catalog/rules.js +178 -0
  52. package/dist/catalog/rules.js.map +1 -0
  53. package/dist/catalog/sync.d.ts +29 -0
  54. package/dist/catalog/sync.js +222 -0
  55. package/dist/catalog/sync.js.map +1 -0
  56. package/dist/cli.d.ts +3 -0
  57. package/dist/cli.js +83 -0
  58. package/dist/cli.js.map +1 -0
  59. package/dist/config/env.d.ts +40 -0
  60. package/dist/config/env.js +71 -0
  61. package/dist/config/env.js.map +1 -0
  62. package/dist/crypto/index.d.ts +28 -0
  63. package/dist/crypto/index.js +88 -0
  64. package/dist/crypto/index.js.map +1 -0
  65. package/dist/crypto/rotate.d.ts +15 -0
  66. package/dist/crypto/rotate.js +61 -0
  67. package/dist/crypto/rotate.js.map +1 -0
  68. package/dist/db/index.d.ts +17 -0
  69. package/dist/db/index.js +29 -0
  70. package/dist/db/index.js.map +1 -0
  71. package/dist/db/schema.d.ts +4389 -0
  72. package/dist/db/schema.js +372 -0
  73. package/dist/db/schema.js.map +1 -0
  74. package/dist/endpoints/slug.d.ts +3 -0
  75. package/dist/endpoints/slug.js +7 -0
  76. package/dist/endpoints/slug.js.map +1 -0
  77. package/dist/errors.d.ts +16 -0
  78. package/dist/errors.js +29 -0
  79. package/dist/errors.js.map +1 -0
  80. package/dist/events.d.ts +43 -0
  81. package/dist/events.js +16 -0
  82. package/dist/events.js.map +1 -0
  83. package/dist/gate/access.d.ts +47 -0
  84. package/dist/gate/access.js +48 -0
  85. package/dist/gate/access.js.map +1 -0
  86. package/dist/gate/attestation.d.ts +23 -0
  87. package/dist/gate/attestation.js +33 -0
  88. package/dist/gate/attestation.js.map +1 -0
  89. package/dist/gate/canonical.d.ts +3 -0
  90. package/dist/gate/canonical.js +11 -0
  91. package/dist/gate/canonical.js.map +1 -0
  92. package/dist/gate/match.d.ts +67 -0
  93. package/dist/gate/match.js +133 -0
  94. package/dist/gate/match.js.map +1 -0
  95. package/dist/gate/pipeline.d.ts +61 -0
  96. package/dist/gate/pipeline.js +284 -0
  97. package/dist/gate/pipeline.js.map +1 -0
  98. package/dist/gate/preapproval.d.ts +24 -0
  99. package/dist/gate/preapproval.js +48 -0
  100. package/dist/gate/preapproval.js.map +1 -0
  101. package/dist/gate/rate-limit.d.ts +35 -0
  102. package/dist/gate/rate-limit.js +82 -0
  103. package/dist/gate/rate-limit.js.map +1 -0
  104. package/dist/gate/redact.d.ts +23 -0
  105. package/dist/gate/redact.js +87 -0
  106. package/dist/gate/redact.js.map +1 -0
  107. package/dist/http/admin/auth.d.ts +33 -0
  108. package/dist/http/admin/auth.js +338 -0
  109. package/dist/http/admin/auth.js.map +1 -0
  110. package/dist/http/admin/instances.d.ts +5 -0
  111. package/dist/http/admin/instances.js +193 -0
  112. package/dist/http/admin/instances.js.map +1 -0
  113. package/dist/http/admin/system.d.ts +5 -0
  114. package/dist/http/admin/system.js +225 -0
  115. package/dist/http/admin/system.js.map +1 -0
  116. package/dist/http/admin-app.d.ts +9 -0
  117. package/dist/http/admin-app.js +51 -0
  118. package/dist/http/admin-app.js.map +1 -0
  119. package/dist/http/common.d.ts +32 -0
  120. package/dist/http/common.js +80 -0
  121. package/dist/http/common.js.map +1 -0
  122. package/dist/http/mcp/approval-routes.d.ts +11 -0
  123. package/dist/http/mcp/approval-routes.js +117 -0
  124. package/dist/http/mcp/approval-routes.js.map +1 -0
  125. package/dist/http/mcp/endpoint.d.ts +32 -0
  126. package/dist/http/mcp/endpoint.js +293 -0
  127. package/dist/http/mcp/endpoint.js.map +1 -0
  128. package/dist/http/mcp/oauth-routes.d.ts +29 -0
  129. package/dist/http/mcp/oauth-routes.js +465 -0
  130. package/dist/http/mcp/oauth-routes.js.map +1 -0
  131. package/dist/http/mcp/pages.d.ts +63 -0
  132. package/dist/http/mcp/pages.js +200 -0
  133. package/dist/http/mcp/pages.js.map +1 -0
  134. package/dist/http/mcp-app.d.ts +7 -0
  135. package/dist/http/mcp-app.js +30 -0
  136. package/dist/http/mcp-app.js.map +1 -0
  137. package/dist/instances/connection.d.ts +37 -0
  138. package/dist/instances/connection.js +109 -0
  139. package/dist/instances/connection.js.map +1 -0
  140. package/dist/instances/manager.d.ts +313 -0
  141. package/dist/instances/manager.js +600 -0
  142. package/dist/instances/manager.js.map +1 -0
  143. package/dist/instances/settings.d.ts +42 -0
  144. package/dist/instances/settings.js +57 -0
  145. package/dist/instances/settings.js.map +1 -0
  146. package/dist/lenient.d.ts +16 -0
  147. package/dist/lenient.js +51 -0
  148. package/dist/lenient.js.map +1 -0
  149. package/dist/lock.d.ts +28 -0
  150. package/dist/lock.js +77 -0
  151. package/dist/lock.js.map +1 -0
  152. package/dist/main.d.ts +1 -0
  153. package/dist/main.js +38 -0
  154. package/dist/main.js.map +1 -0
  155. package/dist/maintenance.d.ts +10 -0
  156. package/dist/maintenance.js +48 -0
  157. package/dist/maintenance.js.map +1 -0
  158. package/dist/notify/service.d.ts +149 -0
  159. package/dist/notify/service.js +358 -0
  160. package/dist/notify/service.js.map +1 -0
  161. package/dist/plugins/discovery.d.ts +39 -0
  162. package/dist/plugins/discovery.js +157 -0
  163. package/dist/plugins/discovery.js.map +1 -0
  164. package/dist/plugins/minisign.d.ts +25 -0
  165. package/dist/plugins/minisign.js +49 -0
  166. package/dist/plugins/minisign.js.map +1 -0
  167. package/dist/plugins/process.d.ts +55 -0
  168. package/dist/plugins/process.js +162 -0
  169. package/dist/plugins/process.js.map +1 -0
  170. package/dist/plugins/repos.d.ts +198 -0
  171. package/dist/plugins/repos.js +612 -0
  172. package/dist/plugins/repos.js.map +1 -0
  173. package/dist/plugins/supervisor.d.ts +50 -0
  174. package/dist/plugins/supervisor.js +125 -0
  175. package/dist/plugins/supervisor.js.map +1 -0
  176. package/dist/runtime/index.d.ts +28 -0
  177. package/dist/runtime/index.js +248 -0
  178. package/dist/runtime/index.js.map +1 -0
  179. package/dist/sandbox/index.d.ts +53 -0
  180. package/dist/sandbox/index.js +197 -0
  181. package/dist/sandbox/index.js.map +1 -0
  182. package/dist/server.d.ts +16 -0
  183. package/dist/server.js +36 -0
  184. package/dist/server.js.map +1 -0
  185. package/dist/settings.d.ts +43 -0
  186. package/dist/settings.js +99 -0
  187. package/dist/settings.js.map +1 -0
  188. package/dist/testing/index.d.ts +73 -0
  189. package/dist/testing/index.js +174 -0
  190. package/dist/testing/index.js.map +1 -0
  191. package/dist/version.d.ts +2 -0
  192. package/dist/version.js +4 -0
  193. package/dist/version.js.map +1 -0
  194. package/drizzle/0000_init.sql +334 -0
  195. package/drizzle/0001_totp_last_step.sql +1 -0
  196. package/drizzle/0002_access_levels.sql +16 -0
  197. package/drizzle/0003_drop_exclusion_flags.sql +2 -0
  198. package/drizzle/0004_grant_instance_ids.sql +1 -0
  199. package/drizzle/0005_rule_strict_miss.sql +1 -0
  200. package/drizzle/0006_attestation_waived.sql +1 -0
  201. package/drizzle/meta/0000_snapshot.json +2318 -0
  202. package/drizzle/meta/0001_snapshot.json +2325 -0
  203. package/drizzle/meta/0002_snapshot.json +2348 -0
  204. package/drizzle/meta/0003_snapshot.json +2332 -0
  205. package/drizzle/meta/0004_snapshot.json +2339 -0
  206. package/drizzle/meta/0005_snapshot.json +2346 -0
  207. package/drizzle/meta/0006_snapshot.json +2354 -0
  208. package/drizzle/meta/_journal.json +55 -0
  209. package/package.json +58 -0
@@ -0,0 +1,612 @@
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ import { existsSync, mkdirSync, readdirSync, renameSync, rmSync, statSync } from 'node:fs';
3
+ import path from 'node:path';
4
+ import { Readable } from 'node:stream';
5
+ import { pipeline } from 'node:stream/promises';
6
+ import { isSdkCompatible } from '@synoikia/plugin-sdk';
7
+ import { asc, eq } from 'drizzle-orm';
8
+ import semver from 'semver';
9
+ import * as tar from 'tar';
10
+ import { z } from 'zod';
11
+ import { writeAudit } from '../audit.js';
12
+ import { pluginInstances, pluginRepos, plugins } from '../db/schema.js';
13
+ import { ConflictError, NotFoundError, ServiceError, ValidationError } from '../errors.js';
14
+ import { CORE_VERSION } from '../version.js';
15
+ import { inspectPluginDir } from './discovery.js';
16
+ import { MinisignError, parsePublicKey, verifySignature } from './minisign.js';
17
+ /**
18
+ * Plugin repositories and installs (design §4.2–4.3). An index is only ever read; installing is an
19
+ * explicit admin action on a pinned version, verified by sha256 and — for signed repos — a minisign
20
+ * signature from the key the admin pinned when adding the repo.
21
+ */
22
+ const LIMITS = {
23
+ indexBytes: 2 * 1024 * 1024,
24
+ tarballBytes: 50 * 1024 * 1024,
25
+ extractedBytes: 200 * 1024 * 1024,
26
+ entries: 5000,
27
+ };
28
+ const VersionSchema = z.object({
29
+ version: z.string().refine((v) => semver.valid(v) !== null, 'must be a semver version'),
30
+ sdk: z.string().refine((v) => semver.validRange(v) !== null, 'must be a semver range'),
31
+ minCoreVersion: z.string().optional(),
32
+ url: z.string().min(1),
33
+ sha256: z.string().regex(/^[a-f0-9]{64}$/i, 'must be a hex sha256'),
34
+ signature: z.string().optional(),
35
+ });
36
+ export const IndexSchema = z.object({
37
+ schema: z.literal(1),
38
+ name: z.string().max(200),
39
+ homepage: z.string().optional(),
40
+ publicKey: z.string().optional(),
41
+ plugins: z
42
+ .array(z.object({
43
+ id: z.string().regex(/^[a-z][a-z0-9-]{1,39}$/),
44
+ name: z.string().max(200),
45
+ description: z.string().max(2000).optional(),
46
+ versions: z.array(VersionSchema).min(1),
47
+ }))
48
+ .max(500),
49
+ });
50
+ export const AddRepoSchema = z.object({
51
+ url: z.url(),
52
+ signingMode: z.enum(['signed', 'unsigned']),
53
+ /**
54
+ * Signed repos: the full public key (`RW…`) as the publisher advertises it out of band. A key id alone
55
+ * is not enough — it is chosen by the key owner, so a hijacked index could reuse it with another key.
56
+ */
57
+ confirmPublicKey: z.string().optional(),
58
+ });
59
+ export const InstallSchema = z.object({
60
+ repoId: z.string(),
61
+ pluginId: z.string(),
62
+ version: z.string(),
63
+ /** Unsigned repos: must equal the plugin id. */
64
+ confirm: z.string().optional(),
65
+ });
66
+ const MAX_REDIRECTS = 5;
67
+ /** The parts of a manifest that change what a plugin may do; an update touching them needs review. */
68
+ export function permissionChanges(before, after) {
69
+ const b = (before ?? {});
70
+ const a = (after ?? {});
71
+ const pick = {
72
+ binding: (m) => m.binding,
73
+ capabilities: (m) => m.capabilities,
74
+ sensitiveKeys: (m) => [...(m.sensitiveKeys ?? [])].sort(),
75
+ 'network.hosts': (m) => [...(m.network?.hosts ?? [])].sort(),
76
+ };
77
+ return Object.entries(pick)
78
+ .filter(([, get]) => canonical(get(b)) !== canonical(get(a)))
79
+ .map(([name]) => name);
80
+ }
81
+ const canonical = (v) => JSON.stringify(v, (_k, x) => x && typeof x === 'object' && !Array.isArray(x)
82
+ ? Object.fromEntries(Object.entries(x).sort(([p], [q]) => p.localeCompare(q)))
83
+ : x) ?? 'null';
84
+ /**
85
+ * Replaces `target` with `next`, keeping the previous copy at `backup` until the swap succeeded. If
86
+ * moving `next` in fails, the previous copy is moved back, so a failed update never leaves no plugin.
87
+ */
88
+ export function swapDirectory(next, target, backup, rename = renameSync) {
89
+ const hadOld = existsSync(target);
90
+ if (hadOld)
91
+ rename(target, backup);
92
+ try {
93
+ rename(next, target);
94
+ }
95
+ catch (err) {
96
+ if (hadOld)
97
+ rename(backup, target);
98
+ throw err;
99
+ }
100
+ rmSync(backup, { recursive: true, force: true });
101
+ }
102
+ export class PluginRepoService {
103
+ opts;
104
+ installing = new Set();
105
+ constructor(opts) {
106
+ this.opts = opts;
107
+ }
108
+ get db() {
109
+ return this.opts.db;
110
+ }
111
+ now() {
112
+ return this.opts.now?.() ?? new Date();
113
+ }
114
+ // ── fetching ──
115
+ checkUrl(raw, base) {
116
+ let url;
117
+ try {
118
+ url = new URL(raw, base);
119
+ }
120
+ catch {
121
+ throw new ValidationError('invalid_url', `Not a URL: ${raw}`);
122
+ }
123
+ if (url.protocol !== 'https:' && !(this.opts.allowHttp && url.protocol === 'http:')) {
124
+ throw new ValidationError('insecure_url', `Only https:// URLs are allowed (${url.origin})`);
125
+ }
126
+ return url.toString();
127
+ }
128
+ async download(url, max) {
129
+ const doFetch = this.opts.fetch ?? ((u, init) => fetch(u, init));
130
+ const signal = AbortSignal.timeout(60_000);
131
+ let res;
132
+ // Redirects are followed by hand, so every hop passes the same URL check (no https → http downgrade).
133
+ for (let hop = 0;; hop++) {
134
+ try {
135
+ res = await doFetch(url, { signal, redirect: 'manual' });
136
+ }
137
+ catch (err) {
138
+ throw new ServiceError(400, 'fetch_failed', `Could not fetch ${url}: ${err instanceof Error ? err.message : err}`);
139
+ }
140
+ const location = res.status >= 300 && res.status < 400 ? res.headers.get('location') : null;
141
+ if (!location)
142
+ break;
143
+ if (hop >= MAX_REDIRECTS)
144
+ throw new ServiceError(400, 'fetch_failed', `Too many redirects from ${url}`);
145
+ await res.body?.cancel().catch(() => undefined);
146
+ url = this.checkUrl(location, url);
147
+ }
148
+ if (!res.ok)
149
+ throw new ServiceError(400, 'fetch_failed', `Could not fetch ${url}: HTTP ${res.status}`);
150
+ if (Number(res.headers.get('content-length') ?? 0) > max)
151
+ throw new ValidationError('too_large', `${url} is too large`);
152
+ const chunks = [];
153
+ let size = 0;
154
+ if (res.body) {
155
+ for await (const chunk of res.body) {
156
+ size += chunk.length;
157
+ if (size > max)
158
+ throw new ValidationError('too_large', `${url} is too large`);
159
+ chunks.push(Buffer.from(chunk));
160
+ }
161
+ }
162
+ return Buffer.concat(chunks);
163
+ }
164
+ async fetchIndex(url) {
165
+ const bytes = await this.download(url, LIMITS.indexBytes);
166
+ let json;
167
+ try {
168
+ json = JSON.parse(bytes.toString('utf8'));
169
+ }
170
+ catch {
171
+ throw new ValidationError('invalid_index', 'index.json is not valid JSON');
172
+ }
173
+ const parsed = IndexSchema.safeParse(json);
174
+ if (!parsed.success) {
175
+ throw new ValidationError('invalid_index', 'index.json does not match the repository schema', parsed.error.issues.slice(0, 20).map((i) => `${i.path.join('.')}: ${i.message}`));
176
+ }
177
+ return parsed.data;
178
+ }
179
+ keyOf(index) {
180
+ if (!index.publicKey)
181
+ throw new ValidationError('no_public_key', 'This repository publishes no publicKey, so it cannot be added as signed');
182
+ try {
183
+ return parsePublicKey(index.publicKey);
184
+ }
185
+ catch (err) {
186
+ throw new ValidationError('invalid_public_key', err.message);
187
+ }
188
+ }
189
+ // ── repositories ──
190
+ repoRow(id) {
191
+ const row = this.db.select().from(pluginRepos).where(eq(pluginRepos.id, id)).get();
192
+ if (!row)
193
+ throw new NotFoundError('repo_not_found', 'No such repository');
194
+ return row;
195
+ }
196
+ publicRepo(row) {
197
+ const index = row.indexCache;
198
+ const offered = index?.publicKey && row.signingMode === 'signed' ? safeKey(index.publicKey) : null;
199
+ return {
200
+ id: row.id,
201
+ url: row.url,
202
+ name: row.name,
203
+ signingMode: row.signingMode,
204
+ publicKey: row.publicKey,
205
+ keyId: row.keyFingerprint,
206
+ keyStatus: row.keyStatus,
207
+ /** When the key changed: the new key awaiting confirmation. */
208
+ offeredKey: row.keyStatus === 'key_changed' && offered ? { publicKey: offered.base64, keyId: offered.keyId } : null,
209
+ pluginCount: index?.plugins.length ?? 0,
210
+ lastFetchedAt: row.lastFetchedAt,
211
+ lastFetchError: row.lastFetchError,
212
+ };
213
+ }
214
+ list() {
215
+ return this.db
216
+ .select()
217
+ .from(pluginRepos)
218
+ .orderBy(asc(pluginRepos.url))
219
+ .all()
220
+ .map((r) => this.publicRepo(r));
221
+ }
222
+ /**
223
+ * Adds a repository. Signed repos take two calls: the first answers 409 `confirm_key` with the key
224
+ * id, the second repeats the request with `confirmKeyId` once the admin has checked it out of band.
225
+ */
226
+ async add(raw, actor = {}) {
227
+ const input = AddRepoSchema.parse(raw);
228
+ const url = this.checkUrl(input.url);
229
+ if (this.db.select().from(pluginRepos).where(eq(pluginRepos.url, url)).get()) {
230
+ throw new ConflictError('repo_exists', 'This repository is already added');
231
+ }
232
+ const index = await this.fetchIndex(url);
233
+ let key;
234
+ if (input.signingMode === 'signed') {
235
+ key = this.keyOf(index);
236
+ if (!sameKey(input.confirmPublicKey, key.base64)) {
237
+ throw new ConflictError('confirm_key', `Confirm the repository public key ${key.base64}`, {
238
+ publicKey: key.base64,
239
+ keyId: key.keyId,
240
+ name: index.name,
241
+ });
242
+ }
243
+ }
244
+ const id = randomUUID();
245
+ this.db.transaction((tx) => {
246
+ tx.insert(pluginRepos)
247
+ .values({
248
+ id,
249
+ url,
250
+ name: index.name,
251
+ signingMode: input.signingMode,
252
+ publicKey: key?.base64 ?? null,
253
+ keyFingerprint: key?.keyId ?? null,
254
+ keyStatus: 'ok',
255
+ indexCache: index,
256
+ lastFetchedAt: this.now(),
257
+ })
258
+ .run();
259
+ writeAudit(tx, {
260
+ kind: 'config',
261
+ decision: 'plugin_repo_added',
262
+ actorKind: 'user',
263
+ actorId: actor.userId,
264
+ detail: { id, url, name: index.name, signingMode: input.signingMode, keyId: key?.keyId ?? null },
265
+ });
266
+ });
267
+ return this.publicRepo(this.repoRow(id));
268
+ }
269
+ /** Re-reads the index. A changed signing key blocks installs until re-confirmed. */
270
+ async refresh(id) {
271
+ const row = this.repoRow(id);
272
+ try {
273
+ const index = await this.fetchIndex(row.url);
274
+ let keyStatus = row.keyStatus;
275
+ if (row.signingMode === 'signed') {
276
+ const offered = index.publicKey ? safeKey(index.publicKey) : null;
277
+ const changed = offered?.base64 !== row.publicKey;
278
+ if (changed && keyStatus !== 'key_changed') {
279
+ keyStatus = 'key_changed';
280
+ writeAudit(this.db, {
281
+ kind: 'config',
282
+ decision: 'plugin_repo_key_changed',
283
+ actorKind: 'system',
284
+ detail: { id, url: row.url, pinned: row.keyFingerprint, offered: offered?.keyId ?? null },
285
+ });
286
+ }
287
+ else if (!changed)
288
+ keyStatus = 'ok';
289
+ }
290
+ this.db
291
+ .update(pluginRepos)
292
+ .set({ indexCache: index, name: index.name, keyStatus, lastFetchedAt: this.now(), lastFetchError: null })
293
+ .where(eq(pluginRepos.id, id))
294
+ .run();
295
+ }
296
+ catch (err) {
297
+ this.db
298
+ .update(pluginRepos)
299
+ .set({
300
+ lastFetchError: (err instanceof Error ? err.message : String(err)).slice(0, 300),
301
+ lastFetchedAt: this.now(),
302
+ })
303
+ .where(eq(pluginRepos.id, id))
304
+ .run();
305
+ throw err;
306
+ }
307
+ return this.publicRepo(this.repoRow(id));
308
+ }
309
+ /** Daily refresh (design §10). Failures are recorded on the row, never thrown. */
310
+ async refreshStale(maxAgeMs = 24 * 60 * 60_000) {
311
+ for (const row of this.db.select().from(pluginRepos).all()) {
312
+ if (row.lastFetchedAt && this.now().getTime() - row.lastFetchedAt.getTime() < maxAgeMs)
313
+ continue;
314
+ await this.refresh(row.id).catch(() => undefined);
315
+ }
316
+ }
317
+ /** Pins the key a refreshed index now offers, after the admin checked it against the publisher's. */
318
+ confirmKey(id, publicKey, actor = {}) {
319
+ const row = this.repoRow(id);
320
+ if (row.signingMode !== 'signed')
321
+ throw new ValidationError('not_signed', 'This repository is unsigned');
322
+ const index = row.indexCache;
323
+ const key = this.keyOf(index);
324
+ if (!sameKey(publicKey, key.base64)) {
325
+ throw new ConflictError('confirm_key', `Confirm the repository public key ${key.base64}`, {
326
+ publicKey: key.base64,
327
+ keyId: key.keyId,
328
+ });
329
+ }
330
+ this.db.transaction((tx) => {
331
+ tx.update(pluginRepos)
332
+ .set({ publicKey: key.base64, keyFingerprint: key.keyId, keyStatus: 'ok' })
333
+ .where(eq(pluginRepos.id, id))
334
+ .run();
335
+ writeAudit(tx, {
336
+ kind: 'config',
337
+ decision: 'plugin_repo_key_confirmed',
338
+ actorKind: 'user',
339
+ actorId: actor.userId,
340
+ detail: { id, url: row.url, previous: row.keyFingerprint, keyId: key.keyId },
341
+ });
342
+ });
343
+ return this.publicRepo(this.repoRow(id));
344
+ }
345
+ remove(id, actor = {}) {
346
+ const row = this.repoRow(id);
347
+ const installed = this.db.select().from(plugins).where(eq(plugins.repoId, id)).all();
348
+ if (installed.length) {
349
+ throw new ConflictError('repo_in_use', 'Uninstall the plugins installed from this repository first', {
350
+ plugins: installed.map((p) => p.pluginId),
351
+ });
352
+ }
353
+ this.db.transaction((tx) => {
354
+ tx.delete(pluginRepos).where(eq(pluginRepos.id, id)).run();
355
+ writeAudit(tx, {
356
+ kind: 'config',
357
+ decision: 'plugin_repo_removed',
358
+ actorKind: 'user',
359
+ actorId: actor.userId,
360
+ detail: { id, url: row.url },
361
+ });
362
+ });
363
+ }
364
+ /** Every plugin offered by every repo, with install/update state. */
365
+ available() {
366
+ const installed = new Map(this.db
367
+ .select()
368
+ .from(plugins)
369
+ .all()
370
+ .map((p) => [p.pluginId, p]));
371
+ const out = [];
372
+ for (const repo of this.db.select().from(pluginRepos).orderBy(asc(pluginRepos.url)).all()) {
373
+ const index = repo.indexCache;
374
+ for (const p of index?.plugins ?? []) {
375
+ const compatible = p.versions
376
+ .filter((v) => isSdkCompatible(v) && (!v.minCoreVersion || semver.gte(CORE_VERSION, v.minCoreVersion)))
377
+ .map((v) => v.version);
378
+ const latest = semver.rsort([...compatible])[0] ?? null;
379
+ const current = installed.get(p.id);
380
+ const fromHere = current?.source === 'repo' && current.repoId === repo.id;
381
+ out.push({
382
+ repoId: repo.id,
383
+ repoName: repo.name,
384
+ signingMode: repo.signingMode,
385
+ pluginId: p.id,
386
+ name: p.name,
387
+ description: p.description ?? null,
388
+ versions: p.versions.map((v) => ({ version: v.version, compatible: compatible.includes(v.version) })),
389
+ latest,
390
+ installed: current ? { version: current.version, fromThisRepo: fromHere, source: current.source } : null,
391
+ updateAvailable: !!(fromHere && latest && semver.gt(latest, current.version)),
392
+ blocked: current?.source === 'core'
393
+ ? 'core_plugin_id'
394
+ : current && !fromHere
395
+ ? 'installed_from_elsewhere'
396
+ : repo.keyStatus === 'key_changed'
397
+ ? 'key_changed'
398
+ : null,
399
+ });
400
+ }
401
+ }
402
+ return out;
403
+ }
404
+ // ── install / uninstall ──
405
+ get pluginsDir() {
406
+ return path.join(this.opts.dataDir, 'plugins');
407
+ }
408
+ get stagingDir() {
409
+ return path.join(this.opts.dataDir, 'plugins-staging');
410
+ }
411
+ /** Extracts regular files and directories only; links, devices and escaping paths fail the install. */
412
+ async extract(tarball, into) {
413
+ mkdirSync(into, { recursive: true });
414
+ let entries = 0;
415
+ let bytes = 0;
416
+ const problems = [];
417
+ await pipeline(Readable.from([tarball]), tar.x({
418
+ cwd: into,
419
+ strict: true,
420
+ preserveOwner: false,
421
+ noMtime: true,
422
+ filter: (p, entry) => {
423
+ const type = 'type' in entry ? entry.type : 'File';
424
+ const size = 'size' in entry ? Number(entry.size) : 0;
425
+ entries++;
426
+ bytes += size;
427
+ if (type !== 'File' && type !== 'OldFile' && type !== 'Directory') {
428
+ problems.push(`${p}: ${type} entries are not allowed`);
429
+ return false;
430
+ }
431
+ if (entries > LIMITS.entries || bytes > LIMITS.extractedBytes) {
432
+ problems.push('archive is too large');
433
+ return false;
434
+ }
435
+ return true;
436
+ },
437
+ })).catch((err) => {
438
+ throw new ValidationError('invalid_archive', `Could not extract the archive: ${err instanceof Error ? err.message : err}`);
439
+ });
440
+ if (problems.length)
441
+ throw new ValidationError('invalid_archive', problems[0], problems.slice(0, 20));
442
+ // Accept both a flat archive and npm-pack style (a single top-level directory, e.g. `package/`).
443
+ if (existsSync(path.join(into, 'manifest.json')))
444
+ return into;
445
+ const top = readdirSync(into);
446
+ if (top.length === 1 &&
447
+ statSync(path.join(into, top[0])).isDirectory() &&
448
+ existsSync(path.join(into, top[0], 'manifest.json'))) {
449
+ return path.join(into, top[0]);
450
+ }
451
+ throw new ValidationError('invalid_archive', 'The archive has no manifest.json at its root');
452
+ }
453
+ async install(raw, actor = {}) {
454
+ const input = InstallSchema.parse(raw);
455
+ if (this.installing.has(input.pluginId)) {
456
+ throw new ConflictError('install_in_progress', `"${input.pluginId}" is already being installed`);
457
+ }
458
+ this.installing.add(input.pluginId);
459
+ try {
460
+ return await this.installLocked(input, actor);
461
+ }
462
+ finally {
463
+ this.installing.delete(input.pluginId);
464
+ }
465
+ }
466
+ async installLocked(input, actor) {
467
+ const repo = this.repoRow(input.repoId);
468
+ if (repo.keyStatus === 'key_changed') {
469
+ throw new ConflictError('key_changed', 'The repository signing key changed; confirm the new key before installing');
470
+ }
471
+ const index = repo.indexCache;
472
+ const entry = index?.plugins.find((p) => p.id === input.pluginId);
473
+ const version = entry?.versions.find((v) => v.version === input.version);
474
+ if (!entry || !version)
475
+ throw new NotFoundError('version_not_found', `${input.pluginId}@${input.version} is not in this repository`);
476
+ if (!isSdkCompatible(version)) {
477
+ throw new ConflictError('incompatible', `${input.pluginId}@${input.version} needs plugin SDK ${version.sdk}`);
478
+ }
479
+ if (version.minCoreVersion && !semver.gte(CORE_VERSION, version.minCoreVersion)) {
480
+ throw new ConflictError('incompatible', `${input.pluginId}@${input.version} needs core ${version.minCoreVersion} or newer`);
481
+ }
482
+ const current = this.db.select().from(plugins).where(eq(plugins.pluginId, input.pluginId)).get();
483
+ if (current?.source === 'core')
484
+ throw new ConflictError('core_plugin_id', `"${input.pluginId}" is a core plugin`);
485
+ if (current && current.repoId !== repo.id) {
486
+ throw new ConflictError('installed_from_elsewhere', `"${input.pluginId}" is installed from another source; uninstall it first`);
487
+ }
488
+ if (repo.signingMode === 'unsigned' && input.confirm !== input.pluginId) {
489
+ throw new ConflictError('confirm_required', `This repository is unsigned. Type "${input.pluginId}" to install anyway`);
490
+ }
491
+ const tarballUrl = this.checkUrl(version.url, repo.url);
492
+ const tarball = await this.download(tarballUrl, LIMITS.tarballBytes);
493
+ const sha256 = createHash('sha256').update(tarball).digest('hex');
494
+ if (sha256 !== version.sha256.toLowerCase()) {
495
+ throw new ValidationError('checksum_mismatch', 'The download does not match the sha256 in the index');
496
+ }
497
+ let signatureVerified = false;
498
+ if (repo.signingMode === 'signed') {
499
+ if (!version.signature)
500
+ throw new ValidationError('signature_missing', 'The index has no signature for this version');
501
+ try {
502
+ verifySignature(tarball, version.signature, parsePublicKey(repo.publicKey));
503
+ }
504
+ catch (err) {
505
+ if (err instanceof MinisignError)
506
+ throw new ValidationError('signature_invalid', err.message);
507
+ throw err;
508
+ }
509
+ signatureVerified = true;
510
+ }
511
+ const work = path.join(this.stagingDir, randomUUID());
512
+ try {
513
+ const root = await this.extract(tarball, work);
514
+ const inspected = inspectPluginDir(root, 'repo');
515
+ if (inspected.status !== 'ok')
516
+ throw new ValidationError('invalid_plugin', inspected.error);
517
+ if (inspected.manifest.id !== input.pluginId || inspected.manifest.version !== input.version) {
518
+ throw new ValidationError('manifest_mismatch', `The archive contains ${inspected.manifest.id}@${inspected.manifest.version}, not ${input.pluginId}@${input.version}`);
519
+ }
520
+ // Swap directories with instances stopped, then let discovery update the registry row.
521
+ if (current)
522
+ await this.opts.stopPlugin(current.id);
523
+ mkdirSync(this.pluginsDir, { recursive: true });
524
+ const target = path.join(this.pluginsDir, input.pluginId);
525
+ try {
526
+ swapDirectory(root, target, path.join(this.stagingDir, `${randomUUID()}-old`));
527
+ }
528
+ catch (err) {
529
+ // The old version is back in place: bring its instances back up before reporting the failure.
530
+ if (current)
531
+ await this.opts.startPlugin(current.id);
532
+ throw err;
533
+ }
534
+ this.opts.discover();
535
+ const row = this.db.select().from(plugins).where(eq(plugins.pluginId, input.pluginId)).get();
536
+ // New installs start disabled, and an update that changes what the plugin may do is disabled
537
+ // again: enabling it is the admin's review of its binding, capabilities and hosts (design §4.2).
538
+ const review = current ? permissionChanges(current.manifest, inspected.manifest) : [];
539
+ const enabled = current ? current.enabled && review.length === 0 : false;
540
+ this.db.transaction((tx) => {
541
+ tx.update(plugins)
542
+ .set({ repoId: repo.id, sha256, signatureVerified, enabled })
543
+ .where(eq(plugins.id, row.id))
544
+ .run();
545
+ writeAudit(tx, {
546
+ kind: 'config',
547
+ decision: current ? 'plugin_updated' : 'plugin_installed',
548
+ actorKind: 'user',
549
+ actorId: actor.userId,
550
+ detail: {
551
+ pluginId: input.pluginId,
552
+ version: input.version,
553
+ previousVersion: current?.version ?? null,
554
+ repo: repo.url,
555
+ sha256,
556
+ signatureVerified,
557
+ enabled,
558
+ ...(review.length ? { needsReview: review } : {}),
559
+ },
560
+ });
561
+ });
562
+ if (enabled)
563
+ await this.opts.startPlugin(row.id);
564
+ return this.db.select().from(plugins).where(eq(plugins.id, row.id)).get();
565
+ }
566
+ finally {
567
+ rmSync(work, { recursive: true, force: true });
568
+ }
569
+ }
570
+ /** Removes an installed (repo) plugin. Blocked while any instance uses it. */
571
+ uninstall(pluginRowOrId, actor = {}) {
572
+ const row = this.db.select().from(plugins).where(eq(plugins.id, pluginRowOrId)).get() ??
573
+ this.db.select().from(plugins).where(eq(plugins.pluginId, pluginRowOrId)).get();
574
+ if (!row)
575
+ throw new NotFoundError('plugin_not_found', 'No such plugin');
576
+ if (row.source === 'core')
577
+ throw new ConflictError('core_plugin', 'Core plugins cannot be uninstalled; disable them instead');
578
+ const instances = this.db.select().from(pluginInstances).where(eq(pluginInstances.pluginId, row.id)).all();
579
+ if (instances.length) {
580
+ throw new ConflictError('plugin_has_instances', 'Delete this plugin’s endpoints first', {
581
+ instances: instances.map((i) => i.slug),
582
+ });
583
+ }
584
+ // Only ever delete inside DATA_DIR/plugins.
585
+ const dir = path.resolve(row.path);
586
+ if (dir.startsWith(path.resolve(this.pluginsDir) + path.sep))
587
+ rmSync(dir, { recursive: true, force: true });
588
+ this.db.transaction((tx) => {
589
+ tx.delete(plugins).where(eq(plugins.id, row.id)).run();
590
+ writeAudit(tx, {
591
+ kind: 'config',
592
+ decision: 'plugin_uninstalled',
593
+ actorKind: 'user',
594
+ actorId: actor.userId,
595
+ detail: { pluginId: row.pluginId, version: row.version },
596
+ });
597
+ });
598
+ }
599
+ }
600
+ function sameKey(submitted, expected) {
601
+ const key = submitted ? safeKey(submitted) : null;
602
+ return !!key && key.base64 === expected;
603
+ }
604
+ function safeKey(publicKey) {
605
+ try {
606
+ return parsePublicKey(publicKey);
607
+ }
608
+ catch {
609
+ return null;
610
+ }
611
+ }
612
+ //# sourceMappingURL=repos.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repos.js","sourceRoot":"","sources":["../../src/plugins/repos.ts"],"names":[],"mappings":"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"}