atproto/packages/identity/tests/did-resolver.test.ts
bnewbold a280ae21e1
identifier tweaks (#1085)
* nsid: reduce 'name' length from 128 chars to 63 chars

* nsid: remove 'nsid-ns' (glob pattern) from main NSID syntax validation

This special variant syntax should be handled separately. Eg, an
"nsid-ns" should not be accepted as an NSID in Lexicons looking for a
regular NSID.

* nsid: update syntax check to match domain rules

This is to be closer to actual underlying specification needs. For
example, domains are allowed to start with a digit (like 4chan.org), and
can't start *or* end with a hyphen.

Restricts the "name" part further, to be alphabetic only.

Note that starts-with-digit domains could break some lang
auto-generation variable name rules. The docs/spec strongly recommend
against such domains for use with NSID, but it seems incorrect to
restrict at the standard/lexicon level without a clear pan-language
consistent set of rules.

* did-resolver: disallow did:web with path segments

* identifier: reduce max length of DID from 8 KB to 2 KB

* identifier: add DID test with escaped ':' in identifier

* did-resolver: have prettier run on tests/

* identifier: add additional punycode test cases

* identifiers: small tweaks from review

- type in did:web comment
- include actual max DID string length in error message

* xrpc-server tests: remove digits from NSIDs

* identity: fix import and function errors

* xrpc-server tests: remove digits from NSIDs

* xrpc-server: include tests/ in prettier:fix

* xrpc-server: lint fix
2023-05-31 16:56:08 -07:00

117 lines
3.5 KiB
TypeScript

import getPort from 'get-port'
import { Secp256k1Keypair } from '@atproto/crypto'
import * as plc from '@did-plc/lib'
import { Database as DidPlcDb, PlcServer } from '@did-plc/server'
import { DidResolver, DidDocument } from '../src'
import { DidWebServer } from './web/server'
import DidWebDb from './web/db'
describe('did resolver', () => {
let close: () => Promise<void>
let webServer: DidWebServer
let plcUrl: string
let resolver: DidResolver
beforeAll(async () => {
const webDb = DidWebDb.memory()
webServer = DidWebServer.create(webDb, await getPort())
await new Promise((resolve, reject) => {
webServer._httpServer?.on('listening', resolve)
webServer._httpServer?.on('error', reject)
})
const plcDB = DidPlcDb.mock()
const plcPort = await getPort()
const plcServer = PlcServer.create({ db: plcDB, port: plcPort })
await plcServer.start()
plcUrl = 'http://localhost:' + plcPort
resolver = new DidResolver({ plcUrl })
close = async () => {
await webServer.close()
await plcServer.destroy()
}
})
afterAll(async () => {
await close()
})
const handle = 'alice.test'
const pds = 'https://service.test'
let signingKey: Secp256k1Keypair
let rotationKey: Secp256k1Keypair
let webDid: string
let plcDid: string
let didWebDoc: DidDocument
let didPlcDoc: DidDocument
it('creates the did on did:web & did:plc', async () => {
signingKey = await Secp256k1Keypair.create()
rotationKey = await Secp256k1Keypair.create()
const client = new plc.Client(plcUrl)
plcDid = await client.createDid({
signingKey: signingKey.did(),
handle,
pds,
rotationKeys: [rotationKey.did()],
signer: rotationKey,
})
didPlcDoc = await client.getDocument(plcDid)
const domain = encodeURIComponent(`localhost:${webServer.port}`)
webDid = `did:web:${domain}`
didWebDoc = {
...didPlcDoc,
id: webDid,
}
await webServer.put(didWebDoc)
})
it('resolve valid did:web', async () => {
const didRes = await resolver.ensureResolve(webDid)
expect(didRes).toEqual(didWebDoc)
})
it('resolve valid atpData from did:web', async () => {
const atpData = await resolver.resolveAtprotoData(webDid)
expect(atpData.did).toEqual(webDid)
expect(atpData.handle).toEqual(handle)
expect(atpData.pds).toEqual(pds)
expect(atpData.signingKey).toEqual(signingKey.did())
expect(atpData.handle).toEqual(handle)
})
it('throws on malformed did:webs', async () => {
await expect(resolver.ensureResolve(`did:web:asdf`)).rejects.toThrow()
await expect(resolver.ensureResolve(`did:web:`)).rejects.toThrow()
await expect(resolver.ensureResolve(``)).rejects.toThrow()
})
it('throws on did:web with path components', async () => {
await expect(
resolver.ensureResolve(`did:web:example.com:u:bob`),
).rejects.toThrow()
})
it('resolve valid did:plc', async () => {
const didRes = await resolver.ensureResolve(plcDid)
expect(didRes).toEqual(didPlcDoc)
})
it('resolve valid atpData from did:plc', async () => {
const atpData = await resolver.resolveAtprotoData(plcDid)
expect(atpData.did).toEqual(plcDid)
expect(atpData.handle).toEqual(handle)
expect(atpData.pds).toEqual(pds)
expect(atpData.signingKey).toEqual(signingKey.did())
expect(atpData.handle).toEqual(handle)
})
it('throws on malformed did:plc', async () => {
await expect(resolver.ensureResolve(`did:plc:asdf`)).rejects.toThrow()
await expect(resolver.ensureResolve(`did:plc`)).rejects.toThrow()
})
})