diff --git a/src/background/modules/AutoRemoteFollow.js b/src/background/modules/AutoRemoteFollow.js index 88ddf66..20286cf 100644 --- a/src/background/modules/AutoRemoteFollow.js +++ b/src/background/modules/AutoRemoteFollow.js @@ -11,6 +11,7 @@ import * as MastodonDetect from "./Detect/Mastodon.js"; import * as GnuSocialDetect from "./Detect/GnuSocial.js"; import * as PleromaDetect from "./Detect/Pleroma.js"; import * as FriendicaDetect from "./Detect/Friendica.js"; +import * as GuppeDetect from "./Detect/Guppe.js"; import * as NetworkTools from "/common/modules/NetworkTools.js"; import * as MastodonRedirect from "./MastodonRedirect.js"; @@ -22,12 +23,15 @@ import * as Notifications from "/common/modules/Notifications.js"; const FEDIVERSE_TYPE = Object.freeze({ MASTODON: Symbol("Mastodon"), + GUPPE: Symbol("Gup.pe"), + FRIENDICA: Symbol("Friendica"), GNU_SOCIAL: Symbol("GNU Social"), PLEROMA: Symbol("Pleroma"), - FRIENDICA: Symbol("Friendica") }); const FEDIVERSE_MODULE = Object.freeze({ [FEDIVERSE_TYPE.MASTODON]: MastodonDetect, + [FEDIVERSE_TYPE.GUPPE]: GuppeDetect, + [FEDIVERSE_TYPE.FRIENDICA]: FriendicaDetect, [FEDIVERSE_TYPE.GNU_SOCIAL]: GnuSocialDetect, [FEDIVERSE_TYPE.PLEROMA]: PleromaDetect, [FEDIVERSE_TYPE.FRIENDICA]: FriendicaDetect @@ -48,10 +52,8 @@ async function handleWebRequest(requestDetails) { return Promise.reject(new Error("URL info not available")); } - const url = new URL(requestDetails.url); - // detect, which network/software it uses - const [software, interaction] = getInteractionType(url); + const [software, interaction] = getInteractionType(requestDetails.url); if (software === null) { // ignore unrelated sites, resolves so error handling is not triggered @@ -66,6 +68,7 @@ async function handleWebRequest(requestDetails) { MastodonRedirect.enableLoadReplace(detectModule.shouldLoadReplace.bind(null, requestDetails)); // and get data and pass to redirect + const url = new URL(requestDetails.url); switch (interaction) { case INTERACTION_TYPE.FOLLOW: { const remoteUser = await detectModule.getUsername(url, requestDetails); @@ -129,13 +132,13 @@ async function handleError(error) { * * @function * @private - * @param {URL} url + * @param {string} fullUrl the full URL as a string * @returns {[FEDIVERSE_TYPE, Symbol]|[null, null]} */ -function getInteractionType(url) { +function getInteractionType(fullUrl) { for (const fedType of Object.values(FEDIVERSE_TYPE)) { for (const [checkRegEx, interactionType] of FEDIVERSE_MODULE[fedType].CATCH_URLS) { - if (url.pathname.match(checkRegEx)) { + if (fullUrl.match(checkRegEx)) { return [fedType, interactionType]; } } diff --git a/src/background/modules/Detect/Guppe.js b/src/background/modules/Detect/Guppe.js new file mode 100644 index 0000000..c8d7f6b --- /dev/null +++ b/src/background/modules/Detect/Guppe.js @@ -0,0 +1,78 @@ +/** + * Module, that detects Gup.pe (https://a.gup.pe) and returns the required values. + * + * @module Detect/AGuppe + */ + +import {NotSupportedError} from "/common/modules/Errors.js"; +import {INTERACTION_TYPE} from "../data/INTERACTION_TYPE.js"; + +// https://regex101.com/r/lKOGPf/1 +const REMOTE_FOLLOW_REGEX = /^https:\/\/a\.gup\.pe\/u\/(\w+)$/; + +/** The URLs to intercept and pass to this module. */ +export const CATCH_URLS = new Map(); +CATCH_URLS.set(REMOTE_FOLLOW_REGEX, INTERACTION_TYPE.FOLLOW); + +/** + * Whether to enable replacing the previous site when redirecting or not. + * + * @private + * @type {boolean} + */ +const ENABLE_LOAD_REPLACE = false; + +/** + * Determinates whether the redirect should replace the site before or not. + * + * @public + * @returns {boolean} + */ +export function shouldLoadReplace() { + return ENABLE_LOAD_REPLACE; +} + +/** + * Determinates which tab should be redirected. + * + * @public + * @param {Object} requestDetails + * @returns {int} + */ +export function getTabToModify(requestDetails) { + return requestDetails.tabId; +} + +/** + * Find the follow URL. + * + * @public + * @returns {Promise} + */ +export function getTootUrl() { + throw new NotSupportedError("getTootUrl() is not supported"); +} + +/** + * Returns the username of the follow page. + * + * @private + * @function + * @param {URL} url + * @returns {string|undefined} + */ +export function getUsername(url) { + const match = REMOTE_FOLLOW_REGEX.exec(url.toString()); + return match[1]; +} + +/** + * Returns the server from the required URL. + * + * @function + * @param {URL} url + * @returns {string|undefined} + */ +export function getServer(url) { + return url.host; +}