From 09395afa8d9bd98324230d6fdc7f13f24aaa769d Mon Sep 17 00:00:00 2001 From: s-ol Date: Fri, 14 Jan 2022 18:26:35 +0100 Subject: server: ActivityStreams reply/link/unlink API --- server/main.ts | 111 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 83 insertions(+), 28 deletions(-) (limited to 'server') diff --git a/server/main.ts b/server/main.ts index 02d5933..7cb21a0 100644 --- a/server/main.ts +++ b/server/main.ts @@ -23,19 +23,47 @@ if (DEBUG) { app.use(express.json()); app.use(cookieParser()); +type LinkOr = string | T; + +type Person = { + id: string; + type: 'Person', + name: string; +}; + type Note = { type: 'Note'; published: string; - attributedTo: string | { - id: string; - type: 'Person', - name: string; - }; + attributedTo: LinkOr; inReplyTo: string[]; replies: string[]; content: string; }; +type Relationship = { + type: 'Relationship'; + relationship: string; + subject: S; + object: O; +}; + +type Create = { + type: 'Create'; + actor: LinkOr; + object: O; +}; + +type Delete = { + type: 'Create'; + actor: LinkOr; + object: O; +}; + +const iri2id = (iri: string) => { + const parts = iri.split('/'); + return parts[parts.length - 1]; +}; + const discdag = express() .post('/login', wrap(async ($req, $res) => { const { username, password } = $req.body; @@ -189,7 +217,6 @@ const discdag = express() { items: { '@id': 'as:items', - '@type': '@id', '@container': '@id' }, }, @@ -202,30 +229,51 @@ const discdag = express() }); })) - .put('/disc/:discussion', wrap(async ($req, $res) => { - const { inReplyTo, content } = $req.body as { inReplyTo: string[], content: string }; + .post('/disc/:discussion', wrap(async ($req, $res) => { const { discussion } = $req.params; const { digest } = $req.cookies; if (!digest || !digest.length) return $res.status(401).end(); - if (!inReplyTo.length || !content.length) - return $res.status(400).end(); + type Activity = + | Create + | Create> + | Delete> + ; + const activity = $req.body as Activity; + + let selection: string[]; + let body: string; + let method = 'GET'; + if (activity.type === 'Create' && activity.object?.type === 'Note') { + method = 'POST'; + selection = activity.object.inReplyTo.map(iri2id); + body = new URLSearchParams({ Action: 'SendReply', ReplyText: activity.object.content }).toString(); + } else if (activity.object?.type === 'Relationship' && activity.object.relationship === 'as:inReplyTo') { + const frm = iri2id(activity.object.object); + const to = iri2id(activity.object.subject); + selection = [frm, to]; + body = new URLSearchParams({ + Action: activity.type === 'Create' ? 'CreateLink' : 'RemoveLink', + N0: frm, + N1: to, + }).toString(); + } else { + return $res.status(501).end(); + } - const parents = inReplyTo.map(id => { - const parts = id.split('/'); - return parts[parts.length - 1]; - }).join(','); + const headers = { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Cookie': `DiscussionID=${discussion}; digest=${digest}; SelectedNodes=${selection.join(',')}`, + }; - const res = await fetch(DISCDAG_URL, { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Cookie': `DiscussionID=${discussion}; digest=${digest}; SelectedNodes=${parents}`, - }, - body: new URLSearchParams({ Action: 'SendReply', ReplyText: content }).toString(), - }); + let res; + if (method === 'POST') { + res = await fetch(DISCDAG_URL, { method, headers, body }); + } else { + res = await fetch(DISCDAG_URL + `?${body}`, { method, headers }); + } if (res.status !== 200) throw new Error("bad response"); @@ -271,11 +319,18 @@ const discdag = express() items[to]?.inReplyTo.push(frm); } - return $res - .json({ - '@context': 'https://www.w3.org/ns/activitystreams', - items, - }); + return $res.json({ + '@context': [ + 'https://www.w3.org/ns/activitystreams', + { + items: { + '@id': 'as:items', + '@container': '@id' + }, + }, + ], + items, + }); })) ; @@ -318,7 +373,7 @@ app.get(/\/remote\/.*/, wrap(async ($req, $res) => { try { app.listen(PORT, (): void => { - console.log(`Connected successfully on port ${PORT}`); + console.log(`Connected successfully on port ${PORT}`); }); } catch (error) { console.error(`Error occured: ${error}`); -- cgit v1.2.3