···
import { didForCreateOp, PlcClientError } from '@did-plc/lib'
describe('PLC server', () => {
9
-
let handle = 'at://alice.example.com'
9
+
let handle1 = 'at://alice.example.com'
10
+
let handle2 = 'at://bob.example.com'
let atpPds = 'https://example.com'
···
let signingKey: P256Keypair
let rotationKey1: P256Keypair
let rotationKey2: P256Keypair
20
+
let rotationKey3: P256Keypair
const server = await runTestServer({
···
signingKey = await P256Keypair.create()
rotationKey1 = await P256Keypair.create()
rotationKey2 = await P256Keypair.create()
36
+
rotationKey3 = await P256Keypair.create()
···
throw new Error('expected doc')
45
-
expect(doc.did).toEqual(did)
49
+
expect(doc.did).toEqual(did1)
expect(doc.verificationMethods).toEqual({ atproto: signingKey.did() })
expect(doc.rotationKeys).toEqual([rotationKey1.did(), rotationKey2.did()])
48
-
expect(doc.alsoKnownAs).toEqual([handle])
52
+
expect(doc.alsoKnownAs).toEqual([handle1])
expect(doc.services).toEqual({
type: 'AtprotoPersonalDataServer',
···
it('registers a did', async () => {
58
-
did = await client.createDid({
62
+
did1 = await client.createDid({
signingKey: signingKey.did(),
rotationKeys: [rotationKey1.did(), rotationKey2.did()],
70
+
did2 = await client.createDid({
71
+
signingKey: signingKey.did(),
72
+
rotationKeys: [rotationKey3.did()],
75
+
signer: rotationKey3,
it('retrieves did doc data', async () => {
68
-
const doc = await client.getDocumentData(did)
80
+
const doc = await client.getDocumentData(did1)
it('can perform some updates', async () => {
const newRotationKey = await P256Keypair.create()
signingKey = await P256Keypair.create()
75
-
handle = 'at://ali.example2.com'
87
+
handle1 = 'at://ali.example2.com'
atpPds = 'https://example2.com'
78
-
await client.updateAtprotoKey(did, rotationKey1, signingKey.did())
79
-
await client.updateRotationKeys(did, rotationKey1, [
90
+
await client.updateAtprotoKey(did1, rotationKey1, signingKey.did())
91
+
await client.updateRotationKeys(did1, rotationKey1, [
rotationKey1 = newRotationKey
85
-
await client.updateHandle(did, rotationKey1, handle)
86
-
await client.updatePds(did, rotationKey1, atpPds)
97
+
await client.updateHandle(did1, rotationKey1, handle1)
98
+
await client.updatePds(did1, rotationKey1, atpPds)
88
-
const doc = await client.getDocumentData(did)
100
+
const doc = await client.getDocumentData(did1)
92
-
it('does not allow key types that we do not support', async () => {
93
-
// an ed25519 key which we don't yet support
104
+
it('does not allow *rotation* key types that we do not yet support', async () => {
105
+
// an ed25519 key, which we don't yet support
106
+
const newRotationKey =
107
+
'did:key:z6MkjwbBXZnFqL8su24wGL2Fdjti6GSLv9SWdYGswfazUPm9'
109
+
const promise = client.updateRotationKeys(did2, rotationKey3, [
110
+
rotationKey2.did(),
113
+
await expect(promise).rejects.toThrow(PlcClientError)
116
+
it('allows *verificationMethod* key types that we do not explicitly support', async () => {
117
+
// an ed25519 key, which we don't explicitly support
'did:key:z6MkjwbBXZnFqL8su24wGL2Fdjti6GSLv9SWdYGswfazUPm9'
97
-
const promise = client.updateAtprotoKey(did, rotationKey1, newSigningKey)
98
-
await expect(promise).rejects.toThrow(PlcClientError)
121
+
// Note: atproto itself does not currently support ed25519 keys, but PLC
122
+
// does not have opinions about atproto (or other services!)
123
+
await client.updateAtprotoKey(did2, rotationKey3, newSigningKey)
100
-
const promise2 = client.updateRotationKeys(did, rotationKey1, [
126
+
const exoticSigningKeyFromTheFuture =
127
+
'did:key:zUC7K4ndUaGZgV7Cp2yJy6JtMoUHY6u7tkcSYUvPrEidqBmLCTLmi6d5WvwnUqejscAkERJ3bfjEiSYtdPkRSE8kSa11hFBr4sTgnbZ95SJj19PN2jdvJjyzpSZgxkyyxNnBNnY'
128
+
await client.updateAtprotoKey(
131
+
exoticSigningKeyFromTheFuture,
134
+
// check that we can still read back the rendered did document
135
+
const doc = await client.getDocument(did2)
136
+
expect(doc.verificationMethod).toEqual([
138
+
id: did2 + '#atproto',
141
+
publicKeyMultibase: exoticSigningKeyFromTheFuture.slice(8),
146
+
it('does not allow syntactically invalid verificationMethod keys', async () => {
147
+
const promise1 = client.updateAtprotoKey(
150
+
'did:key:BJV2WY5DJMJQXGZJANFZSAYLXMVZW63LFEEQFY3ZP', // not b58 (b32!)
152
+
await expect(promise1).rejects.toThrow(PlcClientError)
153
+
const promise2 = client.updateAtprotoKey(
156
+
'did:banana', // a malformed did:key
await expect(promise2).rejects.toThrow(PlcClientError)
159
+
const promise3 = client.updateAtprotoKey(
162
+
'blah', // an even more malformed did:key
164
+
await expect(promise3).rejects.toThrow(PlcClientError)
167
+
it('does not allow unreasonably long verificationMethod keys', async () => {
168
+
const promise = client.updateAtprotoKey(
171
+
'did:key:z41vu8qtWtp8XRJ9Te5QhkyzU9ByBbiw7bZHKXDjZ8iYorixqZQmEZpxgVSteYirYWMBjqQuEbMYTDsCzXXCAanCSH2xG2cwpbCWGZ2coY2PnhbrDVo7QghsAHpm2X5zsRRwDLyUcm9MTNQAZuRs2B22ygQw3UwkKLA7PZ9ZQ9wMHppmkoaBapmUGaxRNjp1Mt4zxrm9RbEx8FiK3ANBL1fsjggNqvkKpbj6MjntRScPQnJCes9Vt1cFe3iwNP7Ya9RfbaKsVi1eothvSBcbWoouHActGeakHgqFLj1JpbkP7PL3hGGSWLQbXxzmdrfzBCYAtiUxGRvpf3JiaNA2WYbJTh58bzx',
173
+
await expect(promise).rejects.toThrow(PlcClientError)
it('retrieves the operation log', async () => {
107
-
const doc = await client.getDocumentData(did)
108
-
const ops = await client.getOperationLog(did)
109
-
const computedDoc = await plc.validateOperationLog(did, ops)
177
+
const doc = await client.getDocumentData(did1)
178
+
const ops = await client.getOperationLog(did1)
179
+
const computedDoc = await plc.validateOperationLog(did1, ops)
expect(computedDoc).toEqual(doc)
it('rejects on bad updates', async () => {
const newKey = await P256Keypair.create()
115
-
const operation = client.updateAtprotoKey(did, newKey, newKey.did())
185
+
const operation = client.updateAtprotoKey(did1, newKey, newKey.did())
await expect(operation).rejects.toThrow()
it('allows for recovery through a forked history', async () => {
const attackerKey = await P256Keypair.create()
121
-
await client.updateRotationKeys(did, rotationKey2, [attackerKey.did()])
191
+
await client.updateRotationKeys(did1, rotationKey2, [attackerKey.did()])
const newKey = await P256Keypair.create()
124
-
const ops = await client.getOperationLog(did)
194
+
const ops = await client.getOperationLog(did1)
const forkPoint = ops.at(-2)
if (!check.is(forkPoint, plc.def.operation)) {
throw new Error('Could not find fork point')
···
133
-
await client.sendOperation(did, op)
203
+
await client.sendOperation(did1, op)
137
-
const doc = await client.getDocumentData(did)
207
+
const doc = await client.getDocumentData(did1)
it('retrieves the auditable operation log', async () => {
142
-
const log = await client.getOperationLog(did)
143
-
const auditable = await client.getAuditableLog(did)
212
+
const log = await client.getOperationLog(did1)
213
+
const auditable = await client.getAuditableLog(did1)
expect(auditable.length).toBe(log.length + 1)
expect(auditable.filter((op) => op.nullified).length).toBe(1)
···
it('retrieves the did doc', async () => {
154
-
const data = await client.getDocumentData(did)
155
-
const doc = await client.getDocument(did)
224
+
const data = await client.getDocumentData(did1)
225
+
const doc = await client.getDocument(did1)
expect(doc).toEqual(plc.formatDidDoc(data))
···
keys.map(async (key) => {
191
-
await client.updateAtprotoKey(did, rotationKey1, key.did())
261
+
await client.updateAtprotoKey(did1, rotationKey1, key.did())
···
expect(successes).toBe(1)
expect(failures).toBe(19)
201
-
const ops = await client.getOperationLog(did)
202
-
await plc.validateOperationLog(did, ops)
271
+
const ops = await client.getOperationLog(did1)
272
+
await plc.validateOperationLog(did1, ops)
it('tombstones the did', async () => {
206
-
await client.tombstone(did, rotationKey1)
276
+
await client.tombstone(did1, rotationKey1)
208
-
const promise = client.getDocument(did)
278
+
const promise = client.getDocument(did1)
await expect(promise).rejects.toThrow(PlcClientError)
210
-
const promise2 = client.getDocumentData(did)
280
+
const promise2 = client.getDocumentData(did1)
await expect(promise2).rejects.toThrow(PlcClientError)
it('exports the data set', async () => {
const data = await client.export()
expect(data.every((row) => check.is(row, plc.def.exportedOp))).toBeTruthy()
217
-
expect(data.length).toBe(29)
287
+
expect(data.length).toBe(32)
for (let i = 1; i < data.length; i++) {
expect(data[i].createdAt >= data[i - 1].createdAt).toBeTruthy()
···
signingKey: signingKey.did(),
recoveryKey: rotationKey1.did(),