aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests/api/activitypub/helpers.ts
blob: 25e1d982343b34c7805cd92d72af1459ea01fee9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */

import 'mocha'
import { expect } from 'chai'
import { cloneDeep } from 'lodash'
import { buildRequestStub } from '@server/tests/shared'
import { buildAbsoluteFixturePath } from '@shared/core-utils'
import { buildSignedActivity } from '../../../helpers/activitypub'
import { isHTTPSignatureVerified, isJsonLDSignatureVerified, parseHTTPSignature } from '../../../helpers/peertube-crypto'

describe('Test activity pub helpers', function () {
  describe('When checking the Linked Signature', function () {

    it('Should fail with an invalid Mastodon signature', async function () {
      const body = require(buildAbsoluteFixturePath('./ap-json/mastodon/create-bad-signature.json'))
      const publicKey = require(buildAbsoluteFixturePath('./ap-json/mastodon/public-key.json')).publicKey
      const fromActor = { publicKey, url: 'http://localhost:9002/accounts/peertube' }

      const result = await isJsonLDSignatureVerified(fromActor as any, body)

      expect(result).to.be.false
    })

    it('Should fail with an invalid public key', async function () {
      const body = require(buildAbsoluteFixturePath('./ap-json/mastodon/create.json'))
      const publicKey = require(buildAbsoluteFixturePath('./ap-json/mastodon/bad-public-key.json')).publicKey
      const fromActor = { publicKey, url: 'http://localhost:9002/accounts/peertube' }

      const result = await isJsonLDSignatureVerified(fromActor as any, body)

      expect(result).to.be.false
    })

    it('Should succeed with a valid Mastodon signature', async function () {
      const body = require(buildAbsoluteFixturePath('./ap-json/mastodon/create.json'))
      const publicKey = require(buildAbsoluteFixturePath('./ap-json/mastodon/public-key.json')).publicKey
      const fromActor = { publicKey, url: 'http://localhost:9002/accounts/peertube' }

      const result = await isJsonLDSignatureVerified(fromActor as any, body)

      expect(result).to.be.true
    })

    it('Should fail with an invalid PeerTube signature', async function () {
      const keys = require(buildAbsoluteFixturePath('./ap-json/peertube/invalid-keys.json'))
      const body = require(buildAbsoluteFixturePath('./ap-json/peertube/announce-without-context.json'))

      const actorSignature = { url: 'http://localhost:9002/accounts/peertube', privateKey: keys.privateKey }
      const signedBody = await buildSignedActivity(actorSignature as any, body)

      const fromActor = { publicKey: keys.publicKey, url: 'http://localhost:9002/accounts/peertube' }
      const result = await isJsonLDSignatureVerified(fromActor as any, signedBody)

      expect(result).to.be.false
    })

    it('Should succeed with a valid PeerTube signature', async function () {
      const keys = require(buildAbsoluteFixturePath('./ap-json/peertube/keys.json'))
      const body = require(buildAbsoluteFixturePath('./ap-json/peertube/announce-without-context.json'))

      const actorSignature = { url: 'http://localhost:9002/accounts/peertube', privateKey: keys.privateKey }
      const signedBody = await buildSignedActivity(actorSignature as any, body)

      const fromActor = { publicKey: keys.publicKey, url: 'http://localhost:9002/accounts/peertube' }
      const result = await isJsonLDSignatureVerified(fromActor as any, signedBody)

      expect(result).to.be.true
    })
  })

  describe('When checking HTTP signature', function () {
    it('Should fail with an invalid http signature', async function () {
      const req = buildRequestStub()
      req.method = 'POST'
      req.url = '/accounts/ronan/inbox'

      const mastodonObject = cloneDeep(require(buildAbsoluteFixturePath('./ap-json/mastodon/bad-http-signature.json')))
      req.body = mastodonObject.body
      req.headers = mastodonObject.headers

      const parsed = parseHTTPSignature(req, 3600 * 1000 * 365 * 10)
      const publicKey = require(buildAbsoluteFixturePath('./ap-json/mastodon/public-key.json')).publicKey

      const actor = { publicKey }
      const verified = isHTTPSignatureVerified(parsed, actor as any)

      expect(verified).to.be.false
    })

    it('Should fail with an invalid public key', async function () {
      const req = buildRequestStub()
      req.method = 'POST'
      req.url = '/accounts/ronan/inbox'

      const mastodonObject = cloneDeep(require(buildAbsoluteFixturePath('./ap-json/mastodon/http-signature.json')))
      req.body = mastodonObject.body
      req.headers = mastodonObject.headers

      const parsed = parseHTTPSignature(req, 3600 * 1000 * 365 * 10)
      const publicKey = require(buildAbsoluteFixturePath('./ap-json/mastodon/bad-public-key.json')).publicKey

      const actor = { publicKey }
      const verified = isHTTPSignatureVerified(parsed, actor as any)

      expect(verified).to.be.false
    })

    it('Should fail because of clock skew', async function () {
      const req = buildRequestStub()
      req.method = 'POST'
      req.url = '/accounts/ronan/inbox'

      const mastodonObject = cloneDeep(require(buildAbsoluteFixturePath('./ap-json/mastodon/http-signature.json')))
      req.body = mastodonObject.body
      req.headers = mastodonObject.headers

      let errored = false
      try {
        parseHTTPSignature(req)
      } catch {
        errored = true
      }

      expect(errored).to.be.true
    })

    it('Should with a scheme', async function () {
      const req = buildRequestStub()
      req.method = 'POST'
      req.url = '/accounts/ronan/inbox'

      const mastodonObject = cloneDeep(require(buildAbsoluteFixturePath('./ap-json/mastodon/http-signature.json')))
      req.body = mastodonObject.body
      req.headers = mastodonObject.headers
      req.headers = 'Signature ' + mastodonObject.headers

      let errored = false
      try {
        parseHTTPSignature(req, 3600 * 1000 * 365 * 10)
      } catch {
        errored = true
      }

      expect(errored).to.be.true
    })

    it('Should succeed with a valid signature', async function () {
      const req = buildRequestStub()
      req.method = 'POST'
      req.url = '/accounts/ronan/inbox'

      const mastodonObject = cloneDeep(require(buildAbsoluteFixturePath('./ap-json/mastodon/http-signature.json')))
      req.body = mastodonObject.body
      req.headers = mastodonObject.headers

      const parsed = parseHTTPSignature(req, 3600 * 1000 * 365 * 10)
      const publicKey = require(buildAbsoluteFixturePath('./ap-json/mastodon/public-key.json')).publicKey

      const actor = { publicKey }
      const verified = isHTTPSignatureVerified(parsed, actor as any)

      expect(verified).to.be.true
    })

  })

})