dacument 1.0.1 → 1.2.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 +50 -5
- package/dist/Dacument/acl.d.ts +1 -0
- package/dist/Dacument/acl.js +13 -0
- package/dist/Dacument/class.d.ts +42 -4
- package/dist/Dacument/class.js +577 -74
- package/dist/Dacument/crypto.d.ts +3 -0
- package/dist/Dacument/crypto.js +25 -1
- package/dist/Dacument/types.d.ts +43 -1
- package/package.json +2 -2
|
@@ -23,4 +23,7 @@ export declare function verifyToken(publicJwk: JsonWebKey, token: string, expect
|
|
|
23
23
|
header: SignedHeader;
|
|
24
24
|
payload: unknown;
|
|
25
25
|
} | false>;
|
|
26
|
+
export declare function validateActorKeyPair(privateJwk: JsonWebKey, publicJwk: JsonWebKey): Promise<void>;
|
|
27
|
+
export declare function signDetached(privateJwk: JsonWebKey, payload: string): Promise<string>;
|
|
28
|
+
export declare function verifyDetached(publicJwk: JsonWebKey, payload: string, signatureB64: string): Promise<boolean>;
|
|
26
29
|
export {};
|
package/dist/Dacument/crypto.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Bytes } from "bytecodec";
|
|
2
2
|
import { SigningAgent, VerificationAgent } from "zeyra";
|
|
3
|
+
const ACTOR_CHALLENGE = Bytes.fromString("dacument-actor-verify");
|
|
3
4
|
function stableStringify(value) {
|
|
4
5
|
if (value === null || typeof value !== "object")
|
|
5
6
|
return JSON.stringify(value);
|
|
@@ -16,6 +17,11 @@ function decodePart(part) {
|
|
|
16
17
|
const json = Bytes.toString(bytes);
|
|
17
18
|
return JSON.parse(json);
|
|
18
19
|
}
|
|
20
|
+
function toArrayBuffer(bytes) {
|
|
21
|
+
const buffer = new ArrayBuffer(bytes.byteLength);
|
|
22
|
+
new Uint8Array(buffer).set(bytes);
|
|
23
|
+
return buffer;
|
|
24
|
+
}
|
|
19
25
|
export async function signToken(privateJwk, header, payload) {
|
|
20
26
|
const headerJson = stableStringify(header);
|
|
21
27
|
const payloadJson = stableStringify(payload);
|
|
@@ -59,6 +65,24 @@ export async function verifyToken(publicJwk, token, expectedTyp) {
|
|
|
59
65
|
const verifier = new VerificationAgent(publicJwk);
|
|
60
66
|
const signingInput = Bytes.fromString(`${headerB64}.${payloadB64}`);
|
|
61
67
|
const signatureBytes = new Uint8Array(signature);
|
|
62
|
-
const ok = await verifier.verify(signingInput, signatureBytes
|
|
68
|
+
const ok = await verifier.verify(signingInput, toArrayBuffer(signatureBytes));
|
|
63
69
|
return ok ? { header, payload } : false;
|
|
64
70
|
}
|
|
71
|
+
export async function validateActorKeyPair(privateJwk, publicJwk) {
|
|
72
|
+
const signer = new SigningAgent(privateJwk);
|
|
73
|
+
const signatureBytes = new Uint8Array(await signer.sign(ACTOR_CHALLENGE));
|
|
74
|
+
const verifier = new VerificationAgent(publicJwk);
|
|
75
|
+
const ok = await verifier.verify(ACTOR_CHALLENGE, toArrayBuffer(signatureBytes));
|
|
76
|
+
if (!ok)
|
|
77
|
+
throw new Error("Dacument.setActorInfo: publicKeyJwk does not match privateKeyJwk");
|
|
78
|
+
}
|
|
79
|
+
export async function signDetached(privateJwk, payload) {
|
|
80
|
+
const signer = new SigningAgent(privateJwk);
|
|
81
|
+
const signature = await signer.sign(Bytes.fromString(payload));
|
|
82
|
+
return Bytes.toBase64UrlString(signature);
|
|
83
|
+
}
|
|
84
|
+
export async function verifyDetached(publicJwk, payload, signatureB64) {
|
|
85
|
+
const verifier = new VerificationAgent(publicJwk);
|
|
86
|
+
const signatureBytes = Bytes.fromBase64UrlString(signatureB64);
|
|
87
|
+
return verifier.verify(Bytes.fromString(payload), toArrayBuffer(signatureBytes));
|
|
88
|
+
}
|
package/dist/Dacument/types.d.ts
CHANGED
|
@@ -27,6 +27,11 @@ export type RolePublicKeys = {
|
|
|
27
27
|
manager: JsonWebKey;
|
|
28
28
|
editor: JsonWebKey;
|
|
29
29
|
};
|
|
30
|
+
export type ActorInfo = {
|
|
31
|
+
id: string;
|
|
32
|
+
privateKeyJwk: JsonWebKey;
|
|
33
|
+
publicKeyJwk: JsonWebKey;
|
|
34
|
+
};
|
|
30
35
|
export type RegisterSchema<T extends JsTypeName = JsTypeName> = {
|
|
31
36
|
crdt: "register";
|
|
32
37
|
jsType: T;
|
|
@@ -64,7 +69,7 @@ export type RecordSchema<T extends JsTypeName = JsTypeName> = {
|
|
|
64
69
|
export type FieldSchema = RegisterSchema | TextSchema | ArraySchema | SetSchema | MapSchema | RecordSchema;
|
|
65
70
|
export type SchemaDefinition = Record<string, FieldSchema>;
|
|
66
71
|
export type SchemaId = string;
|
|
67
|
-
export type OpKind = "acl.set" | "register.set" | "text.patch" | "array.patch" | "map.patch" | "set.patch" | "record.patch" | "ack";
|
|
72
|
+
export type OpKind = "acl.set" | "register.set" | "text.patch" | "array.patch" | "map.patch" | "set.patch" | "record.patch" | "ack" | "reset";
|
|
68
73
|
export type OpPayload = {
|
|
69
74
|
iss: string;
|
|
70
75
|
sub: string;
|
|
@@ -77,6 +82,17 @@ export type OpPayload = {
|
|
|
77
82
|
};
|
|
78
83
|
export type SignedOp = {
|
|
79
84
|
token: string;
|
|
85
|
+
actorSig?: string;
|
|
86
|
+
};
|
|
87
|
+
export type ResetPatch = {
|
|
88
|
+
newDocId: string;
|
|
89
|
+
reason?: string;
|
|
90
|
+
};
|
|
91
|
+
export type ResetState = {
|
|
92
|
+
ts: HLCStamp;
|
|
93
|
+
by: string;
|
|
94
|
+
newDocId: string;
|
|
95
|
+
reason?: string;
|
|
80
96
|
};
|
|
81
97
|
export type DacumentChangeEvent = {
|
|
82
98
|
type: "change";
|
|
@@ -100,11 +116,20 @@ export type DacumentRevokedEvent = {
|
|
|
100
116
|
by: string;
|
|
101
117
|
stamp: HLCStamp;
|
|
102
118
|
};
|
|
119
|
+
export type DacumentResetEvent = {
|
|
120
|
+
type: "reset";
|
|
121
|
+
oldDocId: string;
|
|
122
|
+
newDocId: string;
|
|
123
|
+
ts: HLCStamp;
|
|
124
|
+
by: string;
|
|
125
|
+
reason?: string;
|
|
126
|
+
};
|
|
103
127
|
export type DacumentEventMap = {
|
|
104
128
|
change: DacumentChangeEvent;
|
|
105
129
|
merge: DacumentMergeEvent;
|
|
106
130
|
error: DacumentErrorEvent;
|
|
107
131
|
revoked: DacumentRevokedEvent;
|
|
132
|
+
reset: DacumentResetEvent;
|
|
108
133
|
};
|
|
109
134
|
export type AclAssignment = {
|
|
110
135
|
id: string;
|
|
@@ -112,6 +137,23 @@ export type AclAssignment = {
|
|
|
112
137
|
role: Role;
|
|
113
138
|
stamp: HLCStamp;
|
|
114
139
|
by: string;
|
|
140
|
+
publicKeyJwk?: JsonWebKey;
|
|
141
|
+
};
|
|
142
|
+
export type VerifyActorIntegrityOptions = {
|
|
143
|
+
token?: string | SignedOp;
|
|
144
|
+
ops?: Array<string | SignedOp>;
|
|
145
|
+
snapshot?: DocSnapshot;
|
|
146
|
+
};
|
|
147
|
+
export type VerificationFailure = {
|
|
148
|
+
index: number;
|
|
149
|
+
reason: string;
|
|
150
|
+
};
|
|
151
|
+
export type VerificationResult = {
|
|
152
|
+
ok: boolean;
|
|
153
|
+
verified: number;
|
|
154
|
+
failed: number;
|
|
155
|
+
missing: number;
|
|
156
|
+
failures: VerificationFailure[];
|
|
115
157
|
};
|
|
116
158
|
export type DocSnapshot = {
|
|
117
159
|
docId: string;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dacument",
|
|
3
|
-
"version": "1.0
|
|
4
|
-
"description": "Schema-driven CRDT document with signed ops
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "Schema-driven CRDT document with signed ops, role-based ACLs, and optional per-actor verification.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"crdt",
|
|
7
7
|
"document",
|