Skip to content

Commit 2c7cb2b

Browse files
Andrew Bernatwolpert
authored andcommitted
Add buffer builder and tests.
The buffer builder is needed to help build a look-a-like [aka fake] authenticator type because it will be used to return cbor encoded data just like real web authentication data. The next PR will create a fake authenticator which implements the CredentialsContainer interface. Once the fake authenticotr exists then we can implement the simulated registration that implements start [already done] and finish. Finish is more complicated b/c it must decode the cbor encoded attestation provided by the fake authenticator.
1 parent e4b8a52 commit 2c7cb2b

2 files changed

Lines changed: 93 additions & 0 deletions

File tree

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// SPDX-License-Identifier: MIT
2+
import { describe, expect, it } from "vitest";
3+
import { BufferUint8 } from "./buffer";
4+
5+
describe("BufferUint8", () => {
6+
it("returns empty bytes when nothing is written", () => {
7+
const buf = new BufferUint8();
8+
expect(buf.bytes()).toEqual(new Uint8Array(0));
9+
});
10+
11+
it("set appends a Uint8Array", () => {
12+
const buf = new BufferUint8();
13+
buf.uint8array(new Uint8Array([1, 2, 3]));
14+
expect(buf.bytes()).toEqual(new Uint8Array([1, 2, 3]));
15+
});
16+
17+
it("uint8 appends a single byte", () => {
18+
const buf = new BufferUint8();
19+
buf.uint8(0x45);
20+
expect(buf.bytes()).toEqual(new Uint8Array([0x45]));
21+
});
22+
23+
it("uint16 appends two bytes big-endian", () => {
24+
const buf = new BufferUint8();
25+
buf.uint16(0x0102);
26+
expect(buf.bytes()).toEqual(new Uint8Array([0x01, 0x02]));
27+
});
28+
29+
it("skip appends zero bytes", () => {
30+
const buf = new BufferUint8();
31+
buf.uint8(0xAA).skip(2).uint8(0xBB);
32+
expect(buf.bytes()).toEqual(new Uint8Array([0xAA, 0x00, 0x00, 0xBB]));
33+
});
34+
35+
it("methods are chainable", () => {
36+
const data = new Uint8Array([10, 20]);
37+
const result = new BufferUint8()
38+
.uint8array(data)
39+
.uint8(0x45)
40+
.skip(4)
41+
.uint16(data.length)
42+
.uint8array(data)
43+
.bytes();
44+
45+
expect(result).toEqual(new Uint8Array([10, 20, 0x45, 0, 0, 0, 0, 0, 2, 10, 20]));
46+
});
47+
48+
it("bytes() can be called multiple times and returns equal results", () => {
49+
const buf = new BufferUint8().uint8(1).uint8(2);
50+
expect(buf.bytes()).toEqual(buf.bytes());
51+
});
52+
});
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// SPDX-License-Identifier: MIT
2+
export class BufferUint8 {
3+
private readonly chunks: Uint8Array[];
4+
5+
constructor() {
6+
this.chunks = [];
7+
}
8+
9+
uint8array(data: Uint8Array): this {
10+
this.chunks.push(data);
11+
return this;
12+
}
13+
14+
uint8(value: number): this {
15+
this.chunks.push(new Uint8Array([value]));
16+
return this;
17+
}
18+
19+
uint16(value: number): this {
20+
const buf = new Uint8Array(2);
21+
new DataView(buf.buffer).setUint16(0, value);
22+
this.chunks.push(buf);
23+
return this;
24+
}
25+
26+
skip(count: number): this {
27+
this.chunks.push(new Uint8Array(count));
28+
return this;
29+
}
30+
31+
bytes(): Uint8Array {
32+
const size = this.chunks.reduce((n, c) => n + c.length, 0);
33+
const out = new Uint8Array(size);
34+
let off = 0;
35+
for (const chunk of this.chunks) {
36+
out.set(chunk, off);
37+
off += chunk.length;
38+
}
39+
return out;
40+
}
41+
}

0 commit comments

Comments
 (0)