kopia lustrzana https://github.com/cloudflare/wildebeest
MOW-107: post in reply to
rodzic
29923fcf92
commit
fb88422a67
|
@ -38,13 +38,13 @@ export async function createPublicNote(
|
|||
cc: [followersURL(actorId)],
|
||||
|
||||
// FIXME: stub values
|
||||
inReplyTo: null,
|
||||
replies: null,
|
||||
sensitive: false,
|
||||
summary: null,
|
||||
tag: [],
|
||||
attachment,
|
||||
|
||||
inReplyTo: null,
|
||||
...extraProperties,
|
||||
}
|
||||
|
||||
|
|
|
@ -37,3 +37,7 @@ export function clientUnknown(): Response {
|
|||
export function internalServerError(): Response {
|
||||
return generateErrorResponse('Internal Server Error', 500)
|
||||
}
|
||||
|
||||
export function statusNotFound(): Response {
|
||||
return generateErrorResponse('Status not found', 404)
|
||||
}
|
||||
|
|
|
@ -543,5 +543,70 @@ describe('Mastodon APIs', () => {
|
|||
assert.equal(deliveredActivity.object, originalObjectId)
|
||||
})
|
||||
})
|
||||
|
||||
test('create new status in reply to non existing status', async () => {
|
||||
const db = await makeDB()
|
||||
const queue = makeQueue()
|
||||
const actor = await createPerson(domain, db, userKEK, 'sven@cloudflare.com')
|
||||
|
||||
const body = {
|
||||
status: 'my reply',
|
||||
in_reply_to_id: 'hein',
|
||||
visibility: 'public',
|
||||
}
|
||||
const req = new Request('https://example.com', {
|
||||
method: 'POST',
|
||||
headers: { 'content-type': 'application/json' },
|
||||
body: JSON.stringify(body),
|
||||
})
|
||||
|
||||
const res = await statuses.handleRequest(req, db, actor, userKEK, queue, kv_cache)
|
||||
assert.equal(res.status, 404)
|
||||
})
|
||||
|
||||
test('create new status in reply to', async () => {
|
||||
const db = await makeDB()
|
||||
const queue = makeQueue()
|
||||
const actor = await createPerson(domain, db, userKEK, 'sven@cloudflare.com')
|
||||
const note = await createPublicNote(domain, db, 'my first status', actor)
|
||||
|
||||
const body = {
|
||||
status: 'my reply',
|
||||
in_reply_to_id: note.mastodonId,
|
||||
visibility: 'public',
|
||||
}
|
||||
const req = new Request('https://example.com', {
|
||||
method: 'POST',
|
||||
headers: { 'content-type': 'application/json' },
|
||||
body: JSON.stringify(body),
|
||||
})
|
||||
|
||||
const res = await statuses.handleRequest(req, db, actor, userKEK, queue, kv_cache)
|
||||
assert.equal(res.status, 200)
|
||||
|
||||
const data = await res.json<any>()
|
||||
|
||||
{
|
||||
const row = await db
|
||||
.prepare(
|
||||
`
|
||||
SELECT json_extract(properties, '$.inReplyTo') as inReplyTo
|
||||
FROM objects
|
||||
WHERE mastodon_id=?
|
||||
`
|
||||
)
|
||||
.bind(data.id)
|
||||
.first()
|
||||
assert(row !== undefined)
|
||||
assert.equal(row.inReplyTo, note.id.toString())
|
||||
}
|
||||
|
||||
{
|
||||
const row = await db.prepare('select * from actor_replies').first()
|
||||
assert(row !== undefined)
|
||||
assert.equal(row.actor_id, actor.id.toString())
|
||||
assert.equal(row.in_reply_to_object_id, note.id.toString())
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// https://docs.joinmastodon.org/methods/statuses/#create
|
||||
|
||||
import { cors } from 'wildebeest/backend/src/utils/cors'
|
||||
import type { Object } from 'wildebeest/backend/src/activitypub/objects'
|
||||
import { insertReply } from 'wildebeest/backend/src/mastodon/reply'
|
||||
import * as timeline from 'wildebeest/backend/src/mastodon/timeline'
|
||||
import type { Queue, DeliverMessageBody } from 'wildebeest/backend/src/types/queue'
|
||||
import { loadLocalMastodonAccount } from 'wildebeest/backend/src/mastodon/account'
|
||||
|
@ -17,12 +19,14 @@ import { addObjectInOutbox } from 'wildebeest/backend/src/activitypub/actors/out
|
|||
import type { Person } from 'wildebeest/backend/src/activitypub/actors'
|
||||
import { getSigningKey } from 'wildebeest/backend/src/mastodon/account'
|
||||
import { readBody } from 'wildebeest/backend/src/utils/body'
|
||||
import * as errors from 'wildebeest/backend/src/errors'
|
||||
|
||||
type StatusCreate = {
|
||||
status: string
|
||||
visibility: string
|
||||
sensitive: boolean
|
||||
media_ids?: Array<string>
|
||||
in_reply_to_id?: string
|
||||
}
|
||||
|
||||
export const onRequest: PagesFunction<Env, any, ContextData> = async ({ request, env, data }) => {
|
||||
|
@ -65,10 +69,29 @@ export async function handleRequest(
|
|||
}
|
||||
}
|
||||
|
||||
let inReplyToObject: Object | null = null
|
||||
|
||||
if (body.in_reply_to_id) {
|
||||
inReplyToObject = await getObjectByMastodonId(db, body.in_reply_to_id)
|
||||
if (inReplyToObject === null) {
|
||||
return errors.statusNotFound()
|
||||
}
|
||||
}
|
||||
|
||||
const extraProperties: any = {}
|
||||
if (inReplyToObject !== null) {
|
||||
extraProperties.inReplyTo = inReplyToObject.id.toString()
|
||||
}
|
||||
|
||||
const domain = new URL(request.url).hostname
|
||||
const note = await createPublicNote(domain, db, body.status, connectedActor, mediaAttachments)
|
||||
const note = await createPublicNote(domain, db, body.status, connectedActor, mediaAttachments, extraProperties)
|
||||
await addObjectInOutbox(db, connectedActor, note)
|
||||
|
||||
if (inReplyToObject !== null) {
|
||||
// after the status has been created, record the reply.
|
||||
await insertReply(db, connectedActor, note, inReplyToObject)
|
||||
}
|
||||
|
||||
const activity = activities.create(domain, connectedActor, note)
|
||||
await deliverFollowers(db, userKEK, connectedActor, activity, queue)
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue