1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
4 import { expect } from 'chai'
5 import { buildRequestStub } from '../../../../shared/extra-utils/miscs/stubs'
6 import { isHTTPSignatureVerified, isJsonLDSignatureVerified, parseHTTPSignature } from '../../../helpers/peertube-crypto'
7 import { cloneDeep } from 'lodash'
8 import { buildSignedActivity } from '../../../helpers/activitypub'
9 import { buildAbsoluteFixturePath } from '@shared/extra-utils'
11 describe('Test activity pub helpers', function () {
12 describe('When checking the Linked Signature', function () {
14 it('Should fail with an invalid Mastodon signature', async function () {
15 const body = require(buildAbsoluteFixturePath('./ap-json/mastodon/create-bad-signature.json'))
16 const publicKey = require(buildAbsoluteFixturePath('./ap-json/mastodon/public-key.json')).publicKey
17 const fromActor = { publicKey, url: 'http://localhost:9002/accounts/peertube' }
19 const result = await isJsonLDSignatureVerified(fromActor as any, body)
21 expect(result).to.be.false
24 it('Should fail with an invalid public key', async function () {
25 const body = require(buildAbsoluteFixturePath('./ap-json/mastodon/create.json'))
26 const publicKey = require(buildAbsoluteFixturePath('./ap-json/mastodon/bad-public-key.json')).publicKey
27 const fromActor = { publicKey, url: 'http://localhost:9002/accounts/peertube' }
29 const result = await isJsonLDSignatureVerified(fromActor as any, body)
31 expect(result).to.be.false
34 it('Should succeed with a valid Mastodon signature', async function () {
35 const body = require(buildAbsoluteFixturePath('./ap-json/mastodon/create.json'))
36 const publicKey = require(buildAbsoluteFixturePath('./ap-json/mastodon/public-key.json')).publicKey
37 const fromActor = { publicKey, url: 'http://localhost:9002/accounts/peertube' }
39 const result = await isJsonLDSignatureVerified(fromActor as any, body)
41 expect(result).to.be.true
44 it('Should fail with an invalid PeerTube signature', async function () {
45 const keys = require(buildAbsoluteFixturePath('./ap-json/peertube/invalid-keys.json'))
46 const body = require(buildAbsoluteFixturePath('./ap-json/peertube/announce-without-context.json'))
48 const actorSignature = { url: 'http://localhost:9002/accounts/peertube', privateKey: keys.privateKey }
49 const signedBody = await buildSignedActivity(actorSignature as any, body)
51 const fromActor = { publicKey: keys.publicKey, url: 'http://localhost:9002/accounts/peertube' }
52 const result = await isJsonLDSignatureVerified(fromActor as any, signedBody)
54 expect(result).to.be.false
57 it('Should succeed with a valid PeerTube signature', async function () {
58 const keys = require(buildAbsoluteFixturePath('./ap-json/peertube/keys.json'))
59 const body = require(buildAbsoluteFixturePath('./ap-json/peertube/announce-without-context.json'))
61 const actorSignature = { url: 'http://localhost:9002/accounts/peertube', privateKey: keys.privateKey }
62 const signedBody = await buildSignedActivity(actorSignature as any, body)
64 const fromActor = { publicKey: keys.publicKey, url: 'http://localhost:9002/accounts/peertube' }
65 const result = await isJsonLDSignatureVerified(fromActor as any, signedBody)
67 expect(result).to.be.true
71 describe('When checking HTTP signature', function () {
72 it('Should fail with an invalid http signature', async function () {
73 const req = buildRequestStub()
75 req.url = '/accounts/ronan/inbox'
77 const mastodonObject = cloneDeep(require(buildAbsoluteFixturePath('./ap-json/mastodon/bad-http-signature.json')))
78 req.body = mastodonObject.body
79 req.headers = mastodonObject.headers
81 const parsed = parseHTTPSignature(req, 3600 * 1000 * 365 * 10)
82 const publicKey = require(buildAbsoluteFixturePath('./ap-json/mastodon/public-key.json')).publicKey
84 const actor = { publicKey }
85 const verified = isHTTPSignatureVerified(parsed, actor as any)
87 expect(verified).to.be.false
90 it('Should fail with an invalid public key', async function () {
91 const req = buildRequestStub()
93 req.url = '/accounts/ronan/inbox'
95 const mastodonObject = cloneDeep(require(buildAbsoluteFixturePath('./ap-json/mastodon/http-signature.json')))
96 req.body = mastodonObject.body
97 req.headers = mastodonObject.headers
99 const parsed = parseHTTPSignature(req, 3600 * 1000 * 365 * 10)
100 const publicKey = require(buildAbsoluteFixturePath('./ap-json/mastodon/bad-public-key.json')).publicKey
102 const actor = { publicKey }
103 const verified = isHTTPSignatureVerified(parsed, actor as any)
105 expect(verified).to.be.false
108 it('Should fail because of clock skew', async function () {
109 const req = buildRequestStub()
111 req.url = '/accounts/ronan/inbox'
113 const mastodonObject = cloneDeep(require(buildAbsoluteFixturePath('./ap-json/mastodon/http-signature.json')))
114 req.body = mastodonObject.body
115 req.headers = mastodonObject.headers
119 parseHTTPSignature(req)
124 expect(errored).to.be.true
127 it('Should with a scheme', async function () {
128 const req = buildRequestStub()
130 req.url = '/accounts/ronan/inbox'
132 const mastodonObject = cloneDeep(require(buildAbsoluteFixturePath('./ap-json/mastodon/http-signature.json')))
133 req.body = mastodonObject.body
134 req.headers = mastodonObject.headers
135 req.headers = 'Signature ' + mastodonObject.headers
139 parseHTTPSignature(req, 3600 * 1000 * 365 * 10)
144 expect(errored).to.be.true
147 it('Should succeed with a valid signature', async function () {
148 const req = buildRequestStub()
150 req.url = '/accounts/ronan/inbox'
152 const mastodonObject = cloneDeep(require(buildAbsoluteFixturePath('./ap-json/mastodon/http-signature.json')))
153 req.body = mastodonObject.body
154 req.headers = mastodonObject.headers
156 const parsed = parseHTTPSignature(req, 3600 * 1000 * 365 * 10)
157 const publicKey = require(buildAbsoluteFixturePath('./ap-json/mastodon/public-key.json')).publicKey
159 const actor = { publicKey }
160 const verified = isHTTPSignatureVerified(parsed, actor as any)
162 expect(verified).to.be.true