@a2a-exposed/control-core 0.8.23 → 0.8.25

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/index.js CHANGED
@@ -293,7 +293,10 @@ var WAKE_SECRET_KEYS = [
293
293
  "WAKE_HMAC_SECRET",
294
294
  "WAKE_ACCESS_CLIENT_ID",
295
295
  "WAKE_ACCESS_CLIENT_SECRET",
296
- "EVENT_SECRET"
296
+ "EVENT_SECRET",
297
+ "UPSTREAM_TOKEN",
298
+ "UPSTREAM_ACCESS_CLIENT_ID",
299
+ "UPSTREAM_ACCESS_CLIENT_SECRET"
297
300
  ];
298
301
  var MAX_WAKE_VALUE = 4096;
299
302
  var MAX_WAKE_PLAIN = (() => {
@@ -560,10 +563,13 @@ async function saveWakeSettings(db, plane, secretsKey, input) {
560
563
  const keyHeader = input.keyHeader.trim();
561
564
  const key = input.key.trim();
562
565
  const hmacSecret = (input.hmacSecret ?? "").trim();
566
+ const accessClientId = (input.accessClientId ?? "").trim();
567
+ const accessClientSecret = (input.accessClientSecret ?? "").trim();
563
568
  if (wakeUrlProblem(url)) return { ok: false, error: "url" };
564
569
  if (!WAKE_PRESETS.includes(preset)) return { ok: false, error: "preset" };
565
570
  if (wakeHeaderProblem(keyHeader)) return { ok: false, error: "header" };
566
- if ([key, hmacSecret].some((value) => value.length > 4096 || /[\u0000-\u001f]/.test(value))) return { ok: false, error: "key" };
571
+ if ([key, hmacSecret, accessClientId, accessClientSecret].some((value) => value.length > 4096 || /[\u0000-\u001f]/.test(value))) return { ok: false, error: "key" };
572
+ if (url && Boolean(accessClientId) !== Boolean(accessClientSecret)) return { ok: false, error: "key" };
567
573
  if (url && preset === "openbot" && (key || keyHeader)) return { ok: false, error: keyHeader ? "header" : "key" };
568
574
  const config = configFields(row.config_json);
569
575
  const plaintext = {};
@@ -576,7 +582,7 @@ async function saveWakeSettings(db, plane, secretsKey, input) {
576
582
  const sameKey = same && (config.WAKE_KEY_HEADER ?? "") === keyHeader;
577
583
  let secretsEnc = row.secrets_enc;
578
584
  const hasSecrets = !!secretsEnc || Object.keys(plaintext).length > 0;
579
- if (hasSecrets || key || hmacSecret || url && preset === "openbot") {
585
+ if (hasSecrets || key || hmacSecret || accessClientId || accessClientSecret || url && preset === "openbot") {
580
586
  const ikm = secretsKey.trim();
581
587
  if (!ikm) return { ok: false, error: "unavailable" };
582
588
  const current = secretsEnc ? await openWakeSecrets(ikm, row.id, secretsEnc) : { ...plaintext };
@@ -584,6 +590,14 @@ async function saveWakeSettings(db, plane, secretsKey, input) {
584
590
  const before = JSON.stringify(current);
585
591
  if (!url || !sameKey || preset === "openbot") delete current.WAKE_WEBHOOK_KEY;
586
592
  if (!url || !same) delete current.WAKE_HMAC_SECRET;
593
+ if (!url || config.WAKE_WEBHOOK_URL !== url) {
594
+ delete current.WAKE_ACCESS_CLIENT_ID;
595
+ delete current.WAKE_ACCESS_CLIENT_SECRET;
596
+ }
597
+ if (url && accessClientId && accessClientSecret) {
598
+ current.WAKE_ACCESS_CLIENT_ID = accessClientId;
599
+ current.WAKE_ACCESS_CLIENT_SECRET = accessClientSecret;
600
+ }
587
601
  if (url && key && preset !== "openbot") current.WAKE_WEBHOOK_KEY = key;
588
602
  if (url && hmacSecret) current.WAKE_HMAC_SECRET = hmacSecret;
589
603
  if (url && preset === "openbot" && !current.WAKE_HMAC_SECRET) return { ok: false, error: "key" };
@@ -608,7 +622,7 @@ async function saveWakeSettings(db, plane, secretsKey, input) {
608
622
  ).bind(configJson, secretsEnc, version, now, row.id, input.accountId, row.config_version),
609
623
  db.prepare(
610
624
  `INSERT INTO config_outbox (tenant_id, version, created_at)
611
- SELECT id, ?, ? FROM tenants WHERE id = ? AND owner_account_id = ? AND config_version = ?`
625
+ SELECT id, ?, ? FROM tenants WHERE id = ? AND owner_account_id = ? AND config_version = ? AND changes() = 1`
612
626
  ).bind(version, now, row.id, input.accountId, version)
613
627
  ]);
614
628
  if (updated[0]?.meta?.changes !== 1) return { ok: false, error: "conflict" };
@@ -1,5 +1,5 @@
1
1
  /** Sealed secret fields. Anything else in the blob is ignored. */
2
- export declare const WAKE_SECRET_KEYS: readonly ["WAKE_WEBHOOK_KEY", "WAKE_HMAC_SECRET", "WAKE_ACCESS_CLIENT_ID", "WAKE_ACCESS_CLIENT_SECRET", "EVENT_SECRET"];
2
+ export declare const WAKE_SECRET_KEYS: readonly ["WAKE_WEBHOOK_KEY", "WAKE_HMAC_SECRET", "WAKE_ACCESS_CLIENT_ID", "WAKE_ACCESS_CLIENT_SECRET", "EVENT_SECRET", "UPSTREAM_TOKEN", "UPSTREAM_ACCESS_CLIENT_ID", "UPSTREAM_ACCESS_CLIENT_SECRET"];
3
3
  export type WakeSecretKey = (typeof WAKE_SECRET_KEYS)[number];
4
4
  export type WakeSecrets = Partial<Record<WakeSecretKey, string>>;
5
5
  /** One secret. The form uses the same cap. */
@@ -7,7 +7,7 @@ export interface WakeSettings {
7
7
  preset: string;
8
8
  keyHeader: string;
9
9
  }
10
- /** Blank credentials retain a saved value only for the same URL and authentication mode.
10
+ /** Blank webhook/signing credentials retain a saved value only for the same URL and authentication mode.
11
11
  * Callers validate public DNS before saving; the Worker enforces its delivery policy separately. */
12
12
  export interface WakeSaveInput {
13
13
  accountId: string;
@@ -17,6 +17,9 @@ export interface WakeSaveInput {
17
17
  keyHeader: string;
18
18
  key: string;
19
19
  hmacSecret?: string;
20
+ /** Both fields are required when replacing a tunnel Access service token. */
21
+ accessClientId?: string;
22
+ accessClientSecret?: string;
20
23
  /** Version of the settings the caller tested. A stale version makes no write. */
21
24
  expectedVersion?: number;
22
25
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a2a-exposed/control-core",
3
- "version": "0.8.23",
3
+ "version": "0.8.25",
4
4
  "description": "A2A endpoint provisioning, routing, and D1 migrations for a2a-exposed.",
5
5
  "type": "module",
6
6
  "scripts": {