-
Notifications
You must be signed in to change notification settings - Fork 5
/
utils.ts
94 lines (74 loc) · 2.71 KB
/
utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import {
decode as _fromBase64Url,
encode as _toBase64Url,
} from '@cfworker/base64url';
export { decode as cborDecode } from 'cbor-x/decode';
const encoder = new TextEncoder();
const decoder = new TextDecoder();
export const encode = encoder.encode.bind(encoder);
export const decode = decoder.decode.bind(decoder);
export const byteStringToBuffer = (byteString: string) =>
Uint8Array.from(byteString, (e) => e.charCodeAt(0)).buffer;
export const bufferToByteString = (buffer: ArrayBuffer) =>
String.fromCharCode(...new Uint8Array(buffer));
export const toBase64Url = _toBase64Url;
export const fromBase64Url = _fromBase64Url;
export const marshal = (data: object) => toBase64Url(JSON.stringify(data));
export const unmarshal = (data: string) => JSON.parse(fromBase64Url(data));
export const safeDecode = (data: string): Uint8Array => encode(fromBase64Url(data));
export const safeEncode = (data: ArrayBuffer): string => toBase64Url(decode(data));
export const safeByteDecode = (data: string): ArrayBufferLike =>
byteStringToBuffer(fromBase64Url(data));
export const safeByteEncode = (data: ArrayBuffer): string =>
toBase64Url(bufferToByteString(data));
export function concatBuffer(...buffers: ArrayBuffer[]) {
const length = buffers.reduce((acc, b) => acc + b.byteLength, 0);
const tmp = new Uint8Array(length);
let prev = 0;
for (let buffer of buffers) {
tmp.set(new Uint8Array(buffer), prev);
prev += buffer.byteLength;
}
return tmp.buffer;
}
export function isBiggerBuffer(a: ArrayBuffer, b: ArrayBuffer) {
const dvA = new DataView(a);
const dvB = new DataView(b);
if (dvA.byteLength > dvB.byteLength) {
return true;
}
for (let i = 0; i < dvA.byteLength; i++) {
if (dvA.getUint8(i) > dvB.getUint8(i)) {
return true;
}
}
return false;
}
export function isEqualBuffer(a: ArrayBuffer, b: ArrayBuffer) {
const dvA = new DataView(a);
const dvB = new DataView(b);
if (dvA.byteLength !== dvB.byteLength) {
return false;
}
for (let i = 0; i < dvA.byteLength; i++) {
if (dvA.getUint8(i) !== dvB.getUint8(i)) {
return false;
}
}
return true;
}
export const PasskeySignCounter = new Uint8Array([0, 0, 0, 0]).buffer;
export function isValidSignCounter(current: ArrayBuffer, next: ArrayBuffer) {
if (
isEqualBuffer(current, PasskeySignCounter) &&
isEqualBuffer(next, PasskeySignCounter)
) {
return true;
}
return isBiggerBuffer(next, current);
}
const UUID_V4_REGEX =
/^[0-9A-F]{8}-[0-9A-F]{4}-[4][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i;
export function isUUIDv4(uuid: string) {
return UUID_V4_REGEX.test(uuid);
}