Files
Ricardo 4e514235c2 feat: ActivityPub reader — timeline, notifications, compose, moderation
Add a dedicated fediverse reader view with:
- Timeline view showing posts from followed accounts with threading,
  content warnings, boosts, and media display
- Compose form with dual-path posting (quick AP reply + Micropub blog post)
- Native AP interactions (like, boost, reply, follow/unfollow)
- Notifications view for likes, boosts, follows, mentions, replies
- Moderation tools (mute/block actors, keyword filters)
- Remote actor profile pages with follow state
- Automatic timeline cleanup with configurable retention
- CSRF protection, XSS prevention, input validation throughout

Removes Microsub bridge dependency — AP content now lives in its own
MongoDB collections (ap_timeline, ap_notifications, ap_interactions,
ap_muted, ap_blocked).

Bumps version to 1.1.0.
2026-02-21 12:13:10 +01:00

50 lines
1.1 KiB
JavaScript

/**
* Simple CSRF token generation and validation.
* Tokens are stored in the Express session.
*/
import { randomBytes, timingSafeEqual } from "node:crypto";
/**
* Get or generate a CSRF token for the current session.
* @param {object} session - Express session object
* @returns {string} CSRF token
*/
export function getToken(session) {
if (!session._csrfToken) {
session._csrfToken = randomBytes(32).toString("hex");
}
return session._csrfToken;
}
/**
* Validate a CSRF token from a request.
* Checks both the request body `_csrf` field and the `X-CSRF-Token` header.
* @param {object} request - Express request object
* @returns {boolean} Whether the token is valid
*/
export function validateToken(request) {
const sessionToken = request.session?._csrfToken;
if (!sessionToken) {
return false;
}
const requestToken =
request.body?._csrf || request.headers["x-csrf-token"];
if (!requestToken) {
return false;
}
if (sessionToken.length !== requestToken.length) {
return false;
}
return timingSafeEqual(
Buffer.from(sessionToken),
Buffer.from(requestToken),
);
}