@oktis-works/core 0.5.15 → 0.7.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 (55) hide show
  1. package/dist/cache/tags.d.ts +12 -0
  2. package/dist/cache/tags.d.ts.map +1 -0
  3. package/dist/cache/tags.js +55 -0
  4. package/dist/cache/tags.js.map +1 -0
  5. package/dist/comments/service.d.ts +54 -0
  6. package/dist/comments/service.d.ts.map +1 -0
  7. package/dist/comments/service.js +166 -0
  8. package/dist/comments/service.js.map +1 -0
  9. package/dist/content/service.d.ts.map +1 -1
  10. package/dist/content/service.js +24 -14
  11. package/dist/content/service.js.map +1 -1
  12. package/dist/fields/location-rules.d.ts +3 -1
  13. package/dist/fields/location-rules.d.ts.map +1 -1
  14. package/dist/fields/location-rules.js +1 -0
  15. package/dist/fields/location-rules.js.map +1 -1
  16. package/dist/fields/service.d.ts +41 -0
  17. package/dist/fields/service.d.ts.map +1 -1
  18. package/dist/fields/service.js +134 -0
  19. package/dist/fields/service.js.map +1 -1
  20. package/dist/fields/types/registry.d.ts +18 -0
  21. package/dist/fields/types/registry.d.ts.map +1 -1
  22. package/dist/fields/types/registry.js +13 -0
  23. package/dist/fields/types/registry.js.map +1 -1
  24. package/dist/hooks/points.d.ts +6 -0
  25. package/dist/hooks/points.d.ts.map +1 -1
  26. package/dist/hooks/points.js +7 -0
  27. package/dist/hooks/points.js.map +1 -1
  28. package/dist/index.d.ts +6 -1
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +6 -1
  31. package/dist/index.js.map +1 -1
  32. package/dist/mail/service.d.ts +26 -0
  33. package/dist/mail/service.d.ts.map +1 -0
  34. package/dist/mail/service.js +117 -0
  35. package/dist/mail/service.js.map +1 -0
  36. package/dist/plugin/load.d.ts +80 -13
  37. package/dist/plugin/load.d.ts.map +1 -1
  38. package/dist/plugin/load.js +315 -50
  39. package/dist/plugin/load.js.map +1 -1
  40. package/dist/plugin/service.d.ts.map +1 -1
  41. package/dist/plugin/service.js +5 -1
  42. package/dist/plugin/service.js.map +1 -1
  43. package/dist/queue/producer.d.ts +12 -1
  44. package/dist/queue/producer.d.ts.map +1 -1
  45. package/dist/queue/producer.js +92 -0
  46. package/dist/queue/producer.js.map +1 -1
  47. package/dist/role/plugin-roles.d.ts +39 -0
  48. package/dist/role/plugin-roles.d.ts.map +1 -0
  49. package/dist/role/plugin-roles.js +161 -0
  50. package/dist/role/plugin-roles.js.map +1 -0
  51. package/dist/webhooks/service.d.ts +33 -0
  52. package/dist/webhooks/service.d.ts.map +1 -0
  53. package/dist/webhooks/service.js +57 -0
  54. package/dist/webhooks/service.js.map +1 -0
  55. package/package.json +6 -6
