@evanp/activitypub-bot 0.9.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/main.yml +34 -0
- package/.github/workflows/{tag-docker.yml → tag.yml} +57 -5
- package/.nvmrc +1 -0
- package/Dockerfile +10 -16
- package/README.md +87 -13
- package/bin/activitypub-bot.js +68 -0
- package/lib/activitydeliverer.js +260 -0
- package/lib/activityhandler.js +14 -0
- package/lib/activitypubclient.js +52 -1
- package/lib/activitystreams.js +31 -0
- package/lib/actorstorage.js +18 -28
- package/lib/app.js +18 -7
- package/lib/bot.js +7 -0
- package/lib/botcontext.js +62 -0
- package/lib/botdatastorage.js +0 -13
- package/lib/botfactory.js +24 -0
- package/lib/botmaker.js +23 -0
- package/lib/index.js +3 -0
- package/lib/keystorage.js +7 -24
- package/lib/migrations/001-initial.js +107 -0
- package/lib/migrations/index.js +28 -0
- package/lib/objectcache.js +4 -1
- package/lib/objectstorage.js +0 -36
- package/lib/remotekeystorage.js +0 -24
- package/lib/routes/collection.js +6 -2
- package/lib/routes/inbox.js +7 -20
- package/lib/routes/sharedinbox.js +54 -0
- package/lib/routes/user.js +11 -5
- package/lib/routes/webfinger.js +11 -2
- package/lib/urlformatter.js +8 -0
- package/package.json +14 -7
- package/tests/activitydistributor.test.js +3 -3
- package/tests/activityhandler.test.js +96 -5
- package/tests/activitypubclient.test.js +115 -130
- package/tests/actorstorage.test.js +26 -4
- package/tests/authorizer.test.js +3 -8
- package/tests/botcontext.test.js +109 -63
- package/tests/botdatastorage.test.js +3 -2
- package/tests/botfactory.provincebotfactory.test.js +430 -0
- package/tests/fixtures/bots.js +13 -1
- package/tests/fixtures/eventloggingbot.js +57 -0
- package/tests/fixtures/provincebotfactory.js +53 -0
- package/tests/httpsignature.test.js +3 -4
- package/tests/httpsignatureauthenticator.test.js +3 -3
- package/tests/index.test.js +10 -0
- package/tests/keystorage.test.js +37 -2
- package/tests/microsyntax.test.js +3 -2
- package/tests/objectstorage.test.js +4 -3
- package/tests/remotekeystorage.test.js +10 -8
- package/tests/routes.actor.test.js +7 -0
- package/tests/routes.collection.test.js +0 -1
- package/tests/routes.inbox.test.js +1 -0
- package/tests/routes.object.test.js +44 -38
- package/tests/routes.sharedinbox.test.js +473 -0
- package/tests/routes.webfinger.test.js +27 -0
- package/tests/utils/nock.js +250 -27
- package/.github/workflows/main-docker.yml +0 -45
- package/index.js +0 -23
|
@@ -4,128 +4,62 @@ import { UrlFormatter } from '../lib/urlformatter.js'
|
|
|
4
4
|
import { ActivityPubClient } from '../lib/activitypubclient.js'
|
|
5
5
|
import assert from 'node:assert'
|
|
6
6
|
import { Sequelize } from 'sequelize'
|
|
7
|
-
import nock from 'nock'
|
|
8
7
|
import as2 from '../lib/activitystreams.js'
|
|
9
8
|
import Logger from 'pino'
|
|
10
9
|
import { HTTPSignature } from '../lib/httpsignature.js'
|
|
11
10
|
import { Digester } from '../lib/digester.js'
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
followers: `https://social.example/user/${username}/followers`,
|
|
21
|
-
following: `https://social.example/user/${username}/following`,
|
|
22
|
-
liked: `https://social.example/user/${username}/liked`,
|
|
23
|
-
publicKey: {
|
|
24
|
-
id: `https://social.example/user/${username}/publickey`,
|
|
25
|
-
owner: `https://social.example/user/${username}`,
|
|
26
|
-
type: 'CryptographicKey',
|
|
27
|
-
publicKeyPem: '-----BEGIN PUBLIC KEY-----\nFAKEFAKEFAKE\n-----END PUBLIC KEY-----'
|
|
28
|
-
}
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
const makeKey = (username) =>
|
|
32
|
-
as2.import({
|
|
33
|
-
id: `https://social.example/user/${username}/publickey`,
|
|
34
|
-
owner: `https://social.example/user/${username}`,
|
|
35
|
-
type: 'CryptographicKey',
|
|
36
|
-
publicKeyPem: '-----BEGIN PUBLIC KEY-----\nFAKEFAKEFAKE\n-----END PUBLIC KEY-----'
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
const makeNote = (username, num) =>
|
|
40
|
-
as2.import({
|
|
41
|
-
id: `https://social.example/user/${username}/note/${num}`,
|
|
42
|
-
type: 'Object',
|
|
43
|
-
attributedTo: `https://social.example/user/${username}`,
|
|
44
|
-
to: 'https://www.w3.org/ns/activitystreams#Public',
|
|
45
|
-
content: `This is note ${num} by ${username}.`
|
|
46
|
-
})
|
|
11
|
+
import { runMigrations } from '../lib/migrations/index.js'
|
|
12
|
+
import {
|
|
13
|
+
nockSetup,
|
|
14
|
+
getRequestHeaders,
|
|
15
|
+
resetRequestHeaders,
|
|
16
|
+
addToCollection,
|
|
17
|
+
nockFormat
|
|
18
|
+
} from './utils/nock.js'
|
|
47
19
|
|
|
48
20
|
describe('ActivityPubClient', async () => {
|
|
49
21
|
let connection = null
|
|
50
22
|
let keyStorage = null
|
|
51
23
|
let formatter = null
|
|
52
24
|
let client = null
|
|
53
|
-
let postInbox = null
|
|
54
|
-
let signature = null
|
|
55
|
-
let digest = null
|
|
56
|
-
let date = null
|
|
57
25
|
let signer = null
|
|
58
26
|
let digester = null
|
|
59
27
|
let logger = null
|
|
28
|
+
const remoteUser = 'remote1'
|
|
29
|
+
const remoteCollection = 1
|
|
30
|
+
const remoteOrderedCollection = 2
|
|
31
|
+
const remotePagedCollection = 3
|
|
32
|
+
const remotePagedOrderedCollection = 4
|
|
33
|
+
const maxItems = 10
|
|
60
34
|
before(async () => {
|
|
61
35
|
logger = new Logger({
|
|
62
36
|
level: 'silent'
|
|
63
37
|
})
|
|
64
38
|
digester = new Digester(logger)
|
|
65
39
|
signer = new HTTPSignature(logger)
|
|
66
|
-
connection = new Sequelize('sqlite
|
|
40
|
+
connection = new Sequelize({ dialect: 'sqlite', storage: ':memory:', logging: false })
|
|
67
41
|
await connection.authenticate()
|
|
42
|
+
await runMigrations(connection)
|
|
68
43
|
keyStorage = new KeyStorage(connection, logger)
|
|
69
|
-
await keyStorage.initialize()
|
|
70
44
|
formatter = new UrlFormatter('https://activitypubbot.example')
|
|
71
|
-
const remote = '
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
digest[remote + uri] = headers.digest
|
|
90
|
-
date[remote + uri] = headers.date
|
|
91
|
-
const username = uri.match(/\/user\/(\w+)\/inbox$/)[1]
|
|
92
|
-
if (username in postInbox) {
|
|
93
|
-
postInbox[username] += 1
|
|
94
|
-
} else {
|
|
95
|
-
postInbox[username] = 1
|
|
96
|
-
}
|
|
97
|
-
return [202, 'accepted']
|
|
98
|
-
})
|
|
99
|
-
.persist()
|
|
100
|
-
.get(/\/user\/(\w+)\/note\/(\d+)$/)
|
|
101
|
-
.reply(async function (uri, requestBody) {
|
|
102
|
-
const headers = this.req.headers
|
|
103
|
-
signature[remote + uri] = headers.signature
|
|
104
|
-
digest[remote + uri] = headers.digest
|
|
105
|
-
date[remote + uri] = headers.date
|
|
106
|
-
const match = uri.match(/\/user\/(\w+)\/note\/(\d+)$/)
|
|
107
|
-
const username = match[1]
|
|
108
|
-
const num = match[2]
|
|
109
|
-
const obj = await makeNote(username, num)
|
|
110
|
-
const objText = await obj.write()
|
|
111
|
-
return [200, objText, { 'Content-Type': 'application/activity+json' }]
|
|
112
|
-
})
|
|
113
|
-
.get(/\/user\/(\w+)\/inbox$/)
|
|
114
|
-
.reply(async function (uri, requestBody) {
|
|
115
|
-
return [403, 'Forbidden', { 'Content-Type': 'text/plain' }]
|
|
116
|
-
})
|
|
117
|
-
.get(/\/user\/(\w+)\/publickey$/)
|
|
118
|
-
.reply(async function (uri, requestBody) {
|
|
119
|
-
const headers = this.req.headers
|
|
120
|
-
signature[remote + uri] = headers.signature
|
|
121
|
-
digest[remote + uri] = headers.digest
|
|
122
|
-
date[remote + uri] = headers.date
|
|
123
|
-
const username = uri.match(/\/user\/(\w+)\/publickey$/)[1]
|
|
124
|
-
const key = await makeKey(username)
|
|
125
|
-
const keyText = await key.write()
|
|
126
|
-
return [200, keyText, { 'Content-Type': 'application/activity+json' }]
|
|
127
|
-
})
|
|
128
|
-
.persist()
|
|
45
|
+
const remote = 'social.example'
|
|
46
|
+
nockSetup(remote, logger)
|
|
47
|
+
for (let i = 0; i < maxItems; i++) {
|
|
48
|
+
const id = nockFormat({ username: remoteUser, type: 'note', num: i })
|
|
49
|
+
addToCollection(remoteUser, remoteCollection, id, remote)
|
|
50
|
+
}
|
|
51
|
+
for (let i = maxItems; i < 2 * maxItems; i++) {
|
|
52
|
+
const id = nockFormat({ username: remoteUser, type: 'note', num: i })
|
|
53
|
+
addToCollection(remoteUser, remoteOrderedCollection, id, remote)
|
|
54
|
+
}
|
|
55
|
+
for (let i = 2 * maxItems; i < 7 * maxItems; i++) {
|
|
56
|
+
const id = nockFormat({ username: remoteUser, type: 'note', num: i })
|
|
57
|
+
addToCollection(remoteUser, remotePagedCollection, id, remote)
|
|
58
|
+
}
|
|
59
|
+
for (let i = 7 * maxItems; i < 12 * maxItems; i++) {
|
|
60
|
+
const id = nockFormat({ username: remoteUser, type: 'note', num: i })
|
|
61
|
+
addToCollection(remoteUser, remotePagedOrderedCollection, id, remote)
|
|
62
|
+
}
|
|
129
63
|
})
|
|
130
64
|
after(async () => {
|
|
131
65
|
await connection.close()
|
|
@@ -133,17 +67,12 @@ describe('ActivityPubClient', async () => {
|
|
|
133
67
|
connection = null
|
|
134
68
|
formatter = null
|
|
135
69
|
client = null
|
|
136
|
-
postInbox = null
|
|
137
|
-
signature = null
|
|
138
70
|
logger = null
|
|
139
71
|
digester = null
|
|
140
72
|
signer = null
|
|
141
73
|
})
|
|
142
74
|
beforeEach(async () => {
|
|
143
|
-
|
|
144
|
-
digest = {}
|
|
145
|
-
postInbox = {}
|
|
146
|
-
date = {}
|
|
75
|
+
resetRequestHeaders()
|
|
147
76
|
})
|
|
148
77
|
it('can initialize', () => {
|
|
149
78
|
client = new ActivityPubClient(keyStorage, formatter, signer, digester, logger)
|
|
@@ -155,13 +84,14 @@ describe('ActivityPubClient', async () => {
|
|
|
155
84
|
assert.ok(obj)
|
|
156
85
|
assert.equal(typeof obj, 'object')
|
|
157
86
|
assert.equal(obj.id, id)
|
|
158
|
-
|
|
159
|
-
assert.
|
|
160
|
-
assert.
|
|
161
|
-
assert.equal(typeof
|
|
162
|
-
assert.
|
|
87
|
+
const h = getRequestHeaders(id)
|
|
88
|
+
assert.ok(h.signature)
|
|
89
|
+
assert.match(h.signature, /^keyId="https:\/\/activitypubbot\.example\/user\/foobot\/publickey",headers="\(request-target\) host date user-agent accept",signature=".*",algorithm="rsa-sha256"$/)
|
|
90
|
+
assert.equal(typeof h.digest, 'undefined')
|
|
91
|
+
assert.equal(typeof h.date, 'string')
|
|
92
|
+
assert.match(h.date, /^\w{3}, \d{2} \w{3} \d{4} \d{2}:\d{2}:\d{2} GMT$/)
|
|
163
93
|
assert.doesNotThrow(() => {
|
|
164
|
-
Date.parse(date
|
|
94
|
+
Date.parse(h.date)
|
|
165
95
|
})
|
|
166
96
|
})
|
|
167
97
|
it('can get a remote object without a username', async () => {
|
|
@@ -170,13 +100,14 @@ describe('ActivityPubClient', async () => {
|
|
|
170
100
|
assert.ok(obj)
|
|
171
101
|
assert.equal(typeof obj, 'object')
|
|
172
102
|
assert.equal(obj.id, id)
|
|
173
|
-
|
|
174
|
-
assert.
|
|
175
|
-
assert.
|
|
176
|
-
assert.equal(typeof
|
|
177
|
-
assert.
|
|
103
|
+
const h = getRequestHeaders(id)
|
|
104
|
+
assert.ok(h.signature)
|
|
105
|
+
assert.match(h.signature, /^keyId="https:\/\/activitypubbot\.example\/publickey",headers="\(request-target\) host date user-agent accept",signature=".*",algorithm="rsa-sha256"$/)
|
|
106
|
+
assert.equal(typeof h.digest, 'undefined')
|
|
107
|
+
assert.equal(typeof h.date, 'string')
|
|
108
|
+
assert.match(h.date, /^\w{3}, \d{2} \w{3} \d{4} \d{2}:\d{2}:\d{2} GMT$/)
|
|
178
109
|
assert.doesNotThrow(() => {
|
|
179
|
-
Date.parse(date
|
|
110
|
+
Date.parse(h.date)
|
|
180
111
|
})
|
|
181
112
|
})
|
|
182
113
|
it('can get a remote key without a signature', async () => {
|
|
@@ -185,12 +116,13 @@ describe('ActivityPubClient', async () => {
|
|
|
185
116
|
assert.ok(obj)
|
|
186
117
|
assert.equal(typeof obj, 'object')
|
|
187
118
|
assert.equal(obj.id, id)
|
|
188
|
-
|
|
189
|
-
assert.equal(
|
|
190
|
-
assert.equal(typeof
|
|
191
|
-
assert.
|
|
119
|
+
const h = getRequestHeaders(id)
|
|
120
|
+
assert.equal(h.signature, undefined)
|
|
121
|
+
assert.equal(typeof h.digest, 'undefined')
|
|
122
|
+
assert.equal(typeof h.date, 'string')
|
|
123
|
+
assert.match(h.date, /^\w{3}, \d{2} \w{3} \d{4} \d{2}:\d{2}:\d{2} GMT$/)
|
|
192
124
|
assert.doesNotThrow(() => {
|
|
193
|
-
Date.parse(date
|
|
125
|
+
Date.parse(h.date)
|
|
194
126
|
})
|
|
195
127
|
})
|
|
196
128
|
it('can deliver an activity', async () => {
|
|
@@ -202,14 +134,15 @@ describe('ActivityPubClient', async () => {
|
|
|
202
134
|
.get()
|
|
203
135
|
const inbox = 'https://social.example/user/evan/inbox'
|
|
204
136
|
await client.post(inbox, obj, 'foobot')
|
|
205
|
-
|
|
206
|
-
assert.ok(
|
|
207
|
-
assert.
|
|
208
|
-
assert.match(
|
|
209
|
-
assert.
|
|
210
|
-
assert.
|
|
137
|
+
const h = getRequestHeaders(inbox)
|
|
138
|
+
assert.ok(h.signature)
|
|
139
|
+
assert.ok(h.digest)
|
|
140
|
+
assert.match(h.signature, /^keyId="https:\/\/activitypubbot\.example\/user\/foobot\/publickey",headers="\(request-target\) host date user-agent content-type digest",signature=".*",algorithm="rsa-sha256"$/)
|
|
141
|
+
assert.match(h.digest, /^sha-256=[0-9a-zA-Z=+/]*$/)
|
|
142
|
+
assert.equal(typeof h.date, 'string')
|
|
143
|
+
assert.match(h.date, /^\w{3}, \d{2} \w{3} \d{4} \d{2}:\d{2}:\d{2} GMT$/)
|
|
211
144
|
assert.doesNotThrow(() => {
|
|
212
|
-
Date.parse(date
|
|
145
|
+
Date.parse(h.date)
|
|
213
146
|
})
|
|
214
147
|
})
|
|
215
148
|
it('throws an error on a non-2xx response', async () => {
|
|
@@ -222,4 +155,56 @@ describe('ActivityPubClient', async () => {
|
|
|
222
155
|
assert.equal(error.status, 403)
|
|
223
156
|
}
|
|
224
157
|
})
|
|
158
|
+
it('can iterate over a Collection', async () => {
|
|
159
|
+
const collectionUri = nockFormat({
|
|
160
|
+
username: remoteUser,
|
|
161
|
+
type: 'Collection',
|
|
162
|
+
num: remoteCollection
|
|
163
|
+
})
|
|
164
|
+
let counter = 0
|
|
165
|
+
for await (const item of client.items(collectionUri)) {
|
|
166
|
+
assert.ok(item)
|
|
167
|
+
counter = counter + 1
|
|
168
|
+
}
|
|
169
|
+
assert.strictEqual(counter, maxItems)
|
|
170
|
+
})
|
|
171
|
+
it('can iterate over an OrderedCollection', async () => {
|
|
172
|
+
const collectionUri = nockFormat({
|
|
173
|
+
username: remoteUser,
|
|
174
|
+
type: 'OrderedCollection',
|
|
175
|
+
num: remoteOrderedCollection
|
|
176
|
+
})
|
|
177
|
+
let counter = 0
|
|
178
|
+
for await (const item of client.items(collectionUri)) {
|
|
179
|
+
assert.ok(item)
|
|
180
|
+
counter = counter + 1
|
|
181
|
+
}
|
|
182
|
+
assert.strictEqual(counter, maxItems)
|
|
183
|
+
})
|
|
184
|
+
it('can iterate over a paged Collection', async () => {
|
|
185
|
+
const collectionUri = nockFormat({
|
|
186
|
+
username: remoteUser,
|
|
187
|
+
type: 'PagedCollection', // Fake type
|
|
188
|
+
num: remotePagedCollection
|
|
189
|
+
})
|
|
190
|
+
let counter = 0
|
|
191
|
+
for await (const item of client.items(collectionUri)) {
|
|
192
|
+
assert.ok(item)
|
|
193
|
+
counter = counter + 1
|
|
194
|
+
}
|
|
195
|
+
assert.strictEqual(counter, 5 * maxItems)
|
|
196
|
+
})
|
|
197
|
+
it('can iterate over a paged OrderedCollection', async () => {
|
|
198
|
+
const collectionUri = nockFormat({
|
|
199
|
+
username: remoteUser,
|
|
200
|
+
type: 'PagedOrderedCollection', // Fake type
|
|
201
|
+
num: remotePagedOrderedCollection
|
|
202
|
+
})
|
|
203
|
+
let counter = 0
|
|
204
|
+
for await (const item of client.items(collectionUri)) {
|
|
205
|
+
assert.ok(item)
|
|
206
|
+
counter = counter + 1
|
|
207
|
+
}
|
|
208
|
+
assert.strictEqual(counter, 5 * maxItems)
|
|
209
|
+
})
|
|
225
210
|
})
|
|
@@ -4,6 +4,7 @@ import { ActorStorage } from '../lib/actorstorage.js'
|
|
|
4
4
|
import { Sequelize } from 'sequelize'
|
|
5
5
|
import { UrlFormatter } from '../lib/urlformatter.js'
|
|
6
6
|
import as2 from '../lib/activitystreams.js'
|
|
7
|
+
import { runMigrations } from '../lib/migrations/index.js'
|
|
7
8
|
|
|
8
9
|
const AS2_NS = 'https://www.w3.org/ns/activitystreams#'
|
|
9
10
|
|
|
@@ -12,14 +13,20 @@ describe('ActorStorage', () => {
|
|
|
12
13
|
let storage = null
|
|
13
14
|
let formatter = null
|
|
14
15
|
let other = null
|
|
16
|
+
let unfollowed = null
|
|
15
17
|
before(async () => {
|
|
16
|
-
connection = new Sequelize('sqlite
|
|
18
|
+
connection = new Sequelize({ dialect: 'sqlite', storage: ':memory:', logging: false })
|
|
17
19
|
await connection.authenticate()
|
|
20
|
+
await runMigrations(connection)
|
|
18
21
|
formatter = new UrlFormatter('https://activitypubbot.example')
|
|
19
22
|
other = await as2.import({
|
|
20
23
|
id: 'https://social.example/user/test2',
|
|
21
24
|
type: 'Person'
|
|
22
25
|
})
|
|
26
|
+
unfollowed = await as2.import({
|
|
27
|
+
id: 'https://social.example/user/test3',
|
|
28
|
+
type: 'Person'
|
|
29
|
+
})
|
|
23
30
|
})
|
|
24
31
|
after(async () => {
|
|
25
32
|
await connection.close()
|
|
@@ -31,7 +38,6 @@ describe('ActorStorage', () => {
|
|
|
31
38
|
assert.ok(storage instanceof ActorStorage)
|
|
32
39
|
})
|
|
33
40
|
it('can initialize the storage', async () => {
|
|
34
|
-
await storage.initialize()
|
|
35
41
|
})
|
|
36
42
|
it('can get an actor', async () => {
|
|
37
43
|
const actor = await storage.getActor('test')
|
|
@@ -252,10 +258,26 @@ describe('ActorStorage', () => {
|
|
|
252
258
|
assert.strictEqual(actor.get('preferredUsername').first, 'test8')
|
|
253
259
|
assert.strictEqual(actor.name.get(), 'Test User')
|
|
254
260
|
assert.strictEqual(actor.summary.get(), 'A test user')
|
|
255
|
-
console.log(actor.type)
|
|
256
|
-
console.log(await actor.write())
|
|
257
261
|
assert.ok(Array.isArray(actor.type))
|
|
258
262
|
assert.ok(actor.type.includes(AS2_NS + 'Person'))
|
|
259
263
|
assert.ok(actor.type.includes(AS2_NS + 'Service'))
|
|
260
264
|
})
|
|
265
|
+
|
|
266
|
+
it('can get all actors with an object in a collection', async () => {
|
|
267
|
+
for (const i of [101, 102, 103, 104, 105]) {
|
|
268
|
+
await storage.addToCollection(`test${i}`, 'following', other)
|
|
269
|
+
}
|
|
270
|
+
const usernames = await storage.getUsernamesWith('following', other)
|
|
271
|
+
assert.strictEqual(usernames.length, 5)
|
|
272
|
+
assert.ok(usernames.includes('test101'))
|
|
273
|
+
assert.ok(usernames.includes('test102'))
|
|
274
|
+
assert.ok(usernames.includes('test103'))
|
|
275
|
+
assert.ok(usernames.includes('test104'))
|
|
276
|
+
assert.ok(usernames.includes('test105'))
|
|
277
|
+
})
|
|
278
|
+
|
|
279
|
+
it('gets zero usernames when an object is in no collection', async () => {
|
|
280
|
+
const usernames = await storage.getUsernamesWith('following', unfollowed)
|
|
281
|
+
assert.strictEqual(usernames.length, 0)
|
|
282
|
+
})
|
|
261
283
|
})
|
package/tests/authorizer.test.js
CHANGED
|
@@ -3,7 +3,6 @@ import { Authorizer } from '../lib/authorizer.js'
|
|
|
3
3
|
import { ActorStorage } from '../lib/actorstorage.js'
|
|
4
4
|
import { Sequelize } from 'sequelize'
|
|
5
5
|
import { UrlFormatter } from '../lib/urlformatter.js'
|
|
6
|
-
import { ObjectStorage } from '../lib/objectstorage.js'
|
|
7
6
|
import { KeyStorage } from '../lib/keystorage.js'
|
|
8
7
|
import { ActivityPubClient } from '../lib/activitypubclient.js'
|
|
9
8
|
import as2 from '../lib/activitystreams.js'
|
|
@@ -12,13 +11,13 @@ import { nanoid } from 'nanoid'
|
|
|
12
11
|
import { HTTPSignature } from '../lib/httpsignature.js'
|
|
13
12
|
import Logger from 'pino'
|
|
14
13
|
import { Digester } from '../lib/digester.js'
|
|
14
|
+
import { runMigrations } from '../lib/migrations/index.js'
|
|
15
15
|
|
|
16
16
|
describe('Authorizer', () => {
|
|
17
17
|
let authorizer = null
|
|
18
18
|
let actorStorage = null
|
|
19
19
|
let formatter = null
|
|
20
20
|
let connection = null
|
|
21
|
-
let objectStorage = null
|
|
22
21
|
let keyStorage = null
|
|
23
22
|
let client = null
|
|
24
23
|
|
|
@@ -39,14 +38,11 @@ describe('Authorizer', () => {
|
|
|
39
38
|
level: 'silent'
|
|
40
39
|
})
|
|
41
40
|
formatter = new UrlFormatter('https://activitypubbot.example')
|
|
42
|
-
connection = new Sequelize('sqlite
|
|
41
|
+
connection = new Sequelize({ dialect: 'sqlite', storage: ':memory:', logging: false })
|
|
43
42
|
await connection.authenticate()
|
|
43
|
+
await runMigrations(connection)
|
|
44
44
|
actorStorage = new ActorStorage(connection, formatter)
|
|
45
|
-
await actorStorage.initialize()
|
|
46
|
-
objectStorage = new ObjectStorage(connection)
|
|
47
|
-
await objectStorage.initialize()
|
|
48
45
|
keyStorage = new KeyStorage(connection, logger)
|
|
49
|
-
await keyStorage.initialize()
|
|
50
46
|
const signer = new HTTPSignature(logger)
|
|
51
47
|
const digester = new Digester(logger)
|
|
52
48
|
client = new ActivityPubClient(keyStorage, formatter, signer, digester, logger)
|
|
@@ -134,7 +130,6 @@ describe('Authorizer', () => {
|
|
|
134
130
|
actorStorage = null
|
|
135
131
|
connection = null
|
|
136
132
|
authorizer = null
|
|
137
|
-
objectStorage = null
|
|
138
133
|
})
|
|
139
134
|
|
|
140
135
|
it('should be a class', async () => {
|