From a7194027d8b2a9a0d427421b4004d66d1af41835 Mon Sep 17 00:00:00 2001 From: Christian Beutel <> Date: Fri, 4 Jul 2025 11:11:56 +0200 Subject: [PATCH] allows public acces to public profiles --- db/federation/actor.go | 50 ++++++++++--------- web/src/lib/stores/follow_store.ts | 2 +- web/src/lib/util/authorization_util.ts | 1 - web/src/routes/api/v1/follow/+server.ts | 2 +- .../routes/profile/[handle]/+layout.server.ts | 4 +- .../routes/profile/[handle]/+layout.svelte | 2 +- 6 files changed, 31 insertions(+), 30 deletions(-) diff --git a/db/federation/actor.go b/db/federation/actor.go index aed47492..aeb81df7 100644 --- a/db/federation/actor.go +++ b/db/federation/actor.go @@ -325,32 +325,34 @@ func FetchCollection(actor *core.Record, url string) (*pub.OrderedCollection, er req.Header.Add(k, v) } - dbPrivateKey := actor.GetString("private_key") - if dbPrivateKey != "" { - algs := []httpsig.Algorithm{httpsig.RSA_SHA256} - postHeaders := []string{"(request-target)", "Date", "Digest", "Content-Type", "Host"} - expiresIn := 60 + if actor != nil && actor.GetString("private_key") != "" { + dbPrivateKey := actor.GetString("private_key") + if dbPrivateKey != "" { + algs := []httpsig.Algorithm{httpsig.RSA_SHA256} + postHeaders := []string{"(request-target)", "Date", "Digest", "Content-Type", "Host"} + expiresIn := 60 + + signer, _, err := httpsig.NewSigner(algs, httpsig.DigestSha256, postHeaders, httpsig.Signature, int64(expiresIn)) + if err != nil { + return nil, err + } + + decryptedPrivateKey, err := security.Decrypt(dbPrivateKey, encryptionKey) + if err != nil { + return nil, err + } + privateKey, err := x509.ParsePKCS1PrivateKey(decryptedPrivateKey) + if err != nil { + return nil, err + } + + pubID := actor.GetString("iri") + "#main-key" + + if err := signer.SignRequest(privateKey, pubID, req, []byte{}); err != nil { + return nil, err + } - signer, _, err := httpsig.NewSigner(algs, httpsig.DigestSha256, postHeaders, httpsig.Signature, int64(expiresIn)) - if err != nil { - return nil, err } - - decryptedPrivateKey, err := security.Decrypt(dbPrivateKey, encryptionKey) - if err != nil { - return nil, err - } - privateKey, err := x509.ParsePKCS1PrivateKey(decryptedPrivateKey) - if err != nil { - return nil, err - } - - pubID := actor.GetString("iri") + "#main-key" - - if err := signer.SignRequest(privateKey, pubID, req, []byte{}); err != nil { - return nil, err - } - } resp, err := http.DefaultClient.Do(req) diff --git a/web/src/lib/stores/follow_store.ts b/web/src/lib/stores/follow_store.ts index 5d9291a7..7b0cb8fc 100644 --- a/web/src/lib/stores/follow_store.ts +++ b/web/src/lib/stores/follow_store.ts @@ -44,7 +44,7 @@ export async function follows_a_b(a: string, b: string, f: (url: RequestInfo | U const response: ListResult = await r.json(); - return response.items.at(0); + return response.items.at(0) ?? null; } export async function follows_create(followee: string) { diff --git a/web/src/lib/util/authorization_util.ts b/web/src/lib/util/authorization_util.ts index c0282b2c..a40efbbd 100644 --- a/web/src/lib/util/authorization_util.ts +++ b/web/src/lib/util/authorization_util.ts @@ -3,7 +3,6 @@ import { env } from "$env/dynamic/public"; const privateRoutes = [ "/settings", "/trail/edit/new", - "/profile", "/lists/edit/new", ] diff --git a/web/src/routes/api/v1/follow/+server.ts b/web/src/routes/api/v1/follow/+server.ts index 5ccc771f..271d1c9c 100644 --- a/web/src/routes/api/v1/follow/+server.ts +++ b/web/src/routes/api/v1/follow/+server.ts @@ -26,7 +26,7 @@ export async function GET(event: RequestEvent) { let followers: APOrderedCollectionPage; // fetch followers locally to not run into auth issues with private profiles - if (actor.id === event.locals.user.actor) { + if (actor.id === event.locals.user?.actor) { const r = await event.fetch(actor[type as "followers" | "following"]! + '?' + new URLSearchParams({ page })) if (!r.ok) { diff --git a/web/src/routes/profile/[handle]/+layout.server.ts b/web/src/routes/profile/[handle]/+layout.server.ts index 0d935ed9..4069a647 100644 --- a/web/src/routes/profile/[handle]/+layout.server.ts +++ b/web/src/routes/profile/[handle]/+layout.server.ts @@ -12,9 +12,9 @@ export const load: ServerLoad = async ({ params, locals, fetch }) => { try { const { actor, profile } = await profile_show(params.handle, fetch); - const isOwnProfile = profile.id === locals.user.actor; + const isOwnProfile = profile.id === locals.user?.actor; - const follow = await follows_a_b(locals.user.actor!, profile.id, fetch) ?? null + const follow = locals.user?.actor ? await follows_a_b(locals.user.actor!, profile.id, fetch) : null return { profile, isOwnProfile, follow: follow, actor } } catch (e) { diff --git a/web/src/routes/profile/[handle]/+layout.svelte b/web/src/routes/profile/[handle]/+layout.svelte index f2534725..59cfc649 100644 --- a/web/src/routes/profile/[handle]/+layout.svelte +++ b/web/src/routes/profile/[handle]/+layout.svelte @@ -134,7 +134,7 @@

{data.profile.following}

{$_("following")}

- {#if !data.isOwnProfile} + {#if !data.isOwnProfile && data.user}