@rmdes/indiekit-endpoint-microsub 1.0.0-beta.10 → 1.0.0-beta.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +4 -0
- package/lib/controllers/reader.js +28 -0
- package/lib/storage/channels.js +17 -2
- package/lib/storage/feeds.js +15 -2
- package/locales/en.json +4 -0
- package/package.json +1 -1
- package/views/settings.njk +14 -0
package/index.js
CHANGED
|
@@ -78,6 +78,10 @@ export default class MicrosubEndpoint {
|
|
|
78
78
|
"/channels/:uid/settings",
|
|
79
79
|
readerController.updateSettings,
|
|
80
80
|
);
|
|
81
|
+
readerRouter.post(
|
|
82
|
+
"/channels/:uid/delete",
|
|
83
|
+
readerController.deleteChannel,
|
|
84
|
+
);
|
|
81
85
|
readerRouter.get("/channels/:uid/feeds", readerController.feeds);
|
|
82
86
|
readerRouter.post("/channels/:uid/feeds", readerController.addFeed);
|
|
83
87
|
readerRouter.post(
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
getChannel,
|
|
11
11
|
createChannel,
|
|
12
12
|
updateChannelSettings,
|
|
13
|
+
deleteChannel,
|
|
13
14
|
} from "../storage/channels.js";
|
|
14
15
|
import {
|
|
15
16
|
getFeedsForChannel,
|
|
@@ -171,6 +172,32 @@ export async function updateSettings(request, response) {
|
|
|
171
172
|
response.redirect(`${request.baseUrl}/channels/${uid}`);
|
|
172
173
|
}
|
|
173
174
|
|
|
175
|
+
/**
|
|
176
|
+
* Delete channel
|
|
177
|
+
* @param {object} request - Express request
|
|
178
|
+
* @param {object} response - Express response
|
|
179
|
+
* @returns {Promise<void>}
|
|
180
|
+
*/
|
|
181
|
+
export async function deleteChannelAction(request, response) {
|
|
182
|
+
const { application } = request.app.locals;
|
|
183
|
+
const userId = request.session?.userId;
|
|
184
|
+
const { uid } = request.params;
|
|
185
|
+
|
|
186
|
+
// Don't allow deleting notifications channel
|
|
187
|
+
if (uid === "notifications") {
|
|
188
|
+
return response.redirect(`${request.baseUrl}/channels`);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const channelDocument = await getChannel(application, uid, userId);
|
|
192
|
+
if (!channelDocument) {
|
|
193
|
+
return response.status(404).render("404");
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
await deleteChannel(application, uid, userId);
|
|
197
|
+
|
|
198
|
+
response.redirect(`${request.baseUrl}/channels`);
|
|
199
|
+
}
|
|
200
|
+
|
|
174
201
|
/**
|
|
175
202
|
* View feeds for a channel
|
|
176
203
|
* @param {object} request - Express request
|
|
@@ -394,6 +421,7 @@ export const readerController = {
|
|
|
394
421
|
channel,
|
|
395
422
|
settings,
|
|
396
423
|
updateSettings,
|
|
424
|
+
deleteChannel: deleteChannelAction,
|
|
397
425
|
feeds,
|
|
398
426
|
addFeed,
|
|
399
427
|
removeFeed,
|
package/lib/storage/channels.js
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
import { ObjectId } from "mongodb";
|
|
7
7
|
|
|
8
|
+
import { deleteFeedsForChannel } from "./feeds.js";
|
|
9
|
+
import { deleteItemsForChannel } from "./items.js";
|
|
8
10
|
import { generateChannelUid } from "../utils/jf2.js";
|
|
9
11
|
|
|
10
12
|
/**
|
|
@@ -184,7 +186,7 @@ export async function updateChannel(application, uid, updates, userId) {
|
|
|
184
186
|
}
|
|
185
187
|
|
|
186
188
|
/**
|
|
187
|
-
* Delete a channel
|
|
189
|
+
* Delete a channel and all its feeds and items
|
|
188
190
|
* @param {object} application - Indiekit application
|
|
189
191
|
* @param {string} uid - Channel UID
|
|
190
192
|
* @param {string} [userId] - User ID
|
|
@@ -200,7 +202,20 @@ export async function deleteChannel(application, uid, userId) {
|
|
|
200
202
|
return false;
|
|
201
203
|
}
|
|
202
204
|
|
|
203
|
-
|
|
205
|
+
// Find the channel first to get its ObjectId
|
|
206
|
+
const channel = await collection.findOne(query);
|
|
207
|
+
if (!channel) {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Cascade delete: items first, then feeds, then channel
|
|
212
|
+
const itemsDeleted = await deleteItemsForChannel(application, channel._id);
|
|
213
|
+
const feedsDeleted = await deleteFeedsForChannel(application, channel._id);
|
|
214
|
+
console.info(
|
|
215
|
+
`[Microsub] Deleted channel ${uid}: ${feedsDeleted} feeds, ${itemsDeleted} items`,
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
const result = await collection.deleteOne({ _id: channel._id });
|
|
204
219
|
return result.deletedCount > 0;
|
|
205
220
|
}
|
|
206
221
|
|
package/lib/storage/feeds.js
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
import { ObjectId } from "mongodb";
|
|
7
7
|
|
|
8
|
+
import { deleteItemsForFeed } from "./items.js";
|
|
9
|
+
|
|
8
10
|
/**
|
|
9
11
|
* Get feeds collection from application
|
|
10
12
|
* @param {object} application - Indiekit application
|
|
@@ -122,7 +124,7 @@ export async function updateFeed(application, id, updates) {
|
|
|
122
124
|
}
|
|
123
125
|
|
|
124
126
|
/**
|
|
125
|
-
* Delete a feed subscription
|
|
127
|
+
* Delete a feed subscription and all its items
|
|
126
128
|
* @param {object} application - Indiekit application
|
|
127
129
|
* @param {ObjectId|string} channelId - Channel ObjectId
|
|
128
130
|
* @param {string} url - Feed URL
|
|
@@ -133,7 +135,18 @@ export async function deleteFeed(application, channelId, url) {
|
|
|
133
135
|
const objectId =
|
|
134
136
|
typeof channelId === "string" ? new ObjectId(channelId) : channelId;
|
|
135
137
|
|
|
136
|
-
|
|
138
|
+
// Find the feed first to get its ID for cascade delete
|
|
139
|
+
const feed = await collection.findOne({ channelId: objectId, url });
|
|
140
|
+
if (!feed) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Delete all items from this feed
|
|
145
|
+
const itemsDeleted = await deleteItemsForFeed(application, feed._id);
|
|
146
|
+
console.info(`[Microsub] Deleted ${itemsDeleted} items from feed ${url}`);
|
|
147
|
+
|
|
148
|
+
// Delete the feed itself
|
|
149
|
+
const result = await collection.deleteOne({ _id: feed._id });
|
|
137
150
|
return result.deletedCount > 0;
|
|
138
151
|
}
|
|
139
152
|
|
package/locales/en.json
CHANGED
|
@@ -55,6 +55,10 @@
|
|
|
55
55
|
"excludeRegex": "Exclude pattern",
|
|
56
56
|
"excludeRegexHelp": "Regular expression to filter out matching content",
|
|
57
57
|
"save": "Save settings",
|
|
58
|
+
"dangerZone": "Danger zone",
|
|
59
|
+
"deleteWarning": "Deleting this channel will permanently remove all feeds and items. This action cannot be undone.",
|
|
60
|
+
"deleteConfirm": "Are you sure you want to delete this channel and all its content?",
|
|
61
|
+
"delete": "Delete channel",
|
|
58
62
|
"types": {
|
|
59
63
|
"like": "Likes",
|
|
60
64
|
"repost": "Reposts",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rmdes/indiekit-endpoint-microsub",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.12",
|
|
4
4
|
"description": "Microsub endpoint for Indiekit. Enables subscribing to feeds and reading content using the Microsub protocol.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"indiekit",
|
package/views/settings.njk
CHANGED
|
@@ -55,5 +55,19 @@
|
|
|
55
55
|
</a>
|
|
56
56
|
</div>
|
|
57
57
|
</form>
|
|
58
|
+
|
|
59
|
+
{% if channel.uid !== "notifications" %}
|
|
60
|
+
<hr class="divider">
|
|
61
|
+
<div class="danger-zone">
|
|
62
|
+
<h3>{{ __("microsub.settings.dangerZone") }}</h3>
|
|
63
|
+
<p class="hint">{{ __("microsub.settings.deleteWarning") }}</p>
|
|
64
|
+
<form method="post" action="{{ baseUrl }}/channels/{{ channel.uid }}/delete" onsubmit="return confirm('{{ __("microsub.settings.deleteConfirm") }}');">
|
|
65
|
+
{{ button({
|
|
66
|
+
text: __("microsub.settings.delete"),
|
|
67
|
+
classes: "button--danger"
|
|
68
|
+
}) }}
|
|
69
|
+
</form>
|
|
70
|
+
</div>
|
|
71
|
+
{% endif %}
|
|
58
72
|
</div>
|
|
59
73
|
{% endblock %}
|