@absolutejs/auth 0.27.0-beta.7 → 0.27.0-beta.8
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/audit/integrity.d.ts +5 -1
- package/dist/index.js +31 -8
- package/dist/index.js.map +3 -3
- package/package.json +1 -1
|
@@ -2,14 +2,18 @@ import type { AuditEvent, AuditSink } from './types';
|
|
|
2
2
|
export type AuditIntegrity = {
|
|
3
3
|
hash: string;
|
|
4
4
|
previousHash: string;
|
|
5
|
+
writerId?: string;
|
|
5
6
|
};
|
|
6
7
|
export type AuditChainResult = {
|
|
7
8
|
brokenAt?: number;
|
|
8
9
|
ok: boolean;
|
|
9
10
|
};
|
|
10
|
-
export declare const createTamperEvidentSink: ({ secret, sink }: {
|
|
11
|
+
export declare const createTamperEvidentSink: ({ loadWriterHead, secret, seedScanLimit, sink, writerId }: {
|
|
12
|
+
loadWriterHead?: (writerId: string) => Promise<string | undefined> | string | undefined;
|
|
11
13
|
secret?: string;
|
|
14
|
+
seedScanLimit?: number;
|
|
12
15
|
sink: AuditSink;
|
|
16
|
+
writerId?: string;
|
|
13
17
|
}) => AuditSink;
|
|
14
18
|
export declare const hashAuditEvent: (event: AuditEvent, previousHash: string, secret?: string) => Promise<string>;
|
|
15
19
|
export declare const verifyAuditChain: (events: AuditEvent[], secret?: string) => Promise<AuditChainResult>;
|
package/dist/index.js
CHANGED
|
@@ -18710,6 +18710,7 @@ var INTEGRITY_KEY = "__integrity";
|
|
|
18710
18710
|
var GENESIS = "";
|
|
18711
18711
|
var HEX_RADIX2 = 16;
|
|
18712
18712
|
var HEX_PAD = 2;
|
|
18713
|
+
var DEFAULT_SEED_SCAN_LIMIT = 1000;
|
|
18713
18714
|
var encoder = new TextEncoder;
|
|
18714
18715
|
var toHex = (buffer) => [...new Uint8Array(buffer)].map((byte) => byte.toString(HEX_RADIX2).padStart(HEX_PAD, "0")).join("");
|
|
18715
18716
|
var sha256Hex = async (message) => toHex(await crypto.subtle.digest("SHA-256", encoder.encode(message)));
|
|
@@ -18740,15 +18741,31 @@ var brokenAt = (index) => {
|
|
|
18740
18741
|
return result;
|
|
18741
18742
|
};
|
|
18742
18743
|
var createTamperEvidentSink = ({
|
|
18744
|
+
loadWriterHead,
|
|
18743
18745
|
secret,
|
|
18744
|
-
|
|
18746
|
+
seedScanLimit = DEFAULT_SEED_SCAN_LIMIT,
|
|
18747
|
+
sink,
|
|
18748
|
+
writerId
|
|
18745
18749
|
}) => {
|
|
18750
|
+
const chainWriterId = writerId ?? crypto.randomUUID();
|
|
18751
|
+
const isResuming = writerId !== undefined;
|
|
18746
18752
|
let lastHash;
|
|
18753
|
+
let seeded = false;
|
|
18747
18754
|
const seed = async () => {
|
|
18748
|
-
if (
|
|
18755
|
+
if (seeded)
|
|
18749
18756
|
return;
|
|
18750
|
-
|
|
18751
|
-
|
|
18757
|
+
seeded = true;
|
|
18758
|
+
if (!isResuming) {
|
|
18759
|
+
lastHash = GENESIS;
|
|
18760
|
+
return;
|
|
18761
|
+
}
|
|
18762
|
+
if (loadWriterHead) {
|
|
18763
|
+
lastHash = await loadWriterHead(chainWriterId) ?? GENESIS;
|
|
18764
|
+
return;
|
|
18765
|
+
}
|
|
18766
|
+
const recent = await sink.list?.({ limit: seedScanLimit }) ?? [];
|
|
18767
|
+
const head = recent.find((event) => readIntegrity(event)?.writerId === chainWriterId);
|
|
18768
|
+
lastHash = head ? readIntegrity(head)?.hash ?? GENESIS : GENESIS;
|
|
18752
18769
|
};
|
|
18753
18770
|
return {
|
|
18754
18771
|
list: sink.list,
|
|
@@ -18757,7 +18774,11 @@ var createTamperEvidentSink = ({
|
|
|
18757
18774
|
const previousHash = lastHash ?? GENESIS;
|
|
18758
18775
|
const hash = await hashAuditEvent(event, previousHash, secret);
|
|
18759
18776
|
lastHash = hash;
|
|
18760
|
-
const integrity = {
|
|
18777
|
+
const integrity = {
|
|
18778
|
+
hash,
|
|
18779
|
+
previousHash,
|
|
18780
|
+
writerId: chainWriterId
|
|
18781
|
+
};
|
|
18761
18782
|
await sink.append({
|
|
18762
18783
|
...event,
|
|
18763
18784
|
metadata: { ...event.metadata, [INTEGRITY_KEY]: integrity }
|
|
@@ -18773,17 +18794,19 @@ var hashAuditEvent = async (event, previousHash, secret) => {
|
|
|
18773
18794
|
return secret === undefined ? sha256Hex(message) : hmacSha256Hex(secret, message);
|
|
18774
18795
|
};
|
|
18775
18796
|
var verifyAuditChain = async (events, secret) => {
|
|
18776
|
-
|
|
18797
|
+
const heads = new Map;
|
|
18777
18798
|
for (let index = 0;index < events.length; index += 1) {
|
|
18778
18799
|
const event = events[index];
|
|
18779
18800
|
if (event === undefined)
|
|
18780
18801
|
return brokenAt(index);
|
|
18781
18802
|
const integrity = readIntegrity(event);
|
|
18803
|
+
const chain = integrity?.writerId ?? GENESIS;
|
|
18804
|
+
const previousHash = heads.get(chain) ?? GENESIS;
|
|
18782
18805
|
const expected = await hashAuditEvent(event, previousHash, secret);
|
|
18783
18806
|
if (integrity === undefined || integrity.previousHash !== previousHash || integrity.hash !== expected) {
|
|
18784
18807
|
return brokenAt(index);
|
|
18785
18808
|
}
|
|
18786
|
-
|
|
18809
|
+
heads.set(chain, integrity.hash);
|
|
18787
18810
|
}
|
|
18788
18811
|
const valid = { ok: true };
|
|
18789
18812
|
return valid;
|
|
@@ -20976,5 +20999,5 @@ export {
|
|
|
20976
20999
|
AuthIdentityConflictError
|
|
20977
21000
|
};
|
|
20978
21001
|
|
|
20979
|
-
//# debugId=
|
|
21002
|
+
//# debugId=B234E4311897F15C64756E2164756E21
|
|
20980
21003
|
//# sourceMappingURL=index.js.map
|