merge: Allow user-initiated object lookups (/ap/show endpoint) to follow cross-domain redirects (resolves #820) (!878)

View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/878

Closes #820

Approved-by: dakkar <dakkar@thenautilus.net>
Approved-by: Marie <github@yuugi.dev>
This commit is contained in:
Hazelnoot 2025-02-10 16:22:20 +00:00
commit 2f84d151f5
3 changed files with 44 additions and 7 deletions

View file

@ -185,7 +185,7 @@ export class ApRequestService {
* @param url URL to fetch
*/
@bindThis
public async signedGet(url: string, user: { id: MiUser['id'] }, followAlternate?: boolean): Promise<unknown> {
public async signedGet(url: string, user: { id: MiUser['id'] }, followAlternate?: boolean): Promise<object> {
const _followAlternate = followAlternate ?? true;
const keypair = await this.userKeypairService.getUserKeypair(user.id);
@ -239,7 +239,18 @@ export class ApRequestService {
try {
document.documentElement.innerHTML = html;
const alternate = document.querySelector('head > link[rel="alternate"][type="application/activity+json"]');
// Search for any matching value in priority order:
// 1. Type=AP > Type=none > Type=anything
// 2. Alternate > Canonical
// 3. Page order (fallback)
const alternate =
document.querySelector('head > link[href][rel="alternate"][type="application/activity+json"]') ??
document.querySelector('head > link[href][rel="canonical"][type="application/activity+json"]') ??
document.querySelector('head > link[href][rel="alternate"]:not([type])') ??
document.querySelector('head > link[href][rel="canonical"]:not([type])') ??
document.querySelector('head > link[href][rel="alternate"]') ??
document.querySelector('head > link[href][rel="canonical"]');
if (alternate) {
const href = alternate.getAttribute('href');
if (href) {

View file

@ -56,10 +56,17 @@ export function getOneApId(value: ApObject): string {
return getApId(firstOne);
}
/**
* Minimal AP payload - just an object with optional ID.
*/
export interface ObjectWithId {
id?: string;
}
/**
* Get ActivityStreams Object id
*/
export function getApId(value: string | IObject | [string | IObject]): string {
export function getApId(value: string | ObjectWithId | [string | ObjectWithId]): string {
// eslint-disable-next-line no-param-reassign
value = fromTuple(value);
@ -71,7 +78,7 @@ export function getApId(value: string | IObject | [string | IObject]): string {
/**
* Get ActivityStreams Object id, or null if not present
*/
export function getNullableApId(value: string | IObject | [string | IObject]): string | null {
export function getNullableApId(value: string | ObjectWithId | [string | ObjectWithId]): string | null {
// eslint-disable-next-line no-param-reassign
value = fromTuple(value);