wildebeest/backend/src/mastodon/idempotency.ts

52 wiersze
1.4 KiB
TypeScript

import type { APObject } from 'wildebeest/backend/src/activitypub/objects'
import {
mastodonIdSymbol,
originalActorIdSymbol,
originalObjectIdSymbol,
} from 'wildebeest/backend/src/activitypub/objects'
export async function insertKey(db: D1Database, key: string, obj: APObject): Promise<void> {
const query = `
INSERT INTO idempotency_keys (key, object_id, expires_at)
VALUES (?1, ?2, datetime('now', '+1 hour'))
`
const { success, error } = await db.prepare(query).bind(key, obj.id.toString()).run()
if (!success) {
throw new Error('SQL error: ' + error)
}
}
export async function hasKey(db: D1Database, key: string): Promise<APObject | null> {
const query = `
SELECT objects.*
FROM idempotency_keys
INNER JOIN objects ON objects.id = idempotency_keys.object_id
WHERE idempotency_keys.key = ?1 AND expires_at >= datetime()
`
const { results, success, error } = await db.prepare(query).bind(key).all<any>()
if (!success) {
throw new Error('SQL error: ' + error)
}
if (!results || results.length === 0) {
return null
}
const result = results[0]
const properties = JSON.parse(result.properties)
return {
published: new Date(result.cdate).toISOString(),
...properties,
type: result.type,
id: new URL(result.id),
[mastodonIdSymbol]: result.mastodon_id,
[originalActorIdSymbol]: result.original_actor_id,
[originalObjectIdSymbol]: result.original_object_id,
} as APObject
}