@nextera.one/axis-server-sdk 0.2.0 → 0.3.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.d.mts +634 -2
- package/dist/index.d.ts +634 -2
- package/dist/index.js +1345 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1313 -12
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -37,13 +37,22 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
37
37
|
// src/index.ts
|
|
38
38
|
var index_exports = {};
|
|
39
39
|
__export(index_exports, {
|
|
40
|
+
ATS1_HDR: () => ATS1_HDR,
|
|
41
|
+
ATS1_SCHEMA: () => ATS1_SCHEMA,
|
|
40
42
|
AXIS_MAGIC: () => AXIS_MAGIC,
|
|
41
43
|
AXIS_VERSION: () => AXIS_VERSION,
|
|
44
|
+
Ats1Codec: () => ats1_exports,
|
|
42
45
|
AxisFrameZ: () => AxisFrameZ,
|
|
46
|
+
AxisPacketTags: () => T,
|
|
47
|
+
ContractViolationError: () => ContractViolationError,
|
|
48
|
+
DEFAULT_CONTRACTS: () => DEFAULT_CONTRACTS,
|
|
49
|
+
Decision: () => Decision,
|
|
43
50
|
ERR_BAD_SIGNATURE: () => ERR_BAD_SIGNATURE,
|
|
44
51
|
ERR_CONTRACT_VIOLATION: () => ERR_CONTRACT_VIOLATION,
|
|
45
52
|
ERR_INVALID_PACKET: () => ERR_INVALID_PACKET,
|
|
46
53
|
ERR_REPLAY_DETECTED: () => ERR_REPLAY_DETECTED,
|
|
54
|
+
ExecutionMeter: () => ExecutionMeter,
|
|
55
|
+
FALLBACK_CONTRACT: () => FALLBACK_CONTRACT,
|
|
47
56
|
FLAG_BODY_TLV: () => FLAG_BODY_TLV,
|
|
48
57
|
FLAG_CHAIN_REQ: () => FLAG_CHAIN_REQ,
|
|
49
58
|
FLAG_HAS_WITNESS: () => FLAG_HAS_WITNESS,
|
|
@@ -60,6 +69,11 @@ __export(index_exports, {
|
|
|
60
69
|
PROOF_JWT: () => PROOF_JWT,
|
|
61
70
|
PROOF_LOOM: () => PROOF_LOOM,
|
|
62
71
|
PROOF_MTLS: () => PROOF_MTLS,
|
|
72
|
+
Schema2002_PasskeyLoginOptionsRes: () => Schema2002_PasskeyLoginOptionsRes,
|
|
73
|
+
Schema2011_PasskeyLoginVerifyReq: () => Schema2011_PasskeyLoginVerifyReq,
|
|
74
|
+
Schema2012_PasskeyLoginVerifyRes: () => Schema2012_PasskeyLoginVerifyRes,
|
|
75
|
+
Schema2021_PasskeyRegisterOptionsReq: () => Schema2021_PasskeyRegisterOptionsReq,
|
|
76
|
+
SensorDecisions: () => SensorDecisions,
|
|
63
77
|
TLV_ACTOR_ID: () => TLV_ACTOR_ID,
|
|
64
78
|
TLV_AUD: () => TLV_AUD,
|
|
65
79
|
TLV_EFFECT: () => TLV_EFFECT,
|
|
@@ -83,22 +97,50 @@ __export(index_exports, {
|
|
|
83
97
|
TLV_RID: () => TLV_RID,
|
|
84
98
|
TLV_TRACE_ID: () => TLV_TRACE_ID,
|
|
85
99
|
TLV_TS: () => TLV_TS,
|
|
100
|
+
axis1SigningBytes: () => axis1SigningBytes,
|
|
101
|
+
b64urlDecode: () => b64urlDecode,
|
|
102
|
+
b64urlDecodeString: () => b64urlDecodeString,
|
|
103
|
+
b64urlEncode: () => b64urlEncode,
|
|
104
|
+
b64urlEncodeString: () => b64urlEncodeString,
|
|
105
|
+
buildAts1Hdr: () => buildAts1Hdr,
|
|
106
|
+
buildPacket: () => buildPacket,
|
|
107
|
+
buildTLVs: () => buildTLVs,
|
|
108
|
+
bytes: () => bytes,
|
|
109
|
+
canonicalJson: () => canonicalJson,
|
|
110
|
+
canonicalJsonExcluding: () => canonicalJsonExcluding,
|
|
86
111
|
computeReceiptHash: () => computeReceiptHash,
|
|
87
112
|
computeSignaturePayload: () => computeSignaturePayload,
|
|
88
113
|
decodeArray: () => decodeArray,
|
|
114
|
+
decodeAxis1Frame: () => decodeAxis1Frame,
|
|
89
115
|
decodeFrame: () => decodeFrame,
|
|
90
116
|
decodeObject: () => decodeObject,
|
|
91
117
|
decodeTLVs: () => decodeTLVs,
|
|
92
118
|
decodeTLVsList: () => decodeTLVsList,
|
|
93
119
|
decodeVarint: () => decodeVarint,
|
|
120
|
+
encVarint: () => encVarint,
|
|
121
|
+
encodeAxis1Frame: () => encodeAxis1Frame,
|
|
94
122
|
encodeFrame: () => encodeFrame,
|
|
95
123
|
encodeTLVs: () => encodeTLVs,
|
|
96
124
|
encodeVarint: () => encodeVarint,
|
|
97
125
|
generateEd25519KeyPair: () => generateEd25519KeyPair,
|
|
98
126
|
getSignTarget: () => getSignTarget,
|
|
127
|
+
nonce16: () => nonce16,
|
|
128
|
+
normalizeSensorDecision: () => normalizeSensorDecision,
|
|
129
|
+
packPasskeyLoginOptionsReq: () => packPasskeyLoginOptionsReq,
|
|
130
|
+
packPasskeyLoginOptionsRes: () => packPasskeyLoginOptionsRes,
|
|
131
|
+
packPasskeyLoginVerifyReq: () => packPasskeyLoginVerifyReq,
|
|
132
|
+
packPasskeyLoginVerifyRes: () => packPasskeyLoginVerifyRes,
|
|
133
|
+
packPasskeyRegisterOptionsReq: () => packPasskeyRegisterOptionsReq,
|
|
99
134
|
sha256: () => sha256,
|
|
100
135
|
signFrame: () => signFrame,
|
|
136
|
+
tlv: () => tlv,
|
|
137
|
+
u64be: () => u64be,
|
|
138
|
+
unpackPasskeyLoginOptionsReq: () => unpackPasskeyLoginOptionsReq,
|
|
139
|
+
unpackPasskeyLoginVerifyReq: () => unpackPasskeyLoginVerifyReq,
|
|
140
|
+
unpackPasskeyRegisterOptionsReq: () => unpackPasskeyRegisterOptionsReq,
|
|
141
|
+
utf8: () => utf8,
|
|
101
142
|
varintLength: () => varintLength,
|
|
143
|
+
varintU: () => varintU,
|
|
102
144
|
verifyFrameSignature: () => verifyFrameSignature
|
|
103
145
|
});
|
|
104
146
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -336,17 +378,17 @@ var ERR_CONTRACT_VIOLATION = "CONTRACT_VIOLATION";
|
|
|
336
378
|
// src/core/varint.ts
|
|
337
379
|
function encodeVarint(value) {
|
|
338
380
|
if (value < 0) throw new Error("Varint must be unsigned");
|
|
339
|
-
const
|
|
381
|
+
const bytes2 = [];
|
|
340
382
|
while (true) {
|
|
341
383
|
const byte = value & 127;
|
|
342
384
|
value >>>= 7;
|
|
343
385
|
if (value === 0) {
|
|
344
|
-
|
|
386
|
+
bytes2.push(byte);
|
|
345
387
|
break;
|
|
346
388
|
}
|
|
347
|
-
|
|
389
|
+
bytes2.push(byte | 128);
|
|
348
390
|
}
|
|
349
|
-
return new Uint8Array(
|
|
391
|
+
return new Uint8Array(bytes2);
|
|
350
392
|
}
|
|
351
393
|
function decodeVarint(buf, offset = 0) {
|
|
352
394
|
let value = 0;
|
|
@@ -447,21 +489,21 @@ function decodeTLVs(buf) {
|
|
|
447
489
|
}
|
|
448
490
|
return map2;
|
|
449
491
|
}
|
|
450
|
-
function decodeObject(
|
|
492
|
+
function decodeObject(bytes2, depth = 0, limits = { maxDepth: 8, maxItems: 128 }) {
|
|
451
493
|
if (depth > limits.maxDepth) {
|
|
452
494
|
throw new Error("OBJECT_DEPTH_EXCEEDED");
|
|
453
495
|
}
|
|
454
|
-
const map2 = decodeTLVs(
|
|
496
|
+
const map2 = decodeTLVs(bytes2);
|
|
455
497
|
return map2;
|
|
456
498
|
}
|
|
457
|
-
function decodeArray(
|
|
458
|
-
const list = decodeTLVsList(
|
|
499
|
+
function decodeArray(bytes2, itemType, maxItems = 256) {
|
|
500
|
+
const list = decodeTLVsList(bytes2, maxItems);
|
|
459
501
|
const items = [];
|
|
460
|
-
for (const
|
|
461
|
-
if (
|
|
462
|
-
throw new Error(`INVALID_ARRAY_ITEM:${
|
|
502
|
+
for (const tlv2 of list) {
|
|
503
|
+
if (tlv2.type !== itemType) {
|
|
504
|
+
throw new Error(`INVALID_ARRAY_ITEM:${tlv2.type}`);
|
|
463
505
|
}
|
|
464
|
-
items.push(
|
|
506
|
+
items.push(tlv2.value);
|
|
465
507
|
}
|
|
466
508
|
return items;
|
|
467
509
|
}
|
|
@@ -680,15 +722,1273 @@ function computeReceiptHash(receiptBytes, prevHash) {
|
|
|
680
722
|
}
|
|
681
723
|
return hasher.digest();
|
|
682
724
|
}
|
|
725
|
+
|
|
726
|
+
// src/codec/ats1.constants.ts
|
|
727
|
+
var ATS1_HDR = {
|
|
728
|
+
INTENT_ID: 1,
|
|
729
|
+
// uvarint
|
|
730
|
+
ACTOR_KEY_ID: 2,
|
|
731
|
+
// bytes (key fingerprint / credentialId hash)
|
|
732
|
+
CAPSULE_ID: 3,
|
|
733
|
+
// bytes or varint
|
|
734
|
+
NONCE: 4,
|
|
735
|
+
// 16 bytes
|
|
736
|
+
TS_MS: 5,
|
|
737
|
+
// u64be (8)
|
|
738
|
+
SCHEMA_ID: 6,
|
|
739
|
+
// uvarint
|
|
740
|
+
BODY_HASH: 7,
|
|
741
|
+
// 32 bytes (sha256)
|
|
742
|
+
TRACE_ID: 8
|
|
743
|
+
// 16 bytes
|
|
744
|
+
};
|
|
745
|
+
var ATS1_SCHEMA = {
|
|
746
|
+
PASSKEY_LOGIN_OPTIONS_REQ: 2001,
|
|
747
|
+
PASSKEY_LOGIN_OPTIONS_RES: 2002,
|
|
748
|
+
PASSKEY_LOGIN_VERIFY_REQ: 2011,
|
|
749
|
+
PASSKEY_LOGIN_VERIFY_RES: 2012,
|
|
750
|
+
PASSKEY_REGISTER_OPTIONS_REQ: 2021,
|
|
751
|
+
PASSKEY_REGISTER_OPTIONS_RES: 2022,
|
|
752
|
+
PASSKEY_REGISTER_VERIFY_REQ: 2031,
|
|
753
|
+
PASSKEY_REGISTER_VERIFY_RES: 2032
|
|
754
|
+
};
|
|
755
|
+
|
|
756
|
+
// src/codec/ats1.ts
|
|
757
|
+
var ats1_exports = {};
|
|
758
|
+
__export(ats1_exports, {
|
|
759
|
+
DEFAULT_LIMITS: () => DEFAULT_LIMITS,
|
|
760
|
+
HDR_TAGS: () => HDR_TAGS,
|
|
761
|
+
Schema2001_PasskeyLoginOptionsReq: () => Schema2001_PasskeyLoginOptionsReq,
|
|
762
|
+
Schema3100_DeviceContext: () => Schema3100_DeviceContext,
|
|
763
|
+
Schema4001_LoginWithDeviceReq: () => Schema4001_LoginWithDeviceReq,
|
|
764
|
+
decodeAxisHeaderFromTLVs: () => decodeAxisHeaderFromTLVs,
|
|
765
|
+
decodeAxisRequestBinary: () => decodeAxisRequestBinary,
|
|
766
|
+
decodeTLVStream: () => decodeTLVStream,
|
|
767
|
+
decodeU64BE: () => decodeU64BE,
|
|
768
|
+
decodeUVarint: () => decodeUVarint,
|
|
769
|
+
encodeAxisHeaderToTLVs: () => encodeAxisHeaderToTLVs,
|
|
770
|
+
encodeAxisRequestBinary: () => encodeAxisRequestBinary,
|
|
771
|
+
encodeTLV: () => encodeTLV,
|
|
772
|
+
encodeTLVStreamCanonical: () => encodeTLVStreamCanonical,
|
|
773
|
+
encodeU64BE: () => encodeU64BE,
|
|
774
|
+
encodeUVarint: () => encodeUVarint,
|
|
775
|
+
logicalBodyToTLVs: () => logicalBodyToTLVs,
|
|
776
|
+
sha256: () => sha2562,
|
|
777
|
+
tlvsToLogicalBody: () => tlvsToLogicalBody,
|
|
778
|
+
tlvsToMap: () => tlvsToMap,
|
|
779
|
+
validateTLVsAgainstSchema: () => validateTLVsAgainstSchema
|
|
780
|
+
});
|
|
781
|
+
var import_crypto = require("crypto");
|
|
782
|
+
var DEFAULT_LIMITS = {
|
|
783
|
+
maxVarintBytes: 10,
|
|
784
|
+
maxTlvCount: 512,
|
|
785
|
+
maxValueBytes: 1048576,
|
|
786
|
+
// 1 MiB
|
|
787
|
+
maxNestingDepth: 4
|
|
788
|
+
};
|
|
789
|
+
function encodeUVarint(n) {
|
|
790
|
+
let x = typeof n === "bigint" ? n : BigInt(n);
|
|
791
|
+
if (x < 0n) throw new Error("encodeUVarint: negative not allowed");
|
|
792
|
+
const out = [];
|
|
793
|
+
while (x >= 0x80n) {
|
|
794
|
+
out.push(Number(x & 0x7fn | 0x80n));
|
|
795
|
+
x >>= 7n;
|
|
796
|
+
}
|
|
797
|
+
out.push(Number(x));
|
|
798
|
+
return Buffer.from(out);
|
|
799
|
+
}
|
|
800
|
+
function decodeUVarint(buf, offset, limits = DEFAULT_LIMITS) {
|
|
801
|
+
let x = 0n;
|
|
802
|
+
let shift = 0n;
|
|
803
|
+
const start = offset;
|
|
804
|
+
for (let i = 0; i < limits.maxVarintBytes; i++) {
|
|
805
|
+
if (offset >= buf.length) throw new Error("decodeUVarint: truncated");
|
|
806
|
+
const b = buf[offset++];
|
|
807
|
+
x |= BigInt(b & 127) << shift;
|
|
808
|
+
if ((b & 128) === 0) {
|
|
809
|
+
const bytesRead = offset - start;
|
|
810
|
+
const re = encodeUVarint(x);
|
|
811
|
+
const original = buf.subarray(start, offset);
|
|
812
|
+
if (!re.equals(original))
|
|
813
|
+
throw new Error("decodeUVarint: non-minimal varint");
|
|
814
|
+
return { value: x, offset, bytesRead };
|
|
815
|
+
}
|
|
816
|
+
shift += 7n;
|
|
817
|
+
}
|
|
818
|
+
throw new Error("decodeUVarint: too long");
|
|
819
|
+
}
|
|
820
|
+
function encodeU64BE(n) {
|
|
821
|
+
if (n < 0n) throw new Error("encodeU64BE: negative not allowed");
|
|
822
|
+
const b = Buffer.alloc(8);
|
|
823
|
+
b.writeBigUInt64BE(n, 0);
|
|
824
|
+
return b;
|
|
825
|
+
}
|
|
826
|
+
function decodeU64BE(buf) {
|
|
827
|
+
if (buf.length !== 8) throw new Error("decodeU64BE: length must be 8");
|
|
828
|
+
return buf.readBigUInt64BE(0);
|
|
829
|
+
}
|
|
830
|
+
function sha2562(data) {
|
|
831
|
+
return (0, import_crypto.createHash)("sha256").update(data).digest();
|
|
832
|
+
}
|
|
833
|
+
function encodeTLV(tag, value) {
|
|
834
|
+
if (!Number.isInteger(tag) || tag <= 0)
|
|
835
|
+
throw new Error("encodeTLV: tag must be positive int");
|
|
836
|
+
const t = encodeUVarint(tag);
|
|
837
|
+
const l = encodeUVarint(value.length);
|
|
838
|
+
return Buffer.concat([t, l, value]);
|
|
839
|
+
}
|
|
840
|
+
function encodeTLVStreamCanonical(entries) {
|
|
841
|
+
const sorted = [...entries].sort((a, b) => a.tag - b.tag);
|
|
842
|
+
const parts = [];
|
|
843
|
+
for (const e of sorted) parts.push(encodeTLV(e.tag, e.value));
|
|
844
|
+
return Buffer.concat(parts);
|
|
845
|
+
}
|
|
846
|
+
function decodeTLVStream(stream, limits = DEFAULT_LIMITS) {
|
|
847
|
+
const out = [];
|
|
848
|
+
let off = 0;
|
|
849
|
+
while (off < stream.length) {
|
|
850
|
+
if (out.length >= limits.maxTlvCount)
|
|
851
|
+
throw new Error("decodeTLVStream: too many TLVs");
|
|
852
|
+
const tagRes = decodeUVarint(stream, off, limits);
|
|
853
|
+
const tag = Number(tagRes.value);
|
|
854
|
+
off = tagRes.offset;
|
|
855
|
+
const lenRes = decodeUVarint(stream, off, limits);
|
|
856
|
+
const len = Number(lenRes.value);
|
|
857
|
+
off = lenRes.offset;
|
|
858
|
+
if (len < 0) throw new Error("decodeTLVStream: negative length");
|
|
859
|
+
if (len > limits.maxValueBytes)
|
|
860
|
+
throw new Error("decodeTLVStream: value too large");
|
|
861
|
+
if (off + len > stream.length)
|
|
862
|
+
throw new Error("decodeTLVStream: truncated value");
|
|
863
|
+
const value = stream.subarray(off, off + len);
|
|
864
|
+
off += len;
|
|
865
|
+
out.push({ tag, value: Buffer.from(value) });
|
|
866
|
+
}
|
|
867
|
+
for (let i = 1; i < out.length; i++) {
|
|
868
|
+
if (out[i].tag < out[i - 1].tag)
|
|
869
|
+
throw new Error("decodeTLVStream: non-canonical tag order");
|
|
870
|
+
}
|
|
871
|
+
return out;
|
|
872
|
+
}
|
|
873
|
+
function tlvsToMap(entries) {
|
|
874
|
+
const m = /* @__PURE__ */ new Map();
|
|
875
|
+
for (const e of entries) {
|
|
876
|
+
const arr = m.get(e.tag) ?? [];
|
|
877
|
+
arr.push(e.value);
|
|
878
|
+
m.set(e.tag, arr);
|
|
879
|
+
}
|
|
880
|
+
return m;
|
|
881
|
+
}
|
|
882
|
+
function validateTLVsAgainstSchema(schema, tlvs, depth = 0, limits = DEFAULT_LIMITS) {
|
|
883
|
+
if (depth > Math.min(schema.maxNestingDepth, limits.maxNestingDepth)) {
|
|
884
|
+
throw new Error("validateTLVsAgainstSchema: nesting depth exceeded");
|
|
885
|
+
}
|
|
886
|
+
if (schema.maxBodyBytes && tlvsBytes(tlvs) > schema.maxBodyBytes) {
|
|
887
|
+
throw new Error("validateTLVsAgainstSchema: body too large");
|
|
888
|
+
}
|
|
889
|
+
const byTag = /* @__PURE__ */ new Map();
|
|
890
|
+
for (const t of tlvs) {
|
|
891
|
+
if (!byTag.has(t.tag)) byTag.set(t.tag, []);
|
|
892
|
+
byTag.get(t.tag).push(t);
|
|
893
|
+
}
|
|
894
|
+
const fieldByTag = new Map(schema.fields.map((f) => [f.tag, f]));
|
|
895
|
+
if (schema.strict) {
|
|
896
|
+
for (const tag of byTag.keys()) {
|
|
897
|
+
if (!fieldByTag.has(tag))
|
|
898
|
+
throw new Error(`validateTLVsAgainstSchema: unknown tag ${tag}`);
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
for (const f of schema.fields) {
|
|
902
|
+
const vals = byTag.get(f.tag) ?? [];
|
|
903
|
+
if (f.required && vals.length === 0)
|
|
904
|
+
throw new Error(`validateTLVsAgainstSchema: missing ${f.name}`);
|
|
905
|
+
if (!f.repeated && vals.length > 1) {
|
|
906
|
+
throw new Error(
|
|
907
|
+
`validateTLVsAgainstSchema: duplicate tag not allowed for ${f.name}`
|
|
908
|
+
);
|
|
909
|
+
}
|
|
910
|
+
if (typeof f.maxLen === "number") {
|
|
911
|
+
for (const v of vals) {
|
|
912
|
+
if (v.value.length > f.maxLen)
|
|
913
|
+
throw new Error(`validateTLVsAgainstSchema: ${f.name} too long`);
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
for (const v of vals) {
|
|
917
|
+
switch (f.type) {
|
|
918
|
+
case "u64be":
|
|
919
|
+
if (v.value.length !== 8)
|
|
920
|
+
throw new Error(
|
|
921
|
+
`validateTLVsAgainstSchema: ${f.name} u64be must be 8 bytes`
|
|
922
|
+
);
|
|
923
|
+
break;
|
|
924
|
+
case "nested": {
|
|
925
|
+
if (!f.nestedSchema)
|
|
926
|
+
throw new Error(
|
|
927
|
+
`validateTLVsAgainstSchema: ${f.name} missing nestedSchema`
|
|
928
|
+
);
|
|
929
|
+
const nestedTlvs = decodeTLVStream(v.value, limits);
|
|
930
|
+
validateTLVsAgainstSchema(
|
|
931
|
+
f.nestedSchema,
|
|
932
|
+
nestedTlvs,
|
|
933
|
+
depth + 1,
|
|
934
|
+
limits
|
|
935
|
+
);
|
|
936
|
+
break;
|
|
937
|
+
}
|
|
938
|
+
default:
|
|
939
|
+
break;
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
function tlvsBytes(tlvs) {
|
|
945
|
+
let n = 0;
|
|
946
|
+
for (const t of tlvs) {
|
|
947
|
+
n += encodeUVarint(t.tag).length + encodeUVarint(t.value.length).length + t.value.length;
|
|
948
|
+
}
|
|
949
|
+
return n;
|
|
950
|
+
}
|
|
951
|
+
function logicalBodyToTLVs(schema, body, limits = DEFAULT_LIMITS) {
|
|
952
|
+
if (body.schemaId !== schema.schemaId)
|
|
953
|
+
throw new Error("logicalBodyToTLVs: schemaId mismatch");
|
|
954
|
+
const fieldsByName = new Map(schema.fields.map((f) => [f.name, f]));
|
|
955
|
+
const tlvs = [];
|
|
956
|
+
for (const [name, val] of Object.entries(body.fields ?? {})) {
|
|
957
|
+
const f = fieldsByName.get(name);
|
|
958
|
+
if (!f) {
|
|
959
|
+
if (schema.strict)
|
|
960
|
+
throw new Error(`logicalBodyToTLVs: unknown field ${name}`);
|
|
961
|
+
continue;
|
|
962
|
+
}
|
|
963
|
+
const pushOne = (v) => {
|
|
964
|
+
const valueBuf = encodeFieldValue(f, v, limits);
|
|
965
|
+
if (valueBuf.length > limits.maxValueBytes)
|
|
966
|
+
throw new Error("logicalBodyToTLVs: value too large");
|
|
967
|
+
tlvs.push({ tag: f.tag, value: valueBuf });
|
|
968
|
+
};
|
|
969
|
+
if (f.repeated) {
|
|
970
|
+
if (!Array.isArray(val))
|
|
971
|
+
throw new Error(
|
|
972
|
+
`logicalBodyToTLVs: repeated field ${name} must be array`
|
|
973
|
+
);
|
|
974
|
+
for (const item of val) pushOne(item);
|
|
975
|
+
} else {
|
|
976
|
+
pushOne(val);
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
validateTLVsAgainstSchema(schema, tlvs, 0, limits);
|
|
980
|
+
return tlvs;
|
|
981
|
+
}
|
|
982
|
+
function encodeFieldValue(f, val, limits) {
|
|
983
|
+
switch (f.type) {
|
|
984
|
+
case "bytes":
|
|
985
|
+
if (Buffer.isBuffer(val)) return Buffer.from(val);
|
|
986
|
+
if (val instanceof Uint8Array) return Buffer.from(val);
|
|
987
|
+
throw new Error(`encodeFieldValue: ${f.name} expects bytes`);
|
|
988
|
+
case "utf8":
|
|
989
|
+
if (typeof val !== "string")
|
|
990
|
+
throw new Error(`encodeFieldValue: ${f.name} expects string`);
|
|
991
|
+
return Buffer.from(val, "utf8");
|
|
992
|
+
case "uvarint":
|
|
993
|
+
if (typeof val !== "number" && typeof val !== "bigint")
|
|
994
|
+
throw new Error(`encodeFieldValue: ${f.name} expects number/bigint`);
|
|
995
|
+
return encodeUVarint(val);
|
|
996
|
+
case "u64be":
|
|
997
|
+
if (typeof val !== "bigint")
|
|
998
|
+
throw new Error(`encodeFieldValue: ${f.name} expects bigint`);
|
|
999
|
+
return encodeU64BE(val);
|
|
1000
|
+
case "nested": {
|
|
1001
|
+
if (!f.nestedSchema)
|
|
1002
|
+
throw new Error(`encodeFieldValue: ${f.name} missing nestedSchema`);
|
|
1003
|
+
const nestedFields = val && typeof val === "object" && "fields" in val ? val.fields : val;
|
|
1004
|
+
if (!nestedFields || typeof nestedFields !== "object")
|
|
1005
|
+
throw new Error(`encodeFieldValue: ${f.name} expects object`);
|
|
1006
|
+
const nestedBody = {
|
|
1007
|
+
schemaId: f.nestedSchema.schemaId,
|
|
1008
|
+
fields: nestedFields
|
|
1009
|
+
};
|
|
1010
|
+
const nestedTlvs = logicalBodyToTLVs(f.nestedSchema, nestedBody, limits);
|
|
1011
|
+
const nestedBytes = encodeTLVStreamCanonical(nestedTlvs);
|
|
1012
|
+
const re = decodeTLVStream(nestedBytes, limits);
|
|
1013
|
+
validateTLVsAgainstSchema(f.nestedSchema, re, 1, limits);
|
|
1014
|
+
return nestedBytes;
|
|
1015
|
+
}
|
|
1016
|
+
default:
|
|
1017
|
+
throw new Error(`encodeFieldValue: unsupported type ${f.type}`);
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
function tlvsToLogicalBody(schema, tlvs, limits = DEFAULT_LIMITS) {
|
|
1021
|
+
validateTLVsAgainstSchema(schema, tlvs, 0, limits);
|
|
1022
|
+
const fields = {};
|
|
1023
|
+
const fieldByTag = new Map(schema.fields.map((f) => [f.tag, f]));
|
|
1024
|
+
for (const t of tlvs) {
|
|
1025
|
+
const f = fieldByTag.get(t.tag);
|
|
1026
|
+
if (!f) {
|
|
1027
|
+
if (schema.strict)
|
|
1028
|
+
throw new Error(`tlvsToLogicalBody: unknown tag ${t.tag}`);
|
|
1029
|
+
continue;
|
|
1030
|
+
}
|
|
1031
|
+
const decoded = decodeFieldValue(f, t.value, limits);
|
|
1032
|
+
if (f.repeated) {
|
|
1033
|
+
if (!Array.isArray(fields[f.name])) fields[f.name] = [];
|
|
1034
|
+
fields[f.name].push(decoded);
|
|
1035
|
+
} else {
|
|
1036
|
+
fields[f.name] = decoded;
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
return { schemaId: schema.schemaId, fields };
|
|
1040
|
+
}
|
|
1041
|
+
function decodeFieldValue(f, value, limits) {
|
|
1042
|
+
switch (f.type) {
|
|
1043
|
+
case "bytes":
|
|
1044
|
+
return Buffer.from(value);
|
|
1045
|
+
case "utf8":
|
|
1046
|
+
return value.toString("utf8");
|
|
1047
|
+
case "uvarint": {
|
|
1048
|
+
const r = decodeUVarint(value, 0, limits);
|
|
1049
|
+
if (r.offset !== value.length)
|
|
1050
|
+
throw new Error(
|
|
1051
|
+
`decodeFieldValue: ${f.name} uvarint has trailing bytes`
|
|
1052
|
+
);
|
|
1053
|
+
const asNum = Number(r.value);
|
|
1054
|
+
return Number.isSafeInteger(asNum) ? asNum : r.value;
|
|
1055
|
+
}
|
|
1056
|
+
case "u64be":
|
|
1057
|
+
return decodeU64BE(value);
|
|
1058
|
+
case "nested": {
|
|
1059
|
+
if (!f.nestedSchema)
|
|
1060
|
+
throw new Error(`decodeFieldValue: ${f.name} missing nestedSchema`);
|
|
1061
|
+
const nestedTlvs = decodeTLVStream(value, limits);
|
|
1062
|
+
const nestedBody = tlvsToLogicalBody(f.nestedSchema, nestedTlvs, limits);
|
|
1063
|
+
return nestedBody.fields;
|
|
1064
|
+
}
|
|
1065
|
+
default:
|
|
1066
|
+
throw new Error(`decodeFieldValue: unsupported type ${f.type}`);
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
var HDR_TAGS = {
|
|
1070
|
+
intent_id: 1,
|
|
1071
|
+
actor_key_id: 2,
|
|
1072
|
+
capsule_id: 3,
|
|
1073
|
+
nonce: 4,
|
|
1074
|
+
ts_ms: 5,
|
|
1075
|
+
schema_id: 6,
|
|
1076
|
+
body_hash: 7,
|
|
1077
|
+
trace_id: 8
|
|
1078
|
+
};
|
|
1079
|
+
function encodeAxisHeaderToTLVs(hdr) {
|
|
1080
|
+
if (hdr.nonce.byteLength !== 16)
|
|
1081
|
+
throw new Error("encodeAxisHeaderToTLVs: nonce must be 16 bytes");
|
|
1082
|
+
if (hdr.bodyHash.byteLength !== 32)
|
|
1083
|
+
throw new Error("encodeAxisHeaderToTLVs: bodyHash must be 32 bytes");
|
|
1084
|
+
if (hdr.traceId && hdr.traceId.byteLength !== 16)
|
|
1085
|
+
throw new Error("encodeAxisHeaderToTLVs: traceId must be 16 bytes");
|
|
1086
|
+
const tlvs = [
|
|
1087
|
+
{ tag: HDR_TAGS.intent_id, value: encodeUVarint(hdr.intentId) },
|
|
1088
|
+
{ tag: HDR_TAGS.actor_key_id, value: Buffer.from(hdr.actorKeyId) },
|
|
1089
|
+
{ tag: HDR_TAGS.nonce, value: Buffer.from(hdr.nonce) },
|
|
1090
|
+
{ tag: HDR_TAGS.ts_ms, value: encodeU64BE(hdr.tsMs) },
|
|
1091
|
+
{ tag: HDR_TAGS.schema_id, value: encodeUVarint(hdr.schemaId) },
|
|
1092
|
+
{ tag: HDR_TAGS.body_hash, value: Buffer.from(hdr.bodyHash) }
|
|
1093
|
+
];
|
|
1094
|
+
if (hdr.capsuleId)
|
|
1095
|
+
tlvs.push({ tag: HDR_TAGS.capsule_id, value: Buffer.from(hdr.capsuleId) });
|
|
1096
|
+
if (hdr.traceId)
|
|
1097
|
+
tlvs.push({ tag: HDR_TAGS.trace_id, value: Buffer.from(hdr.traceId) });
|
|
1098
|
+
return tlvs;
|
|
1099
|
+
}
|
|
1100
|
+
function decodeAxisHeaderFromTLVs(hdrTlvs, limits = DEFAULT_LIMITS) {
|
|
1101
|
+
const m = tlvsToMap(hdrTlvs);
|
|
1102
|
+
const get1 = (tag) => {
|
|
1103
|
+
const arr = m.get(tag);
|
|
1104
|
+
if (!arr || arr.length !== 1)
|
|
1105
|
+
throw new Error(
|
|
1106
|
+
`decodeAxisHeaderFromTLVs: missing/dup header tag ${tag}`
|
|
1107
|
+
);
|
|
1108
|
+
return arr[0];
|
|
1109
|
+
};
|
|
1110
|
+
const getOpt1 = (tag) => {
|
|
1111
|
+
const arr = m.get(tag);
|
|
1112
|
+
if (!arr) return void 0;
|
|
1113
|
+
if (arr.length !== 1)
|
|
1114
|
+
throw new Error(`decodeAxisHeaderFromTLVs: dup header tag ${tag}`);
|
|
1115
|
+
return arr[0];
|
|
1116
|
+
};
|
|
1117
|
+
const intentIdVar = decodeUVarint(get1(HDR_TAGS.intent_id), 0, limits);
|
|
1118
|
+
if (intentIdVar.offset !== get1(HDR_TAGS.intent_id).length)
|
|
1119
|
+
throw new Error("decodeAxisHeaderFromTLVs: intent_id trailing bytes");
|
|
1120
|
+
const schemaIdVar = decodeUVarint(get1(HDR_TAGS.schema_id), 0, limits);
|
|
1121
|
+
if (schemaIdVar.offset !== get1(HDR_TAGS.schema_id).length)
|
|
1122
|
+
throw new Error("decodeAxisHeaderFromTLVs: schema_id trailing bytes");
|
|
1123
|
+
const ts = decodeU64BE(get1(HDR_TAGS.ts_ms));
|
|
1124
|
+
const nonce = get1(HDR_TAGS.nonce);
|
|
1125
|
+
if (nonce.length !== 16)
|
|
1126
|
+
throw new Error("decodeAxisHeaderFromTLVs: nonce must be 16 bytes");
|
|
1127
|
+
const bodyHash = get1(HDR_TAGS.body_hash);
|
|
1128
|
+
if (bodyHash.length !== 32)
|
|
1129
|
+
throw new Error("decodeAxisHeaderFromTLVs: body_hash must be 32 bytes");
|
|
1130
|
+
const trace = getOpt1(HDR_TAGS.trace_id);
|
|
1131
|
+
if (trace && trace.length !== 16)
|
|
1132
|
+
throw new Error("decodeAxisHeaderFromTLVs: trace_id must be 16 bytes");
|
|
1133
|
+
return {
|
|
1134
|
+
intentId: Number(intentIdVar.value),
|
|
1135
|
+
actorKeyId: Buffer.from(get1(HDR_TAGS.actor_key_id)),
|
|
1136
|
+
capsuleId: getOpt1(HDR_TAGS.capsule_id) ? Buffer.from(getOpt1(HDR_TAGS.capsule_id)) : void 0,
|
|
1137
|
+
nonce: Buffer.from(nonce),
|
|
1138
|
+
tsMs: ts,
|
|
1139
|
+
schemaId: Number(schemaIdVar.value),
|
|
1140
|
+
bodyHash: Buffer.from(bodyHash),
|
|
1141
|
+
traceId: trace ? Buffer.from(trace) : void 0
|
|
1142
|
+
};
|
|
1143
|
+
}
|
|
1144
|
+
function encodeAxisRequestBinary(schema, req, limits = DEFAULT_LIMITS) {
|
|
1145
|
+
const bodyTlvs = logicalBodyToTLVs(schema, req.body, limits);
|
|
1146
|
+
const bodyBytes = encodeTLVStreamCanonical(bodyTlvs);
|
|
1147
|
+
const bodyHash = sha2562(bodyBytes);
|
|
1148
|
+
const hdr = {
|
|
1149
|
+
...req.hdr,
|
|
1150
|
+
schemaId: schema.schemaId,
|
|
1151
|
+
bodyHash
|
|
1152
|
+
};
|
|
1153
|
+
const hdrTlvs = encodeAxisHeaderToTLVs(hdr);
|
|
1154
|
+
const hdrBytes = encodeTLVStreamCanonical(hdrTlvs);
|
|
1155
|
+
return { hdrBytes, bodyBytes, bodyHash };
|
|
1156
|
+
}
|
|
1157
|
+
function decodeAxisRequestBinary(schema, hdrBytes, bodyBytes, limits = DEFAULT_LIMITS) {
|
|
1158
|
+
const hdrTlvs = decodeTLVStream(hdrBytes, limits);
|
|
1159
|
+
const bodyTlvs = decodeTLVStream(bodyBytes, limits);
|
|
1160
|
+
const hdr = decodeAxisHeaderFromTLVs(hdrTlvs, limits);
|
|
1161
|
+
if (hdr.schemaId !== schema.schemaId)
|
|
1162
|
+
throw new Error("decodeAxisRequestBinary: schemaId mismatch");
|
|
1163
|
+
const bh = sha2562(bodyBytes);
|
|
1164
|
+
if (!Buffer.from(hdr.bodyHash).equals(bh))
|
|
1165
|
+
throw new Error("decodeAxisRequestBinary: body_hash mismatch");
|
|
1166
|
+
const body = tlvsToLogicalBody(schema, bodyTlvs, limits);
|
|
1167
|
+
const sensorInput = {
|
|
1168
|
+
hdrTLVs: tlvsToMap(hdrTlvs),
|
|
1169
|
+
bodyTLVs: tlvsToMap(bodyTlvs),
|
|
1170
|
+
schemaId: hdr.schemaId,
|
|
1171
|
+
intentId: hdr.intentId
|
|
1172
|
+
};
|
|
1173
|
+
return { hdr, body, sensorInput };
|
|
1174
|
+
}
|
|
1175
|
+
var Schema3100_DeviceContext = {
|
|
1176
|
+
schemaId: 3100,
|
|
1177
|
+
name: "device.context",
|
|
1178
|
+
strict: true,
|
|
1179
|
+
maxNestingDepth: 4,
|
|
1180
|
+
fields: [
|
|
1181
|
+
{ tag: 1, name: "deviceId", type: "bytes", required: true, maxLen: 128 },
|
|
1182
|
+
{ tag: 2, name: "os", type: "utf8", required: true, maxLen: 64 },
|
|
1183
|
+
{ tag: 3, name: "hw", type: "utf8", required: true, maxLen: 64 }
|
|
1184
|
+
]
|
|
1185
|
+
};
|
|
1186
|
+
var Schema2001_PasskeyLoginOptionsReq = {
|
|
1187
|
+
schemaId: 2001,
|
|
1188
|
+
name: "axis.auth.passkey.login.options.req",
|
|
1189
|
+
strict: true,
|
|
1190
|
+
maxNestingDepth: 4,
|
|
1191
|
+
fields: [
|
|
1192
|
+
{ tag: 1, name: "username", type: "utf8", required: true, maxLen: 128 }
|
|
1193
|
+
]
|
|
1194
|
+
};
|
|
1195
|
+
var Schema4001_LoginWithDeviceReq = {
|
|
1196
|
+
schemaId: 4001,
|
|
1197
|
+
name: "axis.auth.login.with_device.req",
|
|
1198
|
+
strict: true,
|
|
1199
|
+
maxNestingDepth: 4,
|
|
1200
|
+
fields: [
|
|
1201
|
+
{ tag: 1, name: "username", type: "utf8", required: true, maxLen: 128 },
|
|
1202
|
+
{
|
|
1203
|
+
tag: 2,
|
|
1204
|
+
name: "device",
|
|
1205
|
+
type: "nested",
|
|
1206
|
+
required: true,
|
|
1207
|
+
nestedSchema: Schema3100_DeviceContext
|
|
1208
|
+
}
|
|
1209
|
+
]
|
|
1210
|
+
};
|
|
1211
|
+
|
|
1212
|
+
// src/codec/ats1.passkey.schemas.ts
|
|
1213
|
+
function buildAts1Hdr(params) {
|
|
1214
|
+
const hdr = {
|
|
1215
|
+
intentId: params.intentId,
|
|
1216
|
+
schemaId: params.schemaId,
|
|
1217
|
+
actorKeyId: params.actorKeyId ?? Buffer.alloc(0),
|
|
1218
|
+
capsuleId: params.capsuleId,
|
|
1219
|
+
nonce: params.nonce ?? require("crypto").randomBytes(16),
|
|
1220
|
+
tsMs: params.tsMs ?? BigInt(Date.now()),
|
|
1221
|
+
bodyHash: params.bodyHash ?? Buffer.alloc(32),
|
|
1222
|
+
traceId: params.traceId
|
|
1223
|
+
};
|
|
1224
|
+
const tlvs = encodeAxisHeaderToTLVs(hdr);
|
|
1225
|
+
return encodeTLVStreamCanonical(tlvs);
|
|
1226
|
+
}
|
|
1227
|
+
function packPasskeyLoginOptionsReq(params) {
|
|
1228
|
+
const bodyTlvs = logicalBodyToTLVs(
|
|
1229
|
+
Schema2001_PasskeyLoginOptionsReq,
|
|
1230
|
+
{
|
|
1231
|
+
schemaId: ATS1_SCHEMA.PASSKEY_LOGIN_OPTIONS_REQ,
|
|
1232
|
+
fields: { username: params.username }
|
|
1233
|
+
}
|
|
1234
|
+
);
|
|
1235
|
+
const body = encodeTLVStreamCanonical(bodyTlvs);
|
|
1236
|
+
const bodyHash = sha2562(body);
|
|
1237
|
+
const hdr = buildAts1Hdr({
|
|
1238
|
+
intentId: params.intentId,
|
|
1239
|
+
schemaId: ATS1_SCHEMA.PASSKEY_LOGIN_OPTIONS_REQ,
|
|
1240
|
+
actorKeyId: params.actorKeyId,
|
|
1241
|
+
capsuleId: params.capsuleId,
|
|
1242
|
+
traceId: params.traceId,
|
|
1243
|
+
bodyHash
|
|
1244
|
+
});
|
|
1245
|
+
return { hdr, body };
|
|
1246
|
+
}
|
|
1247
|
+
function unpackPasskeyLoginOptionsReq(body) {
|
|
1248
|
+
const tlvs = decodeTLVStream(body);
|
|
1249
|
+
const decoded = tlvsToLogicalBody(
|
|
1250
|
+
Schema2001_PasskeyLoginOptionsReq,
|
|
1251
|
+
tlvs
|
|
1252
|
+
);
|
|
1253
|
+
return { username: decoded.fields.username };
|
|
1254
|
+
}
|
|
1255
|
+
var Schema2021_PasskeyRegisterOptionsReq = {
|
|
1256
|
+
schemaId: ATS1_SCHEMA.PASSKEY_REGISTER_OPTIONS_REQ,
|
|
1257
|
+
name: "axis.auth.passkey.register.options.req",
|
|
1258
|
+
strict: true,
|
|
1259
|
+
maxNestingDepth: 4,
|
|
1260
|
+
fields: [
|
|
1261
|
+
{ tag: 1, name: "username", type: "utf8", required: true, maxLen: 128 }
|
|
1262
|
+
]
|
|
1263
|
+
};
|
|
1264
|
+
var Schema2011_PasskeyLoginVerifyReq = {
|
|
1265
|
+
schemaId: ATS1_SCHEMA.PASSKEY_LOGIN_VERIFY_REQ,
|
|
1266
|
+
name: "axis.auth.passkey.login.verify.req",
|
|
1267
|
+
strict: true,
|
|
1268
|
+
maxNestingDepth: 4,
|
|
1269
|
+
fields: [
|
|
1270
|
+
{ tag: 1, name: "username", type: "utf8", required: true, maxLen: 128 },
|
|
1271
|
+
{
|
|
1272
|
+
tag: 2,
|
|
1273
|
+
name: "credentialId",
|
|
1274
|
+
type: "bytes",
|
|
1275
|
+
required: true,
|
|
1276
|
+
maxLen: 1024
|
|
1277
|
+
},
|
|
1278
|
+
{
|
|
1279
|
+
tag: 3,
|
|
1280
|
+
name: "clientDataJSON",
|
|
1281
|
+
type: "bytes",
|
|
1282
|
+
required: true,
|
|
1283
|
+
maxLen: 4096
|
|
1284
|
+
},
|
|
1285
|
+
{
|
|
1286
|
+
tag: 4,
|
|
1287
|
+
name: "authenticatorData",
|
|
1288
|
+
type: "bytes",
|
|
1289
|
+
required: true,
|
|
1290
|
+
maxLen: 1024
|
|
1291
|
+
},
|
|
1292
|
+
{ tag: 5, name: "signature", type: "bytes", required: true, maxLen: 1024 },
|
|
1293
|
+
{ tag: 6, name: "userHandle", type: "bytes", required: false, maxLen: 128 }
|
|
1294
|
+
]
|
|
1295
|
+
};
|
|
1296
|
+
function packPasskeyRegisterOptionsReq(params) {
|
|
1297
|
+
const bodyTlvs = logicalBodyToTLVs(
|
|
1298
|
+
Schema2021_PasskeyRegisterOptionsReq,
|
|
1299
|
+
{
|
|
1300
|
+
schemaId: ATS1_SCHEMA.PASSKEY_REGISTER_OPTIONS_REQ,
|
|
1301
|
+
fields: { username: params.username }
|
|
1302
|
+
}
|
|
1303
|
+
);
|
|
1304
|
+
const body = encodeTLVStreamCanonical(bodyTlvs);
|
|
1305
|
+
const bodyHash = sha2562(body);
|
|
1306
|
+
const hdr = buildAts1Hdr({
|
|
1307
|
+
intentId: params.intentId,
|
|
1308
|
+
schemaId: ATS1_SCHEMA.PASSKEY_REGISTER_OPTIONS_REQ,
|
|
1309
|
+
actorKeyId: params.actorKeyId,
|
|
1310
|
+
traceId: params.traceId,
|
|
1311
|
+
bodyHash
|
|
1312
|
+
});
|
|
1313
|
+
return { hdr, body };
|
|
1314
|
+
}
|
|
1315
|
+
function unpackPasskeyRegisterOptionsReq(body) {
|
|
1316
|
+
const tlvs = decodeTLVStream(body);
|
|
1317
|
+
const decoded = tlvsToLogicalBody(
|
|
1318
|
+
Schema2021_PasskeyRegisterOptionsReq,
|
|
1319
|
+
tlvs
|
|
1320
|
+
);
|
|
1321
|
+
return { username: decoded.fields.username };
|
|
1322
|
+
}
|
|
1323
|
+
function packPasskeyLoginVerifyReq(params) {
|
|
1324
|
+
const bodyTlvs = logicalBodyToTLVs(Schema2011_PasskeyLoginVerifyReq, {
|
|
1325
|
+
schemaId: ATS1_SCHEMA.PASSKEY_LOGIN_VERIFY_REQ,
|
|
1326
|
+
fields: {
|
|
1327
|
+
username: params.username,
|
|
1328
|
+
credentialId: params.credentialId,
|
|
1329
|
+
clientDataJSON: params.clientDataJSON,
|
|
1330
|
+
authenticatorData: params.authenticatorData,
|
|
1331
|
+
signature: params.signature,
|
|
1332
|
+
userHandle: params.userHandle
|
|
1333
|
+
}
|
|
1334
|
+
});
|
|
1335
|
+
const body = encodeTLVStreamCanonical(bodyTlvs);
|
|
1336
|
+
const bodyHash = sha2562(body);
|
|
1337
|
+
const hdr = buildAts1Hdr({
|
|
1338
|
+
intentId: params.intentId,
|
|
1339
|
+
schemaId: ATS1_SCHEMA.PASSKEY_LOGIN_VERIFY_REQ,
|
|
1340
|
+
actorKeyId: params.actorKeyId,
|
|
1341
|
+
traceId: params.traceId,
|
|
1342
|
+
bodyHash
|
|
1343
|
+
});
|
|
1344
|
+
return { hdr, body };
|
|
1345
|
+
}
|
|
1346
|
+
function unpackPasskeyLoginVerifyReq(body) {
|
|
1347
|
+
const tlvs = decodeTLVStream(body);
|
|
1348
|
+
const decoded = tlvsToLogicalBody(
|
|
1349
|
+
Schema2011_PasskeyLoginVerifyReq,
|
|
1350
|
+
tlvs
|
|
1351
|
+
);
|
|
1352
|
+
const f = decoded.fields;
|
|
1353
|
+
return {
|
|
1354
|
+
username: f.username,
|
|
1355
|
+
credentialId: f.credentialId,
|
|
1356
|
+
clientDataJSON: f.clientDataJSON,
|
|
1357
|
+
authenticatorData: f.authenticatorData,
|
|
1358
|
+
signature: f.signature,
|
|
1359
|
+
userHandle: f.userHandle
|
|
1360
|
+
};
|
|
1361
|
+
}
|
|
1362
|
+
var Schema2002_PasskeyLoginOptionsRes = {
|
|
1363
|
+
schemaId: ATS1_SCHEMA.PASSKEY_LOGIN_OPTIONS_RES,
|
|
1364
|
+
name: "axis.auth.passkey.login.options.res",
|
|
1365
|
+
strict: false,
|
|
1366
|
+
// allow extra fields from WebAuthn library
|
|
1367
|
+
maxNestingDepth: 4,
|
|
1368
|
+
fields: [
|
|
1369
|
+
{ tag: 1, name: "challenge", type: "utf8", required: true },
|
|
1370
|
+
// base64url string
|
|
1371
|
+
{ tag: 2, name: "timeout", type: "uvarint", required: false },
|
|
1372
|
+
{ tag: 3, name: "rpId", type: "utf8", required: false },
|
|
1373
|
+
{ tag: 4, name: "userVerification", type: "utf8", required: false },
|
|
1374
|
+
{ tag: 5, name: "allowCredentialsJson", type: "utf8", required: false }
|
|
1375
|
+
// JSON array for simplicity
|
|
1376
|
+
]
|
|
1377
|
+
};
|
|
1378
|
+
function packPasskeyLoginOptionsRes(params) {
|
|
1379
|
+
const fields = {
|
|
1380
|
+
challenge: params.challenge
|
|
1381
|
+
};
|
|
1382
|
+
if (params.timeout !== void 0) fields.timeout = params.timeout;
|
|
1383
|
+
if (params.rpId) fields.rpId = params.rpId;
|
|
1384
|
+
if (params.userVerification)
|
|
1385
|
+
fields.userVerification = params.userVerification;
|
|
1386
|
+
if (params.allowCredentials)
|
|
1387
|
+
fields.allowCredentialsJson = JSON.stringify(params.allowCredentials);
|
|
1388
|
+
const bodyTlvs = logicalBodyToTLVs(Schema2002_PasskeyLoginOptionsRes, {
|
|
1389
|
+
schemaId: ATS1_SCHEMA.PASSKEY_LOGIN_OPTIONS_RES,
|
|
1390
|
+
fields
|
|
1391
|
+
});
|
|
1392
|
+
return encodeTLVStreamCanonical(bodyTlvs);
|
|
1393
|
+
}
|
|
1394
|
+
var Schema2012_PasskeyLoginVerifyRes = {
|
|
1395
|
+
schemaId: ATS1_SCHEMA.PASSKEY_LOGIN_VERIFY_RES,
|
|
1396
|
+
name: "axis.auth.passkey.login.verify.res",
|
|
1397
|
+
strict: true,
|
|
1398
|
+
maxNestingDepth: 4,
|
|
1399
|
+
fields: [
|
|
1400
|
+
{ tag: 1, name: "actorId", type: "utf8", required: true, maxLen: 256 },
|
|
1401
|
+
{ tag: 2, name: "keyId", type: "utf8", required: true, maxLen: 256 },
|
|
1402
|
+
{ tag: 3, name: "capsule", type: "bytes", required: true, maxLen: 4096 },
|
|
1403
|
+
{ tag: 4, name: "expiresAt", type: "u64be", required: true }
|
|
1404
|
+
]
|
|
1405
|
+
};
|
|
1406
|
+
function packPasskeyLoginVerifyRes(params) {
|
|
1407
|
+
const bodyTlvs = logicalBodyToTLVs(Schema2012_PasskeyLoginVerifyRes, {
|
|
1408
|
+
schemaId: ATS1_SCHEMA.PASSKEY_LOGIN_VERIFY_RES,
|
|
1409
|
+
fields: {
|
|
1410
|
+
actorId: params.actorId,
|
|
1411
|
+
keyId: params.keyId,
|
|
1412
|
+
capsule: params.capsule,
|
|
1413
|
+
expiresAt: params.expiresAt
|
|
1414
|
+
}
|
|
1415
|
+
});
|
|
1416
|
+
return encodeTLVStreamCanonical(bodyTlvs);
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
// src/codec/tlv.encode.ts
|
|
1420
|
+
var import_crypto2 = require("crypto");
|
|
1421
|
+
function encVarint(x) {
|
|
1422
|
+
if (x < 0n) throw new Error("VARINT_NEG");
|
|
1423
|
+
const out = [];
|
|
1424
|
+
while (x >= 0x80n) {
|
|
1425
|
+
out.push(Number(x & 0x7fn | 0x80n));
|
|
1426
|
+
x >>= 7n;
|
|
1427
|
+
}
|
|
1428
|
+
out.push(Number(x));
|
|
1429
|
+
return Buffer.from(out);
|
|
1430
|
+
}
|
|
1431
|
+
function varintU(x) {
|
|
1432
|
+
const v = typeof x === "number" ? BigInt(x) : x;
|
|
1433
|
+
return encVarint(v);
|
|
1434
|
+
}
|
|
1435
|
+
function u64be(x) {
|
|
1436
|
+
if (x < 0n) throw new Error("U64_NEG");
|
|
1437
|
+
const b = Buffer.alloc(8);
|
|
1438
|
+
b.writeBigUInt64BE(x, 0);
|
|
1439
|
+
return b;
|
|
1440
|
+
}
|
|
1441
|
+
function utf8(s) {
|
|
1442
|
+
return Buffer.from(s, "utf8");
|
|
1443
|
+
}
|
|
1444
|
+
function bytes(b) {
|
|
1445
|
+
return Buffer.isBuffer(b) ? b : Buffer.from(b);
|
|
1446
|
+
}
|
|
1447
|
+
function nonce16() {
|
|
1448
|
+
return (0, import_crypto2.randomBytes)(16);
|
|
1449
|
+
}
|
|
1450
|
+
function tlv(type, value) {
|
|
1451
|
+
if (!Number.isSafeInteger(type) || type < 0) throw new Error("TLV_BAD_TYPE");
|
|
1452
|
+
return Buffer.concat([
|
|
1453
|
+
encVarint(BigInt(type)),
|
|
1454
|
+
encVarint(BigInt(value.length)),
|
|
1455
|
+
value
|
|
1456
|
+
]);
|
|
1457
|
+
}
|
|
1458
|
+
function buildTLVs(items, opts) {
|
|
1459
|
+
const allow = opts?.allowDupTypes ?? /* @__PURE__ */ new Set();
|
|
1460
|
+
const sorted = [...items].sort((a, b) => a.type - b.type);
|
|
1461
|
+
for (let i = 1; i < sorted.length; i++) {
|
|
1462
|
+
if (sorted[i].type === sorted[i - 1].type && !allow.has(sorted[i].type)) {
|
|
1463
|
+
throw new Error(`TLV_DUP_TYPE_${sorted[i].type}`);
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
return Buffer.concat(sorted.map((it) => tlv(it.type, it.value)));
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
// src/codec/axis1.encode.ts
|
|
1470
|
+
var MAGIC = Buffer.from("AXIS1", "ascii");
|
|
1471
|
+
function encodeAxis1Frame(f) {
|
|
1472
|
+
if (!Buffer.isBuffer(f.hdr) || !Buffer.isBuffer(f.body) || !Buffer.isBuffer(f.sig)) {
|
|
1473
|
+
throw new Error("AXIS1_BAD_BUFFERS");
|
|
1474
|
+
}
|
|
1475
|
+
if (f.ver !== 1) throw new Error("AXIS1_BAD_VER");
|
|
1476
|
+
const hdrLen = encVarint(BigInt(f.hdr.length));
|
|
1477
|
+
const bodyLen = encVarint(BigInt(f.body.length));
|
|
1478
|
+
const sigLen = encVarint(BigInt(f.sig.length));
|
|
1479
|
+
return Buffer.concat([
|
|
1480
|
+
MAGIC,
|
|
1481
|
+
Buffer.from([f.ver & 255]),
|
|
1482
|
+
Buffer.from([f.flags & 255]),
|
|
1483
|
+
hdrLen,
|
|
1484
|
+
bodyLen,
|
|
1485
|
+
sigLen,
|
|
1486
|
+
f.hdr,
|
|
1487
|
+
f.body,
|
|
1488
|
+
f.sig
|
|
1489
|
+
]);
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
// src/codec/axis1.signing.ts
|
|
1493
|
+
var MAGIC2 = Buffer.from("AXIS1", "ascii");
|
|
1494
|
+
function axis1SigningBytes(params) {
|
|
1495
|
+
if (params.ver !== 1) throw new Error("AXIS1_BAD_VER");
|
|
1496
|
+
const hdrLen = encVarint(BigInt(params.hdr.length));
|
|
1497
|
+
const bodyLen = encVarint(BigInt(params.body.length));
|
|
1498
|
+
const sigLenZero = encVarint(0n);
|
|
1499
|
+
return Buffer.concat([
|
|
1500
|
+
MAGIC2,
|
|
1501
|
+
Buffer.from([params.ver & 255]),
|
|
1502
|
+
Buffer.from([params.flags & 255]),
|
|
1503
|
+
hdrLen,
|
|
1504
|
+
bodyLen,
|
|
1505
|
+
sigLenZero,
|
|
1506
|
+
params.hdr,
|
|
1507
|
+
params.body
|
|
1508
|
+
]);
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
// src/crypto/b64url.ts
|
|
1512
|
+
function b64urlEncode(buf) {
|
|
1513
|
+
return buf.toString("base64").replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
|
|
1514
|
+
}
|
|
1515
|
+
function b64urlDecode(str) {
|
|
1516
|
+
const pad = str.length % 4 ? "=".repeat(4 - str.length % 4) : "";
|
|
1517
|
+
const base64 = (str + pad).replace(/-/g, "+").replace(/_/g, "/");
|
|
1518
|
+
return Buffer.from(base64, "base64");
|
|
1519
|
+
}
|
|
1520
|
+
function b64urlEncodeString(str, encoding = "utf8") {
|
|
1521
|
+
return b64urlEncode(Buffer.from(str, encoding));
|
|
1522
|
+
}
|
|
1523
|
+
function b64urlDecodeString(str, encoding = "utf8") {
|
|
1524
|
+
return b64urlDecode(str).toString(encoding);
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
// src/crypto/canonical-json.ts
|
|
1528
|
+
function sortRec(value) {
|
|
1529
|
+
if (value === null) {
|
|
1530
|
+
return null;
|
|
1531
|
+
}
|
|
1532
|
+
if (value === void 0) {
|
|
1533
|
+
return void 0;
|
|
1534
|
+
}
|
|
1535
|
+
if (Array.isArray(value)) {
|
|
1536
|
+
return value.map(sortRec);
|
|
1537
|
+
}
|
|
1538
|
+
if (typeof value === "object") {
|
|
1539
|
+
const sorted = {};
|
|
1540
|
+
const keys = Object.keys(value).sort();
|
|
1541
|
+
for (const key of keys) {
|
|
1542
|
+
const sortedValue = sortRec(value[key]);
|
|
1543
|
+
if (sortedValue !== void 0) {
|
|
1544
|
+
sorted[key] = sortedValue;
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
return sorted;
|
|
1548
|
+
}
|
|
1549
|
+
return value;
|
|
1550
|
+
}
|
|
1551
|
+
function canonicalJson(value) {
|
|
1552
|
+
return JSON.stringify(sortRec(value));
|
|
1553
|
+
}
|
|
1554
|
+
function canonicalJsonExcluding(obj, exclude) {
|
|
1555
|
+
const filtered = {};
|
|
1556
|
+
for (const key in obj) {
|
|
1557
|
+
if (!exclude.includes(key) && obj[key] !== void 0) {
|
|
1558
|
+
filtered[key] = obj[key];
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
return canonicalJson(filtered);
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
// src/contract/execution-meter.ts
|
|
1565
|
+
var ContractViolationError = class extends Error {
|
|
1566
|
+
constructor(code, message) {
|
|
1567
|
+
super(message);
|
|
1568
|
+
this.code = code;
|
|
1569
|
+
this.name = "ContractViolationError";
|
|
1570
|
+
}
|
|
1571
|
+
};
|
|
1572
|
+
var ExecutionMeter = class {
|
|
1573
|
+
// ExecutionContract
|
|
1574
|
+
constructor(contract) {
|
|
1575
|
+
this.dbWrites = 0;
|
|
1576
|
+
this.dbReads = 0;
|
|
1577
|
+
this.externalCalls = 0;
|
|
1578
|
+
this.contract = contract;
|
|
1579
|
+
this.startTime = Date.now();
|
|
1580
|
+
}
|
|
1581
|
+
recordDbWrite() {
|
|
1582
|
+
this.dbWrites++;
|
|
1583
|
+
if (this.dbWrites > this.contract.maxDbWrites) {
|
|
1584
|
+
throw new ContractViolationError(
|
|
1585
|
+
"MAX_DB_WRITES_EXCEEDED",
|
|
1586
|
+
`DB writes exceeded: ${this.dbWrites}/${this.contract.maxDbWrites}`
|
|
1587
|
+
);
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
recordDbRead() {
|
|
1591
|
+
this.dbReads++;
|
|
1592
|
+
if (this.contract.maxDbReads && this.dbReads > this.contract.maxDbReads) {
|
|
1593
|
+
throw new ContractViolationError(
|
|
1594
|
+
"MAX_DB_READS_EXCEEDED",
|
|
1595
|
+
`DB reads exceeded: ${this.dbReads}/${this.contract.maxDbReads}`
|
|
1596
|
+
);
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
recordExternalCall() {
|
|
1600
|
+
this.externalCalls++;
|
|
1601
|
+
if (this.externalCalls > this.contract.maxExternalCalls) {
|
|
1602
|
+
throw new ContractViolationError(
|
|
1603
|
+
"MAX_EXTERNAL_CALLS_EXCEEDED",
|
|
1604
|
+
`External calls exceeded: ${this.externalCalls}/${this.contract.maxExternalCalls}`
|
|
1605
|
+
);
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
checkTime() {
|
|
1609
|
+
const elapsed = Date.now() - this.startTime;
|
|
1610
|
+
if (elapsed > this.contract.maxTimeMs) {
|
|
1611
|
+
throw new ContractViolationError(
|
|
1612
|
+
"MAX_TIME_EXCEEDED",
|
|
1613
|
+
`Execution time exceeded: ${elapsed}ms/${this.contract.maxTimeMs}ms`
|
|
1614
|
+
);
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
validateEffect(effect) {
|
|
1618
|
+
if (this.contract.allowedEffects.includes("*")) {
|
|
1619
|
+
return;
|
|
1620
|
+
}
|
|
1621
|
+
if (!this.contract.allowedEffects.includes(effect)) {
|
|
1622
|
+
throw new ContractViolationError(
|
|
1623
|
+
"INVALID_EFFECT",
|
|
1624
|
+
`Effect '${effect}' not allowed. Allowed: ${this.contract.allowedEffects.join(", ")}`
|
|
1625
|
+
);
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
getMetrics() {
|
|
1629
|
+
return {
|
|
1630
|
+
dbWrites: this.dbWrites,
|
|
1631
|
+
dbReads: this.dbReads,
|
|
1632
|
+
externalCalls: this.externalCalls,
|
|
1633
|
+
elapsedMs: Date.now() - this.startTime
|
|
1634
|
+
};
|
|
1635
|
+
}
|
|
1636
|
+
getContract() {
|
|
1637
|
+
return this.contract;
|
|
1638
|
+
}
|
|
1639
|
+
};
|
|
1640
|
+
|
|
1641
|
+
// src/contract/contract.interface.ts
|
|
1642
|
+
var DEFAULT_CONTRACTS = {
|
|
1643
|
+
// System intents
|
|
1644
|
+
"system.ping": {
|
|
1645
|
+
maxDbWrites: 0,
|
|
1646
|
+
maxExternalCalls: 0,
|
|
1647
|
+
maxTimeMs: 100,
|
|
1648
|
+
allowedEffects: ["system.pong"]
|
|
1649
|
+
},
|
|
1650
|
+
// Catalog intents
|
|
1651
|
+
"catalog.list": {
|
|
1652
|
+
maxDbWrites: 0,
|
|
1653
|
+
maxExternalCalls: 0,
|
|
1654
|
+
maxTimeMs: 200,
|
|
1655
|
+
allowedEffects: ["catalog.listed"]
|
|
1656
|
+
},
|
|
1657
|
+
"catalog.search": {
|
|
1658
|
+
maxDbWrites: 0,
|
|
1659
|
+
maxExternalCalls: 0,
|
|
1660
|
+
maxTimeMs: 300,
|
|
1661
|
+
allowedEffects: ["catalog.searched"]
|
|
1662
|
+
},
|
|
1663
|
+
// Passport intents
|
|
1664
|
+
"passport.issue": {
|
|
1665
|
+
maxDbWrites: 10,
|
|
1666
|
+
maxExternalCalls: 0,
|
|
1667
|
+
maxTimeMs: 500,
|
|
1668
|
+
allowedEffects: ["passport.issued", "passport.rejected"]
|
|
1669
|
+
},
|
|
1670
|
+
"passport.revoke": {
|
|
1671
|
+
maxDbWrites: 5,
|
|
1672
|
+
maxExternalCalls: 0,
|
|
1673
|
+
maxTimeMs: 300,
|
|
1674
|
+
allowedEffects: ["passport.revoked", "passport.revoke_failed"]
|
|
1675
|
+
},
|
|
1676
|
+
// File intents
|
|
1677
|
+
"file.init": {
|
|
1678
|
+
maxDbWrites: 2,
|
|
1679
|
+
maxExternalCalls: 0,
|
|
1680
|
+
maxTimeMs: 200,
|
|
1681
|
+
allowedEffects: ["file.initialized"]
|
|
1682
|
+
},
|
|
1683
|
+
"file.chunk": {
|
|
1684
|
+
maxDbWrites: 2,
|
|
1685
|
+
maxExternalCalls: 0,
|
|
1686
|
+
maxTimeMs: 1e3,
|
|
1687
|
+
allowedEffects: ["file.chunk.stored"]
|
|
1688
|
+
},
|
|
1689
|
+
"file.finalize": {
|
|
1690
|
+
maxDbWrites: 2,
|
|
1691
|
+
maxExternalCalls: 0,
|
|
1692
|
+
maxTimeMs: 500,
|
|
1693
|
+
allowedEffects: ["file.finalized"]
|
|
1694
|
+
},
|
|
1695
|
+
// Stream intents
|
|
1696
|
+
"stream.publish": {
|
|
1697
|
+
maxDbWrites: 1,
|
|
1698
|
+
maxExternalCalls: 0,
|
|
1699
|
+
maxTimeMs: 200,
|
|
1700
|
+
allowedEffects: ["stream.published"]
|
|
1701
|
+
},
|
|
1702
|
+
"stream.read": {
|
|
1703
|
+
maxDbWrites: 0,
|
|
1704
|
+
maxExternalCalls: 0,
|
|
1705
|
+
maxTimeMs: 300,
|
|
1706
|
+
allowedEffects: ["stream.data"]
|
|
1707
|
+
},
|
|
1708
|
+
// Mail intents
|
|
1709
|
+
"mail.send": {
|
|
1710
|
+
maxDbWrites: 3,
|
|
1711
|
+
maxExternalCalls: 1,
|
|
1712
|
+
// Email service
|
|
1713
|
+
maxTimeMs: 2e3,
|
|
1714
|
+
allowedEffects: ["mail.sent", "mail.failed"]
|
|
1715
|
+
}
|
|
1716
|
+
};
|
|
1717
|
+
var FALLBACK_CONTRACT = {
|
|
1718
|
+
maxDbWrites: 10,
|
|
1719
|
+
maxExternalCalls: 0,
|
|
1720
|
+
maxTimeMs: 1e3,
|
|
1721
|
+
allowedEffects: ["*"]
|
|
1722
|
+
// Allow any effect
|
|
1723
|
+
};
|
|
1724
|
+
|
|
1725
|
+
// src/types/tlv.ts
|
|
1726
|
+
function decVarint(buf, off) {
|
|
1727
|
+
let shift = 0n;
|
|
1728
|
+
let x = 0n;
|
|
1729
|
+
while (true) {
|
|
1730
|
+
if (off >= buf.length) throw new Error("varint overflow");
|
|
1731
|
+
const b = BigInt(buf[off++]);
|
|
1732
|
+
x |= (b & 0x7fn) << shift;
|
|
1733
|
+
if ((b & 0x80n) === 0n) break;
|
|
1734
|
+
shift += 7n;
|
|
1735
|
+
if (shift > 63n) throw new Error("varint too large");
|
|
1736
|
+
}
|
|
1737
|
+
return { val: x, off };
|
|
1738
|
+
}
|
|
1739
|
+
function parseTLVs(buf, maxItems = 512) {
|
|
1740
|
+
const out = [];
|
|
1741
|
+
let off = 0;
|
|
1742
|
+
while (off < buf.length) {
|
|
1743
|
+
if (out.length >= maxItems) throw new Error("TLV_TOO_MANY_ITEMS");
|
|
1744
|
+
const t1 = decVarint(buf, off);
|
|
1745
|
+
off = t1.off;
|
|
1746
|
+
const t2 = decVarint(buf, off);
|
|
1747
|
+
off = t2.off;
|
|
1748
|
+
const type = Number(t1.val);
|
|
1749
|
+
const len = Number(t2.val);
|
|
1750
|
+
if (len < 0 || off + len > buf.length) {
|
|
1751
|
+
throw new Error("TLV_LEN_INVALID");
|
|
1752
|
+
}
|
|
1753
|
+
const value = buf.subarray(off, off + len);
|
|
1754
|
+
off += len;
|
|
1755
|
+
out.push({ type, value });
|
|
1756
|
+
}
|
|
1757
|
+
return out;
|
|
1758
|
+
}
|
|
1759
|
+
function tlvMap(buf) {
|
|
1760
|
+
const m = /* @__PURE__ */ new Map();
|
|
1761
|
+
for (const it of parseTLVs(buf)) {
|
|
1762
|
+
const arr = m.get(it.type) ?? [];
|
|
1763
|
+
arr.push(it.value);
|
|
1764
|
+
m.set(it.type, arr);
|
|
1765
|
+
}
|
|
1766
|
+
return m;
|
|
1767
|
+
}
|
|
1768
|
+
function asUtf8(b) {
|
|
1769
|
+
if (!b) return void 0;
|
|
1770
|
+
return b.toString("utf8");
|
|
1771
|
+
}
|
|
1772
|
+
function asBigintVarint(b) {
|
|
1773
|
+
if (!b) return void 0;
|
|
1774
|
+
const { val, off } = decVarint(b, 0);
|
|
1775
|
+
if (off !== b.length) throw new Error("VARINT_TRAILING_BYTES");
|
|
1776
|
+
return val;
|
|
1777
|
+
}
|
|
1778
|
+
function asBigint64BE(b) {
|
|
1779
|
+
if (!b) return void 0;
|
|
1780
|
+
if (b.length !== 8) throw new Error("Expected 8 bytes for u64");
|
|
1781
|
+
return b.readBigUInt64BE(0);
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
// src/types/frame.ts
|
|
1785
|
+
var MAGIC3 = Buffer.from("AXIS1", "ascii");
|
|
1786
|
+
function decodeAxis1Frame(buf) {
|
|
1787
|
+
let off = 0;
|
|
1788
|
+
const magic = buf.subarray(off, off + 5);
|
|
1789
|
+
off += 5;
|
|
1790
|
+
if (magic.length !== 5 || !magic.equals(MAGIC3))
|
|
1791
|
+
throw new Error("AXIS1_BAD_MAGIC");
|
|
1792
|
+
if (off + 2 > buf.length) throw new Error("AXIS1_TRUNCATED");
|
|
1793
|
+
const ver = buf[off++];
|
|
1794
|
+
const flags = buf[off++];
|
|
1795
|
+
const h1 = decVarint(buf, off);
|
|
1796
|
+
off = h1.off;
|
|
1797
|
+
const b1 = decVarint(buf, off);
|
|
1798
|
+
off = b1.off;
|
|
1799
|
+
const s1 = decVarint(buf, off);
|
|
1800
|
+
off = s1.off;
|
|
1801
|
+
const hdrLen = Number(h1.val);
|
|
1802
|
+
const bodyLen = Number(b1.val);
|
|
1803
|
+
const sigLen = Number(s1.val);
|
|
1804
|
+
if (hdrLen < 0 || bodyLen < 0 || sigLen < 0) throw new Error("AXIS1_LEN_NEG");
|
|
1805
|
+
if (off + hdrLen + bodyLen + sigLen > buf.length)
|
|
1806
|
+
throw new Error("AXIS1_TRUNCATED_PAYLOAD");
|
|
1807
|
+
const hdr = buf.subarray(off, off + hdrLen);
|
|
1808
|
+
off += hdrLen;
|
|
1809
|
+
const body = buf.subarray(off, off + bodyLen);
|
|
1810
|
+
off += bodyLen;
|
|
1811
|
+
const sig = buf.subarray(off, off + sigLen);
|
|
1812
|
+
off += sigLen;
|
|
1813
|
+
if (off !== buf.length) throw new Error("AXIS1_TRAILING_BYTES");
|
|
1814
|
+
return { ver, flags, hdr, body, sig, frameSize: buf.length };
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1817
|
+
// src/types/packet.ts
|
|
1818
|
+
var T = {
|
|
1819
|
+
/** The specific intent or action (e.g., 'vault.create') */
|
|
1820
|
+
INTENT: TLV_INTENT,
|
|
1821
|
+
/** Package identifier / ID */
|
|
1822
|
+
PID: TLV_PID,
|
|
1823
|
+
/** Versioning of the intent schema */
|
|
1824
|
+
INTENT_VERSION: 10,
|
|
1825
|
+
// Defaulting to TRACE_ID for now or a new tag if available
|
|
1826
|
+
/** Unique identifier for the requesting actor */
|
|
1827
|
+
ACTOR_ID: TLV_ACTOR_ID,
|
|
1828
|
+
/** Optional Capability Token identifier (16 bytes) */
|
|
1829
|
+
CAPSULE_ID: TLV_PROOF_REF,
|
|
1830
|
+
/** Unique session/request identifier (16 bytes) */
|
|
1831
|
+
NONCE: TLV_NONCE,
|
|
1832
|
+
/** High-precision Unix timestamp in milliseconds */
|
|
1833
|
+
TS_MS: TLV_TS,
|
|
1834
|
+
/** Proof type */
|
|
1835
|
+
PROOF_TYPE: TLV_PROOF_TYPE,
|
|
1836
|
+
/** Standard binary body tag */
|
|
1837
|
+
BODY: 100,
|
|
1838
|
+
/** Standard JSON-encoded body tag */
|
|
1839
|
+
JSON: 200
|
|
1840
|
+
};
|
|
1841
|
+
function buildPacket(hdr, body, sig, flags = 0) {
|
|
1842
|
+
const hm = tlvMap(hdr);
|
|
1843
|
+
const BODY_IS_TLV = 1;
|
|
1844
|
+
const bm = flags & BODY_IS_TLV ? tlvMap(body) : /* @__PURE__ */ new Map();
|
|
1845
|
+
const intent = asUtf8(hm.get(T.INTENT)?.[0]);
|
|
1846
|
+
const intentVerRaw = hm.get(T.INTENT_VERSION)?.[0];
|
|
1847
|
+
const intentVer = intentVerRaw ? Number(asBigintVarint(intentVerRaw)) : 1;
|
|
1848
|
+
const actorIdRaw = hm.get(T.ACTOR_ID)?.[0];
|
|
1849
|
+
const actorId = actorIdRaw ? actorIdRaw.toString("hex") : void 0;
|
|
1850
|
+
const capsuleId = hm.get(T.CAPSULE_ID)?.[0];
|
|
1851
|
+
const pid = hm.get(T.PID)?.[0] || hm.get(T.NONCE)?.[0];
|
|
1852
|
+
const nonce = hm.get(T.NONCE)?.[0];
|
|
1853
|
+
const tsMs = asBigint64BE(hm.get(T.TS_MS)?.[0]);
|
|
1854
|
+
if (!intent) throw new Error("PACKET_MISSING_INTENT");
|
|
1855
|
+
if (!actorId) throw new Error("PACKET_MISSING_ACTOR_ID");
|
|
1856
|
+
if (!nonce || nonce.length < 16 || nonce.length > 32)
|
|
1857
|
+
throw new Error("PACKET_BAD_NONCE");
|
|
1858
|
+
if (!pid) throw new Error("PACKET_MISSING_PID");
|
|
1859
|
+
if (!tsMs) throw new Error("PACKET_MISSING_TS");
|
|
1860
|
+
return {
|
|
1861
|
+
intent,
|
|
1862
|
+
intentVersion: intentVer,
|
|
1863
|
+
actorId,
|
|
1864
|
+
capsuleId,
|
|
1865
|
+
pid,
|
|
1866
|
+
nonce,
|
|
1867
|
+
tsMs,
|
|
1868
|
+
headersMap: hm,
|
|
1869
|
+
bodyMap: bm,
|
|
1870
|
+
hdrBytes: hdr,
|
|
1871
|
+
bodyBytes: body,
|
|
1872
|
+
sig
|
|
1873
|
+
};
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1876
|
+
// src/sensor/axis-sensor.ts
|
|
1877
|
+
var Decision = /* @__PURE__ */ ((Decision2) => {
|
|
1878
|
+
Decision2["ALLOW"] = "ALLOW";
|
|
1879
|
+
Decision2["DENY"] = "DENY";
|
|
1880
|
+
Decision2["THROTTLE"] = "THROTTLE";
|
|
1881
|
+
Decision2["FLAG"] = "FLAG";
|
|
1882
|
+
return Decision2;
|
|
1883
|
+
})(Decision || {});
|
|
1884
|
+
function normalizeSensorDecision(sensorDecision) {
|
|
1885
|
+
if ("action" in sensorDecision) {
|
|
1886
|
+
switch (sensorDecision.action) {
|
|
1887
|
+
case "ALLOW":
|
|
1888
|
+
return {
|
|
1889
|
+
allow: true,
|
|
1890
|
+
riskScore: 0,
|
|
1891
|
+
reasons: [],
|
|
1892
|
+
meta: sensorDecision.meta
|
|
1893
|
+
};
|
|
1894
|
+
case "DENY":
|
|
1895
|
+
return {
|
|
1896
|
+
allow: false,
|
|
1897
|
+
riskScore: 100,
|
|
1898
|
+
reasons: [sensorDecision.code, sensorDecision.reason].filter(
|
|
1899
|
+
Boolean
|
|
1900
|
+
),
|
|
1901
|
+
meta: sensorDecision.meta,
|
|
1902
|
+
retryAfterMs: sensorDecision.retryAfterMs
|
|
1903
|
+
};
|
|
1904
|
+
case "THROTTLE":
|
|
1905
|
+
return {
|
|
1906
|
+
allow: false,
|
|
1907
|
+
riskScore: 50,
|
|
1908
|
+
reasons: ["RATE_LIMIT"],
|
|
1909
|
+
retryAfterMs: sensorDecision.retryAfterMs,
|
|
1910
|
+
meta: sensorDecision.meta
|
|
1911
|
+
};
|
|
1912
|
+
case "FLAG":
|
|
1913
|
+
return {
|
|
1914
|
+
allow: true,
|
|
1915
|
+
riskScore: sensorDecision.scoreDelta,
|
|
1916
|
+
reasons: sensorDecision.reasons,
|
|
1917
|
+
meta: sensorDecision.meta
|
|
1918
|
+
};
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
return {
|
|
1922
|
+
allow: sensorDecision.allow,
|
|
1923
|
+
riskScore: sensorDecision.riskScore,
|
|
1924
|
+
reasons: sensorDecision.reasons,
|
|
1925
|
+
tags: sensorDecision.tags,
|
|
1926
|
+
meta: sensorDecision.meta,
|
|
1927
|
+
tighten: sensorDecision.tighten,
|
|
1928
|
+
retryAfterMs: sensorDecision.retryAfterMs
|
|
1929
|
+
};
|
|
1930
|
+
}
|
|
1931
|
+
var SensorDecisions = {
|
|
1932
|
+
allow(meta, tags) {
|
|
1933
|
+
return {
|
|
1934
|
+
decision: "ALLOW" /* ALLOW */,
|
|
1935
|
+
allow: true,
|
|
1936
|
+
riskScore: 0,
|
|
1937
|
+
reasons: [],
|
|
1938
|
+
tags,
|
|
1939
|
+
meta
|
|
1940
|
+
};
|
|
1941
|
+
},
|
|
1942
|
+
deny(code, reason, meta) {
|
|
1943
|
+
return {
|
|
1944
|
+
decision: "DENY" /* DENY */,
|
|
1945
|
+
allow: false,
|
|
1946
|
+
riskScore: 100,
|
|
1947
|
+
code,
|
|
1948
|
+
reasons: [code, reason].filter(Boolean),
|
|
1949
|
+
meta
|
|
1950
|
+
};
|
|
1951
|
+
},
|
|
1952
|
+
throttle(retryAfterMs, meta) {
|
|
1953
|
+
return {
|
|
1954
|
+
decision: "THROTTLE" /* THROTTLE */,
|
|
1955
|
+
allow: false,
|
|
1956
|
+
riskScore: 50,
|
|
1957
|
+
retryAfterMs,
|
|
1958
|
+
code: "RATE_LIMIT",
|
|
1959
|
+
reasons: ["RATE_LIMIT"],
|
|
1960
|
+
meta
|
|
1961
|
+
};
|
|
1962
|
+
},
|
|
1963
|
+
flag(scoreDelta, reasons, meta) {
|
|
1964
|
+
return {
|
|
1965
|
+
decision: "FLAG" /* FLAG */,
|
|
1966
|
+
allow: true,
|
|
1967
|
+
riskScore: scoreDelta,
|
|
1968
|
+
scoreDelta,
|
|
1969
|
+
reasons,
|
|
1970
|
+
meta
|
|
1971
|
+
};
|
|
1972
|
+
}
|
|
1973
|
+
};
|
|
683
1974
|
// Annotate the CommonJS export names for ESM import in node:
|
|
684
1975
|
0 && (module.exports = {
|
|
1976
|
+
ATS1_HDR,
|
|
1977
|
+
ATS1_SCHEMA,
|
|
685
1978
|
AXIS_MAGIC,
|
|
686
1979
|
AXIS_VERSION,
|
|
1980
|
+
Ats1Codec,
|
|
687
1981
|
AxisFrameZ,
|
|
1982
|
+
AxisPacketTags,
|
|
1983
|
+
ContractViolationError,
|
|
1984
|
+
DEFAULT_CONTRACTS,
|
|
1985
|
+
Decision,
|
|
688
1986
|
ERR_BAD_SIGNATURE,
|
|
689
1987
|
ERR_CONTRACT_VIOLATION,
|
|
690
1988
|
ERR_INVALID_PACKET,
|
|
691
1989
|
ERR_REPLAY_DETECTED,
|
|
1990
|
+
ExecutionMeter,
|
|
1991
|
+
FALLBACK_CONTRACT,
|
|
692
1992
|
FLAG_BODY_TLV,
|
|
693
1993
|
FLAG_CHAIN_REQ,
|
|
694
1994
|
FLAG_HAS_WITNESS,
|
|
@@ -705,6 +2005,11 @@ function computeReceiptHash(receiptBytes, prevHash) {
|
|
|
705
2005
|
PROOF_JWT,
|
|
706
2006
|
PROOF_LOOM,
|
|
707
2007
|
PROOF_MTLS,
|
|
2008
|
+
Schema2002_PasskeyLoginOptionsRes,
|
|
2009
|
+
Schema2011_PasskeyLoginVerifyReq,
|
|
2010
|
+
Schema2012_PasskeyLoginVerifyRes,
|
|
2011
|
+
Schema2021_PasskeyRegisterOptionsReq,
|
|
2012
|
+
SensorDecisions,
|
|
708
2013
|
TLV_ACTOR_ID,
|
|
709
2014
|
TLV_AUD,
|
|
710
2015
|
TLV_EFFECT,
|
|
@@ -728,22 +2033,50 @@ function computeReceiptHash(receiptBytes, prevHash) {
|
|
|
728
2033
|
TLV_RID,
|
|
729
2034
|
TLV_TRACE_ID,
|
|
730
2035
|
TLV_TS,
|
|
2036
|
+
axis1SigningBytes,
|
|
2037
|
+
b64urlDecode,
|
|
2038
|
+
b64urlDecodeString,
|
|
2039
|
+
b64urlEncode,
|
|
2040
|
+
b64urlEncodeString,
|
|
2041
|
+
buildAts1Hdr,
|
|
2042
|
+
buildPacket,
|
|
2043
|
+
buildTLVs,
|
|
2044
|
+
bytes,
|
|
2045
|
+
canonicalJson,
|
|
2046
|
+
canonicalJsonExcluding,
|
|
731
2047
|
computeReceiptHash,
|
|
732
2048
|
computeSignaturePayload,
|
|
733
2049
|
decodeArray,
|
|
2050
|
+
decodeAxis1Frame,
|
|
734
2051
|
decodeFrame,
|
|
735
2052
|
decodeObject,
|
|
736
2053
|
decodeTLVs,
|
|
737
2054
|
decodeTLVsList,
|
|
738
2055
|
decodeVarint,
|
|
2056
|
+
encVarint,
|
|
2057
|
+
encodeAxis1Frame,
|
|
739
2058
|
encodeFrame,
|
|
740
2059
|
encodeTLVs,
|
|
741
2060
|
encodeVarint,
|
|
742
2061
|
generateEd25519KeyPair,
|
|
743
2062
|
getSignTarget,
|
|
2063
|
+
nonce16,
|
|
2064
|
+
normalizeSensorDecision,
|
|
2065
|
+
packPasskeyLoginOptionsReq,
|
|
2066
|
+
packPasskeyLoginOptionsRes,
|
|
2067
|
+
packPasskeyLoginVerifyReq,
|
|
2068
|
+
packPasskeyLoginVerifyRes,
|
|
2069
|
+
packPasskeyRegisterOptionsReq,
|
|
744
2070
|
sha256,
|
|
745
2071
|
signFrame,
|
|
2072
|
+
tlv,
|
|
2073
|
+
u64be,
|
|
2074
|
+
unpackPasskeyLoginOptionsReq,
|
|
2075
|
+
unpackPasskeyLoginVerifyReq,
|
|
2076
|
+
unpackPasskeyRegisterOptionsReq,
|
|
2077
|
+
utf8,
|
|
746
2078
|
varintLength,
|
|
2079
|
+
varintU,
|
|
747
2080
|
verifyFrameSignature
|
|
748
2081
|
});
|
|
749
2082
|
//# sourceMappingURL=index.js.map
|