From 1636b6671d84e7f9690474a107cc31e983516784 Mon Sep 17 00:00:00 2001 From: Tom Casavant Date: Fri, 12 Apr 2024 10:52:11 -0400 Subject: [PATCH 1/4] Added profile fields for testing --- account.json.example | 9 ++++++++- src/activity-pub-db.js | 2 ++ src/activitypub.js | 31 +++++++++++++++++++++++++++++++ src/pages/about.hbs | 18 +++++++++++++++--- 4 files changed, 56 insertions(+), 4 deletions(-) diff --git a/account.json.example b/account.json.example index e095d76..7525986 100644 --- a/account.json.example +++ b/account.json.example @@ -2,5 +2,12 @@ "username": "bookmarks", "avatar": "https://cdn.glitch.global/8eaf209c-2fa9-4353-9b99-e8d8f3a5f8d4/postmarks-logo-white-small.png?v=1693610556689", "displayName": "Postmarks", - "description": "An ActivityPub bookmarking and sharing site built with Postmarks" + "description": "An ActivityPub bookmarking and sharing site built with Postmarks", + "attachment": [ + { + "type": "PropertyValue", + "name": "Source Code", + "value": "https://github.com/ckolderup/postmarks" + } + ] } diff --git a/src/activity-pub-db.js b/src/activity-pub-db.js index f26fdf3..d843dca 100644 --- a/src/activity-pub-db.js +++ b/src/activity-pub-db.js @@ -11,6 +11,7 @@ import sqlite3 from 'sqlite3'; import { open } from 'sqlite'; import crypto from 'crypto'; import { account, domain, actorInfo } from './util.js'; +import { updateProfile } from './activitypub.js' const dbFile = './.data/activitypub.db'; let db; @@ -245,6 +246,7 @@ function setup() { const publicKey = await getPublicKey(); const actorRecord = actorJson(publicKey); await db.run('UPDATE accounts SET name = ?, actor = ?', actorName, JSON.stringify(actorRecord)); + //updateProfile(account, domain) // Uncomment this line to send a profile update to all followers } catch (dbError) { console.error(dbError); } diff --git a/src/activitypub.js b/src/activitypub.js index 09fd880..dbb66dd 100644 --- a/src/activitypub.js +++ b/src/activitypub.js @@ -4,6 +4,7 @@ import escapeHTML from 'escape-html'; import { signedGetJSON, signedPostJSON } from './signature.js'; import { actorInfo, actorMatchesUsername, replaceEmptyText } from './util.js'; +import * as apDb from './activity-pub-db.js' function getGuidFromPermalink(urlString) { return urlString.match(/(?:\/m\/)([a-zA-Z0-9+/]+)/)[1]; @@ -267,6 +268,36 @@ export async function broadcastMessage(bookmark, action, db, account, domain) { } } + +export async function updateProfile(account, domain) { + if (actorInfo.disabled) { + return; // no fediverse setup + } + const publicKey = await apDb.getPublicKey() + const actorRecord = apDb.actorJson(publicKey) + + const guidUpdate = crypto.randomBytes(16).toString('hex'); + const updateMessage = { + '@context': ['https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1'], + type: 'Update', + id: `https://${domain}/m/${guidUpdate}`, + actor: `https://${domain}/u/${account}`, + to: ['https://www.w3.org/ns/activitystreams#Public'], + object: actorRecord, + }; + + apDb.insertMessage(guidUpdate, null, JSON.stringify(updateMessage)); + const result = await apDb.getFollowers(); + const followers = JSON.parse(result); + // eslint-disable-next-line no-restricted-syntax + for (const follower of followers) { + const myURL = new URL(follower); + const targetDomain = myURL.host; + const inbox = `https://${targetDomain}/inbox`; + signAndSend(updateMessage, account, domain, apDb, targetDomain, inbox); + } +} + export function synthesizeActivity(note) { return { // Fake activity URI adds a "a-" prefix to the Note/message guid diff --git a/src/pages/about.hbs b/src/pages/about.hbs index b6a26d2..3ba8f5c 100644 --- a/src/pages/about.hbs +++ b/src/pages/about.hbs @@ -11,9 +11,21 @@ {{else}}
-

- {{actorInfo.description}} -

+
+

+ {{{actorInfo.description}}} +

+ + + {{#each actorInfo.attachment}} + + + + + {{/each}} + +
{{name}}: {{{value}}}
+

Follow on the Fediverse From 7ebfc7b887174e4531bdb23af9383a75b674450c Mon Sep 17 00:00:00 2001 From: Tom Casavant Date: Fri, 12 Apr 2024 11:03:04 -0400 Subject: [PATCH 2/4] Added attachments to actor json --- src/activity-pub-db.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/activity-pub-db.js b/src/activity-pub-db.js index d843dca..8ab8fd6 100644 --- a/src/activity-pub-db.js +++ b/src/activity-pub-db.js @@ -16,7 +16,7 @@ import { updateProfile } from './activitypub.js' const dbFile = './.data/activitypub.db'; let db; -function actorJson(pubkey) { +export function actorJson(pubkey) { return { '@context': ['https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1'], @@ -34,6 +34,7 @@ function actorJson(pubkey) { outbox: `https://${domain}/u/${account}/outbox`, followers: `https://${domain}/u/${account}/followers`, following: `https://${domain}/u/${account}/following`, + attachment: actorInfo.attachment, publicKey: { id: `https://${domain}/u/${account}#main-key`, From 237052a04ef3fa8c48f2974fbdb7ade2a5daaa5a Mon Sep 17 00:00:00 2001 From: Tom Casavant Date: Fri, 12 Apr 2024 12:05:05 -0400 Subject: [PATCH 3/4] Fixed some linting issues --- src/activity-pub-db.js | 4 ++-- src/activitypub.js | 19 +++++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/activity-pub-db.js b/src/activity-pub-db.js index 8ab8fd6..125f7a2 100644 --- a/src/activity-pub-db.js +++ b/src/activity-pub-db.js @@ -11,7 +11,7 @@ import sqlite3 from 'sqlite3'; import { open } from 'sqlite'; import crypto from 'crypto'; import { account, domain, actorInfo } from './util.js'; -import { updateProfile } from './activitypub.js' +import { updateProfile } from './activitypub.js'; const dbFile = './.data/activitypub.db'; let db; @@ -247,7 +247,7 @@ function setup() { const publicKey = await getPublicKey(); const actorRecord = actorJson(publicKey); await db.run('UPDATE accounts SET name = ?, actor = ?', actorName, JSON.stringify(actorRecord)); - //updateProfile(account, domain) // Uncomment this line to send a profile update to all followers + // updateProfile(account, domain) // Uncomment this line to send a profile update to all followers } catch (dbError) { console.error(dbError); } diff --git a/src/activitypub.js b/src/activitypub.js index dbb66dd..62fd90c 100644 --- a/src/activitypub.js +++ b/src/activitypub.js @@ -4,7 +4,7 @@ import escapeHTML from 'escape-html'; import { signedGetJSON, signedPostJSON } from './signature.js'; import { actorInfo, actorMatchesUsername, replaceEmptyText } from './util.js'; -import * as apDb from './activity-pub-db.js' +import * as apDb from './activity-pub-db.js'; function getGuidFromPermalink(urlString) { return urlString.match(/(?:\/m\/)([a-zA-Z0-9+/]+)/)[1]; @@ -268,14 +268,13 @@ export async function broadcastMessage(bookmark, action, db, account, domain) { } } - export async function updateProfile(account, domain) { if (actorInfo.disabled) { return; // no fediverse setup } - const publicKey = await apDb.getPublicKey() - const actorRecord = apDb.actorJson(publicKey) - + const publicKey = await apDb.getPublicKey(); + const actorRecord = apDb.actorJson(publicKey); + const guidUpdate = crypto.randomBytes(16).toString('hex'); const updateMessage = { '@context': ['https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1'], @@ -285,16 +284,16 @@ export async function updateProfile(account, domain) { to: ['https://www.w3.org/ns/activitystreams#Public'], object: actorRecord, }; - + apDb.insertMessage(guidUpdate, null, JSON.stringify(updateMessage)); const result = await apDb.getFollowers(); const followers = JSON.parse(result); // eslint-disable-next-line no-restricted-syntax for (const follower of followers) { - const myURL = new URL(follower); - const targetDomain = myURL.host; - const inbox = `https://${targetDomain}/inbox`; - signAndSend(updateMessage, account, domain, apDb, targetDomain, inbox); + const myURL = new URL(follower); + const targetDomain = myURL.host; + const inbox = `https://${targetDomain}/inbox`; + signAndSend(updateMessage, account, domain, apDb, targetDomain, inbox); } } From 637884b919012d815228fb2caf8ce3dfd7f6e86a Mon Sep 17 00:00:00 2001 From: Tom Casavant Date: Fri, 12 Apr 2024 13:11:26 -0400 Subject: [PATCH 4/4] Moved updateProfile calls to fix linting issues --- server.js | 4 ++++ src/activity-pub-db.js | 2 -- src/activitypub.js | 13 ++++++------- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/server.js b/server.js index cd31faa..da0be6b 100644 --- a/server.js +++ b/server.js @@ -10,6 +10,7 @@ import * as bookmarksDb from './src/bookmarks-db.js'; import * as apDb from './src/activity-pub-db.js'; import routes from './src/routes/index.js'; +import { updateProfile } from './src/activitypub.js'; dotenv.config(); @@ -132,3 +133,6 @@ app.use('/nodeinfo/2.1', routes.nodeinfo); app.use('/opensearch.xml', routes.opensearch); app.listen(PORT, () => console.log(`App listening on port ${PORT}`)); +app.on('listening', function () { + // updateProfile(apDb, account, domain); +}); diff --git a/src/activity-pub-db.js b/src/activity-pub-db.js index 125f7a2..d68cb08 100644 --- a/src/activity-pub-db.js +++ b/src/activity-pub-db.js @@ -11,7 +11,6 @@ import sqlite3 from 'sqlite3'; import { open } from 'sqlite'; import crypto from 'crypto'; import { account, domain, actorInfo } from './util.js'; -import { updateProfile } from './activitypub.js'; const dbFile = './.data/activitypub.db'; let db; @@ -247,7 +246,6 @@ function setup() { const publicKey = await getPublicKey(); const actorRecord = actorJson(publicKey); await db.run('UPDATE accounts SET name = ?, actor = ?', actorName, JSON.stringify(actorRecord)); - // updateProfile(account, domain) // Uncomment this line to send a profile update to all followers } catch (dbError) { console.error(dbError); } diff --git a/src/activitypub.js b/src/activitypub.js index 62fd90c..c2d80bd 100644 --- a/src/activitypub.js +++ b/src/activitypub.js @@ -4,7 +4,6 @@ import escapeHTML from 'escape-html'; import { signedGetJSON, signedPostJSON } from './signature.js'; import { actorInfo, actorMatchesUsername, replaceEmptyText } from './util.js'; -import * as apDb from './activity-pub-db.js'; function getGuidFromPermalink(urlString) { return urlString.match(/(?:\/m\/)([a-zA-Z0-9+/]+)/)[1]; @@ -268,12 +267,12 @@ export async function broadcastMessage(bookmark, action, db, account, domain) { } } -export async function updateProfile(account, domain) { +export async function updateProfile(db, account, domain) { if (actorInfo.disabled) { return; // no fediverse setup } - const publicKey = await apDb.getPublicKey(); - const actorRecord = apDb.actorJson(publicKey); + const publicKey = await db.getPublicKey(); + const actorRecord = db.actorJson(publicKey); const guidUpdate = crypto.randomBytes(16).toString('hex'); const updateMessage = { @@ -285,15 +284,15 @@ export async function updateProfile(account, domain) { object: actorRecord, }; - apDb.insertMessage(guidUpdate, null, JSON.stringify(updateMessage)); - const result = await apDb.getFollowers(); + db.insertMessage(guidUpdate, null, JSON.stringify(updateMessage)); + const result = await db.getFollowers(); const followers = JSON.parse(result); // eslint-disable-next-line no-restricted-syntax for (const follower of followers) { const myURL = new URL(follower); const targetDomain = myURL.host; const inbox = `https://${targetDomain}/inbox`; - signAndSend(updateMessage, account, domain, apDb, targetDomain, inbox); + signAndSend(updateMessage, account, domain, db, targetDomain, inbox); } }