@serve.zone/gitops 3.1.1 → 32.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 (38) hide show
  1. package/.smartconfig.json +26 -7
  2. package/changelog.md +42 -0
  3. package/deno.json +1 -1
  4. package/dist_serve/bundle.js +327 -299
  5. package/dist_serve/bundle.js.map +1 -0
  6. package/dist_ts/00_commitinfo_data.js +2 -2
  7. package/dist_ts/cache/classes.cachedb.d.ts +1 -1
  8. package/dist_ts/cache/classes.cachedb.js +1 -1
  9. package/dist_ts/classes/connectionmanager.d.ts +41 -0
  10. package/dist_ts/classes/connectionmanager.js +143 -9
  11. package/dist_ts/opsserver/handlers/webhook.handler.d.ts +20 -0
  12. package/dist_ts/opsserver/handlers/webhook.handler.js +132 -14
  13. package/dist_ts/opsserver/helpers/webhookverification.d.ts +70 -0
  14. package/dist_ts/opsserver/helpers/webhookverification.js +158 -0
  15. package/dist_ts/plugins.d.ts +2 -1
  16. package/dist_ts/plugins.js +3 -2
  17. package/dist_ts/providers/classes.giteaprovider.d.ts +10 -0
  18. package/dist_ts/providers/classes.giteaprovider.js +11 -1
  19. package/dist_ts/providers/classes.gitlabprovider.d.ts +10 -0
  20. package/dist_ts/providers/classes.gitlabprovider.js +11 -1
  21. package/dist_ts_interfaces/data/connection.d.ts +27 -0
  22. package/dist_ts_interfaces/requests/webhook.d.ts +31 -0
  23. package/package.json +9 -9
  24. package/readme.md +60 -3
  25. package/ts/00_commitinfo_data.ts +1 -1
  26. package/ts/cache/classes.cachedb.ts +1 -1
  27. package/ts/classes/connectionmanager.ts +150 -8
  28. package/ts/opsserver/handlers/webhook.handler.ts +175 -14
  29. package/ts/opsserver/helpers/webhookverification.ts +202 -0
  30. package/ts/plugins.ts +2 -1
  31. package/ts/providers/classes.giteaprovider.ts +11 -0
  32. package/ts/providers/classes.gitlabprovider.ts +11 -0
  33. package/ts_interfaces/data/connection.ts +29 -0
  34. package/ts_interfaces/requests/webhook.ts +42 -0
  35. package/ts_web/00_commitinfo_data.ts +1 -1
  36. package/ts_web/appstate.ts +46 -0
  37. package/ts_web/elements/views/connections/index.ts +89 -0
  38. package/readme.todo.md +0 -3
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/gitops',
6
- version: '3.1.1',
6
+ version: '32.1.0',
7
7
  description: 'GitOps management app for Gitea and GitLab - manage secrets, browse projects, view CI pipelines, and stream build logs'
8
8
  };
9
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxvQkFBb0I7SUFDMUIsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLHdIQUF3SDtDQUN0SSxDQUFBIn0=
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxvQkFBb0I7SUFDMUIsT0FBTyxFQUFFLFFBQVE7SUFDakIsV0FBVyxFQUFFLHdIQUF3SDtDQUN0SSxDQUFBIn0=
@@ -5,7 +5,7 @@ export interface ICacheDbOptions {
5
5
  debug?: boolean;
6
6
  }
7
7
  /**
8
- * Singleton wrapper around LocalTsmDb + SmartdataDb.
8
+ * Singleton wrapper around SmartMongo's NoSQLDB memory server and SmartData.
9
9
  * Provides a managed MongoDB-compatible cache database.
10
10
  */
