diff options
| author | Andrew Branson <andrew.branson@jolla.com> | 2026-02-14 16:22:38 +0100 |
|---|---|---|
| committer | Andrew Branson <andrew.branson@jolla.com> | 2026-02-14 16:22:38 +0100 |
| commit | 5335519ab47e89316858168d4ae540c9a3c6542d (patch) | |
| tree | 12a53748249a3722ee2e077544841121e22a7272 | |
| parent | 7ffdb036406bd15e75159597434e70cbaa542b8e (diff) | |
| -rw-r--r-- | RPMS/sailfish-account-mastodon-1.0.0-1.aarch64.rpm | bin | 0 -> 3968946 bytes | |||
| -rw-r--r-- | buteo-plugins/buteo-sync-plugin-mastodon-notifications/mastodonnotificationssyncadaptor.cpp | 30 | ||||
| -rw-r--r-- | eventsview-plugins/eventsview-plugin-mastodon/mastodon-delegate.qml | 31 |
3 files changed, 59 insertions, 2 deletions
diff --git a/RPMS/sailfish-account-mastodon-1.0.0-1.aarch64.rpm b/RPMS/sailfish-account-mastodon-1.0.0-1.aarch64.rpm Binary files differnew file mode 100644 index 0000000..604e7d1 --- /dev/null +++ b/RPMS/sailfish-account-mastodon-1.0.0-1.aarch64.rpm diff --git a/buteo-plugins/buteo-sync-plugin-mastodon-notifications/mastodonnotificationssyncadaptor.cpp b/buteo-plugins/buteo-sync-plugin-mastodon-notifications/mastodonnotificationssyncadaptor.cpp index d5d1766..7775841 100644 --- a/buteo-plugins/buteo-sync-plugin-mastodon-notifications/mastodonnotificationssyncadaptor.cpp +++ b/buteo-plugins/buteo-sync-plugin-mastodon-notifications/mastodonnotificationssyncadaptor.cpp @@ -143,6 +143,34 @@ namespace { return hasActiveNotifications; } + QString authorizeInteractionUrl(const QString &apiHost, const QString &targetUrl) + { + const QUrl parsedApiHost(apiHost); + const QUrl parsedTargetUrl(targetUrl); + if (!parsedApiHost.isValid() + || parsedApiHost.scheme().isEmpty() + || parsedApiHost.host().isEmpty() + || !parsedTargetUrl.isValid() + || parsedTargetUrl.scheme().isEmpty() + || parsedTargetUrl.host().isEmpty()) { + return targetUrl; + } + + // Links on the account's own instance should open directly. + const bool sameScheme = QString::compare(parsedApiHost.scheme(), parsedTargetUrl.scheme(), Qt::CaseInsensitive) == 0; + const bool sameHost = QString::compare(parsedApiHost.host(), parsedTargetUrl.host(), Qt::CaseInsensitive) == 0; + const int apiPort = parsedApiHost.port(parsedApiHost.scheme() == QLatin1String("https") ? 443 : 80); + const int targetPort = parsedTargetUrl.port(parsedTargetUrl.scheme() == QLatin1String("https") ? 443 : 80); + if (sameScheme && sameHost && apiPort == targetPort) { + return targetUrl; + } + + QUrl authorizeUrl(parsedApiHost); + authorizeUrl.setPath(QStringLiteral("/authorize_interaction")); + authorizeUrl.setQuery(QStringLiteral("uri=") + QString::fromUtf8(QUrl::toPercentEncoding(targetUrl))); + return authorizeUrl.toString(); + } + } MastodonNotificationsSyncAdaptor::MastodonNotificationsSyncAdaptor(QObject *parent) @@ -655,7 +683,7 @@ void MastodonNotificationsSyncAdaptor::publishSystemNotification(int accountId, && !parsedOpenUrl.host().isEmpty() ? openUrl : fallbackUrl; - notification->setRemoteAction(OPEN_URL_ACTION(safeOpenUrl)); + notification->setRemoteAction(OPEN_URL_ACTION(authorizeInteractionUrl(apiHost(accountId), safeOpenUrl))); notification->publish(); if (notification->replacesId() == 0) { qCWarning(lcSocialPlugin) << "failed to publish Mastodon notification" diff --git a/eventsview-plugins/eventsview-plugin-mastodon/mastodon-delegate.qml b/eventsview-plugins/eventsview-plugin-mastodon/mastodon-delegate.qml index aefaa96..c8e8713 100644 --- a/eventsview-plugins/eventsview-plugin-mastodon/mastodon-delegate.qml +++ b/eventsview-plugins/eventsview-plugin-mastodon/mastodon-delegate.qml @@ -46,7 +46,7 @@ SocialMediaAccountDelegate { imageList: delegateItem.variantRole(model, ["images", "mediaAttachments", "media"]) avatarSource: delegateItem.convertUrl(delegateItem.stringRole(model, ["icon", "avatar", "avatarUrl"])) fallbackAvatarSource: delegateItem.stringRole(model, ["icon", "avatar", "avatarUrl"]) - resolvedStatusUrl: delegateItem.statusUrl(model) + resolvedStatusUrl: delegateItem.authorizeInteractionUrl(model) postId: delegateItem.stringRole(model, ["mastodonId", "statusId", "id", "twitterId"]) postActions: mastodonPostActions accountId: delegateItem.firstAccountId(model) @@ -163,6 +163,35 @@ SocialMediaAccountDelegate { return instanceUrl + "/explore" } + function authorizeInteractionUrl(modelData) { + var targetUrl = statusUrl(modelData) + if (targetUrl.length === 0) { + return targetUrl + } + + var instanceUrl = stringRole(modelData, ["instanceUrl", "serverUrl", "baseUrl"]) + if (instanceUrl.length === 0) { + return targetUrl + } + while (instanceUrl.length > 0 && instanceUrl.charAt(instanceUrl.length - 1) === "/") { + instanceUrl = instanceUrl.slice(0, instanceUrl.length - 1) + } + + // Links on the user's own instance should open directly. + var sameServer = /^([a-z][a-z0-9+.-]*):\/\/([^\/?#]+)/i + var targetMatch = targetUrl.match(sameServer) + var instanceMatch = instanceUrl.match(sameServer) + if (targetMatch && instanceMatch + && targetMatch.length > 2 + && instanceMatch.length > 2 + && targetMatch[1].toLowerCase() === instanceMatch[1].toLowerCase() + && targetMatch[2].toLowerCase() === instanceMatch[2].toLowerCase()) { + return targetUrl + } + + return instanceUrl + "/authorize_interaction?uri=" + encodeURIComponent(targetUrl) + } + function convertUrl(source) { if (source.indexOf("_normal.") !== -1) { return source.replace("_normal.", "_bigger.") |
