mirror of
https://github.com/glitch-soc/mastodon.git
synced 2026-03-29 11:11:11 +02:00
Add support for FEP-3b86 (Activity Intents) (#38120)
This commit is contained in:
@@ -39,18 +39,57 @@ const findLink = (rel: string, data: unknown): JRDLink | undefined => {
|
||||
}
|
||||
};
|
||||
|
||||
const findTemplateLink = (data: unknown) =>
|
||||
findLink('http://ostatus.org/schema/1.0/subscribe', data)?.template;
|
||||
const intentParams = (intent: string) => {
|
||||
switch (intent) {
|
||||
case 'follow':
|
||||
return ['https://w3id.org/fep/3b86/Follow', 'object'] as [string, string];
|
||||
case 'reblog':
|
||||
return ['https://w3id.org/fep/3b86/Announce', 'object'] as [
|
||||
string,
|
||||
string,
|
||||
];
|
||||
case 'favourite':
|
||||
return ['https://w3id.org/fep/3b86/Like', 'object'] as [string, string];
|
||||
case 'vote':
|
||||
case 'reply':
|
||||
return ['https://w3id.org/fep/3b86/Object', 'object'] as [string, string];
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const findTemplateLink = (data: unknown, intent: string) => {
|
||||
const [needle, param] = intentParams(intent) ?? [
|
||||
'http://ostatus.org/schema/1.0/subscribe',
|
||||
'uri',
|
||||
];
|
||||
|
||||
const match = findLink(needle, data);
|
||||
|
||||
if (match) {
|
||||
return [match.template, param] as [string, string];
|
||||
}
|
||||
|
||||
const fallback = findLink('http://ostatus.org/schema/1.0/subscribe', data);
|
||||
|
||||
if (fallback) {
|
||||
return [fallback.template, 'uri'] as [string, string];
|
||||
}
|
||||
|
||||
return [null, null];
|
||||
};
|
||||
|
||||
const fetchInteractionURLSuccess = (
|
||||
uri_or_domain: string,
|
||||
template: string,
|
||||
param: string,
|
||||
) => {
|
||||
window.parent.postMessage(
|
||||
{
|
||||
type: 'fetchInteractionURL-success',
|
||||
uri_or_domain,
|
||||
template,
|
||||
param,
|
||||
},
|
||||
window.origin,
|
||||
);
|
||||
@@ -74,7 +113,7 @@ const isValidDomain = (value: unknown) => {
|
||||
};
|
||||
|
||||
// Attempt to find a remote interaction URL from a domain
|
||||
const fromDomain = (domain: string) => {
|
||||
const fromDomain = (domain: string, intent: string) => {
|
||||
const fallbackTemplate = `https://${domain}/authorize_interaction?uri={uri}`;
|
||||
|
||||
axios
|
||||
@@ -82,17 +121,21 @@ const fromDomain = (domain: string) => {
|
||||
params: { resource: `https://${domain}` },
|
||||
})
|
||||
.then(({ data }) => {
|
||||
const template = findTemplateLink(data);
|
||||
fetchInteractionURLSuccess(domain, template ?? fallbackTemplate);
|
||||
const [template, param] = findTemplateLink(data, intent);
|
||||
fetchInteractionURLSuccess(
|
||||
domain,
|
||||
template ?? fallbackTemplate,
|
||||
param ?? 'uri',
|
||||
);
|
||||
return;
|
||||
})
|
||||
.catch(() => {
|
||||
fetchInteractionURLSuccess(domain, fallbackTemplate);
|
||||
fetchInteractionURLSuccess(domain, fallbackTemplate, 'uri');
|
||||
});
|
||||
};
|
||||
|
||||
// Attempt to find a remote interaction URL from an arbitrary URL
|
||||
const fromURL = (url: string) => {
|
||||
const fromURL = (url: string, intent: string) => {
|
||||
const domain = new URL(url).host;
|
||||
const fallbackTemplate = `https://${domain}/authorize_interaction?uri={uri}`;
|
||||
|
||||
@@ -101,17 +144,21 @@ const fromURL = (url: string) => {
|
||||
params: { resource: url },
|
||||
})
|
||||
.then(({ data }) => {
|
||||
const template = findTemplateLink(data);
|
||||
fetchInteractionURLSuccess(url, template ?? fallbackTemplate);
|
||||
const [template, param] = findTemplateLink(data, intent);
|
||||
fetchInteractionURLSuccess(
|
||||
url,
|
||||
template ?? fallbackTemplate,
|
||||
param ?? 'uri',
|
||||
);
|
||||
return;
|
||||
})
|
||||
.catch(() => {
|
||||
fromDomain(domain);
|
||||
fromDomain(domain, intent);
|
||||
});
|
||||
};
|
||||
|
||||
// Attempt to find a remote interaction URL from a `user@domain` string
|
||||
const fromAcct = (acct: string) => {
|
||||
const fromAcct = (acct: string, intent: string) => {
|
||||
acct = acct.replace(/^@/, '');
|
||||
|
||||
const segments = acct.split('@');
|
||||
@@ -134,25 +181,29 @@ const fromAcct = (acct: string) => {
|
||||
params: { resource: `acct:${acct}` },
|
||||
})
|
||||
.then(({ data }) => {
|
||||
const template = findTemplateLink(data);
|
||||
fetchInteractionURLSuccess(acct, template ?? fallbackTemplate);
|
||||
const [template, param] = findTemplateLink(data, intent);
|
||||
fetchInteractionURLSuccess(
|
||||
acct,
|
||||
template ?? fallbackTemplate,
|
||||
param ?? 'uri',
|
||||
);
|
||||
return;
|
||||
})
|
||||
.catch(() => {
|
||||
// TODO: handle host-meta?
|
||||
fromDomain(domain);
|
||||
fromDomain(domain, intent);
|
||||
});
|
||||
};
|
||||
|
||||
const fetchInteractionURL = (uri_or_domain: string) => {
|
||||
const fetchInteractionURL = (uri_or_domain: string, intent: string) => {
|
||||
if (uri_or_domain === '') {
|
||||
fetchInteractionURLFailure();
|
||||
} else if (/^https?:\/\//.test(uri_or_domain)) {
|
||||
fromURL(uri_or_domain);
|
||||
fromURL(uri_or_domain, intent);
|
||||
} else if (uri_or_domain.includes('@')) {
|
||||
fromAcct(uri_or_domain);
|
||||
fromAcct(uri_or_domain, intent);
|
||||
} else {
|
||||
fromDomain(uri_or_domain);
|
||||
fromDomain(uri_or_domain, intent);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -172,8 +223,10 @@ window.addEventListener('message', (event: MessageEvent<unknown>) => {
|
||||
'type' in event.data &&
|
||||
event.data.type === 'fetchInteractionURL' &&
|
||||
'uri_or_domain' in event.data &&
|
||||
typeof event.data.uri_or_domain === 'string'
|
||||
typeof event.data.uri_or_domain === 'string' &&
|
||||
'intent' in event.data &&
|
||||
typeof event.data.intent === 'string'
|
||||
) {
|
||||
fetchInteractionURL(event.data.uri_or_domain);
|
||||
fetchInteractionURL(event.data.uri_or_domain, event.data.intent);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user