11
11
  export declare class CacheDb {
@@ -1,7 +1,7 @@
1
1
  import * as plugins from '../plugins.js';
2
2
  import { logger } from '../logging.js';
3
3
  /**
4
- * Singleton wrapper around LocalTsmDb + SmartdataDb.
4
+ * Singleton wrapper around SmartMongo's NoSQLDB memory server and SmartData.
5
5
  * Provides a managed MongoDB-compatible cache database.
6
6
  */
7
7
  export class CacheDb {
@@ -30,8 +30,20 @@ export declare class ConnectionManager {
30
30
  */
31
31
  private migrateTokenToKeychain;
32
32
  private migrateRegistryTokenToKeychain;
33
+ /**
34
+ * Connections stored before webhook verification existed carry no secret. Nothing in
35
+ * gitops can create the webhook at the provider (neither provider implementation nor
36
+ * the Gitea/GitLab clients expose a hooks endpoint), so the secret is minted here and
37
+ * the connection is marked 'unverified': its deliveries stay refused until an operator
38
+ * copies the secret into the provider's webhook configuration and confirms it.
39
+ */
40
+ private backfillWebhookSecret;
33
41
  private persistConnection;
34
42
  private removeConnection;
43
+ /**
44
+ * The shape handed to API callers: every secret is masked, never the real value.
45
+ */
46
+ private toPublicConnection;
35
47
  getConnections(): interfaces.data.IProviderConnection[];
36
48
  getConnection(id: string): interfaces.data.IProviderConnection | undefined;
37
49
  createConnection(name: string, providerType: interfaces.data.TProviderType, baseUrl: string, token: string, groupFilter?: string, registryUrl?: string, registryUsername?: string, registryToken?: string): Promise<interfaces.data.IProviderConnection>;
@@ -46,6 +58,35 @@ export declare class ConnectionManager {
46
58
  }): Promise<interfaces.data.IProviderConnection>;
47
59
  deleteConnection(id: string): Promise<void>;
48
60
  pauseConnection(id: string, paused: boolean): Promise<interfaces.data.IProviderConnection>;
61
+ /**
62
+ * Reveals the webhook secret to an already authenticated caller — the operator has to
63
+ * transfer it into the provider's webhook configuration by hand, because no provider
64
+ * API surface in this app creates webhooks.
65
+ */
66
+ /**
67
+ * A stored-but-unreadable secret is reported as such, so an operator sees a secret-store
68
+ * outage instead of a connection that appears to have lost its secret.
69
+ */
70
+ private assertWebhookSecretReadable;
71
+ getWebhookSecret(id: string): {
72
+ secret: string;
73
+ status: interfaces.data.TWebhookStatus;
74
+ };
75
+ /**
76
+ * Mints a fresh webhook secret. The provider still holds the previous one, so the
77
+ * connection goes back to 'unverified' until the new secret is confirmed.
78
+ */
79
+ rotateWebhookSecret(id: string): Promise<{
80
+ secret: string;
81
+ status: interfaces.data.TWebhookStatus;
82
+ }>;
83
+ /**
84
+ * Records that the provider side now holds the current secret; deliveries that carry a
85
+ * valid signature are accepted from here on.
86
+ */
87
+ confirmWebhookSecret(id: string): Promise<{
88
+ status: interfaces.data.TWebhookStatus;
89
+ }>;
49
90
  testConnection(id: string): Promise<{
50
91
  ok: boolean;
51
92
  error?: string;
@@ -5,6 +5,12 @@ const LEGACY_CONNECTIONS_FILE = './.nogit/connections.json';
5
5
  const CONNECTIONS_PREFIX = '/connections/';
6
6
  const KEYCHAIN_PREFIX = 'keychain:';
7
7
  const getRegistryTokenSecretId = (connectionId) => `${connectionId}:registry`;
8
+ const getWebhookSecretId = (connectionId) => `${connectionId}:webhook`;
9
+ /**
10
+ * Mints a webhook secret. 32 random bytes as hex: long enough that a delivery carrying
11
+ * it proves the sender was configured by us, short enough to paste into a provider UI.
12
+ */
13
+ const mintWebhookSecret = () => plugins.crypto.randomBytes(32).toString('hex');
8
14
  /**
9
15
  * Manages provider connections — persists each connection as an
10
16
  * individual JSON file via StorageManager. Tokens are stored in
@@ -109,7 +115,25 @@ export class ConnectionManager {
109
115
  else if (conn.registryToken && conn.registryToken !== '***') {
110
116
  await this.migrateRegistryTokenToKeychain(conn);
111
117
  }
118
+ if (conn.webhookSecret?.startsWith(KEYCHAIN_PREFIX)) {
119
+ const webhookSecretId = conn.webhookSecret.substring(KEYCHAIN_PREFIX.length);
120
+ const realWebhookSecret = await this.smartSecret.getSecret(webhookSecretId);
121
+ if (realWebhookSecret) {
122
+ conn.webhookSecret = realWebhookSecret;
123
+ }
124
+ else {
125
+ // The sentinel proves a secret was stored under this id, so an empty read is a
126
+ // keychain failure, not a missing secret. Minting a replacement here would
127
+ // overwrite the operator's confirmed secret under the same id and lose it, so
128
+ // the connection is flagged instead and its deliveries are refused by name.
129
+ logger.warn(`Webhook secret for connection ${conn.id} is stored but unreadable — deliveries are ` +
130
+ 'refused until the secret store returns it again; the stored secret is left untouched');
131
+ conn.webhookSecret = undefined;
132
+ conn.webhookSecretUnreadable = true;
133
+ }
134
+ }
112
135
  this.connections.push(conn);
136
+ await this.backfillWebhookSecret(conn);
113
137
  }
114
138
  }
115
139
  if (this.connections.length > 0) {
@@ -150,6 +174,29 @@ export class ConnectionManager {
150
174
  logger.warn(`Failed to migrate registry token for ${conn.id} to keychain: ${err}`);
151
175
  }
152
176
  }
177
+ /**
178
+ * Connections stored before webhook verification existed carry no secret. Nothing in
179
+ * gitops can create the webhook at the provider (neither provider implementation nor
180
+ * the Gitea/GitLab clients expose a hooks endpoint), so the secret is minted here and
181
+ * the connection is marked 'unverified': its deliveries stay refused until an operator
182
+ * copies the secret into the provider's webhook configuration and confirms it.
183
+ */
184
+ async backfillWebhookSecret(conn) {
185
+ // A stored-but-unreadable secret is not a missing one. Minting here would write a new
186
+ // secret over the same keychain id and destroy confirmed operator material because of
187
+ // a transient read failure, so this connection is left exactly as it is on disk.
188
+ if (conn.webhookSecretUnreadable)
189
+ return;
190
+ if (conn.webhookSecret && conn.webhookStatus)
191
+ return;
192
+ if (!conn.webhookSecret) {
193
+ conn.webhookSecret = mintWebhookSecret();
194
+ }
195
+ conn.webhookStatus = 'unverified';
196
+ await this.persistConnection(conn);
197
+ logger.warn(`Connection "${conn.name}" had no webhook secret — minted one and marked the webhook unverified. ` +
198
+ 'Webhook deliveries are refused until the secret is set at the provider and confirmed.');
199
+ }
153
200
  async persistConnection(conn) {
154
201
  // Store real token in keychain
155
202
  await this.smartSecret.setSecret(conn.id, conn.token);
@@ -159,25 +206,52 @@ export class ConnectionManager {
159
206
  else {
160
207
  await this.smartSecret.deleteSecret(getRegistryTokenSecretId(conn.id));
161
208
  }
209
+ // A connection whose secret is stored but unreadable keeps both its keychain entry and
210
+ // its sentinel: writing would replace material we could not read, deleting would throw
211
+ // it away. Every other persist path (status updates, health checks) runs through here,
212
+ // so this is where the stored secret survives a secret-store outage.
213
+ if (conn.webhookSecretUnreadable) {
214
+ // nothing to write — the stored secret and sentinel stay as they are
215
+ }
216
+ else if (conn.webhookSecret) {
217
+ await this.smartSecret.setSecret(getWebhookSecretId(conn.id), conn.webhookSecret);
218
+ }
219
+ else {
220
+ await this.smartSecret.deleteSecret(getWebhookSecretId(conn.id));
221
+ }
162
222
  // Save JSON with sentinel value
163
223
  const jsonConn = {
164
224
  ...conn,
165
225
  token: `${KEYCHAIN_PREFIX}${conn.id}`,
166
226
  registryToken: conn.registryToken ? `${KEYCHAIN_PREFIX}${getRegistryTokenSecretId(conn.id)}` : undefined,
227
+ webhookSecret: conn.webhookSecret || conn.webhookSecretUnreadable
228
+ ? `${KEYCHAIN_PREFIX}${getWebhookSecretId(conn.id)}`
229
+ : undefined,
230
+ // Runtime-only flag: it describes this process's view of the secret store, not the
231
+ // connection, and persisting it would outlive the outage that caused it.
232
+ webhookSecretUnreadable: undefined,
167
233
  };
168
234
  await this.storageManager.setJSON(`${CONNECTIONS_PREFIX}${conn.id}.json`, jsonConn);
169
235
  }
170
236
  async removeConnection(id) {
171
237
  await this.smartSecret.deleteSecret(id);
172
238
  await this.smartSecret.deleteSecret(getRegistryTokenSecretId(id));
239
+ await this.smartSecret.deleteSecret(getWebhookSecretId(id));
173
240
  await this.storageManager.delete(`${CONNECTIONS_PREFIX}${id}.json`);
174
241
  }
175
- getConnections() {
176
- return this.connections.map((c) => ({
177
- ...c,
242
+ /**
243
+ * The shape handed to API callers: every secret is masked, never the real value.
244
+ */
245
+ toPublicConnection(conn) {
246
+ return {
247
+ ...conn,
178
248
  token: '***',
179
- registryToken: c.registryToken ? '***' : undefined,
180
- }));
249
+ registryToken: conn.registryToken ? '***' : undefined,
250
+ webhookSecret: conn.webhookSecret ? '***' : undefined,
251
+ };
252
+ }
253
+ getConnections() {
254
+ return this.connections.map((c) => this.toPublicConnection(c));
181
255
  }
182
256
  getConnection(id) {
183
257
  return this.connections.find((c) => c.id === id);
@@ -195,11 +269,15 @@ export class ConnectionManager {
195
269
  registryUrl: registryUrl || undefined,
196
270
  registryUsername: registryUsername || undefined,
197
271
  registryToken: registryToken || undefined,
272
+ // Minted with the connection so the operator can paste it into the provider's
273
+ // webhook form right away; no earlier provider state can hold a stale secret.
274
+ webhookSecret: mintWebhookSecret(),
275
+ webhookStatus: 'active',
198
276
  };
199
277
  this.connections.push(connection);
200
278
  await this.persistConnection(connection);
201
279
  logger.success(`Connection created: ${name} (${providerType})`);
202
- return { ...connection, token: '***', registryToken: connection.registryToken ? '***' : undefined };
280
+ return this.toPublicConnection(connection);
203
281
  }
204
282
  async updateConnection(id, updates) {
205
283
  const conn = this.connections.find((c) => c.id === id);
@@ -222,7 +300,7 @@ export class ConnectionManager {
222
300
  if (updates.registryToken !== undefined)
223
301
  conn.registryToken = updates.registryToken || undefined;
224
302
  await this.persistConnection(conn);
225
- return { ...conn, token: '***', registryToken: conn.registryToken ? '***' : undefined };
303
+ return this.toPublicConnection(conn);
226
304
  }
227
305
  async deleteConnection(id) {
228
306
  const idx = this.connections.findIndex((c) => c.id === id);
@@ -239,7 +317,63 @@ export class ConnectionManager {
239
317
  conn.status = paused ? 'paused' : 'disconnected';
240
318
  await this.persistConnection(conn);
241
319
  logger.info(`Connection ${paused ? 'paused' : 'resumed'}: ${conn.name}`);
242
- return { ...conn, token: '***', registryToken: conn.registryToken ? '***' : undefined };
320
+ return this.toPublicConnection(conn);
321
+ }
322
+ /**
323
+ * Reveals the webhook secret to an already authenticated caller — the operator has to
324
+ * transfer it into the provider's webhook configuration by hand, because no provider
325
+ * API surface in this app creates webhooks.
326
+ */
327
+ /**
328
+ * A stored-but-unreadable secret is reported as such, so an operator sees a secret-store
329
+ * outage instead of a connection that appears to have lost its secret.
330
+ */
331
+ assertWebhookSecretReadable(conn) {
332
+ if (conn.webhookSecretUnreadable) {
333
+ throw new Error(`Webhook secret for connection ${conn.id} is stored but unreadable — the secret store did not return it`);
334
+ }
335
+ }
336
+ getWebhookSecret(id) {
337
+ const conn = this.connections.find((c) => c.id === id);
338
+ if (!conn)
339
+ throw new Error(`Connection not found: ${id}`);
340
+ this.assertWebhookSecretReadable(conn);
341
+ if (!conn.webhookSecret)
342
+ throw new Error(`Connection has no webhook secret: ${id}`);
343
+ return { secret: conn.webhookSecret, status: conn.webhookStatus ?? 'unverified' };
344
+ }
345
+ /**
346
+ * Mints a fresh webhook secret. The provider still holds the previous one, so the
347
+ * connection goes back to 'unverified' until the new secret is confirmed.
348
+ */
349
+ async rotateWebhookSecret(id) {
350
+ const conn = this.connections.find((c) => c.id === id);
351
+ if (!conn)
352
+ throw new Error(`Connection not found: ${id}`);
353
+ conn.webhookSecret = mintWebhookSecret();
354
+ conn.webhookStatus = 'unverified';
355
+ // Rotation is the operator's explicit decision to replace the stored secret, which is
356
+ // also the way out of an unreadable one — unlike the automatic backfill.
357
+ conn.webhookSecretUnreadable = undefined;
358
+ await this.persistConnection(conn);
359
+ logger.info(`Webhook secret rotated for connection "${conn.name}" — webhook is unverified again`);
360
+ return { secret: conn.webhookSecret, status: conn.webhookStatus };
361
+ }
362
+ /**
363
+ * Records that the provider side now holds the current secret; deliveries that carry a
364
+ * valid signature are accepted from here on.
365
+ */
366
+ async confirmWebhookSecret(id) {
367
+ const conn = this.connections.find((c) => c.id === id);
368
+ if (!conn)
369
+ throw new Error(`Connection not found: ${id}`);
370
+ this.assertWebhookSecretReadable(conn);
371
+ if (!conn.webhookSecret)
372
+ throw new Error(`Connection has no webhook secret: ${id}`);
373
+ conn.webhookStatus = 'active';
374
+ await this.persistConnection(conn);
375
+ logger.success(`Webhook confirmed for connection "${conn.name}"`);
376
+ return { status: conn.webhookStatus };
243
377
  }
244
378
  async testConnection(id) {
245
379
  const conn = this.connections.find((c) => c.id === id);
@@ -299,4 +433,4 @@ export class ConnectionManager {
299
433
  }
300
434
  }
301
435
  }
302
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29ubmVjdGlvbm1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9jbGFzc2VzL2Nvbm5lY3Rpb25tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFdkMsT0FBTyxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFHcEYsTUFBTSx1QkFBdUIsR0FBRywyQkFBMkIsQ0FBQztBQUM1RCxNQUFNLGtCQUFrQixHQUFHLGVBQWUsQ0FBQztBQUMzQyxNQUFNLGVBQWUsR0FBRyxXQUFXLENBQUM7QUFFcEMsTUFBTSx3QkFBd0IsR0FBRyxDQUFDLFlBQW9CLEVBQVUsRUFBRSxDQUFDLEdBQUcsWUFBWSxXQUFXLENBQUM7QUFFOUY7Ozs7R0FJRztBQUNILE1BQU0sT0FBTyxpQkFBaUI7SUFDcEIsV0FBVyxHQUEwQyxFQUFFLENBQUM7SUFDeEQsY0FBYyxDQUFpQjtJQUMvQixXQUFXLENBQWtDO0lBQ3JELGlFQUFpRTtJQUMxRCxlQUFlLEdBQWtCLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUUxRCxZQUFZLGNBQThCLEVBQUUsV0FBNEM7UUFDdEYsSUFBSSxDQUFDLGNBQWMsR0FBRyxjQUFjLENBQUM7UUFDckMsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7SUFDakMsQ0FBQztJQUVELEtBQUssQ0FBQyxJQUFJO1FBQ1IsTUFBTSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUMvQixNQUFNLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUM3Qiw4Q0FBOEM7UUFDOUMsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztJQUNuRCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssS0FBSyxD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
436
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29ubmVjdGlvbm1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9jbGFzc2VzL2Nvbm5lY3Rpb25tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFdkMsT0FBTyxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFHcEYsTUFBTSx1QkFBdUIsR0FBRywyQkFBMkIsQ0FBQztBQUM1RCxNQUFNLGtCQUFrQixHQUFHLGVBQWUsQ0FBQztBQUMzQyxNQUFNLGVBQWUsR0FBRyxXQUFXLENBQUM7QUFFcEMsTUFBTSx3QkFBd0IsR0FBRyxDQUFDLFlBQW9CLEVBQVUsRUFBRSxDQUFDLEdBQUcsWUFBWSxXQUFXLENBQUM7QUFDOUYsTUFBTSxrQkFBa0IsR0FBRyxDQUFDLFlBQW9CLEVBQVUsRUFBRSxDQUFDLEdBQUcsWUFBWSxVQUFVLENBQUM7QUFFdkY7OztHQUdHO0FBQ0gsTUFBTSxpQkFBaUIsR0FBRyxHQUFXLEVBQUUsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7QUFFdkY7Ozs7R0FJRztBQUNILE1BQU0sT0FBTyxpQkFBaUI7SUFDcEIsV0FBVyxHQUEwQyxFQUFFLENBQUM7SUFDeEQsY0FBYyxDQUFpQjtJQUMvQixXQUFXLENBQWtDO0lBQ3JELGlFQUFpRTtJQUMxRCxlQUFlLEdBQWtCLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUUxRCxZQUFZLGNBQThCLEVBQUUsV0FBNEM7UUFDdEYsSUFBSSxDQUFDLGNBQWMsR0FBRyxjQUFjLENBQUM7UUFDckMsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7SUFDakMsQ0FBQztJQUVE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
@@ -1,7 +1,27 @@
1
1
  import * as plugins from '../../plugins.js';
2
2
  import type { OpsServer } from '../classes.opsserver.js';
3
+ import * as interfaces from '../../../dist_ts_interfaces/index.js';
4
+ /** Route pattern of the delivery endpoint. */
5
+ export declare const webhookRoutePattern = "/webhook/:connectionId";
6
+ /** The concrete delivery path an operator configures at the provider. */
7
+ export declare const webhookDeliveryPath: (connectionIdArg: string) => string;
3
8
  export declare class WebhookHandler {
4
9
  private opsServerRef;
10
+ typedrouter: plugins.typedrequest.TypedRouter<interfaces.typedrequestInterfaces.ITypedRequest>;
5
11
  constructor(opsServerRef: OpsServer);
12
+ private get connectionManager();
13
+ private get actionLog();
14
+ /**
15
+ * Refuses a delivery. The refusal name is the whole answer — no payload is echoed and
16
+ * nothing about the presented or expected secret is logged.
17
+ */
18
+ private refuse;
19
+ private webhookSettingsFor;
20
+ /**
21
+ * Operator-facing side of the webhook: reveal, rotate and confirm the shared secret.
22
+ * Neither provider implementation creates webhooks through the API, so the secret is
23
+ * transferred into the provider's webhook configuration by hand.
24
+ */
25
+ private registerHandlers;
6
26
  registerRoutes(typedserver: plugins.typedserver.TypedServer): void;
7
27
  }
@@ -1,28 +1,146 @@
1
1
  import * as plugins from '../../plugins.js';
2
2
  import { logger } from '../../logging.js';
3
3
  import * as interfaces from '../../../dist_ts_interfaces/index.js';
4
+ import { requireValidIdentity } from '../helpers/guards.js';
5
+ import { checkWebhookConnection, readBoundedWebhookBody, verifyWebhookDelivery, webhookEventHeaderFor, webhookSecretHeaderFor, } from '../helpers/webhookverification.js';
6
+ /** Route pattern of the delivery endpoint. */
7
+ export const webhookRoutePattern = '/webhook/:connectionId';
8
+ /** The concrete delivery path an operator configures at the provider. */
9
+ export const webhookDeliveryPath = (connectionIdArg) => `/webhook/${connectionIdArg}`;
10
+ /**
11
+ * HTTP status per refusal. Everything the caller could fix by presenting the right
12
+ * secret is a 401; the rest describes the request itself — except
13
+ * 'webhook-secret-unreadable', which is our own transient fault and is answered 503 so a
14
+ * provider retries instead of an operator rotating a secret that is still correct.
15
+ */
16
+ const refusalStatusCodes = {
17
+ 'webhook-connection-unknown': 404,
18
+ 'webhook-connection-unverified': 401,
19
+ 'webhook-secret-missing': 401,
20
+ 'webhook-secret-unreadable': 503,
21
+ 'webhook-length-missing': 411,
22
+ 'webhook-body-too-large': 413,
23
+ 'webhook-body-unreadable': 400,
24
+ 'webhook-signature-missing': 401,
25
+ 'webhook-signature-invalid': 401,
26
+ };
4
27
  export class WebhookHandler {
5
28
  opsServerRef;
29
+ typedrouter = new plugins.typedrequest.TypedRouter();
6
30
  constructor(opsServerRef) {
7
31
  this.opsServerRef = opsServerRef;
32
+ this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
33
+ this.registerHandlers();
34
+ }
35
+ get connectionManager() {
36
+ return this.opsServerRef.gitopsAppRef.connectionManager;
37
+ }
38
+ get actionLog() {
39
+ return this.opsServerRef.gitopsAppRef.actionLog;
40
+ }
41
+ /**
42
+ * Refuses a delivery. The refusal name is the whole answer — no payload is echoed and
43
+ * nothing about the presented or expected secret is logged.
44
+ */
45
+ refuse(refusalArg, connectionIdArg, connectionNameArg) {
46
+ const target = connectionNameArg
47
+ ? `connection ${connectionNameArg} (${connectionIdArg})`
48
+ : `connection ${connectionIdArg}`;
49
+ logger.warn(`Webhook refused: ${refusalArg} for ${target}`);
50
+ return new Response(JSON.stringify({ error: refusalArg }), {
51
+ status: refusalStatusCodes[refusalArg],
52
+ headers: { 'Content-Type': 'application/json' },
53
+ });
54
+ }
55
+ webhookSettingsFor(connectionIdArg) {
56
+ const connection = this.connectionManager.getConnection(connectionIdArg);
57
+ if (!connection) {
58
+ throw new plugins.typedrequest.TypedResponseError(`Connection not found: ${connectionIdArg}`);
59
+ }
60
+ const { secret, status } = this.connectionManager.getWebhookSecret(connectionIdArg);
61
+ return {
62
+ connectionId: connection.id,
63
+ providerType: connection.providerType,
64
+ deliveryPath: webhookDeliveryPath(connection.id),
65
+ headerName: webhookSecretHeaderFor(connection.providerType),
66
+ secret,
67
+ status,
68
+ };
69
+ }
70
+ /**
71
+ * Operator-facing side of the webhook: reveal, rotate and confirm the shared secret.
72
+ * Neither provider implementation creates webhooks through the API, so the secret is
73
+ * transferred into the provider's webhook configuration by hand.
74
+ */
75
+ registerHandlers() {
76
+ this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('getWebhookSettings', async (dataArg) => {
77
+ await requireValidIdentity(this.opsServerRef.adminHandler, dataArg);
78
+ return { webhookSettings: this.webhookSettingsFor(dataArg.connectionId) };
79
+ }));
80
+ this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('rotateWebhookSecret', async (dataArg) => {
81
+ await requireValidIdentity(this.opsServerRef.adminHandler, dataArg);
82
+ await this.connectionManager.rotateWebhookSecret(dataArg.connectionId);
83
+ const webhookSettings = this.webhookSettingsFor(dataArg.connectionId);
84
+ this.actionLog.append({
85
+ actionType: 'update',
86
+ entityType: 'connection',
87
+ entityId: dataArg.connectionId,
88
+ entityName: this.connectionManager.getConnection(dataArg.connectionId)?.name || dataArg.connectionId,
89
+ details: 'Rotated webhook secret — webhook is unverified until the new secret is set at the provider',
90
+ username: dataArg.identity.username,
91
+ });
92
+ return { webhookSettings };
93
+ }));
94
+ this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('confirmWebhookSecret', async (dataArg) => {
95
+ await requireValidIdentity(this.opsServerRef.adminHandler, dataArg);
96
+ const result = await this.connectionManager.confirmWebhookSecret(dataArg.connectionId);
97
+ this.actionLog.append({
98
+ actionType: 'update',
99
+ entityType: 'connection',
100
+ entityId: dataArg.connectionId,
101
+ entityName: this.connectionManager.getConnection(dataArg.connectionId)?.name || dataArg.connectionId,
102
+ details: 'Confirmed the webhook secret is configured at the provider',
103
+ username: dataArg.identity.username,
104
+ });
105
+ return result;
106
+ }));
8
107
  }
9
108
  registerRoutes(typedserver) {
10
- typedserver.addRoute('/webhook/:connectionId', 'POST', async (ctx) => {
109
+ typedserver.addRoute(webhookRoutePattern, 'POST', async (ctx) => {
11
110
  const connectionId = ctx.params.connectionId;
12
- // Validate connection exists
13
- const connection = this.opsServerRef.gitopsAppRef.connectionManager.getConnection(connectionId);
111
+ // The connection carries the secret, so it is resolved before any body work.
112
+ const connection = this.connectionManager.getConnection(connectionId);
14
113
  if (!connection) {
15
- return new Response(JSON.stringify({ error: 'Connection not found' }), {
16
- status: 404,
17
- headers: { 'Content-Type': 'application/json' },
18
- });
114
+ return this.refuse('webhook-connection-unknown', connectionId);
115
+ }
116
+ // Everything that does not need the body is decided before buffering it.
117
+ const precondition = checkWebhookConnection(connection);
118
+ if (precondition) {
119
+ return this.refuse(precondition, connectionId, connection.name);
120
+ }
121
+ // The raw bytes are what the provider signed; parsing and re-serializing would
122
+ // change key order and whitespace and invalidate every genuine signature. The body
123
+ // is read through the bounded reader rather than ctx.arrayBuffer(), which buffers
124
+ // whatever an unauthenticated caller sends.
125
+ const body = await readBoundedWebhookBody({
126
+ headers: ctx.headers,
127
+ body: () => ctx.request.body,
128
+ });
129
+ if (!body.ok) {
130
+ return this.refuse(body.refusal, connectionId, connection.name);
131
+ }
132
+ const verification = verifyWebhookDelivery({
133
+ connection,
134
+ headers: ctx.headers,
135
+ rawBody: body.rawBody,
136
+ });
137
+ if (!verification.ok) {
138
+ return this.refuse(verification.refusal, connectionId, connection.name);
19
139
  }
20
- // Parse event type from provider-specific headers
21
- const giteaEvent = ctx.headers.get('X-Gitea-Event');
22
- const gitlabEvent = ctx.headers.get('X-Gitlab-Event');
23
- const event = giteaEvent || gitlabEvent || 'unknown';
24
- const provider = giteaEvent ? 'gitea' : gitlabEvent ? 'gitlab' : 'unknown';
25
- logger.info(`Webhook received: ${provider}/${event} for connection ${connection.name} (${connectionId})`);
140
+ // The provider is the one we have a connection with, never the one the caller claims.
141
+ const provider = connection.providerType;
142
+ const event = ctx.headers.get(webhookEventHeaderFor(provider)) || 'unknown';
143
+ logger.info(`Webhook accepted: ${provider}/${event} for connection ${connection.name} (${connectionId})`);
26
144
  // Broadcast to all connected frontends via TypedSocket
27
145
  try {
28
146
  const typedsocket = this.opsServerRef.server.typedserver.typedsocket;
@@ -52,4 +170,4 @@ export class WebhookHandler {
52
170
  logger.info('WebhookHandler routes registered');
53
171
  }
54
172
  }
55
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViaG9vay5oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdHMvb3Bzc2VydmVyL2hhbmRsZXJzL3dlYmhvb2suaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBQzVDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUUxQyxPQUFPLEtBQUssVUFBVSxNQUFNLGlDQUFpQyxDQUFDO0FBRTlELE1BQU0sT0FBTyxjQUFjO0lBQ0w7SUFBcEIsWUFBb0IsWUFBdUI7UUFBdkIsaUJBQVksR0FBWixZQUFZLENBQVc7SUFBRyxDQUFDO0lBRXhDLGNBQWMsQ0FBQyxXQUE0QztRQUNoRSxXQUFXLENBQUMsUUFBUSxDQUFDLHdCQUF3QixFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLEVBQUU7WUFDbkUsTUFBTSxZQUFZLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUM7WUFFN0MsNkJBQTZCO1lBQzdCLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLGlCQUFpQixDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUNoRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQ2hCLE9BQU8sSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEtBQUssRUFBRSxzQkFBc0IsRUFBRSxDQUFDLEVBQUU7b0JBQ3JFLE1BQU0sRUFBRSxHQUFHO29CQUNYLE9BQU8sRUFBRSxFQUFFLGNBQWMsRUFBRSxrQkFBa0IsRUFBRTtpQkFDaEQsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUVELGtEQUFrRDtZQUNsRCxNQUFNLFVBQVUsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUNwRCxNQUFNLFdBQVcsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ3RELE1BQU0sS0FBSyxHQUFHLFVBQVUsSUFBSSxXQUFXLElBQUksU0FBUyxDQUFDO1lBQ3JELE1BQU0sUUFBUSxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBRTNFLE1BQU0sQ0FBQyxJQUFJLENBQUMscUJBQXFCLFFBQVEsSUFBSSxLQUFLLG1CQUFtQixVQUFVLENBQUMsSUFBSSxLQUFLLFlBQVksR0FBRyxDQUFDLENBQUM7WUFFMUcsdURBQXVEO1lBQ3ZELElBQUksQ0FBQztnQkFDSCxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDO2dCQUNyRSxJQUFJLFdBQVcsRUFBRSxDQUFDO29CQUNoQixNQUFNLFdBQVcsR0FBRyxNQUFNLFdBQVcsQ0FBQyw2QkFBNkIsQ0FBQyxlQUFlLENBQUMsQ0FBQztvQkFDckYsS0FBSyxNQUFNLElBQUksSUFBSSxXQUFXLEVBQUUsQ0FBQzt3QkFDL0IsTUFBTSxHQUFHLEdBQUcsV0FBVyxDQUFDLGtCQUFrQixDQUN4QyxxQkFBcUIsRUFDckIsSUFBSSxDQUNMLENBQUM7d0JBQ0YsR0FBRyxDQUFDLElBQUksQ0FBQzs0QkFDUCxZQUFZOzRCQUNaLFFBQVE7NEJBQ1IsS0FBSzs0QkFDTCxTQUFTLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRTt5QkFDdEIsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQVEsRUFBRSxFQUFFOzRCQUNwQixNQUFNLENBQUMsSUFBSSxDQUFDLDRCQUE0QixHQUFHLENBQUMsT0FBTyxJQUFJLEdBQUcsRUFBRSxDQUFDLENBQUM7d0JBQ2hFLENBQUMsQ0FBQyxDQUFDO29CQUNMLENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7WUFBQyxPQUFPLEdBQVEsRUFBRSxDQUFDO2dCQUNsQixNQUFNLENBQUMsSUFBSSxDQUFDLHNDQUFzQyxHQUFHLENBQUMsT0FBTyxJQUFJLEdBQUcsRUFBRSxDQUFDLENBQUM7WUFDMUUsQ0FBQztZQUVELE9BQU8sSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFO2dCQUNoRCxNQUFNLEVBQUUsR0FBRztnQkFDWCxPQUFPLEVBQUUsRUFBRSxjQUFjLEVBQUUsa0JBQWtCLEVBQUU7YUFDaEQsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxNQUFNLENBQUMsSUFBSSxDQUFDLGtDQUFrQyxDQUFDLENBQUM7SUFDbEQsQ0FBQztDQUNGIn0=
173
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViaG9vay5oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdHMvb3Bzc2VydmVyL2hhbmRsZXJzL3dlYmhvb2suaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBQzVDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUUxQyxPQUFPLEtBQUssVUFBVSxNQUFNLGlDQUFpQyxDQUFDO0FBQzlELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzVELE9BQU8sRUFDTCxzQkFBc0IsRUFDdEIsc0JBQXNCLEVBQ3RCLHFCQUFxQixFQUNyQixxQkFBcUIsRUFDckIsc0JBQXNCLEdBRXZCLE1BQU0sbUNBQW1DLENBQUM7QUFFM0MsOENBQThDO0FBQzlDLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLHdCQUF3QixDQUFDO0FBRTVELHlFQUF5RTtBQUN6RSxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLGVBQXVCLEVBQVUsRUFBRSxDQUNyRSxZQUFZLGVBQWUsRUFBRSxDQUFDO0FBRWhDOzs7OztHQUtHO0FBQ0gsTUFBTSxrQkFBa0IsR0FBb0M7SUFDMUQsNEJBQTRCLEVBQUUsR0FBRztJQUNqQywrQkFBK0IsRUFBRSxHQUFHO0lBQ3BDLHdCQUF3QixFQUFFLEdBQUc7SUFDN0IsMkJBQTJCLEVBQUUsR0FBRztJQUNoQyx3QkFBd0IsRUFBRSxHQUFHO0lBQzdCLHdCQUF3QixFQUFFLEdBQUc7SUFDN0IseUJBQXlCLEVBQUUsR0FBRztJQUM5QiwyQkFBMkIsRUFBRSxHQUFHO0lBQ2hDLDJCQUEyQixFQUFFLEdBQUc7Q0FDakMsQ0FBQztBQUVGLE1BQU0sT0FBTyxjQUFjO0lBR0w7SUFGYixXQUFXLEdBQUcsSUFBSSxPQUFPLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBRTVE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