@rei-standard/amsg-client 2.8.0 → 2.9.0-next.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/index.cjs CHANGED
@@ -97,6 +97,7 @@ var ReiClient = class {
97
97
  this._userKey = null;
98
98
  this._instantEncryption = instantEncryption;
99
99
  this._instantClientToken = typeof config.instantClientToken === "string" && config.instantClientToken ? config.instantClientToken : "";
100
+ this._serverToken = typeof config.serverToken === "string" && config.serverToken ? config.serverToken : "";
100
101
  this._maxPayloadBytes = normalizeMaxPayloadBytes(config.maxPayloadBytes);
101
102
  this._lowLevelWarned = /* @__PURE__ */ new Set();
102
103
  }
@@ -110,6 +111,17 @@ var ReiClient = class {
110
111
  _resolveBaseUrl(endpointName) {
111
112
  return this._customBaseUrls[endpointName] || this._baseUrl;
112
113
  }
114
+ /**
115
+ * Attach the single-user shared secret to amsg-server endpoint requests.
116
+ * Never applied to the instant path (that uses instantClientToken).
117
+ * @private
118
+ * @param {Record<string, string>} headers
119
+ * @returns {Record<string, string>}
120
+ */
121
+ _withServerToken(headers) {
122
+ if (this._serverToken) headers["X-Client-Token"] = this._serverToken;
123
+ return headers;
124
+ }
113
125
  // ─── Initialisation ─────────────────────────────────────────────
114
126
  /**
115
127
  * Fetch the user-specific encryption key.
@@ -128,7 +140,7 @@ var ReiClient = class {
128
140
  }
129
141
  const res = await fetch(`${this._baseUrl}/get-user-key`, {
130
142
  method: "GET",
131
- headers: { "X-User-Id": this._userId }
143
+ headers: this._withServerToken({ "X-User-Id": this._userId })
132
144
  });
133
145
  const json = await res.json();
134
146
  if (!json.success) throw new Error(json.error?.message || "Failed to fetch user key");
@@ -165,12 +177,12 @@ var ReiClient = class {
165
177
  const encrypted = await this._encrypt(json);
166
178
  const res = await fetch(`${this._baseUrl}/schedule-message`, {
167
179
  method: "POST",
168
- headers: {
180
+ headers: this._withServerToken({
169
181
  "Content-Type": "application/json",
170
182
  "X-User-Id": this._userId,
171
183
  "X-Payload-Encrypted": "true",
172
184
  "X-Encryption-Version": "1"
173
- },
185
+ }),
174
186
  body: JSON.stringify(encrypted)
175
187
  });
176
188
  return res.json();
@@ -508,12 +520,12 @@ var ReiClient = class {
508
520
  const encrypted = await this._encrypt(json);
509
521
  const res = await fetch(`${this._baseUrl}/update-message?id=${encodeURIComponent(uuid)}`, {
510
522
  method: "PUT",
511
- headers: {
523
+ headers: this._withServerToken({
512
524
  "Content-Type": "application/json",
513
525
  "X-User-Id": this._userId,
514
526
  "X-Payload-Encrypted": "true",
515
527
  "X-Encryption-Version": "1"
516
- },
528
+ }),
517
529
  body: JSON.stringify(encrypted)
518
530
  });
519
531
  return res.json();
@@ -527,7 +539,7 @@ var ReiClient = class {
527
539
  async cancelMessage(uuid) {
528
540
  const res = await fetch(`${this._baseUrl}/cancel-message?id=${encodeURIComponent(uuid)}`, {
529
541
  method: "DELETE",
530
- headers: { "X-User-Id": this._userId }
542
+ headers: this._withServerToken({ "X-User-Id": this._userId })
531
543
  });
532
544
  return res.json();
533
545
  }
@@ -549,11 +561,11 @@ var ReiClient = class {
549
561
  const url = `${this._baseUrl}/messages${qs ? "?" + qs : ""}`;
550
562
  const res = await fetch(url, {
551
563
  method: "GET",
552
- headers: {
564
+ headers: this._withServerToken({
553
565
  "X-User-Id": this._userId,
554
566
  "X-Response-Encrypted": "true",
555
567
  "X-Encryption-Version": "1"
556
- }
568
+ })
557
569
  });
558
570
  const json = await res.json();
559
571
  if (!json?.success || json?.encrypted !== true) return json;
package/dist/index.d.cts CHANGED
@@ -75,6 +75,11 @@ const TEXT_ENCODER = new TextEncoder();
75
75
  * inside any frontend bundle that uses it, so
76
76
  * devtools can read it. Use for casual URL-direct
77
77
  * abuse only.
78
+ * @property {string} [serverToken] - Optional shared secret for a single-user amsg-server.
79
+ * When set, sent as the `X-Client-Token` header on
80
+ * amsg-server endpoints (schedule / messages / update /
81
+ * cancel / user-key / init). Not applied to the instant
82
+ * path (that uses `instantClientToken`).
78
83
  * @property {number|null} [maxPayloadBytes=null] - Optional local UTF-8 byte cap for outgoing request
79
84
  * payloads before encryption. `null` / omitted means
80
85
  * no SDK-level request-size limit.
@@ -367,6 +372,10 @@ class ReiClient {
367
372
  ? config.instantClientToken
368
373
  : '';
369
374
  /** @private */
375
+ this._serverToken = typeof config.serverToken === 'string' && config.serverToken
376
+ ? config.serverToken
377
+ : '';
378
+ /** @private */
370
379
  this._maxPayloadBytes = normalizeMaxPayloadBytes(config.maxPayloadBytes);
371
380
  /**
372
381
  * Per-instance latch (set of method names already warned). The
@@ -387,6 +396,18 @@ class ReiClient {
387
396
  return this._customBaseUrls[endpointName] || this._baseUrl;
388
397
  }
389
398
 
399
+ /**
400
+ * Attach the single-user shared secret to amsg-server endpoint requests.
401
+ * Never applied to the instant path (that uses instantClientToken).
402
+ * @private
403
+ * @param {Record<string, string>} headers
404
+ * @returns {Record<string, string>}
405
+ */
406
+ _withServerToken(headers) {
407
+ if (this._serverToken) headers['X-Client-Token'] = this._serverToken;
408
+ return headers;
409
+ }
410
+
390
411
  // ─── Initialisation ─────────────────────────────────────────────
391
412
 
392
413
  /**
@@ -407,7 +428,7 @@ class ReiClient {
407
428
 
408
429
  const res = await fetch(`${this._baseUrl}/get-user-key`, {
409
430
  method: 'GET',
410
- headers: { 'X-User-Id': this._userId }
431
+ headers: this._withServerToken({ 'X-User-Id': this._userId })
411
432
  });
412
433
 
413
434
  const json = await res.json();
@@ -450,12 +471,12 @@ class ReiClient {
450
471
 
451
472
  const res = await fetch(`${this._baseUrl}/schedule-message`, {
452
473
  method: 'POST',
453
- headers: {
474
+ headers: this._withServerToken({
454
475
  'Content-Type': 'application/json',
455
476
  'X-User-Id': this._userId,
456
477
  'X-Payload-Encrypted': 'true',
457
478
  'X-Encryption-Version': '1'
458
- },
479
+ }),
459
480
  body: JSON.stringify(encrypted)
460
481
  });
461
482
 
@@ -883,12 +904,12 @@ class ReiClient {
883
904
 
884
905
  const res = await fetch(`${this._baseUrl}/update-message?id=${encodeURIComponent(uuid)}`, {
885
906
  method: 'PUT',
886
- headers: {
907
+ headers: this._withServerToken({
887
908
  'Content-Type': 'application/json',
888
909
  'X-User-Id': this._userId,
889
910
  'X-Payload-Encrypted': 'true',
890
911
  'X-Encryption-Version': '1'
891
- },
912
+ }),
892
913
  body: JSON.stringify(encrypted)
893
914
  });
894
915
 
@@ -904,7 +925,7 @@ class ReiClient {
904
925
  async cancelMessage(uuid) {
905
926
  const res = await fetch(`${this._baseUrl}/cancel-message?id=${encodeURIComponent(uuid)}`, {
906
927
  method: 'DELETE',
907
- headers: { 'X-User-Id': this._userId }
928
+ headers: this._withServerToken({ 'X-User-Id': this._userId })
908
929
  });
909
930
 
910
931
  return res.json();
@@ -930,11 +951,11 @@ class ReiClient {
930
951
 
931
952
  const res = await fetch(url, {
932
953
  method: 'GET',
933
- headers: {
954
+ headers: this._withServerToken({
934
955
  'X-User-Id': this._userId,
935
956
  'X-Response-Encrypted': 'true',
936
957
  'X-Encryption-Version': '1'
937
- }
958
+ })
938
959
  });
939
960
 
940
961
  const json = await res.json();
package/dist/index.d.ts CHANGED
@@ -75,6 +75,11 @@ const TEXT_ENCODER = new TextEncoder();
75
75
  * inside any frontend bundle that uses it, so
76
76
  * devtools can read it. Use for casual URL-direct
77
77
  * abuse only.
78
+ * @property {string} [serverToken] - Optional shared secret for a single-user amsg-server.
79
+ * When set, sent as the `X-Client-Token` header on
80
+ * amsg-server endpoints (schedule / messages / update /
81
+ * cancel / user-key / init). Not applied to the instant
82
+ * path (that uses `instantClientToken`).
78
83
  * @property {number|null} [maxPayloadBytes=null] - Optional local UTF-8 byte cap for outgoing request
79
84
  * payloads before encryption. `null` / omitted means
80
85
  * no SDK-level request-size limit.
@@ -367,6 +372,10 @@ class ReiClient {
367
372
  ? config.instantClientToken
368
373
  : '';
369
374
  /** @private */
375
+ this._serverToken = typeof config.serverToken === 'string' && config.serverToken
376
+ ? config.serverToken
377
+ : '';
378
+ /** @private */
370
379
  this._maxPayloadBytes = normalizeMaxPayloadBytes(config.maxPayloadBytes);
371
380
  /**
372
381
  * Per-instance latch (set of method names already warned). The
@@ -387,6 +396,18 @@ class ReiClient {
387
396
  return this._customBaseUrls[endpointName] || this._baseUrl;
388
397
  }
389
398
 
399
+ /**
400
+ * Attach the single-user shared secret to amsg-server endpoint requests.
401
+ * Never applied to the instant path (that uses instantClientToken).
402
+ * @private
403
+ * @param {Record<string, string>} headers
404
+ * @returns {Record<string, string>}
405
+ */
406
+ _withServerToken(headers) {
407
+ if (this._serverToken) headers['X-Client-Token'] = this._serverToken;
408
+ return headers;
409
+ }
410
+
390
411
  // ─── Initialisation ─────────────────────────────────────────────
391
412
 
392
413
  /**
@@ -407,7 +428,7 @@ class ReiClient {
407
428
 
408
429
  const res = await fetch(`${this._baseUrl}/get-user-key`, {
409
430
  method: 'GET',
410
- headers: { 'X-User-Id': this._userId }
431
+ headers: this._withServerToken({ 'X-User-Id': this._userId })
411
432
  });
412
433
 
413
434
  const json = await res.json();
@@ -450,12 +471,12 @@ class ReiClient {
450
471
 
451
472
  const res = await fetch(`${this._baseUrl}/schedule-message`, {
452
473
  method: 'POST',
453
- headers: {
474
+ headers: this._withServerToken({
454
475
  'Content-Type': 'application/json',
455
476
  'X-User-Id': this._userId,
456
477
  'X-Payload-Encrypted': 'true',
457
478
  'X-Encryption-Version': '1'
458
- },
479
+ }),
459
480
  body: JSON.stringify(encrypted)
460
481
  });
461
482
 
@@ -883,12 +904,12 @@ class ReiClient {
883
904
 
884
905
  const res = await fetch(`${this._baseUrl}/update-message?id=${encodeURIComponent(uuid)}`, {
885
906
  method: 'PUT',
886
- headers: {
907
+ headers: this._withServerToken({
887
908
  'Content-Type': 'application/json',
888
909
  'X-User-Id': this._userId,
889
910
  'X-Payload-Encrypted': 'true',
890
911
  'X-Encryption-Version': '1'
891
- },
912
+ }),
892
913
  body: JSON.stringify(encrypted)
893
914
  });
894
915
 
@@ -904,7 +925,7 @@ class ReiClient {
904
925
  async cancelMessage(uuid) {
905
926
  const res = await fetch(`${this._baseUrl}/cancel-message?id=${encodeURIComponent(uuid)}`, {
906
927
  method: 'DELETE',
907
- headers: { 'X-User-Id': this._userId }
928
+ headers: this._withServerToken({ 'X-User-Id': this._userId })
908
929
  });
909
930
 
910
931
  return res.json();
@@ -930,11 +951,11 @@ class ReiClient {
930
951
 
931
952
  const res = await fetch(url, {
932
953
  method: 'GET',
933
- headers: {
954
+ headers: this._withServerToken({
934
955
  'X-User-Id': this._userId,
935
956
  'X-Response-Encrypted': 'true',
936
957
  'X-Encryption-Version': '1'
937
- }
958
+ })
938
959
  });
939
960
 
940
961
  const json = await res.json();
package/dist/index.mjs CHANGED
@@ -75,6 +75,7 @@ var ReiClient = class {
75
75
  this._userKey = null;
76
76
  this._instantEncryption = instantEncryption;
77
77
  this._instantClientToken = typeof config.instantClientToken === "string" && config.instantClientToken ? config.instantClientToken : "";
78
+ this._serverToken = typeof config.serverToken === "string" && config.serverToken ? config.serverToken : "";
78
79
  this._maxPayloadBytes = normalizeMaxPayloadBytes(config.maxPayloadBytes);
79
80
  this._lowLevelWarned = /* @__PURE__ */ new Set();
80
81
  }
