kopia lustrzana https://github.com/cloudflare/wildebeest
Merge pull request #109 from cloudflare/sven/fix-duplicate-follow
ignore duplicated followpull/110/head
commit
5ce31c4d75
|
@ -224,12 +224,10 @@ export async function handle(
|
|||
const originalActor = await actors.getAndCache(new URL(actorId), db)
|
||||
const receiverAcct = `${receiver.preferredUsername}@${domain}`
|
||||
|
||||
await Promise.all([
|
||||
addFollowing(db, originalActor, receiver, receiverAcct),
|
||||
acceptFollowing(db, originalActor, receiver),
|
||||
])
|
||||
await addFollowing(db, originalActor, receiver, receiverAcct)
|
||||
|
||||
// Automatically send the Accept reply
|
||||
await acceptFollowing(db, originalActor, receiver)
|
||||
const reply = accept.create(receiver, activity)
|
||||
const signingKey = await getSigningKey(userKEK, db, receiver)
|
||||
await deliverToActor(signingKey, receiver, originalActor, reply)
|
||||
|
|
|
@ -9,7 +9,7 @@ export async function addFollowing(db: D1Database, actor: Actor, target: Actor,
|
|||
const id = crypto.randomUUID()
|
||||
|
||||
const query = `
|
||||
INSERT INTO actor_following (id, actor_id, target_actor_id, state, target_actor_acct)
|
||||
INSERT OR IGNORE INTO actor_following (id, actor_id, target_actor_id, state, target_actor_acct)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
`
|
||||
|
||||
|
|
|
@ -149,5 +149,26 @@ describe('ActivityPub', () => {
|
|||
assert.equal(entry.actor_id.toString(), actor.id.toString())
|
||||
assert.equal(entry.from_actor_id.toString(), actor2.id.toString())
|
||||
})
|
||||
|
||||
test('ignore when trying to follow multiple times', async () => {
|
||||
const db = await makeDB()
|
||||
const actor = await createPerson(domain, db, userKEK, 'sven@cloudflare.com')
|
||||
const actor2 = await createPerson(domain, db, userKEK, 'sven2@cloudflare.com')
|
||||
|
||||
const activity = {
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
type: 'Follow',
|
||||
actor: actor2.id,
|
||||
object: actor.id,
|
||||
}
|
||||
|
||||
await activityHandler.handle(domain, activity, db, userKEK, adminEmail, vapidKeys)
|
||||
await activityHandler.handle(domain, activity, db, userKEK, adminEmail, vapidKeys)
|
||||
await activityHandler.handle(domain, activity, db, userKEK, adminEmail, vapidKeys)
|
||||
|
||||
// Even if we followed multiple times, only one row should be present.
|
||||
const { count } = await db.prepare(`SELECT count(*) as count FROM actor_following`).first()
|
||||
assert.equal(count, 1)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -3,6 +3,7 @@ import type { Queue } from 'wildebeest/backend/src/types/queue'
|
|||
import { createClient } from 'wildebeest/backend/src/mastodon/client'
|
||||
import type { Client } from 'wildebeest/backend/src/mastodon/client'
|
||||
import { promises as fs } from 'fs'
|
||||
import * as path from 'path'
|
||||
import { BetaDatabase } from '@miniflare/d1'
|
||||
import * as Database from 'better-sqlite3'
|
||||
|
||||
|
@ -21,8 +22,12 @@ export async function makeDB(): Promise<any> {
|
|||
const db2 = new BetaDatabase(db)!
|
||||
|
||||
// Manually run our migrations since @miniflare/d1 doesn't support it (yet).
|
||||
const initial = await fs.readFile('./migrations/0000_initial.sql', 'utf-8')
|
||||
await db.exec(initial)
|
||||
const migrations = await fs.readdir('./migrations/')
|
||||
|
||||
for (let i = 0, len = migrations.length; i < len; i++) {
|
||||
const content = await fs.readFile(path.join('migrations', migrations[i]), 'utf-8')
|
||||
await db.exec(content)
|
||||
}
|
||||
|
||||
return db2
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
-- Migration number: 0001 2023-01-16T13:09:04.033Z
|
||||
|
||||
CREATE UNIQUE INDEX unique_actor_following ON actor_following (actor_id, target_actor_id);
|
Ładowanie…
Reference in New Issue