Skip to content

Commit df0324f

Browse files
Address Copilot review on JavaScriptSolidServer#283
1. ActivityPub routes updated. src/ap/index.js still registered the plugin-level endpoints (/profile/card/inbox, /profile/card/outbox, /profile/card/followers, /profile/card/following) on the old path, plus every actorId/actorUrl/profileUrl in src/ap/routes/* and src/ap/keys.js built the legacy /profile/card URL. Auth-bypass in server.js already listed the .jsonld versions, so without this fix remote AP requests would have started 401'ing. All ten files under src/ap/ now use /profile/card.jsonld consistently. 2. Single-user existence check is backward-compatible. Earlier this PR checked only profile/card.jsonld, so a pod created by an older JSS version (legacy extensionless card) would be treated as missing and the startup hook would overwrite /.acl and /settings/* on boot. Accept either /profile/card.jsonld or /profile/card as the "pod already exists" indicator. 3. Stale comments. src/handlers/container.js and src/idp/interactions.js still documented the WebID as "/alice/profile/card#me"; updated to match the generated `.jsonld#me` URLs.
1 parent 489beb9 commit df0324f

10 files changed

Lines changed: 30 additions & 27 deletions

File tree

src/ap/index.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export async function activityPubPlugin(fastify, options = {}) {
6868
const getActorId = (request) => {
6969
const protocol = getProtocol(request)
7070
const host = request.headers['x-forwarded-host'] || request.hostname
71-
return `${protocol}://${host}/profile/card#me`
71+
return `${protocol}://${host}/profile/card.jsonld#me`
7272
}
7373

7474
// Helper to get base URL
@@ -96,11 +96,11 @@ export async function activityPubPlugin(fastify, options = {}) {
9696
return reply.code(404).send({ error: 'Not found' })
9797
}
9898

99-
// For now, accept any username and map to /profile/card#me
99+
// For now, accept any username and map to /profile/card.jsonld#me
100100
// In multi-user mode, we'd look up the user
101101
const baseUrl = getBaseUrl(request)
102-
const actorUrl = `${baseUrl}/profile/card#me`
103-
const profileUrl = `${baseUrl}/profile/card`
102+
const actorUrl = `${baseUrl}/profile/card.jsonld#me`
103+
const profileUrl = `${baseUrl}/profile/card.jsonld`
104104

105105
const response = webfinger.createResponse(
106106
`${parsed.username}@${parsed.domain}`,
@@ -174,18 +174,18 @@ export async function activityPubPlugin(fastify, options = {}) {
174174
// Inbox endpoint
175175
const inboxHandler = createInboxHandler(config, keypair)
176176
fastify.post('/inbox', inboxHandler)
177-
fastify.post('/profile/card/inbox', inboxHandler)
177+
fastify.post('/profile/card.jsonld/inbox', inboxHandler)
178178

179179
// Outbox endpoint
180180
const outboxHandler = createOutboxHandler(config, keypair)
181181
const outboxPostHandler = createOutboxPostHandler(config, keypair)
182-
fastify.get('/profile/card/outbox', outboxHandler)
183-
fastify.post('/profile/card/outbox', outboxPostHandler)
182+
fastify.get('/profile/card.jsonld/outbox', outboxHandler)
183+
fastify.post('/profile/card.jsonld/outbox', outboxPostHandler)
184184

185185
// Followers/Following collections
186186
const collectionsHandler = createCollectionsHandler(config)
187-
fastify.get('/profile/card/followers', (req, reply) => collectionsHandler(req, reply, 'followers'))
188-
fastify.get('/profile/card/following', (req, reply) => collectionsHandler(req, reply, 'following'))
187+
fastify.get('/profile/card.jsonld/followers', (req, reply) => collectionsHandler(req, reply, 'followers'))
188+
fastify.get('/profile/card.jsonld/following', (req, reply) => collectionsHandler(req, reply, 'following'))
189189

190190
// Mastodon-compatible API endpoints
191191
fastify.post('/api/v1/apps', createAppsHandler())

src/ap/keys.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ export function loadOrCreateKeypair(path = DEFAULT_KEY_PATH) {
5252

5353
/**
5454
* Get key ID for HTTP Signatures
55-
* @param {string} actorId - Actor URL (e.g., https://example.com/profile/card#me)
56-
* @returns {string} Key ID (e.g., https://example.com/profile/card#main-key)
55+
* @param {string} actorId - Actor URL (e.g., https://example.com/profile/card.jsonld#me)
56+
* @returns {string} Key ID (e.g., https://example.com/profile/card.jsonld#main-key)
5757
*/
5858
export function getKeyId(actorId) {
5959
// Strip fragment and add #main-key

src/ap/routes/actor.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export function createActorHandler(config, keypair) {
3030
}
3131
protocol = protocol || request.protocol
3232
const baseUrl = `${protocol}://${host}`
33-
const profileUrl = `${baseUrl}/profile/card`
33+
const profileUrl = `${baseUrl}/profile/card.jsonld`
3434
const actorId = `${profileUrl}#me`
3535

3636
const actor = {

src/ap/routes/collections.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export function createCollectionsHandler(config) {
1515
const protocol = request.headers['x-forwarded-proto'] || request.protocol
1616
const host = request.headers['x-forwarded-host'] || request.hostname
1717
const baseUrl = `${protocol}://${host}`
18-
const profileUrl = `${baseUrl}/profile/card`
18+
const profileUrl = `${baseUrl}/profile/card.jsonld`
1919

2020
let items, totalItems
2121

src/ap/routes/inbox.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ export function createInboxHandler(config, keypair) {
150150
const protocol = request.headers['x-forwarded-proto'] || request.protocol
151151
const host = request.headers['x-forwarded-host'] || request.hostname
152152
const baseUrl = `${protocol}://${host}`
153-
const profileUrl = `${baseUrl}/profile/card`
153+
const profileUrl = `${baseUrl}/profile/card.jsonld`
154154
const actorId = `${profileUrl}#me`
155155

156156
request.log.info(`Received ${activity.type} from ${activity.actor}`)

src/ap/routes/mastodon.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ export function createVerifyCredentialsHandler (config) {
7878
acct: config.username,
7979
display_name: config.displayName,
8080
note: config.summary ? `<p>${escapeHtml(config.summary)}</p>` : '',
81-
url: `${baseUrl}/profile/card`,
82-
uri: `${baseUrl}/profile/card#me`,
81+
url: `${baseUrl}/profile/card.jsonld`,
82+
uri: `${baseUrl}/profile/card.jsonld#me`,
8383
avatar: `${baseUrl}/profile/avatar.png`,
8484
header: '',
8585
locked: false,

src/ap/routes/outbox.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export function createOutboxHandler(config, keypair) {
1919
const protocol = request.headers['x-forwarded-proto'] || request.protocol
2020
const host = request.headers['x-forwarded-host'] || request.hostname
2121
const baseUrl = `${protocol}://${host}`
22-
const profileUrl = `${baseUrl}/profile/card`
22+
const profileUrl = `${baseUrl}/profile/card.jsonld`
2323
const actorId = `${profileUrl}#me`
2424

2525
const posts = getPosts(20)
@@ -63,7 +63,7 @@ export function createOutboxPostHandler(config, keypair) {
6363
const protocol = request.headers['x-forwarded-proto'] || request.protocol
6464
const host = request.headers['x-forwarded-host'] || request.hostname
6565
const baseUrl = `${protocol}://${host}`
66-
const profileUrl = `${baseUrl}/profile/card`
66+
const profileUrl = `${baseUrl}/profile/card.jsonld`
6767
const actorId = `${profileUrl}#me`
6868

6969
// Parse body

src/handlers/container.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -272,20 +272,19 @@ export async function handleCreatePod(request, reply) {
272272
return reply.code(409).send({ error: 'Pod already exists' });
273273
}
274274

275-
// Build URIs
276-
// WebID follows standard Solid convention: /alice/profile/card#me
275+
// Build URIs. WebID is the JSON-LD profile with an #me fragment.
277276
const subdomainsEnabled = request.subdomainsEnabled;
278277
const baseDomain = request.baseDomain;
279278

280279
let baseUri, podUri, webId;
281280
if (subdomainsEnabled && baseDomain) {
282-
// Subdomain mode: alice.example.com/profile/card#me
281+
// Subdomain mode: alice.example.com/profile/card.jsonld#me
283282
const podHost = `${name}.${baseDomain}`;
284283
baseUri = `${request.protocol}://${baseDomain}`;
285284
podUri = `${request.protocol}://${podHost}/`;
286285
webId = `${podUri}profile/card.jsonld#me`;
287286
} else {
288-
// Path mode: example.com/alice/profile/card#me
287+
// Path mode: example.com/alice/profile/card.jsonld#me
289288
baseUri = `${request.protocol}://${request.hostname}`;
290289
podUri = `${baseUri}${podPath}`;
291290
webId = `${podUri}profile/card.jsonld#me`;

src/idp/interactions.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -405,18 +405,18 @@ export async function handleRegisterPost(request, reply, issuer, inviteOnly = fa
405405
}
406406

407407
try {
408-
// Build URLs - WebID follows standard Solid convention: /profile/card#me
408+
// Build URLs. WebID is the JSON-LD profile with an #me fragment.
409409
const subdomainsEnabled = request.subdomainsEnabled;
410410
const baseDomain = request.baseDomain;
411411
const baseUrl = issuer.endsWith('/') ? issuer.slice(0, -1) : issuer;
412412

413413
let podUri, webId;
414414
if (subdomainsEnabled && baseDomain) {
415-
// Subdomain mode: alice.example.com/profile/card#me
415+
// Subdomain mode: alice.example.com/profile/card.jsonld#me
416416
podUri = `${request.protocol}://${username}.${baseDomain}/`;
417417
webId = `${podUri}profile/card.jsonld#me`;
418418
} else {
419-
// Path mode: example.com/alice/profile/card#me
419+
// Path mode: example.com/alice/profile/card.jsonld#me
420420
podUri = `${baseUrl}/${username}/`;
421421
webId = `${podUri}profile/card.jsonld#me`;
422422
}

src/server.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -560,8 +560,12 @@ export function createServer(options = {}) {
560560
const webId = `${podUri}profile/card.jsonld#me`;
561561
const displayName = isRootPod ? 'me' : singleUserName;
562562

563-
// Check if pod already exists (profile/card.jsonld is the indicator)
564-
const profileExists = await storage.exists(`${podPath}profile/card.jsonld`);
563+
// Check if pod already exists. Accept either the new `card.jsonld`
564+
// or legacy extensionless `card` layout so we don't re-seed a pod
565+
// that was created by an older JSS version.
566+
const profileExists =
567+
await storage.exists(`${podPath}profile/card.jsonld`) ||
568+
await storage.exists(`${podPath}profile/card`);
565569

566570
if (!profileExists) {
567571
fastify.log.info(`Creating single-user pod at ${podUri}...`);

0 commit comments

Comments
 (0)