fixes private profile issues
This commit is contained in:
@@ -247,8 +247,9 @@ func fetchRemoteActor(actor *core.Record, iri string, includeFollows bool) (*pub
|
|||||||
req.Header.Add(k, v)
|
req.Header.Add(k, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if actor != nil && actor.GetString("private_key") != "" {
|
||||||
dbPrivateKey := actor.GetString("private_key")
|
dbPrivateKey := actor.GetString("private_key")
|
||||||
if dbPrivateKey != "" {
|
|
||||||
algs := []httpsig.Algorithm{httpsig.RSA_SHA256}
|
algs := []httpsig.Algorithm{httpsig.RSA_SHA256}
|
||||||
postHeaders := []string{"(request-target)", "Date", "Digest", "Content-Type", "Host"}
|
postHeaders := []string{"(request-target)", "Date", "Digest", "Content-Type", "Host"}
|
||||||
expiresIn := 60
|
expiresIn := 60
|
||||||
@@ -311,7 +312,6 @@ func FetchCollection(actor *core.Record, url string) (*pub.OrderedCollection, er
|
|||||||
if len(encryptionKey) == 0 {
|
if len(encryptionKey) == 0 {
|
||||||
return nil, fmt.Errorf("POCKETBASE_ENCRYPTION_KEY not set")
|
return nil, fmt.Errorf("POCKETBASE_ENCRYPTION_KEY not set")
|
||||||
}
|
}
|
||||||
|
|
||||||
req, _ := http.NewRequest("GET", url, nil)
|
req, _ := http.NewRequest("GET", url, nil)
|
||||||
|
|
||||||
headers := map[string]string{
|
headers := map[string]string{
|
||||||
@@ -354,9 +354,15 @@ func FetchCollection(actor *core.Record, url string) (*pub.OrderedCollection, er
|
|||||||
}
|
}
|
||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil || resp.StatusCode != http.StatusOK {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("collection fetch failed for %s: %v", url, err)
|
return nil, fmt.Errorf("collection fetch failed for %s: %v", url, err)
|
||||||
}
|
}
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
if resp.StatusCode == http.StatusNotFound {
|
||||||
|
return nil, fmt.Errorf("profile is private")
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("collection fetch %s returned: %v", url, resp.StatusCode)
|
||||||
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
var collection pub.OrderedCollection
|
var collection pub.OrderedCollection
|
||||||
|
|||||||
16
db/main.go
16
db/main.go
@@ -1069,10 +1069,14 @@ func registerRoutes(se *core.ServeEvent, client meilisearch.ServiceManager) {
|
|||||||
iri := e.Request.URL.Query().Get("iri")
|
iri := e.Request.URL.Query().Get("iri")
|
||||||
follows := e.Request.URL.Query().Get("follows") == "true"
|
follows := e.Request.URL.Query().Get("follows") == "true"
|
||||||
|
|
||||||
userActor, err := e.App.FindFirstRecordByData("activitypub_actors", "user", e.Auth.Id)
|
var userActor *core.Record
|
||||||
|
var err error
|
||||||
|
if e.Auth != nil {
|
||||||
|
userActor, err = e.App.FindFirstRecordByData("activitypub_actors", "user", e.Auth.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var actor *core.Record
|
var actor *core.Record
|
||||||
if resource != "" {
|
if resource != "" {
|
||||||
@@ -1088,7 +1092,7 @@ func registerRoutes(se *core.ServeEvent, client meilisearch.ServiceManager) {
|
|||||||
} else if err != nil && actor != nil {
|
} else if err != nil && actor != nil {
|
||||||
if err.Error() == "profile is private" {
|
if err.Error() == "profile is private" {
|
||||||
// this is our own profile
|
// this is our own profile
|
||||||
if actor.GetString("user") == e.Auth.Id {
|
if e.Auth != nil && actor.GetString("user") == e.Auth.Id {
|
||||||
return e.JSON(http.StatusOK, map[string]any{"actor": actor, "error": nil})
|
return e.JSON(http.StatusOK, map[string]any{"actor": actor, "error": nil})
|
||||||
} else {
|
} else {
|
||||||
return e.JSON(http.StatusNotFound, map[string]any{"error": "profile is private"})
|
return e.JSON(http.StatusNotFound, map[string]any{"error": "profile is private"})
|
||||||
@@ -1119,10 +1123,13 @@ func registerRoutes(se *core.ServeEvent, client meilisearch.ServiceManager) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
userActor, err := e.App.FindFirstRecordByData("activitypub_actors", "user", e.Auth.Id)
|
var userActor *core.Record
|
||||||
|
if e.Auth != nil {
|
||||||
|
userActor, err = e.App.FindFirstRecordByData("activitypub_actors", "user", e.Auth.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
url := actor.GetString(followType)
|
url := actor.GetString(followType)
|
||||||
|
|
||||||
@@ -1131,6 +1138,9 @@ func registerRoutes(se *core.ServeEvent, client meilisearch.ServiceManager) {
|
|||||||
}
|
}
|
||||||
collection, err := federation.FetchCollection(userActor, fmt.Sprintf("%s?page=%d", url, intPage))
|
collection, err := federation.FetchCollection(userActor, fmt.Sprintf("%s?page=%d", url, intPage))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if err.Error() == "profile is private" {
|
||||||
|
return e.JSON(http.StatusNotFound, map[string]any{"error": "profile is private"})
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return e.JSON(http.StatusOK, collection)
|
return e.JSON(http.StatusOK, collection)
|
||||||
|
|||||||
@@ -205,7 +205,7 @@
|
|||||||
onmouseenter={() => handleTrailMouseEnter(trail, i)}
|
onmouseenter={() => handleTrailMouseEnter(trail, i)}
|
||||||
onmouseleave={() => handleTrailMouseLeave(trail, i)}
|
onmouseleave={() => handleTrailMouseLeave(trail, i)}
|
||||||
>
|
>
|
||||||
<TrailListItem {trail} showDescription={false}></TrailListItem>
|
<TrailListItem selected={false} hovered={false} {trail} showDescription={false}></TrailListItem>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export async function GET(event: RequestEvent) {
|
|||||||
|
|
||||||
const [username, domain] = splitUsername(fullUsername, env.ORIGIN)
|
const [username, domain] = splitUsername(fullUsername, env.ORIGIN)
|
||||||
|
|
||||||
const actor: Actor = await event.locals.pb.collection("activitypub_actors").getFirstListItem(`username:lower='${username?.toLowerCase()}'&&isLocal=true`)
|
const actor: Actor = await event.locals.pb.collection("activitypub_actors").getFirstListItem(`preferred_username:lower='${username?.toLowerCase()}'&&isLocal=true`)
|
||||||
const user: UserAnonymous = await event.locals.pb.collection("users_anonymous").getOne(actor.user!)
|
const user: UserAnonymous = await event.locals.pb.collection("users_anonymous").getOne(actor.user!)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export async function GET(event: RequestEvent) {
|
|||||||
|
|
||||||
const [username, domain] = splitUsername(fullUsername, env.ORIGIN)
|
const [username, domain] = splitUsername(fullUsername, env.ORIGIN)
|
||||||
|
|
||||||
const actor: Actor = await event.locals.pb.collection("activitypub_actors").getFirstListItem(`username:lower='${username?.toLowerCase()}'&&isLocal=true`)
|
const actor: Actor = await event.locals.pb.collection("activitypub_actors").getFirstListItem(`preferred_username:lower='${username?.toLowerCase()}'&&isLocal=true`)
|
||||||
|
|
||||||
const followers: ListResult<Follow> = await event.locals.pb.collection("follows").getList(intPage, 10, { sort: "-created", filter: `followee='${actor.id}'&&status='accepted'`, expand: "follower" })
|
const followers: ListResult<Follow> = await event.locals.pb.collection("follows").getList(intPage, 10, { sort: "-created", filter: `followee='${actor.id}'&&status='accepted'`, expand: "follower" })
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ export async function GET(event: RequestEvent) {
|
|||||||
...(hasNextPage ? { next: `${id}/outbox?page=${intPage + 1}` } : {}),
|
...(hasNextPage ? { next: `${id}/outbox?page=${intPage + 1}` } : {}),
|
||||||
partOf: id + "/followers",
|
partOf: id + "/followers",
|
||||||
totalItems: followers.totalItems,
|
totalItems: followers.totalItems,
|
||||||
orderedItems: followers.items.map<string>(f => f.expand!.follower.iri)
|
orderedItems: followers.items.filter(f => f.expand?.follower !== undefined).map<string>(f => f.expand!.follower.iri)
|
||||||
}
|
}
|
||||||
|
|
||||||
const headers = new Headers()
|
const headers = new Headers()
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export async function GET(event: RequestEvent) {
|
|||||||
|
|
||||||
const [username, domain] = splitUsername(fullUsername, env.ORIGIN)
|
const [username, domain] = splitUsername(fullUsername, env.ORIGIN)
|
||||||
|
|
||||||
const actor: Actor = await event.locals.pb.collection("activitypub_actors").getFirstListItem(`username:lower='${username?.toLowerCase()}'&&isLocal=true`)
|
const actor: Actor = await event.locals.pb.collection("activitypub_actors").getFirstListItem(`preferred_username:lower='${username?.toLowerCase()}'&&isLocal=true`)
|
||||||
|
|
||||||
const followers: ListResult<Follow> = await event.locals.pb.collection("follows").getList(intPage, 10, { sort: "-created", filter: `follower='${actor.id}'&&status='accepted'`, expand: "followee" })
|
const followers: ListResult<Follow> = await event.locals.pb.collection("follows").getList(intPage, 10, { sort: "-created", filter: `follower='${actor.id}'&&status='accepted'`, expand: "followee" })
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ export async function GET(event: RequestEvent) {
|
|||||||
...(hasNextPage ? { next: `${id}/following?page=${intPage + 1}` } : {}),
|
...(hasNextPage ? { next: `${id}/following?page=${intPage + 1}` } : {}),
|
||||||
partOf: id + "/following",
|
partOf: id + "/following",
|
||||||
totalItems: followers.totalItems,
|
totalItems: followers.totalItems,
|
||||||
orderedItems: followers.items.map<string>(f => f.expand!.followee.iri)
|
orderedItems: followers.items.filter(f => f.expand?.followee !== undefined).map<string>(f => f.expand!.followee.iri)
|
||||||
}
|
}
|
||||||
|
|
||||||
const headers = new Headers()
|
const headers = new Headers()
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export async function GET(event: RequestEvent) {
|
|||||||
const [username, domain] = splitUsername(fullUsername, env.ORIGIN)
|
const [username, domain] = splitUsername(fullUsername, env.ORIGIN)
|
||||||
|
|
||||||
|
|
||||||
const actor: Actor = await event.locals.pb.collection("activitypub_actors").getFirstListItem(`username:lower='${username?.toLowerCase()}'&&isLocal=true`)
|
const actor: Actor = await event.locals.pb.collection("activitypub_actors").getFirstListItem(`preferred_username:lower='${username?.toLowerCase()}'&&isLocal=true`)
|
||||||
|
|
||||||
const filter = `actor='${actor.iri}'&&type='Create'${safeSearchParams.filter ? '&&' + safeSearchParams.filter : ''}`
|
const filter = `actor='${actor.iri}'&&type='Create'${safeSearchParams.filter ? '&&' + safeSearchParams.filter : ''}`
|
||||||
const activities: ListResult<Activity> = await event.locals.pb.collection("activitypub_activities").getList(page, perPage, { sort: safeSearchParams.sort ?? "-created", filter })
|
const activities: ListResult<Activity> = await event.locals.pb.collection("activitypub_activities").getList(page, perPage, { sort: safeSearchParams.sort ?? "-created", filter })
|
||||||
|
|||||||
@@ -23,7 +23,20 @@ export async function GET(event: RequestEvent) {
|
|||||||
|
|
||||||
const page = event.url.searchParams.get("page") ?? "1"
|
const page = event.url.searchParams.get("page") ?? "1"
|
||||||
|
|
||||||
const followers: APOrderedCollectionPage = await event.locals.pb.send(`/activitypub/actor/${actor.id}/${type}?page=${page}`, { method: "GET", fetch: event.fetch, });
|
let followers: APOrderedCollectionPage;
|
||||||
|
|
||||||
|
// fetch followers locally to not run into auth issues with private profiles
|
||||||
|
if (actor.id === event.locals.user.actor) {
|
||||||
|
const r = await event.fetch(actor[type as "followers" | "following"]! + '?' + new URLSearchParams({ page }))
|
||||||
|
|
||||||
|
if (!r.ok) {
|
||||||
|
const errorResponse = await r.json()
|
||||||
|
throw new ClientResponseError({ status: r.status, response: errorResponse });
|
||||||
|
}
|
||||||
|
followers = await r.json()
|
||||||
|
} else {
|
||||||
|
followers = await event.locals.pb.send(`/activitypub/actor/${actor.id}/${type}?page=${page}`, { method: "GET", fetch: event.fetch, });
|
||||||
|
}
|
||||||
|
|
||||||
const followerActors: Actor[] = []
|
const followerActors: Actor[] = []
|
||||||
for (const f of followers.orderedItems ?? []) {
|
for (const f of followers.orderedItems ?? []) {
|
||||||
@@ -37,6 +50,7 @@ export async function GET(event: RequestEvent) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const result: ListResult<Actor> = {
|
const result: ListResult<Actor> = {
|
||||||
items: followerActors,
|
items: followerActors,
|
||||||
page: parseInt(page),
|
page: parseInt(page),
|
||||||
|
|||||||
@@ -32,6 +32,9 @@ export async function POST(event: RequestEvent) {
|
|||||||
r.hits.forEach(h => {
|
r.hits.forEach(h => {
|
||||||
h.thumbnail = `${origin}/api/v1/files/trails/${h.id}/${h.thumbnail}`;
|
h.thumbnail = `${origin}/api/v1/files/trails/${h.id}/${h.thumbnail}`;
|
||||||
h.domain = actor.domain
|
h.domain = actor.domain
|
||||||
|
if(h.iri == '') {
|
||||||
|
h.iri = `${origin}/api/v1/trails/${h.id}`
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -373,7 +373,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="trail-map" class:hidden={!showMap}>
|
<div id="trail-map">
|
||||||
<MapWithElevationMaplibre
|
<MapWithElevationMaplibre
|
||||||
trails={selectedTrail
|
trails={selectedTrail
|
||||||
? [selectedTrail]
|
? [selectedTrail]
|
||||||
@@ -391,9 +391,6 @@
|
|||||||
showTerrain={true}
|
showTerrain={true}
|
||||||
></MapWithElevationMaplibre>
|
></MapWithElevationMaplibre>
|
||||||
</div>
|
</div>
|
||||||
<div class="min-w-0" class:hidden={showMap}>
|
|
||||||
<TrailList trails={selectedList?.expand?.trails ?? []}></TrailList>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ConfirmModal
|
<ConfirmModal
|
||||||
text={$_("delete-list-confirm")}
|
text={$_("delete-list-confirm")}
|
||||||
|
|||||||
Reference in New Issue
Block a user