@homespunapps/core 1.4.3 → 1.5.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.
package/dist/client.d.ts CHANGED
@@ -421,6 +421,34 @@ export declare class HomespunClient {
421
421
  url: string;
422
422
  };
423
423
  }>;
424
+ /**
425
+ * PUT /v1/apps/:id/ingest-hooks/:name/signing-secret provisions or rotates a
426
+ * hook's SIGNING secret (opt-in webhook signature verification, issue #935,
427
+ * shipped dark: nothing verifies a signature yet). This is a DIFFERENT secret
428
+ * from the URL secret rotateIngestHook rotates: it is what a provider (GitHub,
429
+ * Stripe, ...) HMACs the request body with.
430
+ *
431
+ * Omit `secret` to have the relay MINT one (`ihk_...`): the response includes
432
+ * the value ONCE (paste it into the provider). Pass `secret` to store a
433
+ * provider-generated value verbatim: the value is never echoed back, only the
434
+ * fingerprint. A rotation keeps the previous secret valid for `graceSeconds`
435
+ * (default 3600, max 86400) so deliveries verify while you update the provider.
436
+ */
437
+ setIngestSigningSecret(appId: string, name: string, opts?: {
438
+ secret?: string;
439
+ graceSeconds?: number;
440
+ }): Promise<{
441
+ secret?: string;
442
+ fingerprint: string;
443
+ setAt: string;
444
+ }>;
445
+ /**
446
+ * DELETE /v1/apps/:id/ingest-hooks/:name/signing-secret clears a hook's
447
+ * signing secret (current + previous + grace window). Idempotent.
448
+ */
449
+ clearIngestSigningSecret(appId: string, name: string): Promise<{
450
+ ok: boolean;
451
+ }>;
424
452
  /**
425
453
  * POST /v1/apps/:id/grants: mint a grant link. `role` must be a declared
426
454
  * custom role for the app. `mode` is "once" (one-time, first-browser-claims)
@@ -806,6 +834,20 @@ export interface IngestHookInfo {
806
834
  handshake: string | null;
807
835
  disabledAt: string | null;
808
836
  createdAt: string;
837
+ /**
838
+ * Opt-in signature verification state (issue #935), shipped dark. `configured`
839
+ * is true when a signing secret is set; `fingerprint` identifies WHICH one
840
+ * (plaintext-derived, matches the value in the provider's settings) without
841
+ * ever exposing it; `previousUntil` is set during a rotation's grace window.
842
+ */
843
+ signingSecret: {
844
+ configured: boolean;
845
+ fingerprint: string | null;
846
+ setAt: string | null;
847
+ previousUntil: string | null;
848
+ };
849
+ /** Placeholder for the D3 manifest `verify` grammar; always null for now. */
850
+ verify: null;
809
851
  deliveries: {
810
852
  accepted: number;
811
853
  failed: number;
package/dist/client.js CHANGED
@@ -777,6 +777,40 @@ export class HomespunClient {
777
777
  this.fail(r);
778
778
  return this.asObject(r);
779
779
  }
780
+ /**
781
+ * PUT /v1/apps/:id/ingest-hooks/:name/signing-secret provisions or rotates a
782
+ * hook's SIGNING secret (opt-in webhook signature verification, issue #935,
783
+ * shipped dark: nothing verifies a signature yet). This is a DIFFERENT secret
784
+ * from the URL secret rotateIngestHook rotates: it is what a provider (GitHub,
785
+ * Stripe, ...) HMACs the request body with.
786
+ *
787
+ * Omit `secret` to have the relay MINT one (`ihk_...`): the response includes
788
+ * the value ONCE (paste it into the provider). Pass `secret` to store a
789
+ * provider-generated value verbatim: the value is never echoed back, only the
790
+ * fingerprint. A rotation keeps the previous secret valid for `graceSeconds`
791
+ * (default 3600, max 86400) so deliveries verify while you update the provider.
792
+ */
793
+ async setIngestSigningSecret(appId, name, opts = {}) {
794
+ const body = {};
795
+ if (opts.secret !== undefined)
796
+ body.secret = opts.secret;
797
+ if (opts.graceSeconds !== undefined)
798
+ body.graceSeconds = opts.graceSeconds;
799
+ const r = await this.call("PUT", `/v1/apps/${encodeURIComponent(appId)}/ingest-hooks/${encodeURIComponent(name)}/signing-secret`, body);
800
+ if (!r.ok)
801
+ this.fail(r);
802
+ return this.asObject(r);
803
+ }
804
+ /**
805
+ * DELETE /v1/apps/:id/ingest-hooks/:name/signing-secret clears a hook's
806
+ * signing secret (current + previous + grace window). Idempotent.
807
+ */
808
+ async clearIngestSigningSecret(appId, name) {
809
+ const r = await this.call("DELETE", `/v1/apps/${encodeURIComponent(appId)}/ingest-hooks/${encodeURIComponent(name)}/signing-secret`);
810
+ if (!r.ok)
811
+ this.fail(r);
812
+ return this.asObject(r);
813
+ }
780
814
  // -------------------------------------------------------------------------
781
815
  // v2 grant links (M5). An owner/agent mints a capability URL carrying a
782
816
  // DECLARED custom role (x-homespun-manifest.roles) plus an optional row/filter
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homespunapps/core",
3
- "version": "1.4.3",
3
+ "version": "1.5.0",
4
4
  "description": "Homespun relay client: typed HTTP + WebSocket operations against a Homespun relay. Framework-free.",
5
5
  "license": "MIT",
6
6
  "type": "module",