itrm-tools 1.4.6 → 1.4.7

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.
@@ -8,6 +8,9 @@ export interface ApiSignValues {
8
8
  encryptedBody?: string;
9
9
  }
10
10
  export declare class ApiKeySigner implements Signer<ApiSignValues, IKey, string> {
11
+ private readonly windowMilliseconds;
12
+ /** `windowSeconds` decides how old a nonce may be; without it, five minutes. */
13
+ constructor(windowSeconds?: number);
11
14
  sign(input: ApiSignValues, keys: IKey): string;
12
15
  verify(input: ApiSignValues, keys: IKey, signature: string): boolean;
13
16
  private buildSignature;
@@ -2,21 +2,32 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ApiKeySigner = void 0;
4
4
  const crypto_js_1 = require("crypto-js");
5
+ /** Five minutes: enough for the clock skew between stations, short enough to bound a replay. */
6
+ const DEFAULT_NONCE_WINDOW_SECONDS = 300;
5
7
  class ApiKeySigner {
8
+ windowMilliseconds;
9
+ /** `windowSeconds` decides how old a nonce may be; without it, five minutes. */
10
+ constructor(windowSeconds) {
11
+ const usable = windowSeconds !== undefined && Number.isFinite(windowSeconds) && windowSeconds > 0;
12
+ this.windowMilliseconds = (usable ? windowSeconds : DEFAULT_NONCE_WINDOW_SECONDS) * 1000;
13
+ }
6
14
  sign(input, keys) {
15
+ // Milliseconds, as always: two stations may sign in the same millisecond and the verifier
16
+ // accepts both, because it no longer requires the nonce to grow.
7
17
  let nonce = Date.now();
8
18
  return `${keys.publicKey}:${nonce}:${this.buildSignature(input, nonce, keys.signKey)}`;
9
19
  }
10
20
  verify(input, keys, signature) {
11
- let values = this.extractSignatureDetails(signature);
12
- if (values && keys.lastNonce <= values.nonce) {
13
- const matches = this.buildSignature(input, values.nonce, keys.signKey) === values.signature;
21
+ const values = this.extractSignatureDetails(signature);
22
+ if (values !== undefined) {
23
+ // Inside the window and with a matching signature; the nonce need not grow, so two
24
+ // stations share a key without a race, and outside the window a captured request is old.
25
+ const age = Date.now() - values.nonce;
26
+ const matches = Math.abs(age) <= this.windowMilliseconds
27
+ && this.buildSignature(input, values.nonce, keys.signKey) === values.signature;
14
28
  if (matches) {
15
- // The same nonce is accepted again only when the signature is identical: a
16
- // duplicated check or a retry of the same request, not a replayed different one.
17
- if (keys.lastNonce < values.nonce) {
18
- keys.lastNonce = values.nonce;
19
- }
29
+ // `lastNonce` is kept for the records, never to reject a request.
30
+ keys.lastNonce = Math.max(keys.lastNonce ?? 0, values.nonce);
20
31
  return true;
21
32
  }
22
33
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ApiKeySigner.js","sourceRoot":"","sources":["../../../src/cryptography/sign/ApiKeySigner.ts"],"names":[],"mappings":";;;AAEA,yCAA4C;AAU5C,MAAa,YAAY;IACd,IAAI,CAAC,KAAoB,EAAE,IAAU;QACxC,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,OAAO,GAAG,IAAI,CAAC,SAAS,IAAI,KAAK,IAAI,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,OAAQ,CAAC,EAAE,CAAC;IAC5F,CAAC;IAEM,MAAM,CAAC,KAAoB,EAAE,IAAU,EAAE,SAAiB;QAC7D,IAAI,MAAM,GAAG,IAAI,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC;QACrD,IAAI,MAAM,IAAI,IAAI,CAAC,SAAU,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,OAAQ,CAAC,KAAK,MAAM,CAAC,SAAS,CAAC;YAC7F,IAAI,OAAO,EAAE,CAAC;gBACV,2EAA2E;gBAC3E,iFAAiF;gBACjF,IAAI,IAAI,CAAC,SAAU,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;oBACjC,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC;gBAClC,CAAC;gBACD,OAAO,IAAI,CAAC;YAChB,CAAC;QACL,CAAC;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAEO,cAAc,CAAC,KAAoB,EAAE,KAAa,EAAE,OAAe;QACvE,IAAI,OAAO,GAAG,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACxH,MAAM,IAAI,GAAG,IAAA,sBAAU,EAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC1C,OAAO,eAAG,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAEO,uBAAuB,CAAC,SAAiB;QAC7C,IAAI,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAClB,OAAO;gBACH,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;gBACnB,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBACzB,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;aACtB,CAAC;QACN,OAAO,SAAS,CAAC;IACrB,CAAC;CACJ;AAtCD,oCAsCC"}
1
+ {"version":3,"file":"ApiKeySigner.js","sourceRoot":"","sources":["../../../src/cryptography/sign/ApiKeySigner.ts"],"names":[],"mappings":";;;AAEA,yCAA4C;AAU5C,gGAAgG;AAChG,MAAM,4BAA4B,GAAG,GAAG,CAAC;AAEzC,MAAa,YAAY;IACJ,kBAAkB,CAAS;IAE5C,gFAAgF;IAChF,YAAY,aAAsB;QAC9B,MAAM,MAAM,GAAG,aAAa,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,aAAa,GAAG,CAAC,CAAC;QAElG,IAAI,CAAC,kBAAkB,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,4BAA4B,CAAC,GAAG,IAAI,CAAC;IAC7F,CAAC;IAEM,IAAI,CAAC,KAAoB,EAAE,IAAU;QACxC,0FAA0F;QAC1F,iEAAiE;QACjE,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,OAAO,GAAG,IAAI,CAAC,SAAS,IAAI,KAAK,IAAI,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,OAAQ,CAAC,EAAE,CAAC;IAC5F,CAAC;IAEM,MAAM,CAAC,KAAoB,EAAE,IAAU,EAAE,SAAiB;QAC7D,MAAM,MAAM,GAAG,IAAI,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC;QAEvD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACvB,mFAAmF;YACnF,yFAAyF;YACzF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC;YACtC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,kBAAkB;mBACjD,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,OAAQ,CAAC,KAAK,MAAM,CAAC,SAAS,CAAC;YAEpF,IAAI,OAAO,EAAE,CAAC;gBACV,kEAAkE;gBAClE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC7D,OAAO,IAAI,CAAC;YAChB,CAAC;QACL,CAAC;QAED,OAAO,KAAK,CAAC;IACjB,CAAC;IAEO,cAAc,CAAC,KAAoB,EAAE,KAAa,EAAE,OAAe;QACvE,IAAI,OAAO,GAAG,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACxH,MAAM,IAAI,GAAG,IAAA,sBAAU,EAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC1C,OAAO,eAAG,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAEO,uBAAuB,CAAC,SAAiB;QAC7C,IAAI,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAClB,OAAO;gBACH,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;gBACnB,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBACzB,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;aACtB,CAAC;QACN,OAAO,SAAS,CAAC;IACrB,CAAC;CACJ;AArDD,oCAqDC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "itrm-tools",
3
- "version": "1.4.6",
3
+ "version": "1.4.7",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",