@nextera.one/axis-server-sdk 1.3.0 → 1.5.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/README.md +25 -0
- package/dist/core/index.d.mts +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/{index-B5xzROld.d.mts → index-1uEwnW-w.d.mts} +1 -1
- package/dist/{index-B5xzROld.d.ts → index-1uEwnW-w.d.ts} +1 -1
- package/dist/index.d.mts +331 -212
- package/dist/index.d.ts +331 -212
- package/dist/index.js +1029 -593
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1047 -641
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -75,6 +75,22 @@ function IntentSensors(sensors) {
|
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
+
// src/decorators/handler-sensors.decorator.ts
|
|
79
|
+
import "reflect-metadata";
|
|
80
|
+
var HANDLER_SENSORS_KEY = "axis:handler:sensors";
|
|
81
|
+
function HandlerSensors(sensors) {
|
|
82
|
+
return (target) => {
|
|
83
|
+
Reflect.defineMetadata(HANDLER_SENSORS_KEY, sensors, target);
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// src/decorators/sensor.decorator.ts
|
|
88
|
+
import { SetMetadata as SetMetadata2 } from "@nestjs/common";
|
|
89
|
+
var SENSOR_METADATA_KEY = "axis:sensor";
|
|
90
|
+
function Sensor(options) {
|
|
91
|
+
return SetMetadata2(SENSOR_METADATA_KEY, options ?? true);
|
|
92
|
+
}
|
|
93
|
+
|
|
78
94
|
// src/decorators/tlv-field.decorator.ts
|
|
79
95
|
import "reflect-metadata";
|
|
80
96
|
var TLV_FIELDS_KEY = "axis:tlv:fields";
|
|
@@ -455,6 +471,7 @@ var IntentRouter = class {
|
|
|
455
471
|
);
|
|
456
472
|
const prefix = handlerMeta?.intent || instance.name;
|
|
457
473
|
const routes = Reflect.getMetadata(INTENT_ROUTES_KEY, instance.constructor) || [];
|
|
474
|
+
const handlerSensors = Reflect.getMetadata(HANDLER_SENSORS_KEY, instance.constructor) || [];
|
|
458
475
|
for (const route of routes) {
|
|
459
476
|
const intentName = route.absolute ? route.action : `${prefix}.${route.action}`;
|
|
460
477
|
const fn = instance[route.methodName].bind(instance);
|
|
@@ -463,7 +480,12 @@ var IntentRouter = class {
|
|
|
463
480
|
} else {
|
|
464
481
|
this.register(intentName, fn);
|
|
465
482
|
}
|
|
466
|
-
this.registerIntentMeta(
|
|
483
|
+
this.registerIntentMeta(
|
|
484
|
+
intentName,
|
|
485
|
+
Object.getPrototypeOf(instance),
|
|
486
|
+
String(route.methodName),
|
|
487
|
+
handlerSensors
|
|
488
|
+
);
|
|
467
489
|
}
|
|
468
490
|
const proto = Object.getPrototypeOf(instance);
|
|
469
491
|
for (const key of Object.getOwnPropertyNames(proto)) {
|
|
@@ -472,7 +494,7 @@ var IntentRouter = class {
|
|
|
472
494
|
if (!this.handlers.has(meta.intent)) {
|
|
473
495
|
this.register(meta.intent, instance[key].bind(instance));
|
|
474
496
|
}
|
|
475
|
-
this.registerIntentMeta(meta.intent, proto, key);
|
|
497
|
+
this.registerIntentMeta(meta.intent, proto, key, handlerSensors);
|
|
476
498
|
}
|
|
477
499
|
}
|
|
478
500
|
/**
|
|
@@ -608,14 +630,22 @@ var IntentRouter = class {
|
|
|
608
630
|
this.logger.warn(`${intent} failed in ${ms}ms - ${error}`);
|
|
609
631
|
}
|
|
610
632
|
}
|
|
611
|
-
registerIntentMeta(intent, proto, methodName) {
|
|
633
|
+
registerIntentMeta(intent, proto, methodName, handlerSensors) {
|
|
612
634
|
const decoder = Reflect.getMetadata(INTENT_BODY_KEY, proto, methodName);
|
|
613
635
|
if (decoder) {
|
|
614
636
|
this.intentDecoders.set(intent, decoder);
|
|
615
637
|
}
|
|
616
|
-
const
|
|
617
|
-
|
|
618
|
-
|
|
638
|
+
const intentSensors = Reflect.getMetadata(
|
|
639
|
+
INTENT_SENSORS_KEY,
|
|
640
|
+
proto,
|
|
641
|
+
methodName
|
|
642
|
+
);
|
|
643
|
+
const combined = [
|
|
644
|
+
...handlerSensors || [],
|
|
645
|
+
...Array.isArray(intentSensors) ? intentSensors : []
|
|
646
|
+
];
|
|
647
|
+
if (combined.length > 0) {
|
|
648
|
+
this.intentSensors.set(intent, combined);
|
|
619
649
|
}
|
|
620
650
|
const meta = Reflect.getMetadata(INTENT_METADATA_KEY, proto, methodName);
|
|
621
651
|
if (meta) {
|
|
@@ -718,6 +748,182 @@ IntentRouter = __decorateClass([
|
|
|
718
748
|
__decorateParam(0, Optional())
|
|
719
749
|
], IntentRouter);
|
|
720
750
|
|
|
751
|
+
// src/engine/sensor-bands.ts
|
|
752
|
+
var BAND = {
|
|
753
|
+
/** Pre-decode: raw byte validation, geo, budget, magic */
|
|
754
|
+
WIRE: 0,
|
|
755
|
+
/** Post-decode: identity resolution, capsule, proof */
|
|
756
|
+
IDENTITY: 40,
|
|
757
|
+
/** Post-decode: authorization, signature, rate limiting */
|
|
758
|
+
POLICY: 90,
|
|
759
|
+
/** Post-decode: content validation, TLV, schema, files */
|
|
760
|
+
CONTENT: 140,
|
|
761
|
+
/** Post-decode: business logic sensors, streams, WS */
|
|
762
|
+
BUSINESS: 200,
|
|
763
|
+
/** Post-decode: audit, logging (always last) */
|
|
764
|
+
AUDIT: 900
|
|
765
|
+
};
|
|
766
|
+
var PRE_DECODE_BOUNDARY = 40;
|
|
767
|
+
|
|
768
|
+
// src/engine/observation/stable-json.ts
|
|
769
|
+
function normalize(value) {
|
|
770
|
+
if (Array.isArray(value)) {
|
|
771
|
+
return value.map((item) => normalize(item));
|
|
772
|
+
}
|
|
773
|
+
if (value && typeof value === "object") {
|
|
774
|
+
const entries = Object.entries(value).filter(([, nested]) => nested !== void 0).sort(([left], [right]) => left.localeCompare(right));
|
|
775
|
+
const normalized = {};
|
|
776
|
+
for (const [key, nested] of entries) {
|
|
777
|
+
normalized[key] = normalize(nested);
|
|
778
|
+
}
|
|
779
|
+
return normalized;
|
|
780
|
+
}
|
|
781
|
+
return value;
|
|
782
|
+
}
|
|
783
|
+
function stableJsonStringify(value) {
|
|
784
|
+
return JSON.stringify(normalize(value));
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
// src/engine/observation/observation-queue.codec.ts
|
|
788
|
+
function buildQueueMessage(observation, sourceNodeId, previous, lastError) {
|
|
789
|
+
const now = Date.now();
|
|
790
|
+
return {
|
|
791
|
+
v: 1,
|
|
792
|
+
observation,
|
|
793
|
+
attempts: previous ? previous.attempts + 1 : 0,
|
|
794
|
+
firstEnqueuedAt: previous?.firstEnqueuedAt ?? now,
|
|
795
|
+
lastEnqueuedAt: now,
|
|
796
|
+
sourceNodeId,
|
|
797
|
+
lastError
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
function encodeQueueMessage(message) {
|
|
801
|
+
return JSON.stringify(message);
|
|
802
|
+
}
|
|
803
|
+
function decodeQueueMessage(raw) {
|
|
804
|
+
try {
|
|
805
|
+
const parsed = JSON.parse(raw);
|
|
806
|
+
if (!parsed || parsed.v !== 1 || !parsed.observation?.id) {
|
|
807
|
+
return null;
|
|
808
|
+
}
|
|
809
|
+
return parsed;
|
|
810
|
+
} catch {
|
|
811
|
+
return null;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
function parseStreamEntries(raw) {
|
|
815
|
+
if (!Array.isArray(raw)) {
|
|
816
|
+
return [];
|
|
817
|
+
}
|
|
818
|
+
const entries = [];
|
|
819
|
+
for (const streamRow of raw) {
|
|
820
|
+
if (!Array.isArray(streamRow) || streamRow.length < 2) {
|
|
821
|
+
continue;
|
|
822
|
+
}
|
|
823
|
+
const messageRows = streamRow[1];
|
|
824
|
+
if (!Array.isArray(messageRows)) {
|
|
825
|
+
continue;
|
|
826
|
+
}
|
|
827
|
+
for (const row of messageRows) {
|
|
828
|
+
if (!Array.isArray(row) || row.length < 2) {
|
|
829
|
+
continue;
|
|
830
|
+
}
|
|
831
|
+
const id = String(row[0]);
|
|
832
|
+
const fields = Array.isArray(row[1]) ? row[1] : [];
|
|
833
|
+
const fieldMap = fieldsToMap(fields);
|
|
834
|
+
const payload = fieldMap.get("payload");
|
|
835
|
+
if (!payload) {
|
|
836
|
+
continue;
|
|
837
|
+
}
|
|
838
|
+
const message = decodeQueueMessage(payload);
|
|
839
|
+
if (!message) {
|
|
840
|
+
continue;
|
|
841
|
+
}
|
|
842
|
+
entries.push({ id, message });
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
return entries;
|
|
846
|
+
}
|
|
847
|
+
function parseAutoClaimEntries(raw) {
|
|
848
|
+
if (!Array.isArray(raw) || raw.length < 2) {
|
|
849
|
+
return [];
|
|
850
|
+
}
|
|
851
|
+
const rows = Array.isArray(raw[1]) ? raw[1] : [];
|
|
852
|
+
return parseStreamEntries([["stream", rows]]);
|
|
853
|
+
}
|
|
854
|
+
function fieldsToMap(fields) {
|
|
855
|
+
const map3 = /* @__PURE__ */ new Map();
|
|
856
|
+
for (let i = 0; i < fields.length; i += 2) {
|
|
857
|
+
const key = fields[i];
|
|
858
|
+
const value = fields[i + 1];
|
|
859
|
+
if (key !== void 0 && value !== void 0) {
|
|
860
|
+
map3.set(String(key), String(value));
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
return map3;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
// src/engine/observation/observation-hash.ts
|
|
867
|
+
import { createHash } from "crypto";
|
|
868
|
+
function canonicalizeObservation(obs) {
|
|
869
|
+
const obj = {
|
|
870
|
+
id: obs.id,
|
|
871
|
+
startMs: obs.startMs,
|
|
872
|
+
endMs: obs.endMs,
|
|
873
|
+
transport: obs.transport,
|
|
874
|
+
ip: obs.ip,
|
|
875
|
+
intent: obs.intent,
|
|
876
|
+
actorId: obs.actorId,
|
|
877
|
+
capsuleId: obs.capsuleId,
|
|
878
|
+
decision: obs.decision,
|
|
879
|
+
resultCode: obs.resultCode,
|
|
880
|
+
statusCode: obs.statusCode,
|
|
881
|
+
durationMs: obs.durationMs,
|
|
882
|
+
stages: obs.stages.map((s) => ({
|
|
883
|
+
name: s.name,
|
|
884
|
+
status: s.status,
|
|
885
|
+
startMs: s.startMs,
|
|
886
|
+
endMs: s.endMs,
|
|
887
|
+
durationMs: s.durationMs,
|
|
888
|
+
reason: s.reason,
|
|
889
|
+
code: s.code
|
|
890
|
+
})),
|
|
891
|
+
sensors: obs.sensors.map((s) => ({
|
|
892
|
+
name: s.name,
|
|
893
|
+
allowed: s.allowed,
|
|
894
|
+
riskScore: s.riskScore,
|
|
895
|
+
durationMs: s.durationMs,
|
|
896
|
+
reasons: s.reasons,
|
|
897
|
+
code: s.code
|
|
898
|
+
}))
|
|
899
|
+
};
|
|
900
|
+
return stableJsonStringify(obj);
|
|
901
|
+
}
|
|
902
|
+
function hashObservation(obs) {
|
|
903
|
+
const canonical = canonicalizeObservation(obs);
|
|
904
|
+
return createHash("sha256").update(canonical).digest("hex");
|
|
905
|
+
}
|
|
906
|
+
function buildUnsignedWitness(obs) {
|
|
907
|
+
if (!obs.decision || !obs.endMs) {
|
|
908
|
+
return null;
|
|
909
|
+
}
|
|
910
|
+
return {
|
|
911
|
+
v: 1,
|
|
912
|
+
observationId: obs.id,
|
|
913
|
+
payloadHash: hashObservation(obs),
|
|
914
|
+
sealedAt: Date.now(),
|
|
915
|
+
summary: {
|
|
916
|
+
intent: obs.intent,
|
|
917
|
+
actorId: obs.actorId,
|
|
918
|
+
decision: obs.decision,
|
|
919
|
+
statusCode: obs.statusCode,
|
|
920
|
+
durationMs: obs.durationMs,
|
|
921
|
+
sensorCount: obs.sensors.length,
|
|
922
|
+
stageCount: obs.stages.length
|
|
923
|
+
}
|
|
924
|
+
};
|
|
925
|
+
}
|
|
926
|
+
|
|
721
927
|
// src/core/constants.ts
|
|
722
928
|
import {
|
|
723
929
|
AXIS_MAGIC,
|
|
@@ -784,6 +990,51 @@ import {
|
|
|
784
990
|
ERR_CONTRACT_VIOLATION
|
|
785
991
|
} from "@nextera.one/axis-protocol";
|
|
786
992
|
|
|
993
|
+
// src/engine/observation/response-observer.ts
|
|
994
|
+
var SENSITIVE_RESPONSE_TAGS = [4, 5, 6];
|
|
995
|
+
function verifyResponse(ctx, response) {
|
|
996
|
+
if (!response.effect || typeof response.effect !== "string") {
|
|
997
|
+
return {
|
|
998
|
+
passed: false,
|
|
999
|
+
code: "OBSERVER_INVALID_EFFECT",
|
|
1000
|
+
reason: "Response effect is missing or invalid"
|
|
1001
|
+
};
|
|
1002
|
+
}
|
|
1003
|
+
if (response.ok && (!response.body || response.body.length === 0)) {
|
|
1004
|
+
return {
|
|
1005
|
+
passed: false,
|
|
1006
|
+
code: "OBSERVER_EMPTY_BODY",
|
|
1007
|
+
reason: "Successful response must contain a body"
|
|
1008
|
+
};
|
|
1009
|
+
}
|
|
1010
|
+
if (response.body && response.body.length > MAX_BODY_LEN) {
|
|
1011
|
+
return {
|
|
1012
|
+
passed: false,
|
|
1013
|
+
code: "OBSERVER_BODY_OVERFLOW",
|
|
1014
|
+
reason: `Response body exceeds ${MAX_BODY_LEN} bytes`
|
|
1015
|
+
};
|
|
1016
|
+
}
|
|
1017
|
+
if (response.headers) {
|
|
1018
|
+
for (const tag of SENSITIVE_RESPONSE_TAGS) {
|
|
1019
|
+
if (response.headers.has(tag)) {
|
|
1020
|
+
return {
|
|
1021
|
+
passed: false,
|
|
1022
|
+
code: "OBSERVER_DATA_LEAK",
|
|
1023
|
+
reason: `Response must not contain sensitive TLV tag ${tag}`
|
|
1024
|
+
};
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
if (response.effect.includes("Error:") || response.effect.includes("stack") || response.effect.includes("at /")) {
|
|
1029
|
+
return {
|
|
1030
|
+
passed: false,
|
|
1031
|
+
code: "OBSERVER_INFO_LEAK",
|
|
1032
|
+
reason: "Response effect may contain internal error details"
|
|
1033
|
+
};
|
|
1034
|
+
}
|
|
1035
|
+
return { passed: true };
|
|
1036
|
+
}
|
|
1037
|
+
|
|
787
1038
|
// src/core/varint.ts
|
|
788
1039
|
import { encodeVarint, decodeVarint, varintLength } from "@nextera.one/axis-protocol";
|
|
789
1040
|
|
|
@@ -1059,7 +1310,7 @@ __export(ats1_exports, {
|
|
|
1059
1310
|
tlvsToMap: () => tlvsToMap,
|
|
1060
1311
|
validateTLVsAgainstSchema: () => validateTLVsAgainstSchema
|
|
1061
1312
|
});
|
|
1062
|
-
import { createHash as
|
|
1313
|
+
import { createHash as createHash3 } from "crypto";
|
|
1063
1314
|
var DEFAULT_LIMITS = {
|
|
1064
1315
|
maxVarintBytes: 10,
|
|
1065
1316
|
maxTlvCount: 512,
|
|
@@ -1109,7 +1360,7 @@ function decodeU64BE(buf) {
|
|
|
1109
1360
|
return buf.readBigUInt64BE(0);
|
|
1110
1361
|
}
|
|
1111
1362
|
function sha2562(data) {
|
|
1112
|
-
return
|
|
1363
|
+
return createHash3("sha256").update(data).digest();
|
|
1113
1364
|
}
|
|
1114
1365
|
function encodeTLV(tag, value) {
|
|
1115
1366
|
if (!Number.isInteger(tag) || tag <= 0)
|
|
@@ -2272,9 +2523,9 @@ function isAdminOpcode(op) {
|
|
|
2272
2523
|
}
|
|
2273
2524
|
|
|
2274
2525
|
// src/core/receipt.ts
|
|
2275
|
-
import { createHash as
|
|
2526
|
+
import { createHash as createHash4 } from "crypto";
|
|
2276
2527
|
function buildReceiptHash(prevHash, pid, actorId, intent, effect, ts) {
|
|
2277
|
-
const h =
|
|
2528
|
+
const h = createHash4("sha256");
|
|
2278
2529
|
if (prevHash) h.update(prevHash);
|
|
2279
2530
|
h.update(pid);
|
|
2280
2531
|
h.update(Buffer.from(actorId, "utf8"));
|
|
@@ -2679,92 +2930,54 @@ var DiskUploadFileStore = class {
|
|
|
2679
2930
|
}
|
|
2680
2931
|
};
|
|
2681
2932
|
|
|
2682
|
-
// src/
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
TLV_LOOM_PRESENCE_ID: () => TLV_LOOM_PRESENCE_ID,
|
|
2731
|
-
TLV_LOOM_THREAD_HASH: () => TLV_LOOM_THREAD_HASH,
|
|
2732
|
-
TLV_LOOM_WRIT: () => TLV_LOOM_WRIT,
|
|
2733
|
-
TLV_NODE: () => TLV_NODE,
|
|
2734
|
-
TLV_NODE_CERT_HASH: () => TLV_NODE_CERT_HASH,
|
|
2735
|
-
TLV_NODE_KID: () => TLV_NODE_KID,
|
|
2736
|
-
TLV_NONCE: () => TLV_NONCE,
|
|
2737
|
-
TLV_OFFSET: () => TLV_OFFSET,
|
|
2738
|
-
TLV_OK: () => TLV_OK,
|
|
2739
|
-
TLV_PID: () => TLV_PID,
|
|
2740
|
-
TLV_PREV_HASH: () => TLV_PREV_HASH,
|
|
2741
|
-
TLV_PROOF_REF: () => TLV_PROOF_REF,
|
|
2742
|
-
TLV_PROOF_TYPE: () => TLV_PROOF_TYPE,
|
|
2743
|
-
TLV_REALM: () => TLV_REALM,
|
|
2744
|
-
TLV_RECEIPT_HASH: () => TLV_RECEIPT_HASH,
|
|
2745
|
-
TLV_RID: () => TLV_RID,
|
|
2746
|
-
TLV_SHA256_CHUNK: () => TLV_SHA256_CHUNK,
|
|
2747
|
-
TLV_TRACE_ID: () => TLV_TRACE_ID,
|
|
2748
|
-
TLV_TS: () => TLV_TS,
|
|
2749
|
-
TLV_UPLOAD_ID: () => TLV_UPLOAD_ID,
|
|
2750
|
-
computeReceiptHash: () => computeReceiptHash,
|
|
2751
|
-
computeSignaturePayload: () => computeSignaturePayload,
|
|
2752
|
-
decodeArray: () => decodeArray,
|
|
2753
|
-
decodeFrame: () => decodeFrame,
|
|
2754
|
-
decodeObject: () => decodeObject,
|
|
2755
|
-
decodeTLVs: () => decodeTLVs,
|
|
2756
|
-
decodeTLVsList: () => decodeTLVsList,
|
|
2757
|
-
decodeVarint: () => decodeVarint,
|
|
2758
|
-
encodeFrame: () => encodeFrame,
|
|
2759
|
-
encodeTLVs: () => encodeTLVs,
|
|
2760
|
-
encodeVarint: () => encodeVarint,
|
|
2761
|
-
generateEd25519KeyPair: () => generateEd25519KeyPair,
|
|
2762
|
-
getSignTarget: () => getSignTarget,
|
|
2763
|
-
sha256: () => sha256,
|
|
2764
|
-
signFrame: () => signFrame,
|
|
2765
|
-
varintLength: () => varintLength,
|
|
2766
|
-
verifyFrameSignature: () => verifyFrameSignature
|
|
2767
|
-
});
|
|
2933
|
+
// src/decorators/axis-request.decorator.ts
|
|
2934
|
+
import { createParamDecorator } from "@nestjs/common";
|
|
2935
|
+
function resolveIp(req) {
|
|
2936
|
+
return req.headers["x-forwarded-for"]?.split(",")[0]?.trim() || req.headers["x-real-ip"] || req.socket.remoteAddress || void 0;
|
|
2937
|
+
}
|
|
2938
|
+
var AxisRaw = createParamDecorator(
|
|
2939
|
+
(_data, ctx) => {
|
|
2940
|
+
const req = ctx.switchToHttp().getRequest();
|
|
2941
|
+
return req.body;
|
|
2942
|
+
}
|
|
2943
|
+
);
|
|
2944
|
+
var AxisIp = createParamDecorator(
|
|
2945
|
+
(_data, ctx) => {
|
|
2946
|
+
const req = ctx.switchToHttp().getRequest();
|
|
2947
|
+
return resolveIp(req);
|
|
2948
|
+
}
|
|
2949
|
+
);
|
|
2950
|
+
var AxisContext = createParamDecorator(
|
|
2951
|
+
(_data, ctx) => {
|
|
2952
|
+
const req = ctx.switchToHttp().getRequest();
|
|
2953
|
+
const axisData = req.axis || {};
|
|
2954
|
+
return {
|
|
2955
|
+
raw: req.body,
|
|
2956
|
+
ip: resolveIp(req),
|
|
2957
|
+
preDecodeInput: axisData.preDecodeInput,
|
|
2958
|
+
frameBytesCount: axisData.frameBytesCount || 0
|
|
2959
|
+
};
|
|
2960
|
+
}
|
|
2961
|
+
);
|
|
2962
|
+
var AxisDemoPubkey = createParamDecorator(
|
|
2963
|
+
(_data, ctx) => {
|
|
2964
|
+
if (process.env.NODE_ENV !== "development") return void 0;
|
|
2965
|
+
const req = ctx.switchToHttp().getRequest();
|
|
2966
|
+
return req.headers["x-demo-pubkey"];
|
|
2967
|
+
}
|
|
2968
|
+
);
|
|
2969
|
+
var AxisFrame3 = createParamDecorator(
|
|
2970
|
+
(_data, ctx) => {
|
|
2971
|
+
const req = ctx.switchToHttp().getRequest();
|
|
2972
|
+
const decoded = req.axisDecoded;
|
|
2973
|
+
if (!decoded) {
|
|
2974
|
+
throw new Error(
|
|
2975
|
+
"@AxisFrame() requires AxisDecodeInterceptor on the route. Add @UseInterceptors(AxisDecodeInterceptor) to use this decorator."
|
|
2976
|
+
);
|
|
2977
|
+
}
|
|
2978
|
+
return decoded;
|
|
2979
|
+
}
|
|
2980
|
+
);
|
|
2768
2981
|
|
|
2769
2982
|
// src/core/axis-error.ts
|
|
2770
2983
|
var AxisError = class extends Error {
|
|
@@ -2777,341 +2990,240 @@ var AxisError = class extends Error {
|
|
|
2777
2990
|
}
|
|
2778
2991
|
};
|
|
2779
2992
|
|
|
2780
|
-
// src/
|
|
2781
|
-
var crypto_exports = {};
|
|
2782
|
-
__export(crypto_exports, {
|
|
2783
|
-
ProofVerificationService: () => ProofVerificationService,
|
|
2784
|
-
b64urlDecode: () => b64urlDecode,
|
|
2785
|
-
b64urlDecodeString: () => b64urlDecodeString,
|
|
2786
|
-
b64urlEncode: () => b64urlEncode,
|
|
2787
|
-
b64urlEncodeString: () => b64urlEncodeString,
|
|
2788
|
-
canonicalJson: () => canonicalJson,
|
|
2789
|
-
canonicalJsonExcluding: () => canonicalJsonExcluding
|
|
2790
|
-
});
|
|
2791
|
-
|
|
2792
|
-
// src/crypto/proof-verification.service.ts
|
|
2993
|
+
// src/engine/handler-discovery.service.ts
|
|
2793
2994
|
import { Injectable as Injectable4, Logger as Logger3 } from "@nestjs/common";
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
this.
|
|
2799
|
-
|
|
2800
|
-
this.deviceKeys = /* @__PURE__ */ new Map();
|
|
2801
|
-
// Cache of trusted mTLS certificate fingerprints
|
|
2802
|
-
this.trustedCerts = /* @__PURE__ */ new Map();
|
|
2995
|
+
var HandlerDiscoveryService = class {
|
|
2996
|
+
constructor(discovery, scanner, router) {
|
|
2997
|
+
this.discovery = discovery;
|
|
2998
|
+
this.scanner = scanner;
|
|
2999
|
+
this.router = router;
|
|
3000
|
+
this.logger = new Logger3(HandlerDiscoveryService.name);
|
|
2803
3001
|
}
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
async verifyProof(proofType, proofRef, context) {
|
|
2823
|
-
switch (proofType) {
|
|
2824
|
-
case 1:
|
|
2825
|
-
return this.verifyCapsuleProof(proofRef);
|
|
2826
|
-
case 2:
|
|
2827
|
-
return this.verifyJWTProof(proofRef);
|
|
2828
|
-
case 3:
|
|
2829
|
-
return this.verifyMTLSProof(context.mtls);
|
|
2830
|
-
case 4:
|
|
2831
|
-
return this.verifyDeviceSEProof(
|
|
2832
|
-
context.signTarget,
|
|
2833
|
-
context.signature,
|
|
2834
|
-
context.deviceSE
|
|
3002
|
+
onModuleInit() {
|
|
3003
|
+
const providers = this.discovery.getProviders();
|
|
3004
|
+
let totalIntents = 0;
|
|
3005
|
+
for (const wrapper of providers) {
|
|
3006
|
+
const { instance, metatype } = wrapper;
|
|
3007
|
+
if (!instance || !metatype) continue;
|
|
3008
|
+
const handlerMeta = Reflect.getMetadata(HANDLER_METADATA_KEY, metatype);
|
|
3009
|
+
if (!handlerMeta) continue;
|
|
3010
|
+
const handlerName = handlerMeta.intent || metatype.name;
|
|
3011
|
+
const proto = Object.getPrototypeOf(instance);
|
|
3012
|
+
const methods = this.scanner.getAllMethodNames(proto);
|
|
3013
|
+
let registered = 0;
|
|
3014
|
+
const handlerSensors = Reflect.getMetadata(HANDLER_SENSORS_KEY, metatype) || [];
|
|
3015
|
+
for (const methodName of methods) {
|
|
3016
|
+
const meta = Reflect.getMetadata(
|
|
3017
|
+
INTENT_METADATA_KEY,
|
|
3018
|
+
proto,
|
|
3019
|
+
methodName
|
|
2835
3020
|
);
|
|
2836
|
-
|
|
2837
|
-
|
|
3021
|
+
if (!meta?.intent) continue;
|
|
3022
|
+
if (!this.router.has(meta.intent)) {
|
|
3023
|
+
this.router.register(
|
|
3024
|
+
meta.intent,
|
|
3025
|
+
instance[methodName].bind(instance)
|
|
3026
|
+
);
|
|
3027
|
+
registered++;
|
|
3028
|
+
totalIntents++;
|
|
3029
|
+
}
|
|
3030
|
+
this.router.registerIntentMeta(
|
|
3031
|
+
meta.intent,
|
|
3032
|
+
proto,
|
|
3033
|
+
methodName,
|
|
3034
|
+
handlerSensors
|
|
3035
|
+
);
|
|
3036
|
+
}
|
|
3037
|
+
if (registered > 0) {
|
|
3038
|
+
this.logger.log(
|
|
3039
|
+
`Auto-registered ${registered} intents from ${handlerName}`
|
|
3040
|
+
);
|
|
3041
|
+
}
|
|
2838
3042
|
}
|
|
3043
|
+
this.logger.log(
|
|
3044
|
+
`Handler discovery complete: ${totalIntents} intents auto-registered`
|
|
3045
|
+
);
|
|
2839
3046
|
}
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
3047
|
+
};
|
|
3048
|
+
HandlerDiscoveryService = __decorateClass([
|
|
3049
|
+
Injectable4()
|
|
3050
|
+
], HandlerDiscoveryService);
|
|
3051
|
+
|
|
3052
|
+
// src/engine/sensor-discovery.service.ts
|
|
3053
|
+
import { Injectable as Injectable5, Logger as Logger4 } from "@nestjs/common";
|
|
3054
|
+
var SensorDiscoveryService = class {
|
|
3055
|
+
constructor(discovery, reflector, registry) {
|
|
3056
|
+
this.discovery = discovery;
|
|
3057
|
+
this.reflector = reflector;
|
|
3058
|
+
this.registry = registry;
|
|
3059
|
+
this.logger = new Logger4(SensorDiscoveryService.name);
|
|
2849
3060
|
}
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
return { valid: false, error: "Invalid JWT format" };
|
|
2868
|
-
}
|
|
2869
|
-
const header = JSON.parse(Buffer.from(parts[0], "base64url").toString());
|
|
2870
|
-
const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString());
|
|
2871
|
-
if (payload.exp && Date.now() / 1e3 > payload.exp) {
|
|
2872
|
-
return { valid: false, error: "JWT expired" };
|
|
3061
|
+
onApplicationBootstrap() {
|
|
3062
|
+
const providers = this.discovery.getProviders();
|
|
3063
|
+
let count = 0;
|
|
3064
|
+
for (const wrapper of providers) {
|
|
3065
|
+
const { instance } = wrapper;
|
|
3066
|
+
if (!instance || !instance.constructor) continue;
|
|
3067
|
+
const meta = this.reflector.get(
|
|
3068
|
+
SENSOR_METADATA_KEY,
|
|
3069
|
+
instance.constructor
|
|
3070
|
+
);
|
|
3071
|
+
if (!meta) continue;
|
|
3072
|
+
const sensor = instance;
|
|
3073
|
+
if (!sensor.name || sensor.order === void 0) {
|
|
3074
|
+
this.logger.warn(
|
|
3075
|
+
`@Sensor() on ${instance.constructor.name} missing name or order \u2014 skipped`
|
|
3076
|
+
);
|
|
3077
|
+
continue;
|
|
2873
3078
|
}
|
|
2874
|
-
if (
|
|
2875
|
-
|
|
3079
|
+
if (!sensor.phase) {
|
|
3080
|
+
const decoratorPhase = meta !== true ? meta.phase : void 0;
|
|
3081
|
+
sensor.phase = decoratorPhase ?? (sensor.order < PRE_DECODE_BOUNDARY ? "PRE_DECODE" : "POST_DECODE");
|
|
2876
3082
|
}
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
actorId: payload.sub || payload.actor_id,
|
|
2880
|
-
metadata: { iss: payload.iss, scope: payload.scope }
|
|
2881
|
-
};
|
|
2882
|
-
} catch (e) {
|
|
2883
|
-
const message = e instanceof Error ? e.message : "Unknown error";
|
|
2884
|
-
return { valid: false, error: `JWT parse error: ${message}` };
|
|
3083
|
+
this.registry.register(sensor);
|
|
3084
|
+
count++;
|
|
2885
3085
|
}
|
|
3086
|
+
this.logger.log(`Auto-registered ${count} sensors via @Sensor()`);
|
|
3087
|
+
}
|
|
3088
|
+
};
|
|
3089
|
+
SensorDiscoveryService = __decorateClass([
|
|
3090
|
+
Injectable5()
|
|
3091
|
+
], SensorDiscoveryService);
|
|
3092
|
+
|
|
3093
|
+
// src/engine/registry/sensor.registry.ts
|
|
3094
|
+
import { Injectable as Injectable6, Logger as Logger5 } from "@nestjs/common";
|
|
3095
|
+
var SensorRegistry = class {
|
|
3096
|
+
constructor(configService) {
|
|
3097
|
+
this.configService = configService;
|
|
3098
|
+
this.sensors = [];
|
|
3099
|
+
this.logger = new Logger5(SensorRegistry.name);
|
|
2886
3100
|
}
|
|
2887
3101
|
/**
|
|
2888
|
-
*
|
|
3102
|
+
* Registers a new sensor in the registry.
|
|
3103
|
+
*
|
|
3104
|
+
* Validates that:
|
|
3105
|
+
* - AxisSensor has a unique name
|
|
3106
|
+
* - AxisSensor has an order field
|
|
3107
|
+
* - Pre-decode sensors have order < 40
|
|
3108
|
+
* - Post-decode sensors have order >= 40
|
|
3109
|
+
*
|
|
3110
|
+
* @param {AxisSensor} sensor - The sensor instance to register
|
|
3111
|
+
* @throws Error if validation fails
|
|
2889
3112
|
*/
|
|
2890
|
-
|
|
2891
|
-
if (!
|
|
2892
|
-
|
|
3113
|
+
register(sensor) {
|
|
3114
|
+
if (!sensor.name) {
|
|
3115
|
+
throw new Error("AxisSensor must have a name");
|
|
2893
3116
|
}
|
|
2894
|
-
|
|
2895
|
-
|
|
3117
|
+
const enabledSensorsStr = this.configService.get("ENABLED_SENSORS");
|
|
3118
|
+
const disabledSensorsStr = this.configService.get("DISABLED_SENSORS");
|
|
3119
|
+
const enabledSensors = enabledSensorsStr ? enabledSensorsStr.split(",").map((s) => s.trim()) : null;
|
|
3120
|
+
const disabledSensors = disabledSensorsStr ? disabledSensorsStr.split(",").map((s) => s.trim()) : [];
|
|
3121
|
+
if (enabledSensors && !enabledSensors.includes(sensor.name)) {
|
|
3122
|
+
this.logger.log(`Skipping disabled sensor (not in ENABLED_SENSORS): ${sensor.name}`);
|
|
3123
|
+
return;
|
|
2896
3124
|
}
|
|
2897
|
-
if (
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
return {
|
|
2901
|
-
valid: true,
|
|
2902
|
-
actorId: trusted.actorId,
|
|
2903
|
-
metadata: {
|
|
2904
|
-
fingerprint: mtls.clientCertFingerprint,
|
|
2905
|
-
subject: mtls.clientCertSubject
|
|
2906
|
-
}
|
|
2907
|
-
};
|
|
2908
|
-
}
|
|
3125
|
+
if (disabledSensors.includes(sensor.name)) {
|
|
3126
|
+
this.logger.log(`Skipping disabled sensor (in DISABLED_SENSORS): ${sensor.name}`);
|
|
3127
|
+
return;
|
|
2909
3128
|
}
|
|
2910
|
-
if (
|
|
2911
|
-
|
|
2912
|
-
if (cnMatch) {
|
|
2913
|
-
return {
|
|
2914
|
-
valid: true,
|
|
2915
|
-
actorId: cnMatch[1],
|
|
2916
|
-
metadata: {
|
|
2917
|
-
subject: mtls.clientCertSubject,
|
|
2918
|
-
issuer: mtls.clientCertIssuer
|
|
2919
|
-
}
|
|
2920
|
-
};
|
|
2921
|
-
}
|
|
3129
|
+
if (sensor.order === void 0) {
|
|
3130
|
+
throw new Error(`AxisSensor "${sensor.name}" must have an order field`);
|
|
2922
3131
|
}
|
|
2923
|
-
|
|
3132
|
+
const isPreDecodeSensor = this.isPreDecodeSensor(sensor);
|
|
3133
|
+
const isPostDecodeSensor = this.isPostDecodeSensor(sensor);
|
|
3134
|
+
if (isPreDecodeSensor && sensor.order >= 40) {
|
|
3135
|
+
this.logger.warn(
|
|
3136
|
+
`AxisSensor "${sensor.name}" is marked as PRE_DECODE but has order ${sensor.order} (should be < 40)`
|
|
3137
|
+
);
|
|
3138
|
+
}
|
|
3139
|
+
if (isPostDecodeSensor && sensor.order < 40) {
|
|
3140
|
+
this.logger.warn(
|
|
3141
|
+
`AxisSensor "${sensor.name}" is marked as POST_DECODE but has order ${sensor.order} (should be >= 40)`
|
|
3142
|
+
);
|
|
3143
|
+
}
|
|
3144
|
+
this.sensors.push(sensor);
|
|
3145
|
+
const phaseLabel = typeof sensor.phase === "string" ? sensor.phase : sensor.phase?.phase || "UNKNOWN";
|
|
3146
|
+
this.logger.debug(
|
|
3147
|
+
`Registered sensor: ${sensor.name} (order: ${sensor.order}, phase: ${phaseLabel})`
|
|
3148
|
+
);
|
|
2924
3149
|
}
|
|
2925
3150
|
/**
|
|
2926
|
-
*
|
|
3151
|
+
* Returns all registered sensors, sorted by their execution order.
|
|
3152
|
+
*
|
|
3153
|
+
* @returns {AxisSensor[]} A sorted array of sensors
|
|
2927
3154
|
*/
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
let publicKey = deviceSE.publicKey;
|
|
2933
|
-
const registeredKey = this.deviceKeys.get(deviceSE.deviceId);
|
|
2934
|
-
if (registeredKey) {
|
|
2935
|
-
publicKey = registeredKey;
|
|
2936
|
-
}
|
|
2937
|
-
if (!publicKey || publicKey.length !== 32) {
|
|
2938
|
-
return {
|
|
2939
|
-
valid: false,
|
|
2940
|
-
error: "Invalid or unregistered device public key"
|
|
2941
|
-
};
|
|
2942
|
-
}
|
|
2943
|
-
try {
|
|
2944
|
-
const valid = nacl.sign.detached.verify(signTarget, signature, publicKey);
|
|
2945
|
-
if (!valid) {
|
|
2946
|
-
return { valid: false, error: "Device signature verification failed" };
|
|
2947
|
-
}
|
|
2948
|
-
return {
|
|
2949
|
-
valid: true,
|
|
2950
|
-
actorId: deviceSE.deviceId,
|
|
2951
|
-
metadata: { deviceId: deviceSE.deviceId, proofType: "DEVICE_SE" }
|
|
2952
|
-
};
|
|
2953
|
-
} catch (e) {
|
|
2954
|
-
const message = e instanceof Error ? e.message : "Unknown error";
|
|
2955
|
-
return {
|
|
2956
|
-
valid: false,
|
|
2957
|
-
error: `Signature verification error: ${message}`
|
|
2958
|
-
};
|
|
2959
|
-
}
|
|
3155
|
+
list() {
|
|
3156
|
+
return [...this.sensors].sort(
|
|
3157
|
+
(a, b) => (a.order ?? 999) - (b.order ?? 999)
|
|
3158
|
+
);
|
|
2960
3159
|
}
|
|
2961
3160
|
/**
|
|
2962
|
-
*
|
|
2963
|
-
*
|
|
3161
|
+
* Returns only pre-decode sensors (order < 40).
|
|
3162
|
+
* These sensors run in middleware on raw bytes before frame decoding.
|
|
2964
3163
|
*
|
|
2965
|
-
* @
|
|
2966
|
-
* @param {Uint8Array} publicKey - 32-byte Ed25519 public key
|
|
2967
|
-
* @throws {Error} If the public key is not 32 bytes
|
|
3164
|
+
* @returns {AxisPreSensor[]} Pre-decode sensors sorted by order
|
|
2968
3165
|
*/
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
throw new Error("Device public key must be 32 bytes (Ed25519)");
|
|
2972
|
-
}
|
|
2973
|
-
this.deviceKeys.set(deviceId, publicKey);
|
|
2974
|
-
this.logger.log(`Registered device key for ${deviceId}`);
|
|
3166
|
+
getPreDecodeSensors() {
|
|
3167
|
+
return this.list().filter((s) => (s.order ?? 999) < 40);
|
|
2975
3168
|
}
|
|
2976
3169
|
/**
|
|
2977
|
-
*
|
|
3170
|
+
* Returns only post-decode sensors (order >= 40).
|
|
3171
|
+
* These sensors run in the controller on fully decoded frames.
|
|
3172
|
+
*
|
|
3173
|
+
* @returns {AxisPostSensor[]} Post-decode sensors sorted by order
|
|
2978
3174
|
*/
|
|
2979
|
-
|
|
2980
|
-
return this.
|
|
3175
|
+
getPostDecodeSensors() {
|
|
3176
|
+
return this.list().filter(
|
|
3177
|
+
(s) => (s.order ?? 999) >= 40
|
|
3178
|
+
);
|
|
2981
3179
|
}
|
|
2982
3180
|
/**
|
|
2983
|
-
*
|
|
3181
|
+
* Helper: Check if a sensor is a pre-decode sensor.
|
|
2984
3182
|
*
|
|
2985
|
-
* @
|
|
2986
|
-
* @param {
|
|
3183
|
+
* @private
|
|
3184
|
+
* @param {AxisSensor} sensor - The sensor to check
|
|
3185
|
+
* @returns {boolean} True if sensor is pre-decode
|
|
2987
3186
|
*/
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
3187
|
+
isPreDecodeSensor(sensor) {
|
|
3188
|
+
const phase = typeof sensor.phase === "string" ? sensor.phase : sensor.phase?.phase;
|
|
3189
|
+
return phase === "PRE_DECODE" || (sensor.order ?? 999) < 40;
|
|
2991
3190
|
}
|
|
2992
3191
|
/**
|
|
2993
|
-
*
|
|
3192
|
+
* Helper: Check if a sensor is a post-decode sensor.
|
|
3193
|
+
*
|
|
3194
|
+
* @private
|
|
3195
|
+
* @param {AxisSensor} sensor - The sensor to check
|
|
3196
|
+
* @returns {boolean} True if sensor is post-decode
|
|
2994
3197
|
*/
|
|
2995
|
-
|
|
2996
|
-
|
|
3198
|
+
isPostDecodeSensor(sensor) {
|
|
3199
|
+
const phase = typeof sensor.phase === "string" ? sensor.phase : sensor.phase?.phase;
|
|
3200
|
+
return phase === "POST_DECODE" || (sensor.order ?? 999) >= 40;
|
|
2997
3201
|
}
|
|
2998
3202
|
/**
|
|
2999
|
-
*
|
|
3203
|
+
* Returns sensor count by phase.
|
|
3204
|
+
* Useful for diagnostics and monitoring.
|
|
3205
|
+
*
|
|
3206
|
+
* @returns {{preDecodeCount: number, postDecodeCount: number}}
|
|
3000
3207
|
*/
|
|
3001
|
-
|
|
3002
|
-
const der = Buffer.from(
|
|
3003
|
-
certPem.replace(/-----BEGIN CERTIFICATE-----/, "").replace(/-----END CERTIFICATE-----/, "").replace(/\s/g, ""),
|
|
3004
|
-
"base64"
|
|
3005
|
-
);
|
|
3006
|
-
return crypto3.createHash("sha256").update(der).digest("hex");
|
|
3007
|
-
}
|
|
3008
|
-
};
|
|
3009
|
-
ProofVerificationService = __decorateClass([
|
|
3010
|
-
Injectable4()
|
|
3011
|
-
], ProofVerificationService);
|
|
3012
|
-
|
|
3013
|
-
// src/decorators/index.ts
|
|
3014
|
-
var decorators_exports = {};
|
|
3015
|
-
__export(decorators_exports, {
|
|
3016
|
-
AxisContext: () => AxisContext,
|
|
3017
|
-
AxisDemoPubkey: () => AxisDemoPubkey,
|
|
3018
|
-
AxisFrame: () => AxisFrame3,
|
|
3019
|
-
AxisIp: () => AxisIp,
|
|
3020
|
-
AxisRaw: () => AxisRaw,
|
|
3021
|
-
HANDLER_METADATA_KEY: () => HANDLER_METADATA_KEY,
|
|
3022
|
-
Handler: () => Handler,
|
|
3023
|
-
INTENT_BODY_KEY: () => INTENT_BODY_KEY,
|
|
3024
|
-
INTENT_METADATA_KEY: () => INTENT_METADATA_KEY,
|
|
3025
|
-
INTENT_ROUTES_KEY: () => INTENT_ROUTES_KEY,
|
|
3026
|
-
INTENT_SENSORS_KEY: () => INTENT_SENSORS_KEY,
|
|
3027
|
-
Intent: () => Intent,
|
|
3028
|
-
IntentBody: () => IntentBody,
|
|
3029
|
-
IntentSensors: () => IntentSensors,
|
|
3030
|
-
SENSOR_METADATA_KEY: () => SENSOR_METADATA_KEY,
|
|
3031
|
-
Sensor: () => Sensor,
|
|
3032
|
-
TLV_FIELDS_KEY: () => TLV_FIELDS_KEY,
|
|
3033
|
-
TLV_VALIDATORS_KEY: () => TLV_VALIDATORS_KEY,
|
|
3034
|
-
TlvEnum: () => TlvEnum,
|
|
3035
|
-
TlvField: () => TlvField,
|
|
3036
|
-
TlvMinLen: () => TlvMinLen,
|
|
3037
|
-
TlvRange: () => TlvRange,
|
|
3038
|
-
TlvUtf8Pattern: () => TlvUtf8Pattern,
|
|
3039
|
-
TlvValidate: () => TlvValidate,
|
|
3040
|
-
buildDtoDecoder: () => buildDtoDecoder,
|
|
3041
|
-
extractDtoSchema: () => extractDtoSchema
|
|
3042
|
-
});
|
|
3043
|
-
|
|
3044
|
-
// src/decorators/axis-request.decorator.ts
|
|
3045
|
-
import { createParamDecorator } from "@nestjs/common";
|
|
3046
|
-
function resolveIp(req) {
|
|
3047
|
-
return req.headers["x-forwarded-for"]?.split(",")[0]?.trim() || req.headers["x-real-ip"] || req.socket.remoteAddress || void 0;
|
|
3048
|
-
}
|
|
3049
|
-
var AxisRaw = createParamDecorator(
|
|
3050
|
-
(_data, ctx) => {
|
|
3051
|
-
const req = ctx.switchToHttp().getRequest();
|
|
3052
|
-
return req.body;
|
|
3053
|
-
}
|
|
3054
|
-
);
|
|
3055
|
-
var AxisIp = createParamDecorator(
|
|
3056
|
-
(_data, ctx) => {
|
|
3057
|
-
const req = ctx.switchToHttp().getRequest();
|
|
3058
|
-
return resolveIp(req);
|
|
3059
|
-
}
|
|
3060
|
-
);
|
|
3061
|
-
var AxisContext = createParamDecorator(
|
|
3062
|
-
(_data, ctx) => {
|
|
3063
|
-
const req = ctx.switchToHttp().getRequest();
|
|
3064
|
-
const axisData = req.axis || {};
|
|
3208
|
+
getSensorCountByPhase() {
|
|
3065
3209
|
return {
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
preDecodeInput: axisData.preDecodeInput,
|
|
3069
|
-
frameBytesCount: axisData.frameBytesCount || 0
|
|
3210
|
+
preDecodeCount: this.getPreDecodeSensors().length,
|
|
3211
|
+
postDecodeCount: this.getPostDecodeSensors().length
|
|
3070
3212
|
};
|
|
3071
3213
|
}
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
var AxisFrame3 = createParamDecorator(
|
|
3081
|
-
(_data, ctx) => {
|
|
3082
|
-
const req = ctx.switchToHttp().getRequest();
|
|
3083
|
-
const decoded = req.axisDecoded;
|
|
3084
|
-
if (!decoded) {
|
|
3085
|
-
throw new Error(
|
|
3086
|
-
"@AxisFrame() requires AxisDecodeInterceptor on the route. Add @UseInterceptors(AxisDecodeInterceptor) to use this decorator."
|
|
3087
|
-
);
|
|
3088
|
-
}
|
|
3089
|
-
return decoded;
|
|
3214
|
+
/**
|
|
3215
|
+
* Clears all registered sensors.
|
|
3216
|
+
* Useful for testing.
|
|
3217
|
+
*
|
|
3218
|
+
* @internal
|
|
3219
|
+
*/
|
|
3220
|
+
clear() {
|
|
3221
|
+
this.sensors = [];
|
|
3090
3222
|
}
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
var SENSOR_METADATA_KEY = "axis:sensor";
|
|
3096
|
-
function Sensor(options) {
|
|
3097
|
-
return SetMetadata2(SENSOR_METADATA_KEY, options ?? true);
|
|
3098
|
-
}
|
|
3099
|
-
|
|
3100
|
-
// src/engine/index.ts
|
|
3101
|
-
var engine_exports = {};
|
|
3102
|
-
__export(engine_exports, {
|
|
3103
|
-
BAND: () => BAND,
|
|
3104
|
-
HandlerDiscoveryService: () => HandlerDiscoveryService,
|
|
3105
|
-
IntentRouter: () => IntentRouter,
|
|
3106
|
-
PRE_DECODE_BOUNDARY: () => PRE_DECODE_BOUNDARY,
|
|
3107
|
-
SensorDiscoveryService: () => SensorDiscoveryService,
|
|
3108
|
-
SensorRegistry: () => SensorRegistry,
|
|
3109
|
-
createObservation: () => createObservation,
|
|
3110
|
-
endStage: () => endStage,
|
|
3111
|
-
finalizeObservation: () => finalizeObservation,
|
|
3112
|
-
recordSensor: () => recordSensor,
|
|
3113
|
-
startStage: () => startStage
|
|
3114
|
-
});
|
|
3223
|
+
};
|
|
3224
|
+
SensorRegistry = __decorateClass([
|
|
3225
|
+
Injectable6()
|
|
3226
|
+
], SensorRegistry);
|
|
3115
3227
|
|
|
3116
3228
|
// src/engine/axis-observation.ts
|
|
3117
3229
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
@@ -3149,251 +3261,514 @@ function finalizeObservation(obs, decision, statusCode, resultCode) {
|
|
|
3149
3261
|
if (resultCode) obs.resultCode = resultCode;
|
|
3150
3262
|
}
|
|
3151
3263
|
|
|
3152
|
-
// src/
|
|
3153
|
-
import { Injectable as
|
|
3154
|
-
var
|
|
3155
|
-
constructor(
|
|
3156
|
-
this.
|
|
3157
|
-
this.scanner = scanner;
|
|
3158
|
-
this.router = router;
|
|
3159
|
-
this.logger = new Logger4(HandlerDiscoveryService.name);
|
|
3264
|
+
// src/security/axis-sensor-chain.service.ts
|
|
3265
|
+
import { Injectable as Injectable7 } from "@nestjs/common";
|
|
3266
|
+
var AxisSensorChainService = class {
|
|
3267
|
+
constructor(registry) {
|
|
3268
|
+
this.registry = registry;
|
|
3160
3269
|
}
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
const
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
if (!this.router.has(meta.intent)) {
|
|
3181
|
-
this.router.register(
|
|
3182
|
-
meta.intent,
|
|
3183
|
-
instance[methodName].bind(instance)
|
|
3184
|
-
);
|
|
3185
|
-
registered++;
|
|
3186
|
-
totalIntents++;
|
|
3187
|
-
}
|
|
3188
|
-
this.router.registerIntentMeta(meta.intent, proto, methodName);
|
|
3189
|
-
}
|
|
3190
|
-
if (registered > 0) {
|
|
3191
|
-
this.logger.log(
|
|
3192
|
-
`Auto-registered ${registered} intents from ${handlerName}`
|
|
3193
|
-
);
|
|
3194
|
-
}
|
|
3270
|
+
/**
|
|
3271
|
+
* Evaluate all applicable sensors based on phase.
|
|
3272
|
+
*/
|
|
3273
|
+
async evaluate(input, phase = "POST_DECODE", baseDecision) {
|
|
3274
|
+
if (phase === "PRE_DECODE") {
|
|
3275
|
+
return this.evaluateSensors(this.registry.getPreDecodeSensors(), input);
|
|
3276
|
+
}
|
|
3277
|
+
if (phase === "BOTH") {
|
|
3278
|
+
const rawPreResult = await this.evaluateSensors(
|
|
3279
|
+
this.registry.getPreDecodeSensors(),
|
|
3280
|
+
input
|
|
3281
|
+
);
|
|
3282
|
+
const preResult = normalizeSensorDecision(rawPreResult);
|
|
3283
|
+
if (!preResult.allow) return rawPreResult;
|
|
3284
|
+
return this.evaluateSensors(
|
|
3285
|
+
this.registry.getPostDecodeSensors(),
|
|
3286
|
+
input,
|
|
3287
|
+
rawPreResult
|
|
3288
|
+
);
|
|
3195
3289
|
}
|
|
3196
|
-
this.
|
|
3197
|
-
|
|
3290
|
+
return this.evaluateSensors(
|
|
3291
|
+
this.registry.getPostDecodeSensors(),
|
|
3292
|
+
input,
|
|
3293
|
+
baseDecision
|
|
3198
3294
|
);
|
|
3199
3295
|
}
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
], HandlerDiscoveryService);
|
|
3204
|
-
|
|
3205
|
-
// src/engine/sensor-bands.ts
|
|
3206
|
-
var BAND = {
|
|
3207
|
-
/** Pre-decode: raw byte validation, geo, budget, magic */
|
|
3208
|
-
WIRE: 0,
|
|
3209
|
-
/** Post-decode: identity resolution, capsule, proof */
|
|
3210
|
-
IDENTITY: 40,
|
|
3211
|
-
/** Post-decode: authorization, signature, rate limiting */
|
|
3212
|
-
POLICY: 90,
|
|
3213
|
-
/** Post-decode: content validation, TLV, schema, files */
|
|
3214
|
-
CONTENT: 140,
|
|
3215
|
-
/** Post-decode: business logic sensors, streams, WS */
|
|
3216
|
-
BUSINESS: 200,
|
|
3217
|
-
/** Post-decode: audit, logging (always last) */
|
|
3218
|
-
AUDIT: 900
|
|
3219
|
-
};
|
|
3220
|
-
var PRE_DECODE_BOUNDARY = 40;
|
|
3221
|
-
|
|
3222
|
-
// src/engine/sensor-discovery.service.ts
|
|
3223
|
-
import { Injectable as Injectable6, Logger as Logger5 } from "@nestjs/common";
|
|
3224
|
-
var SensorDiscoveryService = class {
|
|
3225
|
-
constructor(discovery, reflector, registry) {
|
|
3226
|
-
this.discovery = discovery;
|
|
3227
|
-
this.reflector = reflector;
|
|
3228
|
-
this.registry = registry;
|
|
3229
|
-
this.logger = new Logger5(SensorDiscoveryService.name);
|
|
3296
|
+
/** Run only pre-decode sensors. */
|
|
3297
|
+
async evaluatePre(input) {
|
|
3298
|
+
return this.evaluateSensors(this.registry.getPreDecodeSensors(), input);
|
|
3230
3299
|
}
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3300
|
+
/** Run only post-decode sensors. */
|
|
3301
|
+
async evaluatePost(input, baseDecision) {
|
|
3302
|
+
return this.evaluateSensors(
|
|
3303
|
+
this.registry.getPostDecodeSensors(),
|
|
3304
|
+
input,
|
|
3305
|
+
baseDecision
|
|
3306
|
+
);
|
|
3307
|
+
}
|
|
3308
|
+
async evaluateSensors(sensors, input, baseDecision) {
|
|
3309
|
+
const relevantSensors = sensors.filter(
|
|
3310
|
+
(s) => !s.supports || s.supports(input)
|
|
3311
|
+
);
|
|
3312
|
+
const normalizedBase = baseDecision ? normalizeSensorDecision(baseDecision) : void 0;
|
|
3313
|
+
let riskScore = normalizedBase?.riskScore ?? 0;
|
|
3314
|
+
const reasons = normalizedBase?.reasons ? [...normalizedBase.reasons] : [];
|
|
3315
|
+
const tags = normalizedBase?.tags ? { ...normalizedBase.tags } : {};
|
|
3316
|
+
let expSecondsMax = normalizedBase?.tighten?.expSecondsMax;
|
|
3317
|
+
let constraintsPatch = normalizedBase?.tighten?.constraintsPatch ? { ...normalizedBase.tighten.constraintsPatch } : {};
|
|
3318
|
+
for (const sensor of relevantSensors) {
|
|
3319
|
+
try {
|
|
3320
|
+
const t0 = Date.now();
|
|
3321
|
+
const rawDecision = await sensor.run(input);
|
|
3322
|
+
const elapsed = Date.now() - t0;
|
|
3323
|
+
const decision = normalizeSensorDecision(rawDecision);
|
|
3324
|
+
const obs = input.metadata?.observation;
|
|
3325
|
+
if (obs) {
|
|
3326
|
+
recordSensor(
|
|
3327
|
+
obs,
|
|
3328
|
+
sensor.name,
|
|
3329
|
+
decision.allow,
|
|
3330
|
+
decision.riskScore,
|
|
3331
|
+
elapsed,
|
|
3332
|
+
decision.reasons,
|
|
3333
|
+
decision.allow ? void 0 : decision.code
|
|
3334
|
+
);
|
|
3335
|
+
}
|
|
3336
|
+
if (!decision.allow) {
|
|
3337
|
+
return {
|
|
3338
|
+
allow: false,
|
|
3339
|
+
riskScore: Math.min(100, riskScore + decision.riskScore),
|
|
3340
|
+
reasons: [...reasons, ...decision.reasons],
|
|
3341
|
+
tags
|
|
3342
|
+
};
|
|
3343
|
+
}
|
|
3344
|
+
riskScore = Math.min(100, riskScore + decision.riskScore);
|
|
3345
|
+
reasons.push(...decision.reasons);
|
|
3346
|
+
if (decision.tags) {
|
|
3347
|
+
Object.assign(tags, decision.tags);
|
|
3348
|
+
}
|
|
3349
|
+
if (decision.tighten?.expSecondsMax !== void 0) {
|
|
3350
|
+
expSecondsMax = expSecondsMax === void 0 ? decision.tighten.expSecondsMax : Math.min(expSecondsMax, decision.tighten.expSecondsMax);
|
|
3351
|
+
}
|
|
3352
|
+
if (decision.tighten?.constraintsPatch) {
|
|
3353
|
+
constraintsPatch = {
|
|
3354
|
+
...constraintsPatch,
|
|
3355
|
+
...decision.tighten.constraintsPatch
|
|
3356
|
+
};
|
|
3357
|
+
}
|
|
3358
|
+
} catch (error) {
|
|
3359
|
+
console.error(`[AXIS][SENSOR] ${sensor.name} failed:`, error);
|
|
3360
|
+
const obs = input.metadata?.observation;
|
|
3361
|
+
if (obs) {
|
|
3362
|
+
recordSensor(obs, sensor.name, false, 100, 0, [
|
|
3363
|
+
`sensor_error:${sensor.name}`
|
|
3364
|
+
]);
|
|
3365
|
+
}
|
|
3366
|
+
return {
|
|
3367
|
+
allow: false,
|
|
3368
|
+
riskScore: 100,
|
|
3369
|
+
reasons: [`sensor_error:${sensor.name}`]
|
|
3370
|
+
};
|
|
3252
3371
|
}
|
|
3253
|
-
this.registry.register(sensor);
|
|
3254
|
-
count++;
|
|
3255
3372
|
}
|
|
3256
|
-
|
|
3373
|
+
const tightenPatch = Object.keys(constraintsPatch).length > 0 ? constraintsPatch : void 0;
|
|
3374
|
+
return {
|
|
3375
|
+
allow: true,
|
|
3376
|
+
riskScore,
|
|
3377
|
+
reasons,
|
|
3378
|
+
tags,
|
|
3379
|
+
tighten: expSecondsMax !== void 0 || tightenPatch ? {
|
|
3380
|
+
expSecondsMax,
|
|
3381
|
+
constraintsPatch: tightenPatch
|
|
3382
|
+
} : void 0
|
|
3383
|
+
};
|
|
3257
3384
|
}
|
|
3258
3385
|
};
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
],
|
|
3386
|
+
AxisSensorChainService = __decorateClass([
|
|
3387
|
+
Injectable7()
|
|
3388
|
+
], AxisSensorChainService);
|
|
3262
3389
|
|
|
3263
|
-
// src/
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3390
|
+
// src/core/index.ts
|
|
3391
|
+
var core_exports = {};
|
|
3392
|
+
__export(core_exports, {
|
|
3393
|
+
AXIS_MAGIC: () => AXIS_MAGIC,
|
|
3394
|
+
AXIS_VERSION: () => AXIS_VERSION,
|
|
3395
|
+
AxisError: () => AxisError,
|
|
3396
|
+
AxisFrameZ: () => AxisFrameZ,
|
|
3397
|
+
BodyProfile: () => BodyProfile,
|
|
3398
|
+
ERR_BAD_SIGNATURE: () => ERR_BAD_SIGNATURE,
|
|
3399
|
+
ERR_CONTRACT_VIOLATION: () => ERR_CONTRACT_VIOLATION,
|
|
3400
|
+
ERR_INVALID_PACKET: () => ERR_INVALID_PACKET,
|
|
3401
|
+
ERR_REPLAY_DETECTED: () => ERR_REPLAY_DETECTED,
|
|
3402
|
+
FLAG_BODY_TLV: () => FLAG_BODY_TLV,
|
|
3403
|
+
FLAG_CHAIN_REQ: () => FLAG_CHAIN_REQ,
|
|
3404
|
+
FLAG_HAS_WITNESS: () => FLAG_HAS_WITNESS,
|
|
3405
|
+
MAX_BODY_LEN: () => MAX_BODY_LEN,
|
|
3406
|
+
MAX_FRAME_LEN: () => MAX_FRAME_LEN,
|
|
3407
|
+
MAX_HDR_LEN: () => MAX_HDR_LEN,
|
|
3408
|
+
MAX_SIG_LEN: () => MAX_SIG_LEN,
|
|
3409
|
+
NCERT_ALG: () => NCERT_ALG,
|
|
3410
|
+
NCERT_EXP: () => NCERT_EXP,
|
|
3411
|
+
NCERT_ISSUER_KID: () => NCERT_ISSUER_KID,
|
|
3412
|
+
NCERT_KID: () => NCERT_KID,
|
|
3413
|
+
NCERT_NBF: () => NCERT_NBF,
|
|
3414
|
+
NCERT_NODE_ID: () => NCERT_NODE_ID,
|
|
3415
|
+
NCERT_PAYLOAD: () => NCERT_PAYLOAD,
|
|
3416
|
+
NCERT_PUB: () => NCERT_PUB,
|
|
3417
|
+
NCERT_SCOPE: () => NCERT_SCOPE,
|
|
3418
|
+
NCERT_SIG: () => NCERT_SIG,
|
|
3419
|
+
PROOF_CAPSULE: () => PROOF_CAPSULE,
|
|
3420
|
+
PROOF_JWT: () => PROOF_JWT,
|
|
3421
|
+
PROOF_LOOM: () => PROOF_LOOM,
|
|
3422
|
+
PROOF_MTLS: () => PROOF_MTLS,
|
|
3423
|
+
PROOF_NONE: () => PROOF_NONE,
|
|
3424
|
+
PROOF_WITNESS: () => PROOF_WITNESS,
|
|
3425
|
+
ProofType: () => ProofType,
|
|
3426
|
+
TLV: () => TLV,
|
|
3427
|
+
TLV_ACTOR_ID: () => TLV_ACTOR_ID,
|
|
3428
|
+
TLV_AUD: () => TLV_AUD,
|
|
3429
|
+
TLV_BODY_ARR: () => TLV_BODY_ARR,
|
|
3430
|
+
TLV_BODY_OBJ: () => TLV_BODY_OBJ,
|
|
3431
|
+
TLV_CAPSULE: () => TLV_CAPSULE,
|
|
3432
|
+
TLV_EFFECT: () => TLV_EFFECT,
|
|
3433
|
+
TLV_ERROR_CODE: () => TLV_ERROR_CODE,
|
|
3434
|
+
TLV_ERROR_MSG: () => TLV_ERROR_MSG,
|
|
3435
|
+
TLV_INDEX: () => TLV_INDEX,
|
|
3436
|
+
TLV_INTENT: () => TLV_INTENT,
|
|
3437
|
+
TLV_KID: () => TLV_KID,
|
|
3438
|
+
TLV_LOOM_PRESENCE_ID: () => TLV_LOOM_PRESENCE_ID,
|
|
3439
|
+
TLV_LOOM_THREAD_HASH: () => TLV_LOOM_THREAD_HASH,
|
|
3440
|
+
TLV_LOOM_WRIT: () => TLV_LOOM_WRIT,
|
|
3441
|
+
TLV_NODE: () => TLV_NODE,
|
|
3442
|
+
TLV_NODE_CERT_HASH: () => TLV_NODE_CERT_HASH,
|
|
3443
|
+
TLV_NODE_KID: () => TLV_NODE_KID,
|
|
3444
|
+
TLV_NONCE: () => TLV_NONCE,
|
|
3445
|
+
TLV_OFFSET: () => TLV_OFFSET,
|
|
3446
|
+
TLV_OK: () => TLV_OK,
|
|
3447
|
+
TLV_PID: () => TLV_PID,
|
|
3448
|
+
TLV_PREV_HASH: () => TLV_PREV_HASH,
|
|
3449
|
+
TLV_PROOF_REF: () => TLV_PROOF_REF,
|
|
3450
|
+
TLV_PROOF_TYPE: () => TLV_PROOF_TYPE,
|
|
3451
|
+
TLV_REALM: () => TLV_REALM,
|
|
3452
|
+
TLV_RECEIPT_HASH: () => TLV_RECEIPT_HASH,
|
|
3453
|
+
TLV_RID: () => TLV_RID,
|
|
3454
|
+
TLV_SHA256_CHUNK: () => TLV_SHA256_CHUNK,
|
|
3455
|
+
TLV_TRACE_ID: () => TLV_TRACE_ID,
|
|
3456
|
+
TLV_TS: () => TLV_TS,
|
|
3457
|
+
TLV_UPLOAD_ID: () => TLV_UPLOAD_ID,
|
|
3458
|
+
computeReceiptHash: () => computeReceiptHash,
|
|
3459
|
+
computeSignaturePayload: () => computeSignaturePayload,
|
|
3460
|
+
decodeArray: () => decodeArray,
|
|
3461
|
+
decodeFrame: () => decodeFrame,
|
|
3462
|
+
decodeObject: () => decodeObject,
|
|
3463
|
+
decodeTLVs: () => decodeTLVs,
|
|
3464
|
+
decodeTLVsList: () => decodeTLVsList,
|
|
3465
|
+
decodeVarint: () => decodeVarint,
|
|
3466
|
+
encodeFrame: () => encodeFrame,
|
|
3467
|
+
encodeTLVs: () => encodeTLVs,
|
|
3468
|
+
encodeVarint: () => encodeVarint,
|
|
3469
|
+
generateEd25519KeyPair: () => generateEd25519KeyPair,
|
|
3470
|
+
getSignTarget: () => getSignTarget,
|
|
3471
|
+
sha256: () => sha256,
|
|
3472
|
+
signFrame: () => signFrame,
|
|
3473
|
+
varintLength: () => varintLength,
|
|
3474
|
+
verifyFrameSignature: () => verifyFrameSignature
|
|
3475
|
+
});
|
|
3476
|
+
|
|
3477
|
+
// src/crypto/index.ts
|
|
3478
|
+
var crypto_exports = {};
|
|
3479
|
+
__export(crypto_exports, {
|
|
3480
|
+
ProofVerificationService: () => ProofVerificationService,
|
|
3481
|
+
b64urlDecode: () => b64urlDecode,
|
|
3482
|
+
b64urlDecodeString: () => b64urlDecodeString,
|
|
3483
|
+
b64urlEncode: () => b64urlEncode,
|
|
3484
|
+
b64urlEncodeString: () => b64urlEncodeString,
|
|
3485
|
+
canonicalJson: () => canonicalJson,
|
|
3486
|
+
canonicalJsonExcluding: () => canonicalJsonExcluding
|
|
3487
|
+
});
|
|
3488
|
+
|
|
3489
|
+
// src/crypto/proof-verification.service.ts
|
|
3490
|
+
import { Injectable as Injectable8, Logger as Logger7 } from "@nestjs/common";
|
|
3491
|
+
import * as crypto3 from "crypto";
|
|
3492
|
+
import * as nacl from "tweetnacl";
|
|
3493
|
+
var ProofVerificationService = class {
|
|
3494
|
+
constructor() {
|
|
3495
|
+
this.logger = new Logger7(ProofVerificationService.name);
|
|
3496
|
+
// Cache of registered device public keys (deviceId -> pubKey)
|
|
3497
|
+
this.deviceKeys = /* @__PURE__ */ new Map();
|
|
3498
|
+
// Cache of trusted mTLS certificate fingerprints
|
|
3499
|
+
this.trustedCerts = /* @__PURE__ */ new Map();
|
|
3270
3500
|
}
|
|
3271
3501
|
/**
|
|
3272
|
-
*
|
|
3502
|
+
* Verifies an authentication proof based on its type.
|
|
3273
3503
|
*
|
|
3274
|
-
*
|
|
3275
|
-
* -
|
|
3276
|
-
* -
|
|
3277
|
-
* -
|
|
3278
|
-
* -
|
|
3504
|
+
* **Supported Types:**
|
|
3505
|
+
* - 1 (CAPSULE): Delegated to `verifyCapsuleProof`
|
|
3506
|
+
* - 2 (JWT): Verified by `verifyJWTProof`
|
|
3507
|
+
* - 3 (MTLS_ID): Verified by `verifyMTLSProof`
|
|
3508
|
+
* - 4 (DEVICE_SE): Verified by `verifyDeviceSEProof`
|
|
3279
3509
|
*
|
|
3280
|
-
* @param {
|
|
3281
|
-
* @
|
|
3510
|
+
* @param {ProofType} proofType - The numeric AXIS proof type
|
|
3511
|
+
* @param {Uint8Array} proofRef - The binary reference or token for the proof
|
|
3512
|
+
* @param {Object} context - Additional metadata required for specific proof types
|
|
3513
|
+
* @param {Uint8Array} [context.signTarget] - The canonical bytes that were signed (for Ed25519)
|
|
3514
|
+
* @param {Uint8Array} [context.signature] - The signature to verify (for Ed25519)
|
|
3515
|
+
* @param {MTLSContext} [context.mtls] - mTLS certificate data
|
|
3516
|
+
* @param {DeviceSEContext} [context.deviceSE] - Device Secure Element information
|
|
3517
|
+
* @returns {Promise<ProofVerificationResult>} The outcome of the verification
|
|
3282
3518
|
*/
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3519
|
+
async verifyProof(proofType, proofRef, context) {
|
|
3520
|
+
switch (proofType) {
|
|
3521
|
+
case 1:
|
|
3522
|
+
return this.verifyCapsuleProof(proofRef);
|
|
3523
|
+
case 2:
|
|
3524
|
+
return this.verifyJWTProof(proofRef);
|
|
3525
|
+
case 3:
|
|
3526
|
+
return this.verifyMTLSProof(context.mtls);
|
|
3527
|
+
case 4:
|
|
3528
|
+
return this.verifyDeviceSEProof(
|
|
3529
|
+
context.signTarget,
|
|
3530
|
+
context.signature,
|
|
3531
|
+
context.deviceSE
|
|
3532
|
+
);
|
|
3533
|
+
default:
|
|
3534
|
+
return { valid: false, error: `Unknown proof type: ${proofType}` };
|
|
3535
|
+
}
|
|
3536
|
+
}
|
|
3537
|
+
/**
|
|
3538
|
+
* Verify CAPSULE proof (delegated to CapsuleService)
|
|
3539
|
+
*/
|
|
3540
|
+
async verifyCapsuleProof(proofRef) {
|
|
3541
|
+
const capsuleId = new TextDecoder().decode(proofRef);
|
|
3542
|
+
return {
|
|
3543
|
+
valid: true,
|
|
3544
|
+
metadata: { capsuleId, requiresCapsuleValidation: true }
|
|
3545
|
+
};
|
|
3546
|
+
}
|
|
3547
|
+
/**
|
|
3548
|
+
* Verifies a JSON Web Token (JWT) proof.
|
|
3549
|
+
*
|
|
3550
|
+
* **Validation Logic:**
|
|
3551
|
+
* 1. Decodes the token string.
|
|
3552
|
+
* 2. Checks for valid 3-part JWT structure.
|
|
3553
|
+
* 3. Validates `exp` (expiration) and `nbf` (not before) claims.
|
|
3554
|
+
* 4. Extracts `actor_id` or `sub` as the identity.
|
|
3555
|
+
*
|
|
3556
|
+
* @param {Uint8Array} proofRef - Binary representation of the JWT string
|
|
3557
|
+
* @returns {Promise<ProofVerificationResult>} Result including the actor identifier
|
|
3558
|
+
*/
|
|
3559
|
+
async verifyJWTProof(proofRef) {
|
|
3560
|
+
try {
|
|
3561
|
+
const token = new TextDecoder().decode(proofRef);
|
|
3562
|
+
const parts = token.split(".");
|
|
3563
|
+
if (parts.length !== 3) {
|
|
3564
|
+
return { valid: false, error: "Invalid JWT format" };
|
|
3565
|
+
}
|
|
3566
|
+
const header = JSON.parse(Buffer.from(parts[0], "base64url").toString());
|
|
3567
|
+
const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString());
|
|
3568
|
+
if (payload.exp && Date.now() / 1e3 > payload.exp) {
|
|
3569
|
+
return { valid: false, error: "JWT expired" };
|
|
3570
|
+
}
|
|
3571
|
+
if (payload.nbf && Date.now() / 1e3 < payload.nbf) {
|
|
3572
|
+
return { valid: false, error: "JWT not yet valid" };
|
|
3573
|
+
}
|
|
3574
|
+
return {
|
|
3575
|
+
valid: true,
|
|
3576
|
+
actorId: payload.sub || payload.actor_id,
|
|
3577
|
+
metadata: { iss: payload.iss, scope: payload.scope }
|
|
3578
|
+
};
|
|
3579
|
+
} catch (e) {
|
|
3580
|
+
const message = e instanceof Error ? e.message : "Unknown error";
|
|
3581
|
+
return { valid: false, error: `JWT parse error: ${message}` };
|
|
3313
3582
|
}
|
|
3314
|
-
this.sensors.push(sensor);
|
|
3315
|
-
const phaseLabel = typeof sensor.phase === "string" ? sensor.phase : sensor.phase?.phase || "UNKNOWN";
|
|
3316
|
-
this.logger.debug(
|
|
3317
|
-
`Registered sensor: ${sensor.name} (order: ${sensor.order}, phase: ${phaseLabel})`
|
|
3318
|
-
);
|
|
3319
3583
|
}
|
|
3320
3584
|
/**
|
|
3321
|
-
*
|
|
3322
|
-
*
|
|
3323
|
-
* @returns {AxisSensor[]} A sorted array of sensors
|
|
3585
|
+
* Verify mTLS client certificate proof
|
|
3324
3586
|
*/
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3587
|
+
async verifyMTLSProof(mtls) {
|
|
3588
|
+
if (!mtls) {
|
|
3589
|
+
return { valid: false, error: "No mTLS context provided" };
|
|
3590
|
+
}
|
|
3591
|
+
if (!mtls.verified) {
|
|
3592
|
+
return { valid: false, error: "mTLS not verified by TLS terminator" };
|
|
3593
|
+
}
|
|
3594
|
+
if (mtls.clientCertFingerprint) {
|
|
3595
|
+
const trusted = this.trustedCerts.get(mtls.clientCertFingerprint);
|
|
3596
|
+
if (trusted) {
|
|
3597
|
+
return {
|
|
3598
|
+
valid: true,
|
|
3599
|
+
actorId: trusted.actorId,
|
|
3600
|
+
metadata: {
|
|
3601
|
+
fingerprint: mtls.clientCertFingerprint,
|
|
3602
|
+
subject: mtls.clientCertSubject
|
|
3603
|
+
}
|
|
3604
|
+
};
|
|
3605
|
+
}
|
|
3606
|
+
}
|
|
3607
|
+
if (mtls.clientCertSubject) {
|
|
3608
|
+
const cnMatch = mtls.clientCertSubject.match(/CN=([^,]+)/);
|
|
3609
|
+
if (cnMatch) {
|
|
3610
|
+
return {
|
|
3611
|
+
valid: true,
|
|
3612
|
+
actorId: cnMatch[1],
|
|
3613
|
+
metadata: {
|
|
3614
|
+
subject: mtls.clientCertSubject,
|
|
3615
|
+
issuer: mtls.clientCertIssuer
|
|
3616
|
+
}
|
|
3617
|
+
};
|
|
3618
|
+
}
|
|
3619
|
+
}
|
|
3620
|
+
return { valid: false, error: "Could not extract actor from certificate" };
|
|
3329
3621
|
}
|
|
3330
3622
|
/**
|
|
3331
|
-
*
|
|
3332
|
-
* These sensors run in middleware on raw bytes before frame decoding.
|
|
3333
|
-
*
|
|
3334
|
-
* @returns {AxisPreSensor[]} Pre-decode sensors sorted by order
|
|
3623
|
+
* Verify Device Secure Element signature
|
|
3335
3624
|
*/
|
|
3336
|
-
|
|
3337
|
-
|
|
3625
|
+
async verifyDeviceSEProof(signTarget, signature, deviceSE) {
|
|
3626
|
+
if (!deviceSE || !signTarget || !signature) {
|
|
3627
|
+
return { valid: false, error: "Missing Device SE context" };
|
|
3628
|
+
}
|
|
3629
|
+
let publicKey = deviceSE.publicKey;
|
|
3630
|
+
const registeredKey = this.deviceKeys.get(deviceSE.deviceId);
|
|
3631
|
+
if (registeredKey) {
|
|
3632
|
+
publicKey = registeredKey;
|
|
3633
|
+
}
|
|
3634
|
+
if (!publicKey || publicKey.length !== 32) {
|
|
3635
|
+
return {
|
|
3636
|
+
valid: false,
|
|
3637
|
+
error: "Invalid or unregistered device public key"
|
|
3638
|
+
};
|
|
3639
|
+
}
|
|
3640
|
+
try {
|
|
3641
|
+
const valid = nacl.sign.detached.verify(signTarget, signature, publicKey);
|
|
3642
|
+
if (!valid) {
|
|
3643
|
+
return { valid: false, error: "Device signature verification failed" };
|
|
3644
|
+
}
|
|
3645
|
+
return {
|
|
3646
|
+
valid: true,
|
|
3647
|
+
actorId: deviceSE.deviceId,
|
|
3648
|
+
metadata: { deviceId: deviceSE.deviceId, proofType: "DEVICE_SE" }
|
|
3649
|
+
};
|
|
3650
|
+
} catch (e) {
|
|
3651
|
+
const message = e instanceof Error ? e.message : "Unknown error";
|
|
3652
|
+
return {
|
|
3653
|
+
valid: false,
|
|
3654
|
+
error: `Signature verification error: ${message}`
|
|
3655
|
+
};
|
|
3656
|
+
}
|
|
3338
3657
|
}
|
|
3339
3658
|
/**
|
|
3340
|
-
*
|
|
3341
|
-
*
|
|
3659
|
+
* Registers a public key for a trusted device.
|
|
3660
|
+
* This key will be used for future `DEVICE_SE` proof verifications.
|
|
3342
3661
|
*
|
|
3343
|
-
* @
|
|
3662
|
+
* @param {string} deviceId - Unique identifier for the device
|
|
3663
|
+
* @param {Uint8Array} publicKey - 32-byte Ed25519 public key
|
|
3664
|
+
* @throws {Error} If the public key is not 32 bytes
|
|
3344
3665
|
*/
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3666
|
+
registerDeviceKey(deviceId, publicKey) {
|
|
3667
|
+
if (publicKey.length !== 32) {
|
|
3668
|
+
throw new Error("Device public key must be 32 bytes (Ed25519)");
|
|
3669
|
+
}
|
|
3670
|
+
this.deviceKeys.set(deviceId, publicKey);
|
|
3671
|
+
this.logger.log(`Registered device key for ${deviceId}`);
|
|
3349
3672
|
}
|
|
3350
3673
|
/**
|
|
3351
|
-
*
|
|
3352
|
-
*
|
|
3353
|
-
* @private
|
|
3354
|
-
* @param {AxisSensor} sensor - The sensor to check
|
|
3355
|
-
* @returns {boolean} True if sensor is pre-decode
|
|
3674
|
+
* Unregister a device
|
|
3356
3675
|
*/
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
return phase === "PRE_DECODE" || (sensor.order ?? 999) < 40;
|
|
3676
|
+
unregisterDevice(deviceId) {
|
|
3677
|
+
return this.deviceKeys.delete(deviceId);
|
|
3360
3678
|
}
|
|
3361
3679
|
/**
|
|
3362
|
-
*
|
|
3680
|
+
* Registers a trusted mTLS certificate fingerprint and associates it with an actor.
|
|
3363
3681
|
*
|
|
3364
|
-
* @
|
|
3365
|
-
* @param {
|
|
3366
|
-
* @returns {boolean} True if sensor is post-decode
|
|
3682
|
+
* @param {string} fingerprint - SHA-256 fingerprint of the client certificate
|
|
3683
|
+
* @param {string} actorId - The actor to associate with this certificate
|
|
3367
3684
|
*/
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3685
|
+
registerMTLSCert(fingerprint, actorId) {
|
|
3686
|
+
this.trustedCerts.set(fingerprint, { actorId, issuedAt: Date.now() });
|
|
3687
|
+
this.logger.log(`Registered mTLS cert ${fingerprint} for actor ${actorId}`);
|
|
3371
3688
|
}
|
|
3372
3689
|
/**
|
|
3373
|
-
*
|
|
3374
|
-
* Useful for diagnostics and monitoring.
|
|
3375
|
-
*
|
|
3376
|
-
* @returns {{preDecodeCount: number, postDecodeCount: number}}
|
|
3690
|
+
* Revoke an mTLS certificate
|
|
3377
3691
|
*/
|
|
3378
|
-
|
|
3379
|
-
return
|
|
3380
|
-
preDecodeCount: this.getPreDecodeSensors().length,
|
|
3381
|
-
postDecodeCount: this.getPostDecodeSensors().length
|
|
3382
|
-
};
|
|
3692
|
+
revokeMTLSCert(fingerprint) {
|
|
3693
|
+
return this.trustedCerts.delete(fingerprint);
|
|
3383
3694
|
}
|
|
3384
3695
|
/**
|
|
3385
|
-
*
|
|
3386
|
-
* Useful for testing.
|
|
3387
|
-
*
|
|
3388
|
-
* @internal
|
|
3696
|
+
* Calculate certificate fingerprint (SHA-256)
|
|
3389
3697
|
*/
|
|
3390
|
-
|
|
3391
|
-
|
|
3698
|
+
static calculateFingerprint(certPem) {
|
|
3699
|
+
const der = Buffer.from(
|
|
3700
|
+
certPem.replace(/-----BEGIN CERTIFICATE-----/, "").replace(/-----END CERTIFICATE-----/, "").replace(/\s/g, ""),
|
|
3701
|
+
"base64"
|
|
3702
|
+
);
|
|
3703
|
+
return crypto3.createHash("sha256").update(der).digest("hex");
|
|
3392
3704
|
}
|
|
3393
3705
|
};
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
],
|
|
3706
|
+
ProofVerificationService = __decorateClass([
|
|
3707
|
+
Injectable8()
|
|
3708
|
+
], ProofVerificationService);
|
|
3709
|
+
|
|
3710
|
+
// src/decorators/index.ts
|
|
3711
|
+
var decorators_exports = {};
|
|
3712
|
+
__export(decorators_exports, {
|
|
3713
|
+
AxisContext: () => AxisContext,
|
|
3714
|
+
AxisDemoPubkey: () => AxisDemoPubkey,
|
|
3715
|
+
AxisFrame: () => AxisFrame3,
|
|
3716
|
+
AxisIp: () => AxisIp,
|
|
3717
|
+
AxisRaw: () => AxisRaw,
|
|
3718
|
+
HANDLER_METADATA_KEY: () => HANDLER_METADATA_KEY,
|
|
3719
|
+
Handler: () => Handler,
|
|
3720
|
+
INTENT_BODY_KEY: () => INTENT_BODY_KEY,
|
|
3721
|
+
INTENT_METADATA_KEY: () => INTENT_METADATA_KEY,
|
|
3722
|
+
INTENT_ROUTES_KEY: () => INTENT_ROUTES_KEY,
|
|
3723
|
+
INTENT_SENSORS_KEY: () => INTENT_SENSORS_KEY,
|
|
3724
|
+
Intent: () => Intent,
|
|
3725
|
+
IntentBody: () => IntentBody,
|
|
3726
|
+
IntentSensors: () => IntentSensors,
|
|
3727
|
+
SENSOR_METADATA_KEY: () => SENSOR_METADATA_KEY,
|
|
3728
|
+
Sensor: () => Sensor,
|
|
3729
|
+
TLV_FIELDS_KEY: () => TLV_FIELDS_KEY,
|
|
3730
|
+
TLV_VALIDATORS_KEY: () => TLV_VALIDATORS_KEY,
|
|
3731
|
+
TlvEnum: () => TlvEnum,
|
|
3732
|
+
TlvField: () => TlvField,
|
|
3733
|
+
TlvMinLen: () => TlvMinLen,
|
|
3734
|
+
TlvRange: () => TlvRange,
|
|
3735
|
+
TlvUtf8Pattern: () => TlvUtf8Pattern,
|
|
3736
|
+
TlvValidate: () => TlvValidate,
|
|
3737
|
+
buildDtoDecoder: () => buildDtoDecoder,
|
|
3738
|
+
extractDtoSchema: () => extractDtoSchema
|
|
3739
|
+
});
|
|
3740
|
+
|
|
3741
|
+
// src/engine/index.ts
|
|
3742
|
+
var engine_exports = {};
|
|
3743
|
+
__export(engine_exports, {
|
|
3744
|
+
BAND: () => BAND,
|
|
3745
|
+
HandlerDiscoveryService: () => HandlerDiscoveryService,
|
|
3746
|
+
IntentRouter: () => IntentRouter,
|
|
3747
|
+
PRE_DECODE_BOUNDARY: () => PRE_DECODE_BOUNDARY,
|
|
3748
|
+
SensorDiscoveryService: () => SensorDiscoveryService,
|
|
3749
|
+
SensorRegistry: () => SensorRegistry,
|
|
3750
|
+
createObservation: () => createObservation,
|
|
3751
|
+
endStage: () => endStage,
|
|
3752
|
+
finalizeObservation: () => finalizeObservation,
|
|
3753
|
+
observation: () => observation_exports,
|
|
3754
|
+
recordSensor: () => recordSensor,
|
|
3755
|
+
startStage: () => startStage
|
|
3756
|
+
});
|
|
3757
|
+
|
|
3758
|
+
// src/engine/observation/index.ts
|
|
3759
|
+
var observation_exports = {};
|
|
3760
|
+
__export(observation_exports, {
|
|
3761
|
+
buildQueueMessage: () => buildQueueMessage,
|
|
3762
|
+
buildUnsignedWitness: () => buildUnsignedWitness,
|
|
3763
|
+
canonicalizeObservation: () => canonicalizeObservation,
|
|
3764
|
+
decodeQueueMessage: () => decodeQueueMessage,
|
|
3765
|
+
encodeQueueMessage: () => encodeQueueMessage,
|
|
3766
|
+
hashObservation: () => hashObservation,
|
|
3767
|
+
parseAutoClaimEntries: () => parseAutoClaimEntries,
|
|
3768
|
+
parseStreamEntries: () => parseStreamEntries,
|
|
3769
|
+
stableJsonStringify: () => stableJsonStringify,
|
|
3770
|
+
verifyResponse: () => verifyResponse
|
|
3771
|
+
});
|
|
3397
3772
|
|
|
3398
3773
|
// src/loom/index.ts
|
|
3399
3774
|
var loom_exports = {};
|
|
@@ -3763,7 +4138,7 @@ var AxisErrorZ = z2.object({
|
|
|
3763
4138
|
});
|
|
3764
4139
|
|
|
3765
4140
|
// src/schemas/body-profile.validator.ts
|
|
3766
|
-
import { Injectable as
|
|
4141
|
+
import { Injectable as Injectable9, Logger as Logger8 } from "@nestjs/common";
|
|
3767
4142
|
var BodyProfile2 = /* @__PURE__ */ ((BodyProfile3) => {
|
|
3768
4143
|
BodyProfile3[BodyProfile3["RAW"] = 0] = "RAW";
|
|
3769
4144
|
BodyProfile3[BodyProfile3["TLV_MAP"] = 1] = "TLV_MAP";
|
|
@@ -3773,7 +4148,7 @@ var BodyProfile2 = /* @__PURE__ */ ((BodyProfile3) => {
|
|
|
3773
4148
|
})(BodyProfile2 || {});
|
|
3774
4149
|
var BodyProfileValidator = class {
|
|
3775
4150
|
constructor() {
|
|
3776
|
-
this.logger = new
|
|
4151
|
+
this.logger = new Logger8(BodyProfileValidator.name);
|
|
3777
4152
|
}
|
|
3778
4153
|
/**
|
|
3779
4154
|
* Validate body matches declared profile
|
|
@@ -3889,12 +4264,13 @@ var BodyProfileValidator = class {
|
|
|
3889
4264
|
}
|
|
3890
4265
|
};
|
|
3891
4266
|
BodyProfileValidator = __decorateClass([
|
|
3892
|
-
|
|
4267
|
+
Injectable9()
|
|
3893
4268
|
], BodyProfileValidator);
|
|
3894
4269
|
|
|
3895
4270
|
// src/security/index.ts
|
|
3896
4271
|
var security_exports = {};
|
|
3897
4272
|
__export(security_exports, {
|
|
4273
|
+
AxisSensorChainService: () => AxisSensorChainService,
|
|
3898
4274
|
CAPABILITIES: () => CAPABILITIES,
|
|
3899
4275
|
INTENT_REQUIREMENTS: () => INTENT_REQUIREMENTS,
|
|
3900
4276
|
PROOF_CAPABILITIES: () => PROOF_CAPABILITIES,
|
|
@@ -3927,7 +4303,7 @@ __export(sensors_exports, {
|
|
|
3927
4303
|
});
|
|
3928
4304
|
|
|
3929
4305
|
// src/sensors/access-profile-resolver.sensor.ts
|
|
3930
|
-
import { Injectable as
|
|
4306
|
+
import { Injectable as Injectable10 } from "@nestjs/common";
|
|
3931
4307
|
var AccessProfileResolverSensor = class {
|
|
3932
4308
|
constructor() {
|
|
3933
4309
|
/** AxisSensor identifier */
|
|
@@ -3953,11 +4329,11 @@ var AccessProfileResolverSensor = class {
|
|
|
3953
4329
|
};
|
|
3954
4330
|
AccessProfileResolverSensor = __decorateClass([
|
|
3955
4331
|
Sensor(),
|
|
3956
|
-
|
|
4332
|
+
Injectable10()
|
|
3957
4333
|
], AccessProfileResolverSensor);
|
|
3958
4334
|
|
|
3959
4335
|
// src/sensors/body-budget.sensor.ts
|
|
3960
|
-
import { Injectable as
|
|
4336
|
+
import { Injectable as Injectable11 } from "@nestjs/common";
|
|
3961
4337
|
var BodyBudgetSensor = class {
|
|
3962
4338
|
constructor() {
|
|
3963
4339
|
/** AxisSensor identifier */
|
|
@@ -4031,14 +4407,14 @@ var BodyBudgetSensor = class {
|
|
|
4031
4407
|
};
|
|
4032
4408
|
BodyBudgetSensor = __decorateClass([
|
|
4033
4409
|
Sensor(),
|
|
4034
|
-
|
|
4410
|
+
Injectable11()
|
|
4035
4411
|
], BodyBudgetSensor);
|
|
4036
4412
|
|
|
4037
4413
|
// src/sensors/capability-enforcement.sensor.ts
|
|
4038
|
-
import { Injectable as
|
|
4414
|
+
import { Injectable as Injectable12, Logger as Logger9 } from "@nestjs/common";
|
|
4039
4415
|
var CapabilityEnforcementSensor = class {
|
|
4040
4416
|
constructor() {
|
|
4041
|
-
this.logger = new
|
|
4417
|
+
this.logger = new Logger9(CapabilityEnforcementSensor.name);
|
|
4042
4418
|
/** AxisSensor identifier for logging and registry */
|
|
4043
4419
|
this.name = "CapabilityEnforcementSensor";
|
|
4044
4420
|
/**
|
|
@@ -4132,12 +4508,12 @@ var CapabilityEnforcementSensor = class {
|
|
|
4132
4508
|
};
|
|
4133
4509
|
CapabilityEnforcementSensor = __decorateClass([
|
|
4134
4510
|
Sensor(),
|
|
4135
|
-
|
|
4511
|
+
Injectable12()
|
|
4136
4512
|
], CapabilityEnforcementSensor);
|
|
4137
4513
|
|
|
4138
4514
|
// src/sensors/chunk-hash.sensor.ts
|
|
4139
|
-
import { Injectable as
|
|
4140
|
-
import { createHash as
|
|
4515
|
+
import { Injectable as Injectable13 } from "@nestjs/common";
|
|
4516
|
+
import { createHash as createHash7 } from "crypto";
|
|
4141
4517
|
var ChunkHashSensor = class {
|
|
4142
4518
|
constructor() {
|
|
4143
4519
|
/** Sensor identifier */
|
|
@@ -4196,7 +4572,7 @@ var ChunkHashSensor = class {
|
|
|
4196
4572
|
reason: "Missing sha256Chunk TLV in header"
|
|
4197
4573
|
};
|
|
4198
4574
|
}
|
|
4199
|
-
const actual =
|
|
4575
|
+
const actual = createHash7("sha256").update(bodyBytes).digest();
|
|
4200
4576
|
if (!Buffer.from(actual).equals(Buffer.from(expected))) {
|
|
4201
4577
|
return {
|
|
4202
4578
|
action: "DENY",
|
|
@@ -4209,15 +4585,15 @@ var ChunkHashSensor = class {
|
|
|
4209
4585
|
};
|
|
4210
4586
|
ChunkHashSensor = __decorateClass([
|
|
4211
4587
|
Sensor(),
|
|
4212
|
-
|
|
4588
|
+
Injectable13()
|
|
4213
4589
|
], ChunkHashSensor);
|
|
4214
4590
|
|
|
4215
4591
|
// src/sensors/entropy.sensor.ts
|
|
4216
|
-
import { Injectable as
|
|
4592
|
+
import { Injectable as Injectable14, Logger as Logger10 } from "@nestjs/common";
|
|
4217
4593
|
import * as crypto4 from "crypto";
|
|
4218
4594
|
var EntropySensor = class {
|
|
4219
4595
|
constructor() {
|
|
4220
|
-
this.logger = new
|
|
4596
|
+
this.logger = new Logger10(EntropySensor.name);
|
|
4221
4597
|
/**
|
|
4222
4598
|
* Minimum acceptable entropy in bits per byte.
|
|
4223
4599
|
*
|
|
@@ -4387,14 +4763,14 @@ var EntropySensor = class {
|
|
|
4387
4763
|
};
|
|
4388
4764
|
EntropySensor = __decorateClass([
|
|
4389
4765
|
Sensor(),
|
|
4390
|
-
|
|
4766
|
+
Injectable14()
|
|
4391
4767
|
], EntropySensor);
|
|
4392
4768
|
|
|
4393
4769
|
// src/sensors/execution-timeout.sensor.ts
|
|
4394
|
-
import { Injectable as
|
|
4770
|
+
import { Injectable as Injectable15, Logger as Logger11 } from "@nestjs/common";
|
|
4395
4771
|
var ExecutionTimeoutSensor = class {
|
|
4396
4772
|
constructor() {
|
|
4397
|
-
this.logger = new
|
|
4773
|
+
this.logger = new Logger11(ExecutionTimeoutSensor.name);
|
|
4398
4774
|
/** AxisSensor identifier */
|
|
4399
4775
|
this.name = "ExecutionTimeoutSensor";
|
|
4400
4776
|
/**
|
|
@@ -4472,11 +4848,11 @@ var ExecutionTimeoutSensor = class {
|
|
|
4472
4848
|
};
|
|
4473
4849
|
ExecutionTimeoutSensor = __decorateClass([
|
|
4474
4850
|
Sensor(),
|
|
4475
|
-
|
|
4851
|
+
Injectable15()
|
|
4476
4852
|
], ExecutionTimeoutSensor);
|
|
4477
4853
|
|
|
4478
4854
|
// src/sensors/frame-budget.sensor.ts
|
|
4479
|
-
import { Injectable as
|
|
4855
|
+
import { Injectable as Injectable16 } from "@nestjs/common";
|
|
4480
4856
|
var FrameBudgetSensor = class {
|
|
4481
4857
|
constructor(config) {
|
|
4482
4858
|
this.config = config;
|
|
@@ -4535,11 +4911,11 @@ var FrameBudgetSensor = class {
|
|
|
4535
4911
|
};
|
|
4536
4912
|
FrameBudgetSensor = __decorateClass([
|
|
4537
4913
|
Sensor({ phase: "PRE_DECODE" }),
|
|
4538
|
-
|
|
4914
|
+
Injectable16()
|
|
4539
4915
|
], FrameBudgetSensor);
|
|
4540
4916
|
|
|
4541
4917
|
// src/sensors/frame-header-sanity.sensor.ts
|
|
4542
|
-
import { Injectable as
|
|
4918
|
+
import { Injectable as Injectable17 } from "@nestjs/common";
|
|
4543
4919
|
var FrameHeaderSanitySensor = class {
|
|
4544
4920
|
constructor() {
|
|
4545
4921
|
this.name = "FrameHeaderSanitySensor";
|
|
@@ -4583,12 +4959,12 @@ var FrameHeaderSanitySensor = class {
|
|
|
4583
4959
|
}
|
|
4584
4960
|
};
|
|
4585
4961
|
FrameHeaderSanitySensor = __decorateClass([
|
|
4586
|
-
|
|
4962
|
+
Injectable17(),
|
|
4587
4963
|
Sensor({ phase: "PRE_DECODE" })
|
|
4588
4964
|
], FrameHeaderSanitySensor);
|
|
4589
4965
|
|
|
4590
4966
|
// src/sensors/header-tlv-limit.sensor.ts
|
|
4591
|
-
import { Injectable as
|
|
4967
|
+
import { Injectable as Injectable18 } from "@nestjs/common";
|
|
4592
4968
|
var HeaderTLVLimitSensor = class {
|
|
4593
4969
|
constructor() {
|
|
4594
4970
|
this.name = "HeaderTLVLimitSensor";
|
|
@@ -4620,12 +4996,12 @@ var HeaderTLVLimitSensor = class {
|
|
|
4620
4996
|
}
|
|
4621
4997
|
};
|
|
4622
4998
|
HeaderTLVLimitSensor = __decorateClass([
|
|
4623
|
-
|
|
4999
|
+
Injectable18(),
|
|
4624
5000
|
Sensor()
|
|
4625
5001
|
], HeaderTLVLimitSensor);
|
|
4626
5002
|
|
|
4627
5003
|
// src/sensors/intent-allowlist.sensor.ts
|
|
4628
|
-
import { Injectable as
|
|
5004
|
+
import { Injectable as Injectable19 } from "@nestjs/common";
|
|
4629
5005
|
var PUBLIC_INTENT_ALLOWLIST = [
|
|
4630
5006
|
"public.",
|
|
4631
5007
|
"schema.",
|
|
@@ -4660,12 +5036,12 @@ var IntentAllowlistSensor = class {
|
|
|
4660
5036
|
}
|
|
4661
5037
|
};
|
|
4662
5038
|
IntentAllowlistSensor = __decorateClass([
|
|
4663
|
-
|
|
5039
|
+
Injectable19(),
|
|
4664
5040
|
Sensor()
|
|
4665
5041
|
], IntentAllowlistSensor);
|
|
4666
5042
|
|
|
4667
5043
|
// src/sensors/intent-registry.sensor.ts
|
|
4668
|
-
import { Injectable as
|
|
5044
|
+
import { Injectable as Injectable20 } from "@nestjs/common";
|
|
4669
5045
|
var IntentRegistrySensor = class {
|
|
4670
5046
|
constructor(router) {
|
|
4671
5047
|
this.router = router;
|
|
@@ -4688,12 +5064,12 @@ var IntentRegistrySensor = class {
|
|
|
4688
5064
|
}
|
|
4689
5065
|
};
|
|
4690
5066
|
IntentRegistrySensor = __decorateClass([
|
|
4691
|
-
|
|
5067
|
+
Injectable20(),
|
|
4692
5068
|
Sensor({ phase: "POST_DECODE" })
|
|
4693
5069
|
], IntentRegistrySensor);
|
|
4694
5070
|
|
|
4695
5071
|
// src/sensors/proof-presence.sensor.ts
|
|
4696
|
-
import { Injectable as
|
|
5072
|
+
import { Injectable as Injectable21 } from "@nestjs/common";
|
|
4697
5073
|
var ProofPresenceSensor = class {
|
|
4698
5074
|
constructor() {
|
|
4699
5075
|
this.name = "ProofPresenceSensor";
|
|
@@ -4741,11 +5117,11 @@ var ProofPresenceSensor = class {
|
|
|
4741
5117
|
};
|
|
4742
5118
|
ProofPresenceSensor = __decorateClass([
|
|
4743
5119
|
Sensor(),
|
|
4744
|
-
|
|
5120
|
+
Injectable21()
|
|
4745
5121
|
], ProofPresenceSensor);
|
|
4746
5122
|
|
|
4747
5123
|
// src/sensors/protocol-strict.sensor.ts
|
|
4748
|
-
import { Injectable as
|
|
5124
|
+
import { Injectable as Injectable22, Logger as Logger12 } from "@nestjs/common";
|
|
4749
5125
|
var VALID_FLAGS = [
|
|
4750
5126
|
0,
|
|
4751
5127
|
// No flags
|
|
@@ -4763,7 +5139,7 @@ var VALID_FLAGS = [
|
|
|
4763
5139
|
var ProtocolStrictSensor = class {
|
|
4764
5140
|
constructor(config) {
|
|
4765
5141
|
this.config = config;
|
|
4766
|
-
this.logger = new
|
|
5142
|
+
this.logger = new Logger12(ProtocolStrictSensor.name);
|
|
4767
5143
|
/** Sensor identifier for logging and registry */
|
|
4768
5144
|
this.name = "ProtocolStrictSensor";
|
|
4769
5145
|
/**
|
|
@@ -5016,11 +5392,11 @@ var ProtocolStrictSensor = class {
|
|
|
5016
5392
|
};
|
|
5017
5393
|
ProtocolStrictSensor = __decorateClass([
|
|
5018
5394
|
Sensor({ phase: "PRE_DECODE" }),
|
|
5019
|
-
|
|
5395
|
+
Injectable22()
|
|
5020
5396
|
], ProtocolStrictSensor);
|
|
5021
5397
|
|
|
5022
5398
|
// src/sensors/receipt-policy.sensor.ts
|
|
5023
|
-
import { Injectable as
|
|
5399
|
+
import { Injectable as Injectable23 } from "@nestjs/common";
|
|
5024
5400
|
var ReceiptPolicySensor = class {
|
|
5025
5401
|
constructor() {
|
|
5026
5402
|
this.name = "ReceiptPolicySensor";
|
|
@@ -5034,12 +5410,12 @@ var ReceiptPolicySensor = class {
|
|
|
5034
5410
|
}
|
|
5035
5411
|
};
|
|
5036
5412
|
ReceiptPolicySensor = __decorateClass([
|
|
5037
|
-
|
|
5413
|
+
Injectable23(),
|
|
5038
5414
|
Sensor()
|
|
5039
5415
|
], ReceiptPolicySensor);
|
|
5040
5416
|
|
|
5041
5417
|
// src/sensors/schema-validation.sensor.ts
|
|
5042
|
-
import { Injectable as
|
|
5418
|
+
import { Injectable as Injectable24 } from "@nestjs/common";
|
|
5043
5419
|
function readU64be(b) {
|
|
5044
5420
|
if (b.length !== 8)
|
|
5045
5421
|
throw new AxisError("SCHEMA_TYPE_MISMATCH", "u64 must be 8 bytes", 400);
|
|
@@ -5214,11 +5590,11 @@ var SchemaValidationSensor = class {
|
|
|
5214
5590
|
};
|
|
5215
5591
|
SchemaValidationSensor = __decorateClass([
|
|
5216
5592
|
Sensor(),
|
|
5217
|
-
|
|
5593
|
+
Injectable24()
|
|
5218
5594
|
], SchemaValidationSensor);
|
|
5219
5595
|
|
|
5220
5596
|
// src/sensors/stream-scope.sensor.ts
|
|
5221
|
-
import { Injectable as
|
|
5597
|
+
import { Injectable as Injectable25 } from "@nestjs/common";
|
|
5222
5598
|
var StreamScopeSensor = class {
|
|
5223
5599
|
constructor() {
|
|
5224
5600
|
/** Sensor identifier */
|
|
@@ -5264,11 +5640,11 @@ var StreamScopeSensor = class {
|
|
|
5264
5640
|
};
|
|
5265
5641
|
StreamScopeSensor = __decorateClass([
|
|
5266
5642
|
Sensor(),
|
|
5267
|
-
|
|
5643
|
+
Injectable25()
|
|
5268
5644
|
], StreamScopeSensor);
|
|
5269
5645
|
|
|
5270
5646
|
// src/sensors/tlv-parse.sensor.ts
|
|
5271
|
-
import { Injectable as
|
|
5647
|
+
import { Injectable as Injectable26 } from "@nestjs/common";
|
|
5272
5648
|
var TLVParseSensor = class {
|
|
5273
5649
|
constructor() {
|
|
5274
5650
|
this.name = "TLVParseSensor";
|
|
@@ -5370,11 +5746,11 @@ var TLVParseSensor = class {
|
|
|
5370
5746
|
};
|
|
5371
5747
|
TLVParseSensor = __decorateClass([
|
|
5372
5748
|
Sensor(),
|
|
5373
|
-
|
|
5749
|
+
Injectable26()
|
|
5374
5750
|
], TLVParseSensor);
|
|
5375
5751
|
|
|
5376
5752
|
// src/sensors/varint-hardening.sensor.ts
|
|
5377
|
-
import { Injectable as
|
|
5753
|
+
import { Injectable as Injectable27 } from "@nestjs/common";
|
|
5378
5754
|
var VarintHardeningSensor = class {
|
|
5379
5755
|
constructor() {
|
|
5380
5756
|
/** Sensor identifier */
|
|
@@ -5437,7 +5813,7 @@ var VarintHardeningSensor = class {
|
|
|
5437
5813
|
};
|
|
5438
5814
|
VarintHardeningSensor = __decorateClass([
|
|
5439
5815
|
Sensor({ phase: "PRE_DECODE" }),
|
|
5440
|
-
|
|
5816
|
+
Injectable27()
|
|
5441
5817
|
], VarintHardeningSensor);
|
|
5442
5818
|
|
|
5443
5819
|
// src/utils/index.ts
|
|
@@ -5508,14 +5884,21 @@ export {
|
|
|
5508
5884
|
AXIS_UPLOAD_SESSION_STORE,
|
|
5509
5885
|
AXIS_VERSION,
|
|
5510
5886
|
ats1_exports as Ats1Codec,
|
|
5887
|
+
AxisContext,
|
|
5888
|
+
AxisDemoPubkey,
|
|
5889
|
+
AxisError,
|
|
5511
5890
|
AxisFilesDownloadHandler,
|
|
5512
5891
|
AxisFilesFinalizeHandler,
|
|
5513
5892
|
AxisFrameZ,
|
|
5514
5893
|
AxisIdDto,
|
|
5894
|
+
AxisIp,
|
|
5515
5895
|
T as AxisPacketTags,
|
|
5516
5896
|
AxisPartialType,
|
|
5897
|
+
AxisRaw,
|
|
5517
5898
|
AxisResponseDto,
|
|
5899
|
+
AxisSensorChainService,
|
|
5518
5900
|
AxisTlvDto,
|
|
5901
|
+
BAND,
|
|
5519
5902
|
BodyProfile,
|
|
5520
5903
|
CAPABILITIES,
|
|
5521
5904
|
ContractViolationError,
|
|
@@ -5533,7 +5916,10 @@ export {
|
|
|
5533
5916
|
FLAG_CHAIN_REQ,
|
|
5534
5917
|
FLAG_HAS_WITNESS,
|
|
5535
5918
|
HANDLER_METADATA_KEY,
|
|
5919
|
+
HANDLER_SENSORS_KEY,
|
|
5536
5920
|
Handler,
|
|
5921
|
+
HandlerDiscoveryService,
|
|
5922
|
+
HandlerSensors,
|
|
5537
5923
|
INTENT_BODY_KEY,
|
|
5538
5924
|
INTENT_METADATA_KEY,
|
|
5539
5925
|
INTENT_REQUIREMENTS,
|
|
@@ -5560,6 +5946,7 @@ export {
|
|
|
5560
5946
|
NCERT_PUB,
|
|
5561
5947
|
NCERT_SCOPE,
|
|
5562
5948
|
NCERT_SIG,
|
|
5949
|
+
PRE_DECODE_BOUNDARY,
|
|
5563
5950
|
PROOF_CAPABILITIES,
|
|
5564
5951
|
PROOF_CAPSULE,
|
|
5565
5952
|
PROOF_JWT,
|
|
@@ -5574,11 +5961,15 @@ export {
|
|
|
5574
5961
|
RESPONSE_TAG_UPDATED_AT,
|
|
5575
5962
|
RESPONSE_TAG_UPDATED_BY,
|
|
5576
5963
|
RiskDecision,
|
|
5964
|
+
SENSOR_METADATA_KEY,
|
|
5577
5965
|
Schema2002_PasskeyLoginOptionsRes,
|
|
5578
5966
|
Schema2011_PasskeyLoginVerifyReq,
|
|
5579
5967
|
Schema2012_PasskeyLoginVerifyRes,
|
|
5580
5968
|
Schema2021_PasskeyRegisterOptionsReq,
|
|
5969
|
+
Sensor,
|
|
5581
5970
|
SensorDecisions,
|
|
5971
|
+
SensorDiscoveryService,
|
|
5972
|
+
SensorRegistry,
|
|
5582
5973
|
TLV,
|
|
5583
5974
|
TLV_ACTOR_ID,
|
|
5584
5975
|
TLV_AUD,
|
|
@@ -5627,21 +6018,26 @@ export {
|
|
|
5627
6018
|
buildAts1Hdr,
|
|
5628
6019
|
buildDtoDecoder,
|
|
5629
6020
|
buildPacket,
|
|
6021
|
+
buildQueueMessage,
|
|
5630
6022
|
buildReceiptHash,
|
|
5631
6023
|
buildTLVs,
|
|
6024
|
+
buildUnsignedWitness,
|
|
5632
6025
|
bytes,
|
|
5633
6026
|
canAccessResource,
|
|
5634
6027
|
canonicalJson,
|
|
5635
6028
|
canonicalJsonExcluding,
|
|
6029
|
+
canonicalizeObservation,
|
|
5636
6030
|
classifyIntent,
|
|
5637
6031
|
computeReceiptHash,
|
|
5638
6032
|
computeSignaturePayload,
|
|
5639
6033
|
core_exports as core,
|
|
6034
|
+
createObservation,
|
|
5640
6035
|
crypto_exports as crypto,
|
|
5641
6036
|
decodeArray,
|
|
5642
6037
|
decodeAxis1Frame,
|
|
5643
6038
|
decodeFrame,
|
|
5644
6039
|
decodeObject,
|
|
6040
|
+
decodeQueueMessage,
|
|
5645
6041
|
decodeTLVs,
|
|
5646
6042
|
decodeTLVsList,
|
|
5647
6043
|
decodeVarint,
|
|
@@ -5649,13 +6045,17 @@ export {
|
|
|
5649
6045
|
encVarint,
|
|
5650
6046
|
encodeAxis1Frame,
|
|
5651
6047
|
encodeFrame,
|
|
6048
|
+
encodeQueueMessage,
|
|
5652
6049
|
encodeTLVs,
|
|
5653
6050
|
encodeVarint,
|
|
6051
|
+
endStage,
|
|
5654
6052
|
engine_exports as engine,
|
|
5655
6053
|
extractDtoSchema,
|
|
6054
|
+
finalizeObservation,
|
|
5656
6055
|
generateEd25519KeyPair,
|
|
5657
6056
|
getSignTarget,
|
|
5658
6057
|
hasScope,
|
|
6058
|
+
hashObservation,
|
|
5659
6059
|
isAdminOpcode,
|
|
5660
6060
|
isKnownOpcode,
|
|
5661
6061
|
isTimestampValid,
|
|
@@ -5667,7 +6067,10 @@ export {
|
|
|
5667
6067
|
packPasskeyLoginVerifyReq,
|
|
5668
6068
|
packPasskeyLoginVerifyRes,
|
|
5669
6069
|
packPasskeyRegisterOptionsReq,
|
|
6070
|
+
parseAutoClaimEntries,
|
|
5670
6071
|
parseScope,
|
|
6072
|
+
parseStreamEntries,
|
|
6073
|
+
recordSensor,
|
|
5671
6074
|
resolveTimeout,
|
|
5672
6075
|
schemas_exports as schemas,
|
|
5673
6076
|
security_exports as security,
|
|
@@ -5675,6 +6078,8 @@ export {
|
|
|
5675
6078
|
sensors_exports as sensors,
|
|
5676
6079
|
sha256,
|
|
5677
6080
|
signFrame,
|
|
6081
|
+
stableJsonStringify,
|
|
6082
|
+
startStage,
|
|
5678
6083
|
tlv,
|
|
5679
6084
|
u64be,
|
|
5680
6085
|
unpackPasskeyLoginOptionsReq,
|
|
@@ -5685,6 +6090,7 @@ export {
|
|
|
5685
6090
|
validateFrameShape,
|
|
5686
6091
|
varintLength,
|
|
5687
6092
|
varintU,
|
|
5688
|
-
verifyFrameSignature
|
|
6093
|
+
verifyFrameSignature,
|
|
6094
|
+
verifyResponse
|
|
5689
6095
|
};
|
|
5690
6096
|
//# sourceMappingURL=index.mjs.map
|