@@ -0,0 +1,57 @@
1
+ // @oktis-works/core - Webhook secret rotation (Item 19 do plugin-parity-plan)
2
+ //
3
+ // Versioned secrets for webhook signing: `rotate` creates the next version,
4
+ // deactivates the previous one (keeping it recorded with rotated_at so
5
+ // consumers have a 24h grace window to swap the key) and returns the new
6
+ // secret exactly once. Signing itself happens in the worker, which picks the
7
+ // newest active version and stamps X-Webhook-Secret-Version.
8
+ import { randomUUID, randomBytes } from 'node:crypto';
9
+ import { getConnection } from '@oktis-works/database';
10
+ export class WebhookSecretService {
11
+ /**
12
+ * Rotates the signing secret: creates version N+1 as the only active one
13
+ * and stamps the previous version with rotated_at (24h grace for
14
+ * consumers). Returns the new secret ONCE — it is never listed again.
15
+ */
16
+ async rotate(webhookId) {
17
+ const sql = getConnection();
18
+ const webhook = await sql.unsafe('SELECT id FROM webhooks WHERE id = $1', [webhookId]);
19
+ if (webhook.length === 0)
20
+ return null;
21
+ const versionRows = await sql.unsafe('SELECT COALESCE(MAX(version), 0)::int AS max_version FROM webhook_secrets WHERE webhook_id = $1', [webhookId]);
22
+ const nextVersion = Number(versionRows[0]?.max_version ?? 0) + 1;
23
+ // Deactivate previous versions (kept for the 24h grace window).
24
+ await sql.unsafe('UPDATE webhook_secrets SET is_active = false, rotated_at = NOW() WHERE webhook_id = $1 AND is_active = true', [webhookId]);
25
+ const secret = randomBytes(32).toString('hex');
26
+ const id = randomUUID();
27
+ await sql.unsafe('INSERT INTO webhook_secrets (id, webhook_id, secret, version, is_active) VALUES ($1, $2, $3, $4, true)', [id, webhookId, secret, nextVersion]);
28
+ return { id, webhookId, version: nextVersion, isActive: true, rotatedAt: null, createdAt: new Date(), secret };
29
+ }
30
+ /** Versioned history WITHOUT the secret values (safe to list). */
31
+ async listVersions(webhookId) {
32
+ const sql = getConnection();
33
+ const rows = await sql.unsafe(`SELECT id, webhook_id, version, is_active, rotated_at, created_at
34
+ FROM webhook_secrets WHERE webhook_id = $1 ORDER BY version DESC`, [webhookId]);
35
+ return rows;
36
+ }
37
+ /** Newest active secret for signing (worker-side; legacy fallback). */
38
+ async getActiveSecret(webhookId) {
39
+ const sql = getConnection();
40
+ const rows = await sql.unsafe(`SELECT secret, version FROM webhook_secrets
41
+ WHERE webhook_id = $1 AND is_active = true ORDER BY version DESC LIMIT 1`, [webhookId]);
42
+ const row = rows[0];
43
+ return row ? { secret: row.secret, version: row.version } : null;
44
+ }
45
+ /**
46
+ * Records a delivery that exhausted its retries into the dead-letter
47
+ * table — one row per failed delivery job (BullMQ already applied the
48
+ * exponential backoff before the handler gives up).
49
+ */
50
+ async recordDeadLetter(webhookId, event, payload, error) {
51
+ const sql = getConnection();
52
+ await sql.unsafe(`INSERT INTO webhook_dead_letters (webhook_id, event, payload, error, attempts)
53
+ VALUES ($1, $2, $3::jsonb, $4, 1)`, [webhookId, event, JSON.stringify(payload ?? {}), error]);
54
+ }
55
+ }
56
+ export const webhookSecretService = new WebhookSecretService();
57
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/webhooks/service.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,EAAE;AACF,4EAA4E;AAC5E,uEAAuE;AACvE,yEAAyE;AACzE,6EAA6E;AAC7E,6DAA6D;AAE7D,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAatD,MAAM,OAAO,oBAAoB;IAC/B;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAC,SAAiB;QAC5B,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;QAE5B,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,uCAAuC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QACvF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEtC,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,MAAM,CAClC,iGAAiG,EACjG,CAAC,SAAS,CAAC,CACZ,CAAC;QACF,MAAM,WAAW,GAAG,MAAM,CAAE,WAAW,CAAC,CAAC,CAA0C,EAAE,WAAW,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAE3G,gEAAgE;QAChE,MAAM,GAAG,CAAC,MAAM,CACd,6GAA6G,EAC7G,CAAC,SAAS,CAAC,CACZ,CAAC;QAEF,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC/C,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;QACxB,MAAM,GAAG,CAAC,MAAM,CACd,wGAAwG,EACxG,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,CACrC,CAAC;QAEF,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC;IACjH,CAAC;IAED,kEAAkE;IAClE,KAAK,CAAC,YAAY,CAAC,SAAiB;QAClC,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,MAAM,CAC3B;wEACkE,EAClE,CAAC,SAAS,CAAC,CACZ,CAAC;QACF,OAAO,IAA8D,CAAC;IACxE,CAAC;IAED,uEAAuE;IACvE,KAAK,CAAC,eAAe,CAAC,SAAiB;QACrC,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,MAAM,CAC3B;gFAC0E,EAC1E,CAAC,SAAS,CAAC,CACZ,CAAC;QACF,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAA+D,CAAC;QAClF,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACnE,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,gBAAgB,CAAC,SAAiB,EAAE,KAAa,EAAE,OAAgB,EAAE,KAAa;QACtF,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;QAC5B,MAAM,GAAG,CAAC,MAAM,CACd;yCACmC,EACnC,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC,CACzD,CAAC;IACJ,CAAC;CACF;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,oBAAoB,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oktis-works/core",
3
- "version": "0.5.15",
3
+ "version": "0.7.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -21,11 +21,11 @@
21
21
  "clean": "rm -rf dist tsconfig.tsbuildinfo"
22
22
  },
23
23
  "dependencies": {
24
- "@oktis-works/types": "^0.7.0",
25
- "@oktis-works/validation": "^0.6.0",
26
- "@oktis-works/config": "^0.6.2",
27
- "@oktis-works/database": "^0.7.0",
28
- "@oktis-works/plugin-runtime": "^0.5.10",
24
+ "@oktis-works/types": "^0.9.0",
25
+ "@oktis-works/validation": "^0.7.0",
26
+ "@oktis-works/config": "^0.6.4",
27
+ "@oktis-works/database": "^0.8.0",
28
+ "@oktis-works/plugin-runtime": "^0.7.0",
29
29
  "@aws-sdk/client-s3": "3.700.0",
30
30
  "bullmq": "5.0.0",
31
31
  "ioredis": "5.3.0",