@spfn/auth 0.2.0-beta.85 → 0.2.0-beta.87
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/README.md +72 -7
- package/dist/{authenticate-ngWdlWWL.d.ts → authenticate-C7w-pLOR.d.ts} +56 -1
- package/dist/client-proof.d.ts +191 -46
- package/dist/client-proof.js +276 -48
- package/dist/client-proof.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/server.d.ts +23 -2
- package/dist/server.js +878 -69
- package/dist/server.js.map +1 -1
- package/package.json +5 -4
package/dist/client-proof.js
CHANGED
|
@@ -345,10 +345,25 @@ function encodeString(value) {
|
|
|
345
345
|
}
|
|
346
346
|
|
|
347
347
|
// src/server/client-proof/proof.ts
|
|
348
|
-
import { createHash,
|
|
348
|
+
import { createHash, createPrivateKey, createPublicKey, sign, verify } from "crypto";
|
|
349
349
|
var CLIENT_PROOF_PROFILE = "clientProofV1";
|
|
350
350
|
var ABSENT_BODY_SHA256 = "0".repeat(64);
|
|
351
351
|
var DEFAULT_REPLAY_WINDOW_MILLIS = 3e5;
|
|
352
|
+
var PROOF_INPUT_FIELDS = [
|
|
353
|
+
"profile",
|
|
354
|
+
"method",
|
|
355
|
+
"path",
|
|
356
|
+
"clientId",
|
|
357
|
+
"keyId",
|
|
358
|
+
"nonce",
|
|
359
|
+
"issuedAtMillis",
|
|
360
|
+
"bodySha256"
|
|
361
|
+
];
|
|
362
|
+
var PROOF_INPUT_SEPARATOR = "\n";
|
|
363
|
+
var PROOF_SIGNATURE_BYTES = 64;
|
|
364
|
+
var PROOF_SIGNATURE_HEX_LENGTH = PROOF_SIGNATURE_BYTES * 2;
|
|
365
|
+
var PROOF_SIGNATURE_PATTERN = /^[0-9a-f]{128}$/;
|
|
366
|
+
var RAW_SIGNATURE_ENCODING = "ieee-p1363";
|
|
352
367
|
var ProofInputError = class extends Error {
|
|
353
368
|
constructor() {
|
|
354
369
|
super("proof input field contains a C0 control character");
|
|
@@ -356,16 +371,17 @@ var ProofInputError = class extends Error {
|
|
|
356
371
|
}
|
|
357
372
|
};
|
|
358
373
|
function canonicalProofInput(input) {
|
|
359
|
-
const
|
|
360
|
-
CLIENT_PROOF_PROFILE,
|
|
361
|
-
input.method,
|
|
362
|
-
input.path,
|
|
363
|
-
input.clientId,
|
|
364
|
-
input.keyId,
|
|
365
|
-
input.nonce,
|
|
366
|
-
input.issuedAtMillis.toString(),
|
|
367
|
-
input.bodySha256
|
|
368
|
-
|
|
374
|
+
const values = {
|
|
375
|
+
profile: CLIENT_PROOF_PROFILE,
|
|
376
|
+
method: input.method,
|
|
377
|
+
path: input.path,
|
|
378
|
+
clientId: input.clientId,
|
|
379
|
+
keyId: input.keyId,
|
|
380
|
+
nonce: input.nonce,
|
|
381
|
+
issuedAtMillis: input.issuedAtMillis.toString(),
|
|
382
|
+
bodySha256: input.bodySha256
|
|
383
|
+
};
|
|
384
|
+
const fields = PROOF_INPUT_FIELDS.map((name) => values[name]);
|
|
369
385
|
for (const field of fields) {
|
|
370
386
|
for (const ch of field) {
|
|
371
387
|
if (ch.codePointAt(0) < 32) {
|
|
@@ -373,21 +389,45 @@ function canonicalProofInput(input) {
|
|
|
373
389
|
}
|
|
374
390
|
}
|
|
375
391
|
}
|
|
376
|
-
return fields.join(
|
|
392
|
+
return fields.join(PROOF_INPUT_SEPARATOR);
|
|
377
393
|
}
|
|
378
|
-
function
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
394
|
+
function parseClientProofPublicKey(spkiDerBase64) {
|
|
395
|
+
const key = createPublicKey({
|
|
396
|
+
key: Buffer.from(spkiDerBase64, "base64"),
|
|
397
|
+
format: "der",
|
|
398
|
+
type: "spki"
|
|
399
|
+
});
|
|
400
|
+
if (key.asymmetricKeyType !== "ec" || key.asymmetricKeyDetails?.namedCurve !== "prime256v1") {
|
|
401
|
+
throw new Error("a clientProofV1 public key must be an ECDSA P-256 key");
|
|
402
|
+
}
|
|
403
|
+
return key;
|
|
383
404
|
}
|
|
384
|
-
function
|
|
385
|
-
const
|
|
386
|
-
|
|
387
|
-
if (a.length !== b.length) {
|
|
405
|
+
function verifyClientProof(input, presentedProof, publicKey) {
|
|
406
|
+
const data = Buffer.from(canonicalProofInput(input), "utf8");
|
|
407
|
+
if (!PROOF_SIGNATURE_PATTERN.test(presentedProof)) {
|
|
388
408
|
return false;
|
|
389
409
|
}
|
|
390
|
-
return
|
|
410
|
+
return verify(
|
|
411
|
+
"sha256",
|
|
412
|
+
data,
|
|
413
|
+
{ key: publicKey, dsaEncoding: RAW_SIGNATURE_ENCODING },
|
|
414
|
+
Buffer.from(presentedProof, "hex")
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
function signClientProof(input, privateKeyPkcs8DerBase64) {
|
|
418
|
+
const key = createPrivateKey({
|
|
419
|
+
key: Buffer.from(privateKeyPkcs8DerBase64, "base64"),
|
|
420
|
+
format: "der",
|
|
421
|
+
type: "pkcs8"
|
|
422
|
+
});
|
|
423
|
+
return sign(
|
|
424
|
+
"sha256",
|
|
425
|
+
Buffer.from(canonicalProofInput(input), "utf8"),
|
|
426
|
+
{ key, dsaEncoding: RAW_SIGNATURE_ENCODING }
|
|
427
|
+
).toString("hex");
|
|
428
|
+
}
|
|
429
|
+
function sha256Hex(bytes) {
|
|
430
|
+
return createHash("sha256").update(bytes).digest("hex");
|
|
391
431
|
}
|
|
392
432
|
|
|
393
433
|
// src/server/client-proof/refusal.ts
|
|
@@ -478,6 +518,86 @@ function contractViolation(message) {
|
|
|
478
518
|
return new ClientProofRefusal("CONTRACT_UNSUPPORTED", message);
|
|
479
519
|
}
|
|
480
520
|
|
|
521
|
+
// src/server/client-proof/replay-store.ts
|
|
522
|
+
import { getCache } from "@spfn/core/cache";
|
|
523
|
+
function replayLedgerKey(clientId, nonce) {
|
|
524
|
+
return JSON.stringify([clientId, nonce]);
|
|
525
|
+
}
|
|
526
|
+
var MemoryReplayLedger = class {
|
|
527
|
+
/** replayLedgerKey(...) → the millis it was spent at. */
|
|
528
|
+
spent = /* @__PURE__ */ new Map();
|
|
529
|
+
isSpent(clientId, nonce) {
|
|
530
|
+
return this.spent.has(replayLedgerKey(clientId, nonce));
|
|
531
|
+
}
|
|
532
|
+
/** Records the pair at `atMillis`; false when it was already spent. */
|
|
533
|
+
spend(clientId, nonce, atMillis) {
|
|
534
|
+
const key = replayLedgerKey(clientId, nonce);
|
|
535
|
+
if (this.spent.has(key)) {
|
|
536
|
+
return false;
|
|
537
|
+
}
|
|
538
|
+
this.spent.set(key, atMillis);
|
|
539
|
+
return true;
|
|
540
|
+
}
|
|
541
|
+
/** Drops entries older than the window, judged against `nowMillis`. */
|
|
542
|
+
prune(nowMillis, windowMillis) {
|
|
543
|
+
for (const [key, spentAtMillis] of this.spent) {
|
|
544
|
+
if (nowMillis - spentAtMillis > windowMillis) {
|
|
545
|
+
this.spent.delete(key);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
get size() {
|
|
550
|
+
return this.spent.size;
|
|
551
|
+
}
|
|
552
|
+
clear() {
|
|
553
|
+
this.spent.clear();
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
var MemoryReplayStore = class {
|
|
557
|
+
constructor(windowMillis = DEFAULT_REPLAY_WINDOW_MILLIS) {
|
|
558
|
+
this.windowMillis = windowMillis;
|
|
559
|
+
}
|
|
560
|
+
ledger = new MemoryReplayLedger();
|
|
561
|
+
async isSpent(clientId, nonce) {
|
|
562
|
+
this.ledger.prune(Date.now(), this.windowMillis);
|
|
563
|
+
return this.ledger.isSpent(clientId, nonce);
|
|
564
|
+
}
|
|
565
|
+
async spend(clientId, nonce) {
|
|
566
|
+
const now = Date.now();
|
|
567
|
+
this.ledger.prune(now, this.windowMillis);
|
|
568
|
+
return this.ledger.spend(clientId, nonce, now);
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
var RedisReplayStore = class {
|
|
572
|
+
constructor(windowMillis = DEFAULT_REPLAY_WINDOW_MILLIS) {
|
|
573
|
+
this.windowMillis = windowMillis;
|
|
574
|
+
}
|
|
575
|
+
async isSpent(clientId, nonce) {
|
|
576
|
+
return await this.cache().exists(this.key(clientId, nonce)) === 1;
|
|
577
|
+
}
|
|
578
|
+
async spend(clientId, nonce) {
|
|
579
|
+
return await this.cache().set(this.key(clientId, nonce), "1", "PX", this.windowMillis, "NX") === "OK";
|
|
580
|
+
}
|
|
581
|
+
cache() {
|
|
582
|
+
const cache = getCache();
|
|
583
|
+
if (!cache) {
|
|
584
|
+
throw new Error("client-proof replay ledger: cache is not available");
|
|
585
|
+
}
|
|
586
|
+
return cache;
|
|
587
|
+
}
|
|
588
|
+
key(clientId, nonce) {
|
|
589
|
+
return `spfn:auth:client-proof:replay:${sha256Hex(Buffer.from(replayLedgerKey(clientId, nonce), "utf8"))}`;
|
|
590
|
+
}
|
|
591
|
+
};
|
|
592
|
+
var configured = null;
|
|
593
|
+
function configureClientProofReplayStore(store) {
|
|
594
|
+
configured = store;
|
|
595
|
+
}
|
|
596
|
+
function getClientProofReplayStore() {
|
|
597
|
+
configured ??= new MemoryReplayStore();
|
|
598
|
+
return configured;
|
|
599
|
+
}
|
|
600
|
+
|
|
481
601
|
// src/server/client-proof/state.ts
|
|
482
602
|
function systemClock() {
|
|
483
603
|
return { nowMillis: () => Date.now() };
|
|
@@ -494,16 +614,14 @@ var TestClock = class {
|
|
|
494
614
|
}
|
|
495
615
|
};
|
|
496
616
|
var DEFAULT_SESSION_TTL_MILLIS = 6e5;
|
|
497
|
-
function replayKeyOf(clientId, nonce) {
|
|
498
|
-
return `${clientId}${nonce}`;
|
|
499
|
-
}
|
|
500
617
|
var ClientProofState = class {
|
|
501
618
|
replayWindowMillis;
|
|
502
619
|
clock;
|
|
503
|
-
|
|
620
|
+
initialPublicKeys;
|
|
621
|
+
publicKeys = /* @__PURE__ */ new Map();
|
|
504
622
|
sessions = /* @__PURE__ */ new Map();
|
|
505
|
-
/**
|
|
506
|
-
spentNonces =
|
|
623
|
+
/** The replay ledger — the shared memory implementation, used dev-only here. */
|
|
624
|
+
spentNonces = new MemoryReplayLedger();
|
|
507
625
|
revokedKeyIds = /* @__PURE__ */ new Set();
|
|
508
626
|
holds = /* @__PURE__ */ new Map();
|
|
509
627
|
initialSessionTtlMillis;
|
|
@@ -518,10 +636,22 @@ var ClientProofState = class {
|
|
|
518
636
|
this.initialSessionTtlMillis = options.sessionTtlMillis ?? DEFAULT_SESSION_TTL_MILLIS;
|
|
519
637
|
this.sessionTtlMillis = this.initialSessionTtlMillis;
|
|
520
638
|
this.replayWindowMillis = options.replayWindowMillis ?? DEFAULT_REPLAY_WINDOW_MILLIS;
|
|
521
|
-
|
|
522
|
-
|
|
639
|
+
this.initialPublicKeys = new Map(
|
|
640
|
+
Object.entries(options.publicKeys).map(([keyId, spki]) => [keyId, parseClientProofPublicKey(spki)])
|
|
641
|
+
);
|
|
642
|
+
for (const [keyId, key] of this.initialPublicKeys) {
|
|
643
|
+
this.publicKeys.set(keyId, key);
|
|
523
644
|
}
|
|
524
645
|
}
|
|
646
|
+
// ---- key registration --------------------------------------------------
|
|
647
|
+
/**
|
|
648
|
+
* Registers (or replaces) the public key `keyId` presents proofs under.
|
|
649
|
+
*
|
|
650
|
+
* @throws when the key is not base64 SPKI DER naming a P-256 key.
|
|
651
|
+
*/
|
|
652
|
+
registerPublicKey(keyId, publicKeySpkiDerBase64) {
|
|
653
|
+
this.publicKeys.set(keyId, parseClientProofPublicKey(publicKeySpkiDerBase64));
|
|
654
|
+
}
|
|
525
655
|
// ---- admission ---------------------------------------------------------
|
|
526
656
|
/**
|
|
527
657
|
* Runs the contract's checks in the contract's order and returns the
|
|
@@ -543,18 +673,17 @@ var ClientProofState = class {
|
|
|
543
673
|
if (age < 0 || age > this.replayWindowMillis) {
|
|
544
674
|
return ClientProofRefusal.proofExpired();
|
|
545
675
|
}
|
|
546
|
-
|
|
547
|
-
if (this.spentNonces.has(replayKey)) {
|
|
676
|
+
if (this.spentNonces.isSpent(args.clientId, args.proofInput.nonce)) {
|
|
548
677
|
return ClientProofRefusal.proofReplayed();
|
|
549
678
|
}
|
|
550
|
-
const
|
|
551
|
-
if (
|
|
679
|
+
const publicKey = this.publicKeys.get(args.keyId);
|
|
680
|
+
if (publicKey === void 0) {
|
|
552
681
|
return ClientProofRefusal.proofInvalid();
|
|
553
682
|
}
|
|
554
|
-
if (!
|
|
683
|
+
if (!verifyClientProof(args.proofInput, args.presentedProof, publicKey)) {
|
|
555
684
|
return ClientProofRefusal.proofInvalid();
|
|
556
685
|
}
|
|
557
|
-
this.spentNonces.
|
|
686
|
+
this.spentNonces.spend(args.clientId, args.proofInput.nonce, Number(args.proofInput.issuedAtMillis));
|
|
558
687
|
return null;
|
|
559
688
|
}
|
|
560
689
|
// ---- sessions ----------------------------------------------------------
|
|
@@ -587,8 +716,12 @@ var ClientProofState = class {
|
|
|
587
716
|
setSessionTtlMillis(millis) {
|
|
588
717
|
this.sessionTtlMillis = millis;
|
|
589
718
|
}
|
|
590
|
-
/** Returns the state to how it started, counters included. */
|
|
719
|
+
/** Returns the state to how it started, counters and registered keys included. */
|
|
591
720
|
reset() {
|
|
721
|
+
this.publicKeys.clear();
|
|
722
|
+
for (const [keyId, key] of this.initialPublicKeys) {
|
|
723
|
+
this.publicKeys.set(keyId, key);
|
|
724
|
+
}
|
|
592
725
|
this.sessions.clear();
|
|
593
726
|
this.spentNonces.clear();
|
|
594
727
|
this.revokedKeyIds.clear();
|
|
@@ -666,11 +799,7 @@ var ClientProofState = class {
|
|
|
666
799
|
this.sessions.delete(sessionId);
|
|
667
800
|
}
|
|
668
801
|
}
|
|
669
|
-
|
|
670
|
-
if (nowMillis - issuedAtMillis > this.replayWindowMillis) {
|
|
671
|
-
this.spentNonces.delete(key);
|
|
672
|
-
}
|
|
673
|
-
}
|
|
802
|
+
this.spentNonces.prune(nowMillis, this.replayWindowMillis);
|
|
674
803
|
}
|
|
675
804
|
};
|
|
676
805
|
|
|
@@ -783,9 +912,78 @@ function isRequestContentType(value) {
|
|
|
783
912
|
|
|
784
913
|
// src/server/client-proof/contract-types.ts
|
|
785
914
|
var CONTRACT_OPERATIONS = [
|
|
786
|
-
{
|
|
787
|
-
|
|
788
|
-
|
|
915
|
+
{
|
|
916
|
+
id: "auth.clientProof.handshake",
|
|
917
|
+
method: "POST",
|
|
918
|
+
path: "/v1/auth/client-proof/handshake",
|
|
919
|
+
authProfile: "clientProofV1",
|
|
920
|
+
requiresSession: false,
|
|
921
|
+
requestType: "HandshakeRequest",
|
|
922
|
+
responseType: "HandshakeResponse",
|
|
923
|
+
summary: "Presents a client proof and opens a session."
|
|
924
|
+
},
|
|
925
|
+
{
|
|
926
|
+
id: "echo.send",
|
|
927
|
+
method: "POST",
|
|
928
|
+
path: "/v1/echo",
|
|
929
|
+
authProfile: "clientProofV1",
|
|
930
|
+
requiresSession: true,
|
|
931
|
+
requestType: "EchoRequest",
|
|
932
|
+
responseType: "EchoResponse",
|
|
933
|
+
summary: "Authenticated round trip used as the smallest real vertical slice."
|
|
934
|
+
},
|
|
935
|
+
{
|
|
936
|
+
id: "items.list",
|
|
937
|
+
method: "POST",
|
|
938
|
+
path: "/v1/items/list",
|
|
939
|
+
authProfile: "clientProofV1",
|
|
940
|
+
requiresSession: true,
|
|
941
|
+
requestType: "ListItemsRequest",
|
|
942
|
+
responseType: "ListItemsResponse",
|
|
943
|
+
summary: "Authenticated paged read covering optional fields and arrays."
|
|
944
|
+
}
|
|
945
|
+
];
|
|
946
|
+
var AUTH_SURFACE_OPERATIONS = [
|
|
947
|
+
{
|
|
948
|
+
id: "auth.enroll.register",
|
|
949
|
+
method: "POST",
|
|
950
|
+
path: "/_auth/register",
|
|
951
|
+
authProfile: "none",
|
|
952
|
+
requiresSession: false,
|
|
953
|
+
requestType: "RegisterRequest",
|
|
954
|
+
responseType: "RegisterResponse",
|
|
955
|
+
summary: "Registers an account with a verification token and enrolls the client-generated public key."
|
|
956
|
+
},
|
|
957
|
+
{
|
|
958
|
+
id: "auth.enroll.login",
|
|
959
|
+
method: "POST",
|
|
960
|
+
path: "/_auth/login",
|
|
961
|
+
authProfile: "none",
|
|
962
|
+
requiresSession: false,
|
|
963
|
+
requestType: "LoginRequest",
|
|
964
|
+
responseType: "LoginResponse",
|
|
965
|
+
summary: "Authenticates with password credentials and enrolls a fresh client-generated public key."
|
|
966
|
+
},
|
|
967
|
+
{
|
|
968
|
+
id: "auth.enroll.oauthNative",
|
|
969
|
+
method: "POST",
|
|
970
|
+
path: "/_auth/oauth/{provider}/native",
|
|
971
|
+
authProfile: "none",
|
|
972
|
+
requiresSession: false,
|
|
973
|
+
requestType: "OauthNativeRequest",
|
|
974
|
+
responseType: "OauthNativeResponse",
|
|
975
|
+
summary: "Verifies a native/web social id_token server-side and enrolls the client-generated public key."
|
|
976
|
+
},
|
|
977
|
+
{
|
|
978
|
+
id: "auth.keys.rotate",
|
|
979
|
+
method: "POST",
|
|
980
|
+
path: "/_auth/keys/rotate",
|
|
981
|
+
authProfile: "clientProofV1",
|
|
982
|
+
requiresSession: false,
|
|
983
|
+
requestType: "RotateKeyRequest",
|
|
984
|
+
responseType: "RotateKeyResponse",
|
|
985
|
+
summary: "Replaces the authenticated key with a new client-generated public key before its TTL runs out."
|
|
986
|
+
}
|
|
789
987
|
];
|
|
790
988
|
var ContractTypeError = class extends Error {
|
|
791
989
|
constructor() {
|
|
@@ -898,6 +1096,8 @@ async function handleControlRequest(state, controlToken, path, request) {
|
|
|
898
1096
|
case "/control/expire-sessions":
|
|
899
1097
|
state.expireSessions();
|
|
900
1098
|
return ok();
|
|
1099
|
+
case "/control/register-key":
|
|
1100
|
+
return registerKey(state, body);
|
|
901
1101
|
case "/control/revoke-key":
|
|
902
1102
|
return revokeKey(state, body);
|
|
903
1103
|
case "/control/session-ttl":
|
|
@@ -922,6 +1122,22 @@ function stats(state) {
|
|
|
922
1122
|
["spentNonceCount", BigInt(counters.spentNonceCount)]
|
|
923
1123
|
])));
|
|
924
1124
|
}
|
|
1125
|
+
function registerKey(state, body) {
|
|
1126
|
+
const keyId = stringField(body, "keyId");
|
|
1127
|
+
const publicKey = stringField(body, "publicKey");
|
|
1128
|
+
if (keyId === null) {
|
|
1129
|
+
return badRequest("keyId");
|
|
1130
|
+
}
|
|
1131
|
+
if (publicKey === null) {
|
|
1132
|
+
return badRequest("publicKey");
|
|
1133
|
+
}
|
|
1134
|
+
try {
|
|
1135
|
+
state.registerPublicKey(keyId, publicKey);
|
|
1136
|
+
} catch {
|
|
1137
|
+
return badRequest("publicKey");
|
|
1138
|
+
}
|
|
1139
|
+
return ok();
|
|
1140
|
+
}
|
|
925
1141
|
function revokeKey(state, body) {
|
|
926
1142
|
const keyId = stringField(body, "keyId");
|
|
927
1143
|
if (keyId === null) {
|
|
@@ -1187,6 +1403,7 @@ function createClientProofGuard(state, options = {}) {
|
|
|
1187
1403
|
}
|
|
1188
1404
|
export {
|
|
1189
1405
|
ABSENT_BODY_SHA256,
|
|
1406
|
+
AUTH_SURFACE_OPERATIONS,
|
|
1190
1407
|
CLIENT_PROOF_CONTENT_TYPE,
|
|
1191
1408
|
CLIENT_PROOF_HEADERS,
|
|
1192
1409
|
CLIENT_PROOF_PROFILE,
|
|
@@ -1201,12 +1418,16 @@ export {
|
|
|
1201
1418
|
DEFAULT_SESSION_TTL_MILLIS,
|
|
1202
1419
|
DEV_CATALOGUE,
|
|
1203
1420
|
DEV_MAX_LIMIT,
|
|
1421
|
+
MemoryReplayLedger,
|
|
1422
|
+
MemoryReplayStore,
|
|
1423
|
+
PROOF_SIGNATURE_BYTES,
|
|
1424
|
+
PROOF_SIGNATURE_HEX_LENGTH,
|
|
1204
1425
|
ProofInputError,
|
|
1426
|
+
RedisReplayStore,
|
|
1205
1427
|
TestClock,
|
|
1206
1428
|
admitClientProofRequest,
|
|
1207
1429
|
canonicalProofInput,
|
|
1208
|
-
|
|
1209
|
-
constantTimeEqualsProof,
|
|
1430
|
+
configureClientProofReplayStore,
|
|
1210
1431
|
createClientProofDevHandler,
|
|
1211
1432
|
createClientProofGuard,
|
|
1212
1433
|
decodeEchoRequest,
|
|
@@ -1216,10 +1437,17 @@ export {
|
|
|
1216
1437
|
encodeEchoResponse,
|
|
1217
1438
|
encodeHandshakeResponse,
|
|
1218
1439
|
encodeListItemsResponse,
|
|
1440
|
+
getClientProofReplayStore,
|
|
1219
1441
|
isCanonicalBytes,
|
|
1442
|
+
isRequestContentType,
|
|
1220
1443
|
newHexId,
|
|
1221
1444
|
parseCanonicalJson,
|
|
1445
|
+
parseClientProofPublicKey,
|
|
1446
|
+
readCredentials,
|
|
1447
|
+
replayLedgerKey,
|
|
1222
1448
|
sha256Hex,
|
|
1223
|
-
|
|
1449
|
+
signClientProof,
|
|
1450
|
+
systemClock,
|
|
1451
|
+
verifyClientProof
|
|
1224
1452
|
};
|
|
1225
1453
|
//# sourceMappingURL=client-proof.js.map
|