@pamoja/audit 0.1.15 → 0.1.16

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.
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Ergonomic facade over the generated audit binding.
3
+ *
4
+ * A log that can be edited after the fact proves nothing. Each record here is
5
+ * signed and carries the hash of the one before it, so altering a record,
6
+ * dropping one, or reordering two breaks the chain at that point and at every
7
+ * point after it. The index is part of what is signed, which is what makes a
8
+ * record removed from the end detectable too.
9
+ *
10
+ * @packageDocumentation
11
+ */
12
+ import { AuditEntry } from '@pamoja/native';
13
+ import { DeviceIdentity } from '@pamoja/security';
14
+ export { AuditEntry, AuditVerifier } from '@pamoja/native';
15
+ /** A log that signs what it is given and chains it onto what came before. */
16
+ export declare class AuditLog {
17
+ #private;
18
+ /**
19
+ * Creates a log that signs with a device identity.
20
+ *
21
+ * @param identity - The identity whose signature each record will carry.
22
+ * @param last - The final record of an existing log to carry on from, or
23
+ * omitted to start empty.
24
+ */
25
+ constructor(identity: DeviceIdentity, last?: AuditEntry);
26
+ /**
27
+ * Creates a log that carries on from the last record an earlier one wrote.
28
+ *
29
+ * This is what a device does after a restart: the chain continues at the next
30
+ * index and hashes onto the record it left off at, so a reboot leaves no gap
31
+ * for a record to be removed through.
32
+ *
33
+ * @param identity - The identity whose signature each record will carry.
34
+ * @param last - The final record of the existing log.
35
+ */
36
+ static resume(identity: DeviceIdentity, last: AuditEntry): AuditLog;
37
+ /**
38
+ * Appends a payload, signing it and chaining it onto the last record.
39
+ *
40
+ * @param payload - The record to store.
41
+ * @returns The new entry.
42
+ */
43
+ append(payload: Uint8Array): AuditEntry;
44
+ }
45
+ /**
46
+ * Checks a whole chain that has already arrived.
47
+ *
48
+ * @param publicKey - The 32-byte key the records were signed with.
49
+ * @param entries - The records, in the order they were written.
50
+ * @throws With the reason the chain does not hold: a record whose signature
51
+ * fails, or one that does not follow the record before it.
52
+ */
53
+ export declare function verifyChain(publicKey: Uint8Array, entries: AuditEntry[]): void;
package/dist/index.js ADDED
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ /**
3
+ * Ergonomic facade over the generated audit binding.
4
+ *
5
+ * A log that can be edited after the fact proves nothing. Each record here is
6
+ * signed and carries the hash of the one before it, so altering a record,
7
+ * dropping one, or reordering two breaks the chain at that point and at every
8
+ * point after it. The index is part of what is signed, which is what makes a
9
+ * record removed from the end detectable too.
10
+ *
11
+ * @packageDocumentation
12
+ */
13
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
14
+ if (kind === "m") throw new TypeError("Private method is not writable");
15
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
16
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
17
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
18
+ };
19
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
20
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
21
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
22
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
23
+ };
24
+ var _AuditLog_inner;
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.AuditLog = exports.AuditVerifier = exports.AuditEntry = void 0;
27
+ exports.verifyChain = verifyChain;
28
+ const native_1 = require("@pamoja/native");
29
+ const security_1 = require("@pamoja/security");
30
+ var native_2 = require("@pamoja/native");
31
+ Object.defineProperty(exports, "AuditEntry", { enumerable: true, get: function () { return native_2.AuditEntry; } });
32
+ Object.defineProperty(exports, "AuditVerifier", { enumerable: true, get: function () { return native_2.AuditVerifier; } });
33
+ /** A log that signs what it is given and chains it onto what came before. */
34
+ class AuditLog {
35
+ /**
36
+ * Creates a log that signs with a device identity.
37
+ *
38
+ * @param identity - The identity whose signature each record will carry.
39
+ * @param last - The final record of an existing log to carry on from, or
40
+ * omitted to start empty.
41
+ */
42
+ constructor(identity, last) {
43
+ _AuditLog_inner.set(this, void 0);
44
+ const signer = security_1.DeviceIdentity.native(identity);
45
+ __classPrivateFieldSet(this, _AuditLog_inner, last === undefined ? new native_1.AuditLog(signer) : native_1.AuditLog.resume(signer, last), "f");
46
+ }
47
+ /**
48
+ * Creates a log that carries on from the last record an earlier one wrote.
49
+ *
50
+ * This is what a device does after a restart: the chain continues at the next
51
+ * index and hashes onto the record it left off at, so a reboot leaves no gap
52
+ * for a record to be removed through.
53
+ *
54
+ * @param identity - The identity whose signature each record will carry.
55
+ * @param last - The final record of the existing log.
56
+ */
57
+ static resume(identity, last) {
58
+ return new AuditLog(identity, last);
59
+ }
60
+ /**
61
+ * Appends a payload, signing it and chaining it onto the last record.
62
+ *
63
+ * @param payload - The record to store.
64
+ * @returns The new entry.
65
+ */
66
+ append(payload) {
67
+ return __classPrivateFieldGet(this, _AuditLog_inner, "f").append(Buffer.from(payload));
68
+ }
69
+ }
70
+ exports.AuditLog = AuditLog;
71
+ _AuditLog_inner = new WeakMap();
72
+ /**
73
+ * Checks a whole chain that has already arrived.
74
+ *
75
+ * @param publicKey - The 32-byte key the records were signed with.
76
+ * @param entries - The records, in the order they were written.
77
+ * @throws With the reason the chain does not hold: a record whose signature
78
+ * fails, or one that does not follow the record before it.
79
+ */
80
+ function verifyChain(publicKey, entries) {
81
+ (0, native_1.verifyAuditChain)(Buffer.from(publicKey), entries);
82
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pamoja/audit",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "A tamper-evident, hash-chained log; altering, reordering, or dropping a record breaks verification.",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -34,7 +34,7 @@
34
34
  "node": ">= 16"
35
35
  },
36
36
  "dependencies": {
37
- "@pamoja/native": "0.1.15",
38
- "@pamoja/security": "0.1.15"
37
+ "@pamoja/native": "0.1.16",
38
+ "@pamoja/security": "0.1.16"
39
39
  }
40
40
  }