Files
indiekit-endpoint-microsub/lib/controllers/channels.js
Ricardo 4819c229cd feat: restore full microsub implementation with reader UI
Restores complete implementation from feat/endpoint-microsub branch:
- Reader UI with views (reader.njk, channel.njk, feeds.njk, etc.)
- Feed polling, parsing, and normalization
- WebSub subscriber
- SSE realtime updates
- Redis caching
- Search indexing
- Media proxy
- Webmention processing
2026-02-06 20:20:25 +01:00

137 lines
3.1 KiB
JavaScript

/**
* Channel management controller
* @module controllers/channels
*/
import { IndiekitError } from "@indiekit/error";
import {
getChannels,
getChannel,
createChannel,
updateChannel,
deleteChannel,
reorderChannels,
} from "../storage/channels.js";
import { getUserId } from "../utils/auth.js";
import {
validateChannel,
validateChannelName,
parseArrayParameter as parseArrayParametereter,
} from "../utils/validation.js";
/**
* List all channels
* GET ?action=channels
* @param {object} request - Express request
* @param {object} response - Express response
*/
export async function list(request, response) {
const { application } = request.app.locals;
const userId = getUserId(request);
const channels = await getChannels(application, userId);
response.json({ channels });
}
/**
* Handle channel actions (create, update, delete, order)
* POST ?action=channels
* @param {object} request - Express request
* @param {object} response - Express response
*/
export async function action(request, response) {
const { application } = request.app.locals;
const userId = getUserId(request);
const { method, name, uid } = request.body;
// Delete channel
if (method === "delete") {
validateChannel(uid);
const deleted = await deleteChannel(application, uid, userId);
if (!deleted) {
throw new IndiekitError("Channel not found or cannot be deleted", {
status: 404,
});
}
return response.json({ deleted: uid });
}
// Reorder channels
if (method === "order") {
const channelUids = parseArrayParametereter(request.body, "channels");
if (channelUids.length === 0) {
throw new IndiekitError("Missing channels[] parameter", {
status: 400,
});
}
await reorderChannels(application, channelUids, userId);
const channels = await getChannels(application, userId);
return response.json({ channels });
}
// Update existing channel
if (uid) {
validateChannel(uid);
if (name) {
validateChannelName(name);
}
const channel = await updateChannel(application, uid, { name }, userId);
if (!channel) {
throw new IndiekitError("Channel not found", {
status: 404,
});
}
return response.json({
uid: channel.uid,
name: channel.name,
});
}
// Create new channel
validateChannelName(name);
const channel = await createChannel(application, { name, userId });
response.status(201).json({
uid: channel.uid,
name: channel.name,
});
}
/**
* Get a single channel by UID
* @param {object} request - Express request
* @param {object} response - Express response
*/
export async function get(request, response) {
const { application } = request.app.locals;
const userId = getUserId(request);
const { uid } = request.params;
validateChannel(uid);
const channel = await getChannel(application, uid, userId);
if (!channel) {
throw new IndiekitError("Channel not found", {
status: 404,
});
}
response.json({
uid: channel.uid,
name: channel.name,
settings: channel.settings,
});
}
export const channelsController = { list, action, get };