Skip to content

Commit 83c22b9

Browse files
authored
feat: add DID document (#202)
Serve a DID document for the gateway at `/.well-known/did.json`.
1 parent de07f48 commit 83c22b9

File tree

4 files changed

+70
-0
lines changed

4 files changed

+70
-0
lines changed

src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
withDelegationStubs,
2828
withOptionsRequest,
2929
withCarParkFetch,
30+
withDidDocumentHandler,
3031
withFormatRawHandler,
3132
withFormatCarHandler
3233
} from './middleware/index.js'
@@ -50,6 +51,7 @@ const middleware = composeMiddleware(
5051
withVersionHeader,
5152
withErrorHandler,
5253
withGatewayIdentity,
54+
withDidDocumentHandler,
5355
withDelegationsStorage,
5456

5557
// Handle UCAN invocations (POST requests only)

src/middleware/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export { withEgressTracker } from './withEgressTracker.js'
1111
export { withFormatCarHandler } from './withFormatCarHandler.js'
1212
export { withFormatRawHandler } from './withFormatRawHandler.js'
1313
export { withDelegationStubs } from './withDelegationStubs.js'
14+
export { withDidDocumentHandler } from './withDidDocumentHandler.js'
1415
export { withGatewayIdentity } from './withGatewayIdentity.js'
1516
export { withUcanInvocationHandler } from './withUcanInvocationHandler.js'
1617
export { withDelegationsStorage } from './withDelegationsStorage.js'
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* @import { Middleware, Environment } from '@web3-storage/gateway-lib'
3+
* @import { GatewayIdentityContext } from './withGatewayIdentity.types.js'
4+
*/
5+
6+
/**
7+
* Handles a GET request for `/.well-known/did.json` and passes on all other
8+
* requests to the next handler in the chain.
9+
*
10+
* @type {Middleware<GatewayIdentityContext, GatewayIdentityContext, Environment>}
11+
*/
12+
export function withDidDocumentHandler (handler) {
13+
return async (request, env, ctx) => {
14+
if (request.method !== 'GET' || new URL(request.url).pathname !== '/.well-known/did.json') {
15+
return handler(request, env, ctx)
16+
}
17+
18+
const webKey = ctx.gatewayIdentity.did()
19+
const publicKeyMultibase = ctx.gatewaySigner.did().replace('did:key:', '')
20+
const verificationMethods = [
21+
{
22+
id: `${webKey}#owner`,
23+
type: 'Ed25519VerificationKey2020',
24+
controller: webKey,
25+
publicKeyMultibase
26+
}
27+
]
28+
29+
const headers = { 'Content-Type': 'application/json' }
30+
const body = JSON.stringify({
31+
'@context': ['https://w3id.org/did/v1'],
32+
id: webKey,
33+
verificationMethod: verificationMethods,
34+
assertionMethod: verificationMethods.map(k => k.id),
35+
authentication: verificationMethods.map(k => k.id)
36+
}, null, 2)
37+
38+
return new Response(body, { headers })
39+
}
40+
}

test/miniflare/freeway.spec.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ describe('freeway', () => {
6767
CONTENT_CLAIMS_SERVICE_URL: claimsService.url.toString(),
6868
CARPARK_PUBLIC_BUCKET_URL: url.toString(),
6969
GATEWAY_SERVICE_DID: 'did:example:gateway',
70+
// did:key:z6MkvB4hvuVZhkKsi67rUKtNTKN4gpWjvWCoGPpBpGUdJMpF
71+
GATEWAY_PRINCIPAL_KEY: 'MgCatBcQ1htL3Q/kXNZ9idtpoP9EeFxUSXD106hMWXc8si+0B6ZTgeQlqgoY9Z21skaKK6FpFRAAEF50T1c9WhWTa14w=',
7072
DAGPB_CONTENT_CACHE: 'DAGPB_CONTENT_CACHE',
7173
FF_DAGPB_CONTENT_CACHE_ENABLED: 'true',
7274
FF_DAGPB_CONTENT_CACHE_TTL_SECONDS: 300,
@@ -763,4 +765,29 @@ describe('freeway', () => {
763765
assertBlobEqual(input, await res.blob())
764766
assert.equal(cachedContent.keys.length, 0, 'Cache should be empty')
765767
})
768+
769+
it('should return DID document', async () => {
770+
const res = await miniflare.dispatchFetch(
771+
'http://localhost:8787/.well-known/did.json'
772+
)
773+
assert(res.ok)
774+
const didDoc = await res.json()
775+
776+
assert(didDoc)
777+
assert(typeof didDoc === 'object')
778+
779+
assert('id' in didDoc)
780+
assert.equal(didDoc.id, 'did:example:gateway')
781+
782+
assert('verificationMethod' in didDoc)
783+
assert(Array.isArray(didDoc.verificationMethod))
784+
assert(didDoc.verificationMethod.length === 1)
785+
786+
const method = didDoc.verificationMethod[0]
787+
assert('publicKeyMultibase' in method)
788+
assert.equal(
789+
method.publicKeyMultibase,
790+
'z6MkvB4hvuVZhkKsi67rUKtNTKN4gpWjvWCoGPpBpGUdJMpF'
791+
)
792+
})
766793
})

0 commit comments

Comments
 (0)