}
function parseHTTPSignature (req: Request, clockSkew?: number) {
- const headers = req.method === 'POST'
- ? HTTP_SIGNATURE.REQUIRED_HEADERS.POST
- : HTTP_SIGNATURE.REQUIRED_HEADERS.ALL
+ const requiredHeaders = req.method === 'POST'
+ ? [ '(request-target)', 'host', 'digest' ]
+ : [ '(request-target)', 'host' ]
- return httpSignature.parse(req, { clockSkew, headers })
+ const parsed = httpSignature.parse(req, { clockSkew, headers: requiredHeaders })
+
+ const parsedHeaders = parsed.params.headers
+ if (!parsedHeaders.includes('date') && !parsedHeaders.includes('(created)')) {
+ throw new Error(`date or (created) must be included in signature`)
+ }
+
+ return parsed
}
// JSONLD
const HTTP_SIGNATURE = {
HEADER_NAME: 'signature',
ALGORITHM: 'rsa-sha256',
- HEADERS_TO_SIGN: [ '(request-target)', 'host', 'date', 'digest' ],
- REQUIRED_HEADERS: {
- ALL: [ '(request-target)', 'host', 'date' ],
- POST: [ '(request-target)', 'host', 'date', 'digest' ]
- },
+ HEADERS_TO_SIGN: [ '(request-target)', '(created)', 'host', 'date', 'digest' ],
CLOCK_SKEW_SECONDS: 1800
}
}
})
+ it('Should succeed with a valid HTTP signature draft 11 (without date but with (created))', async function () {
+ const body = activityPubContextify(getAnnounceWithoutContext(servers[1]), 'Announce')
+ const headers = buildGlobalHeaders(body)
+
+ const signatureOptions = baseHttpSignature()
+ signatureOptions.headers = [ '(request-target)', '(created)', 'host', 'digest' ]
+
+ const { statusCode } = await makePOSTAPRequest(url, body, signatureOptions, headers)
+ expect(statusCode).to.equal(HttpStatusCode.NO_CONTENT_204)
+ })
+
it('Should succeed with a valid HTTP signature', async function () {
const body = activityPubContextify(getAnnounceWithoutContext(servers[1]), 'Announce')
const headers = buildGlobalHeaders(body)