mirror of
https://github.com/AMNatty/Mastodon-Circles.git
synced 2024-11-21 18:47:26 -07:00
Turned Handle into a class and implemented WebFinger with a fall-back
This commit is contained in:
parent
d3299af352
commit
ea3e389d01
2 changed files with 94 additions and 37 deletions
129
create-circle.js
129
create-circle.js
|
@ -19,13 +19,89 @@ async function apiRequest(url, options = null)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Handle(name, instance) {
|
||||||
|
let handleObj = Object.create(Handle.prototype);
|
||||||
|
handleObj.name = name;
|
||||||
|
handleObj.instance = instance;
|
||||||
|
handleObj._baseInstance = null;
|
||||||
|
handleObj._apiInstance = null;
|
||||||
|
|
||||||
|
return handleObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.defineProperty(Handle.prototype, "baseInstance", {
|
||||||
|
get: function () {
|
||||||
|
return this._baseInstance || this.instance;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(Handle.prototype, "apiInstance", {
|
||||||
|
get: function () {
|
||||||
|
return this._apiInstance || this.instance;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(Handle.prototype, "baseHandle", {
|
||||||
|
get: function () {
|
||||||
|
return this.name + "@" + this.baseInstance;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Handle.prototype.toString = function () {
|
||||||
|
return this.name + "@" + this.instance;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {{
|
* @returns {Promise<Handle>} The handle WebFingered, or the original on fail
|
||||||
* handle: string,
|
|
||||||
* name: string,
|
|
||||||
* instance: string,
|
|
||||||
* }} Handle
|
|
||||||
*/
|
*/
|
||||||
|
Handle.prototype.webFinger = async function () {
|
||||||
|
if (this._baseInstance) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
let url = `https://${this.instance}/.well-known/webfinger?` + new URLSearchParams({
|
||||||
|
resource: `acct:${this}`
|
||||||
|
});
|
||||||
|
|
||||||
|
let webFinger = await apiRequest(url);
|
||||||
|
|
||||||
|
if (!webFinger)
|
||||||
|
return this;
|
||||||
|
|
||||||
|
let acct = webFinger["subject"];
|
||||||
|
|
||||||
|
if (typeof acct !== "string")
|
||||||
|
return this;
|
||||||
|
|
||||||
|
if (acct.startsWith("acct:")) {
|
||||||
|
acct = acct.substring("acct:".length);
|
||||||
|
}
|
||||||
|
|
||||||
|
let baseHandle = parseHandle(acct);
|
||||||
|
baseHandle._baseInstance = baseHandle.instance;
|
||||||
|
baseHandle.instance = this.instance;
|
||||||
|
|
||||||
|
const links = webFinger["links"];
|
||||||
|
|
||||||
|
if (!Array.isArray(links)) {
|
||||||
|
return baseHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selfLink = links.find(link => link["rel"] === "self");
|
||||||
|
if (!selfLink) {
|
||||||
|
return baseHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const url = new URL(selfLink["href"])
|
||||||
|
baseHandle._apiInstance = url.hostname;
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`Error parsing WebFinger self link ${selfLink["href"]}: ${e}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return baseHandle;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {{
|
* @typedef {{
|
||||||
|
@ -190,7 +266,7 @@ class MastodonApiClient extends ApiClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUserIdFromHandle(handle) {
|
async getUserIdFromHandle(handle) {
|
||||||
const url = `https://${this._instance}/api/v1/accounts/lookup?acct=${handle.handle}`;
|
const url = `https://${this._instance}/api/v1/accounts/lookup?acct=${handle.baseHandle}`;
|
||||||
const response = await apiRequest(url, null);
|
const response = await apiRequest(url, null);
|
||||||
|
|
||||||
if (!response) {
|
if (!response) {
|
||||||
|
@ -374,8 +450,11 @@ class MisskeyApiClient extends ApiClient {
|
||||||
let id = null;
|
let id = null;
|
||||||
|
|
||||||
for (const user of Array.isArray(lookup) ? lookup : []) {
|
for (const user of Array.isArray(lookup) ? lookup : []) {
|
||||||
if ((user["host"] === handle.instance || this._instance === handle.instance && user["host"] === null)
|
const isLocal = user?.["host"] === handle.instance ||
|
||||||
&& user["username"] === handle.name) {
|
user?.["host"] === handle.baseInstance ||
|
||||||
|
this._instance === handle.apiInstance && user?.["host"] === null;
|
||||||
|
|
||||||
|
if (isLocal && user?.["username"] === handle.name && user["id"]) {
|
||||||
id = user["id"];
|
id = user["id"];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -547,28 +626,7 @@ function parseHandle(fediHandle, fallbackInstance = "") {
|
||||||
fediHandle = fediHandle.replaceAll(" ", "");
|
fediHandle = fediHandle.replaceAll(" ", "");
|
||||||
const [name, instance] = fediHandle.split("@", 2);
|
const [name, instance] = fediHandle.split("@", 2);
|
||||||
|
|
||||||
return {
|
return new Handle(name, instance || fallbackInstance);
|
||||||
handle: fediHandle,
|
|
||||||
name: name,
|
|
||||||
instance: instance || fallbackInstance,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef @param {Handle} handle
|
|
||||||
* @returns {Promise<Handle>}
|
|
||||||
*/
|
|
||||||
async function getDelegatedHandle(handle) {
|
|
||||||
// We're checking webfinger to see which URL is for the user,
|
|
||||||
// since that may be on a different domain than the webfinger request
|
|
||||||
const response = await apiRequest(`https://${handle.instance}/.well-known/webfinger?resource=acct:${handle.handle}`)
|
|
||||||
const selfLink = response.links.find(link => link.rel == 'self')
|
|
||||||
const url = new URL(selfLink.href)
|
|
||||||
handle.instance = url.hostname;
|
|
||||||
// If a user inputs @h@social.besties.house but their handle is actually @h@besties.house,
|
|
||||||
// we want to use the latter
|
|
||||||
handle.handle = response.subject?.replace(/^acct:/, '') ?? handle.handle;
|
|
||||||
return handle
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -583,8 +641,7 @@ async function circleMain() {
|
||||||
generateBtn.style.display = "none";
|
generateBtn.style.display = "none";
|
||||||
|
|
||||||
let fediHandle = document.getElementById("txt_mastodon_handle");
|
let fediHandle = document.getElementById("txt_mastodon_handle");
|
||||||
|
const selfUser = await parseHandle(fediHandle.value).webFinger();
|
||||||
const selfUser = await getDelegatedHandle(parseHandle(fediHandle.value));
|
|
||||||
|
|
||||||
let form = document.getElementById("generateForm");
|
let form = document.getElementById("generateForm");
|
||||||
let backend = form.backend;
|
let backend = form.backend;
|
||||||
|
@ -597,17 +654,17 @@ async function circleMain() {
|
||||||
let client;
|
let client;
|
||||||
switch (backend.value) {
|
switch (backend.value) {
|
||||||
case "mastodon":
|
case "mastodon":
|
||||||
client = new MastodonApiClient(selfUser.instance);
|
client = new MastodonApiClient(selfUser.apiInstance);
|
||||||
break;
|
break;
|
||||||
case "pleroma":
|
case "pleroma":
|
||||||
client = new PleromaApiClient(selfUser.instance, true);
|
client = new PleromaApiClient(selfUser.apiInstance, true);
|
||||||
break;
|
break;
|
||||||
case "misskey":
|
case "misskey":
|
||||||
client = new MisskeyApiClient(selfUser.instance);
|
client = new MisskeyApiClient(selfUser.apiInstance);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
progress.innerText = "Detecting instance...";
|
progress.innerText = "Detecting instance...";
|
||||||
client = await ApiClient.getClient(selfUser.instance);
|
client = await ApiClient.getClient(selfUser.apiInstance);
|
||||||
backend.value = client.getClientName();
|
backend.value = client.getClientName();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
2
image.js
2
image.js
|
@ -50,7 +50,7 @@ function render(users, selfUser) {
|
||||||
centerX - radius[layerIndex],
|
centerX - radius[layerIndex],
|
||||||
centerY - radius[layerIndex],
|
centerY - radius[layerIndex],
|
||||||
radius[layerIndex],
|
radius[layerIndex],
|
||||||
"@" + users[userNum].handle.name + "@" + users[userNum].handle.instance
|
"@" + users[userNum].handle
|
||||||
);
|
);
|
||||||
|
|
||||||
userNum++;
|
userNum++;
|
||||||
|
|
Loading…
Reference in a new issue