Skip to content

Commit 6b2e9d7

Browse files
committed
feat: add NIP-11 root response fields and CORS headers
1 parent 43155c1 commit 6b2e9d7

2 files changed

Lines changed: 37 additions & 1 deletion

File tree

src/handlers/request-handlers/root-request-handler.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export const rootRequestHandler = (request: Request, response: Response, next: N
1313

1414
if (accepts(request).type(['application/nostr+json'])) {
1515
const {
16-
info: { name, description, pubkey: rawPubkey, contact, relay_url },
16+
info: { name, description, banner, icon, pubkey: rawPubkey, self: rawSelf, contact, relay_url, terms_of_service },
1717
} = settings
1818

1919
const paymentsUrl = new URL(relay_url)
@@ -23,16 +23,21 @@ export const rootRequestHandler = (request: Request, response: Response, next: N
2323
const content = settings.limits?.event?.content
2424

2525
const pubkey = rawPubkey.startsWith('npub1') ? fromBech32(rawPubkey) : rawPubkey
26+
const self = rawSelf?.startsWith('npub1') ? fromBech32(rawSelf) : rawSelf
2627

2728
const relayInformationDocument = {
2829
name,
2930
description,
31+
banner,
32+
icon,
3033
pubkey,
34+
self,
3135
contact,
3236
supported_nips: packageJson.supportedNips,
3337
supported_nip_extensions: packageJson.supportedNipExtensions,
3438
software: packageJson.repository.url,
3539
version: packageJson.version,
40+
terms_of_service,
3641
limitation: {
3742
max_message_length: settings.network.maxPayloadSize,
3843
max_subscriptions: settings.limits?.client?.subscription?.maxSubscriptions,
@@ -68,6 +73,8 @@ export const rootRequestHandler = (request: Request, response: Response, next: N
6873
response
6974
.setHeader('content-type', 'application/nostr+json')
7075
.setHeader('access-control-allow-origin', '*')
76+
.setHeader('access-control-allow-headers', '*')
77+
.setHeader('access-control-allow-methods', 'GET, OPTIONS')
7178
.status(200)
7279
.send(relayInformationDocument)
7380

test/unit/handlers/request-handlers/root-request-handler.spec.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ describe('rootRequestHandler', () => {
8383
expect(res.status).to.have.been.calledWith(200)
8484
})
8585

86+
it('sets required NIP-11 CORS headers', () => {
87+
rootRequestHandler(req, res, next)
88+
89+
expect(res.setHeader).to.have.been.calledWith('access-control-allow-origin', '*')
90+
expect(res.setHeader).to.have.been.calledWith('access-control-allow-headers', '*')
91+
expect(res.setHeader).to.have.been.calledWith('access-control-allow-methods', 'GET, OPTIONS')
92+
})
93+
8694
it('includes the relay name in the response', () => {
8795
rootRequestHandler(req, res, next)
8896

@@ -95,6 +103,27 @@ describe('rootRequestHandler', () => {
95103

96104
expect(getTemplateStub).to.not.have.been.called
97105
})
106+
107+
it('includes optional NIP-11 fields when configured', () => {
108+
createSettingsStub.returns({
109+
...baseSettings,
110+
info: {
111+
...baseSettings.info,
112+
banner: 'https://relay.example.com/banner.png',
113+
icon: 'https://relay.example.com/icon.png',
114+
self: 'f'.repeat(64),
115+
terms_of_service: 'https://relay.example.com/terms',
116+
},
117+
})
118+
119+
rootRequestHandler(req, res, next)
120+
121+
const doc = res.send.firstCall.args[0]
122+
expect(doc.banner).to.equal('https://relay.example.com/banner.png')
123+
expect(doc.icon).to.equal('https://relay.example.com/icon.png')
124+
expect(doc.self).to.equal('f'.repeat(64))
125+
expect(doc.terms_of_service).to.equal('https://relay.example.com/terms')
126+
})
98127
})
99128

100129
describe('when serving HTML', () => {

0 commit comments

Comments
 (0)