Add subscription history and backup/restore functionality

- Added `SUBSCRIPTION_BACKUP` note type schema
- Implemented `createBackup`, `fetchHistory`, `restoreBackup`, `rebroadcastBackup` in `SubscriptionsManager`
- Added Subscription History UI modal with list/details view
- Integrated History/Backup buttons into Profile Modal Subscriptions pane
- Fixed XSS vulnerability in history details view
- Added profile fetching for history details

Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
google-labs-jules[bot]andPR0M3TH3AN committed 2026-02-02 03:05:13 +00:00
1 parent 2398d63e53
commit a50e5c861a
6 files changed
+633 -10

No files matched your search

+32
View File
@@ -43,6 +43,7 @@ import {
getLinkPreviewSettings,
setLinkPreviewAutoFetch,
} from "../utils/linkPreviewSettings.js";
import { SubscriptionHistoryController } from "./subscriptionHistoryController.js";
const noop = () => {};
@@ -1436,6 +1437,7 @@ export class ProfileModalController {
this.addAccountButtonState = null;
this.adminEmptyMessages = new Map();
this.hashtagPreferencesUnsubscribe = null;
this.subscriptionHistoryController = new SubscriptionHistoryController();
if (
this.subscriptionsService &&
@@ -1622,6 +1624,10 @@ export class ProfileModalController {
document.getElementById("subscriptionsEmpty") || null;
this.profileSubscriptionsRefreshBtn =
document.getElementById("subscriptionsRefreshBtn") || null;
this.profileSubscriptionsHistoryBtn =
document.getElementById("subscriptionsHistoryBtn") || null;
this.profileSubscriptionsBackupBtn =
document.getElementById("subscriptionsBackupBtn") || null;
this.friendList = document.getElementById("friendsList") || null;
this.friendListEmpty = document.getElementById("friendsEmpty") || null;
this.friendInput = document.getElementById("friendsInput") || null;
@@ -5667,6 +5673,32 @@ export class ProfileModalController {
});
}
if (this.profileSubscriptionsHistoryBtn) {
this.profileSubscriptionsHistoryBtn.addEventListener("click", () => {
const pubkey = this.normalizeHexPubkey(this.getActivePubkey());
if (pubkey) {
this.subscriptionHistoryController.show(pubkey);
} else {
this.showError("Please log in to view subscription history.");
}
});
}
if (this.profileSubscriptionsBackupBtn) {
this.profileSubscriptionsBackupBtn.addEventListener("click", () => {
const pubkey = this.normalizeHexPubkey(this.getActivePubkey());
if (pubkey) {
if (confirm("Create a backup of your current subscription list?")) {
this.subscriptionHistoryController.handleCreateBackup(pubkey).then(() => {
this.showSuccess("Backup created.");
});
}
} else {
this.showError("Please log in to backup subscriptions.");
}
});
}
if (this.walletUriInput instanceof HTMLElement) {
this.walletUriInput.addEventListener("focus", () => {
this.revealSecretInputValue(this.walletUriInput);