@@ -88,6 +89,17 @@ var ReiClient = class {
88
89
  _resolveBaseUrl(endpointName) {
89
90
  return this._customBaseUrls[endpointName] || this._baseUrl;
90
91
  }
92
+ /**
93
+ * Attach the single-user shared secret to amsg-server endpoint requests.
94
+ * Never applied to the instant path (that uses instantClientToken).
95
+ * @private
96
+ * @param {Record<string, string>} headers
97
+ * @returns {Record<string, string>}
98
+ */
99
+ _withServerToken(headers) {
100
+ if (this._serverToken) headers["X-Client-Token"] = this._serverToken;
101
+ return headers;
102
+ }
91
103
  // ─── Initialisation ─────────────────────────────────────────────
92
104
  /**
93
105
  * Fetch the user-specific encryption key.
@@ -106,7 +118,7 @@ var ReiClient = class {
106
118
  }
107
119
  const res = await fetch(`${this._baseUrl}/get-user-key`, {
108
120
  method: "GET",
109
- headers: { "X-User-Id": this._userId }
121
+ headers: this._withServerToken({ "X-User-Id": this._userId })
110
122
  });
111
123
  const json = await res.json();
112
124
  if (!json.success) throw new Error(json.error?.message || "Failed to fetch user key");
@@ -143,12 +155,12 @@ var ReiClient = class {
143
155
  const encrypted = await this._encrypt(json);
144
156
  const res = await fetch(`${this._baseUrl}/schedule-message`, {
145
157
  method: "POST",
146
- headers: {
158
+ headers: this._withServerToken({
147
159
  "Content-Type": "application/json",
148
160
  "X-User-Id": this._userId,
149
161
  "X-Payload-Encrypted": "true",
150
162
  "X-Encryption-Version": "1"
151
- },
163
+ }),
152
164
  body: JSON.stringify(encrypted)
153
165
  });
154
166
  return res.json();
@@ -486,12 +498,12 @@ var ReiClient = class {
486
498
  const encrypted = await this._encrypt(json);
487
499
  const res = await fetch(`${this._baseUrl}/update-message?id=${encodeURIComponent(uuid)}`, {
488
500
  method: "PUT",
489
- headers: {
501
+ headers: this._withServerToken({
490
502
  "Content-Type": "application/json",
491
503
  "X-User-Id": this._userId,
492
504
  "X-Payload-Encrypted": "true",
493
505
  "X-Encryption-Version": "1"
494
- },
506
+ }),
495
507
  body: JSON.stringify(encrypted)
496
508
  });
497
509
  return res.json();
@@ -505,7 +517,7 @@ var ReiClient = class {
505
517
  async cancelMessage(uuid) {
506
518
  const res = await fetch(`${this._baseUrl}/cancel-message?id=${encodeURIComponent(uuid)}`, {
507
519
  method: "DELETE",
508
- headers: { "X-User-Id": this._userId }
520
+ headers: this._withServerToken({ "X-User-Id": this._userId })
509
521
  });
510
522
  return res.json();
511
523
  }
@@ -527,11 +539,11 @@ var ReiClient = class {
527
539
  const url = `${this._baseUrl}/messages${qs ? "?" + qs : ""}`;
528
540
  const res = await fetch(url, {
529
541
  method: "GET",
530
- headers: {
542
+ headers: this._withServerToken({
531
543
  "X-User-Id": this._userId,
532
544
  "X-Response-Encrypted": "true",
533
545
  "X-Encryption-Version": "1"
534
- }
546
+ })
535
547
  });
536
548
  const json = await res.json();
537
549
  if (!json?.success || json?.encrypted !== true) return json;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rei-standard/amsg-client",
3
- "version": "2.8.0",
3
+ "version": "2.9.0-next.0",
4
4
  "description": "ReiStandard Active Messaging browser client SDK — also re-exports shared push types, builders, and guards from @rei-standard/amsg-shared",
5
5
  "repository": {
6
6
  "type": "git",