kopia lustrzana https://github.com/cloudflare/wildebeest
ignore duplicated follow
rodzic
3c1ddb972e
commit
20661b527c
|
@ -224,12 +224,10 @@ export async function handle(
|
||||||
const originalActor = await actors.getAndCache(new URL(actorId), db)
|
const originalActor = await actors.getAndCache(new URL(actorId), db)
|
||||||
const receiverAcct = `${receiver.preferredUsername}@${domain}`
|
const receiverAcct = `${receiver.preferredUsername}@${domain}`
|
||||||
|
|
||||||
await Promise.all([
|
await addFollowing(db, originalActor, receiver, receiverAcct)
|
||||||
addFollowing(db, originalActor, receiver, receiverAcct),
|
|
||||||
acceptFollowing(db, originalActor, receiver),
|
|
||||||
])
|
|
||||||
|
|
||||||
// Automatically send the Accept reply
|
// Automatically send the Accept reply
|
||||||
|
await acceptFollowing(db, originalActor, receiver)
|
||||||
const reply = accept.create(receiver, activity)
|
const reply = accept.create(receiver, activity)
|
||||||
const signingKey = await getSigningKey(userKEK, db, receiver)
|
const signingKey = await getSigningKey(userKEK, db, receiver)
|
||||||
await deliverToActor(signingKey, receiver, originalActor, reply)
|
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 id = crypto.randomUUID()
|
||||||
|
|
||||||
const query = `
|
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 (?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?)
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
|
@ -149,5 +149,26 @@ describe('ActivityPub', () => {
|
||||||
assert.equal(entry.actor_id.toString(), actor.id.toString())
|
assert.equal(entry.actor_id.toString(), actor.id.toString())
|
||||||
assert.equal(entry.from_actor_id.toString(), actor2.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 { createClient } from 'wildebeest/backend/src/mastodon/client'
|
||||||
import type { Client } from 'wildebeest/backend/src/mastodon/client'
|
import type { Client } from 'wildebeest/backend/src/mastodon/client'
|
||||||
import { promises as fs } from 'fs'
|
import { promises as fs } from 'fs'
|
||||||
|
import * as path from 'path'
|
||||||
import { BetaDatabase } from '@miniflare/d1'
|
import { BetaDatabase } from '@miniflare/d1'
|
||||||
import * as Database from 'better-sqlite3'
|
import * as Database from 'better-sqlite3'
|
||||||
|
|
||||||
|
@ -21,8 +22,12 @@ export async function makeDB(): Promise<any> {
|
||||||
const db2 = new BetaDatabase(db)!
|
const db2 = new BetaDatabase(db)!
|
||||||
|
|
||||||
// Manually run our migrations since @miniflare/d1 doesn't support it (yet).
|
// Manually run our migrations since @miniflare/d1 doesn't support it (yet).
|
||||||
const initial = await fs.readFile('./migrations/0000_initial.sql', 'utf-8')
|
const migrations = await fs.readdir('./migrations/')
|
||||||
await db.exec(initial)
|
|
||||||
|
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
|
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