unoffical wafrn mirror
wafrn.net
atproto
social-network
activitypub
1import express, { Request, Response } from "express";
2import cors from "cors";
3import bodyParser from "body-parser";
4import { logger } from "./utils/logger.js";
5
6import {
7 workerInbox,
8 workerPrepareSendPost,
9 workerGetUser,
10 workerSendPostChunk,
11 workerProcessFirehose,
12 workerDeletePost,
13 workerProcessRemotePostView,
14 workerProcessRemoteMediaData,
15 workerGenerateUserKeyPair,
16} from "./utils/workers.js";
17
18import { SignedRequest } from "./interfaces/fediverse/signedRequest.js";
19import { activityPubRoutes } from "./routes/activitypub/activitypub.js";
20import { wellKnownRoutes } from "./routes/activitypub/well-known.js";
21import adminRoutes from "./routes/admin.js";
22import blockRoutes from "./routes/blocks.js";
23import blockUserServerRoutes from "./routes/blockUserServer.js";
24import dashboardRoutes from "./routes/dashboard.js";
25import deletePost from "./routes/deletePost.js";
26import emojiReactRoutes from "./routes/emojiReact.js";
27import emojiRoutes from "./routes/emojis.js";
28import followsRoutes from "./routes/follows.js";
29import forumRoutes from "./routes/forum.js";
30import { frontend } from "./routes/frontend.js";
31import likeRoutes from "./routes/like.js";
32import biteRoutes from "./routes/bite.js";
33import listRoutes from "./routes/lists.js";
34import mediaRoutes from "./routes/media.js";
35import muteRoutes from "./routes/mute.js";
36import { notificationRoutes } from "./routes/notifications.js";
37import pollRoutes from "./routes/polls.js";
38import postsRoutes from "./routes/posts.js";
39import { cacheRoutes } from "./routes/remoteCache.js";
40import searchRoutes from "./routes/search.js";
41import silencePostRoutes from "./routes/silencePost.js";
42import statusRoutes from "./routes/status.js";
43import { userRoutes } from "./routes/users.js";
44import checkIpBlocked from "./utils/checkIpBlocked.js";
45import overrideContentType from "./utils/overrideContentType.js";
46import swagger from "swagger-ui-express";
47import { readFile } from "fs/promises";
48import { Worker } from "bullmq";
49import expressWs from "express-ws";
50import websocketRoutes from "./routes/websocket.js";
51import { followHashtagRoutes } from "./routes/followHashtags.js";
52import { completeEnvironment } from "./utils/backendOptions.js";
53import cron from "node-cron";
54import { nukeBannedUsers } from "./utils/maintenanceTasks/nukeBannedUsers.js";
55import { sequelize } from "./models/sequelize.js";
56
57function errorHandler(err: Error, req: Request, res: Response, next: Function) {
58 console.error(err.stack);
59 res.send(500).json({ error: "Internal Server Error" });
60}
61
62const swaggerJSON = JSON.parse(
63 await readFile(new URL("./swagger.json", import.meta.url), "utf-8")
64);
65// rest of the code remains same
66const app = express();
67const wsServer = expressWs(app);
68const server = wsServer.app;
69const PORT = completeEnvironment.port;
70app.use(errorHandler);
71app.use(overrideContentType);
72app.use(checkIpBlocked);
73app.use(
74 bodyParser.json({
75 limit: "50mb",
76 verify: (req: SignedRequest, res, buf) => {
77 req.rawBody = buf.toString();
78 },
79 })
80);
81app.use(cors());
82app.set("trust proxy", 1);
83
84app.use("/api/apidocs", swagger.serve, swagger.setup(swaggerJSON));
85
86app.get("/api/", (req, res) =>
87 res.send({
88 status: true,
89 swagger: "API docs at /apidocs",
90 readme:
91 "welcome to the wafrn api, you better check https://codeberg.org/wafrn/wafrn to figure out where to poke :D. Also, check api/apidocs",
92 })
93);
94
95// serve static images
96app.use("/api/uploads", express.static("uploads"));
97
98app.use("/api/environment", (req: Request, res: Response) => {
99 res.send({
100 ...completeEnvironment.frontendEnvironment,
101 webpushPublicKey: completeEnvironment.webpushPublicKey,
102 reviewRegistrations: completeEnvironment.reviewRegistrations,
103 maxUploadSize: completeEnvironment.uploadLimit,
104 cacheDomain: new URL(completeEnvironment.externalCacheurl).origin,
105 });
106});
107
108userRoutes(app);
109followsRoutes(app);
110blockRoutes(app);
111notificationRoutes(app);
112mediaRoutes(app);
113postsRoutes(app);
114searchRoutes(app);
115deletePost(app);
116if (completeEnvironment.fediPort == completeEnvironment.port) {
117 app.use("/contexts", express.static("contexts"));
118 activityPubRoutes(app);
119 wellKnownRoutes(app);
120}
121if (completeEnvironment.cachePort == completeEnvironment.port) {
122 cacheRoutes(app);
123}
124likeRoutes(app);
125biteRoutes(app);
126emojiReactRoutes(app);
127adminRoutes(app);
128muteRoutes(app);
129blockUserServerRoutes(app);
130dashboardRoutes(app);
131listRoutes(app);
132forumRoutes(app);
133silencePostRoutes(app);
134statusRoutes(app);
135emojiRoutes(app);
136pollRoutes(app);
137followHashtagRoutes(app);
138// just websocket things
139frontend(app);
140
141server.listen(PORT, completeEnvironment.listenIp, () => {
142 logger.info("started main");
143 const workers = [
144 workerInbox,
145 workerSendPostChunk,
146 workerPrepareSendPost,
147 workerGetUser,
148 workerDeletePost,
149 workerProcessRemotePostView,
150 workerProcessRemoteMediaData,
151 workerGenerateUserKeyPair,
152 ];
153 if (completeEnvironment.enableBsky) {
154 workers.push(workerProcessFirehose as Worker);
155 }
156 if (completeEnvironment.workers.mainThread) {
157 workers.forEach((worker) => {
158 worker.on("error", (err) => {
159 logger.warn({
160 message: `worker ${worker.name} failed`,
161 error: err,
162 });
163 });
164 });
165 } else {
166 workers.forEach(async (worker) => {
167 await worker.pause();
168 });
169 }
170});