mirror of
https://github.com/tdurieux/anonymous_github.git
synced 2026-02-13 02:42:45 +00:00
155 lines
4.5 KiB
TypeScript
155 lines
4.5 KiB
TypeScript
import * as path from "path";
|
|
import * as ofs from "fs";
|
|
import { createClient } from "redis";
|
|
import rateLimit from "express-rate-limit";
|
|
import * as slowDown from "express-slow-down";
|
|
import RedisStore from "rate-limit-redis";
|
|
import * as express from "express";
|
|
import * as compression from "compression";
|
|
import * as db from "./database/database";
|
|
import config from "../config";
|
|
import * as passport from "passport";
|
|
|
|
import * as connection from "./routes/connection";
|
|
import router from "./routes";
|
|
import AnonymizedRepositoryModel from "./database/anonymizedRepositories/anonymizedRepositories.model";
|
|
import { conferenceStatusCheck, repositoryStatusCheck } from "./schedule";
|
|
import { startWorker } from "./queue";
|
|
import AnonymizedPullRequestModel from "./database/anonymizedPullRequests/anonymizedPullRequests.model";
|
|
|
|
function indexResponse(req: express.Request, res: express.Response) {
|
|
if (
|
|
req.params.repoId &&
|
|
req.headers["accept"] &&
|
|
req.headers["accept"].indexOf("text/html") == -1
|
|
) {
|
|
const repoId = req.path.split("/")[2];
|
|
// if it is not an html request, it assumes that the browser try to load a different type of resource
|
|
return res.redirect(
|
|
`/api/repo/${repoId}/file/${req.path.substring(
|
|
req.path.indexOf(repoId) + repoId.length + 1
|
|
)}`
|
|
);
|
|
}
|
|
res.sendFile(path.resolve(__dirname, "..", "public", "index.html"));
|
|
}
|
|
|
|
export default async function start() {
|
|
const app = express();
|
|
app.use(express.json());
|
|
|
|
app.use(compression());
|
|
app.set("trust proxy", true);
|
|
app.set("etag", "strong");
|
|
|
|
app.get("/ip", (request, response) => response.send(request.ip));
|
|
|
|
// handle session and connection
|
|
app.use(connection.appSession);
|
|
app.use(passport.initialize());
|
|
app.use(passport.session());
|
|
|
|
startWorker();
|
|
|
|
const redisClient = createClient({
|
|
socket: {
|
|
host: config.REDIS_HOSTNAME,
|
|
port: config.REDIS_PORT,
|
|
},
|
|
});
|
|
redisClient.on("error", (err) => console.log("Redis Client Error", err));
|
|
|
|
await redisClient.connect();
|
|
|
|
const rate = rateLimit({
|
|
store: new RedisStore({
|
|
sendCommand: (...args: string[]) => redisClient.sendCommand(args),
|
|
}),
|
|
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
max: config.RATE_LIMIT, // limit each IP
|
|
standardHeaders: true,
|
|
legacyHeaders: false,
|
|
});
|
|
const speedLimiter = slowDown({
|
|
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
delayAfter: 50,
|
|
delayMs: 150,
|
|
maxDelayMs: 5000,
|
|
headers: true,
|
|
});
|
|
|
|
app.use("/github", rate, speedLimiter, connection.router);
|
|
|
|
// api routes
|
|
const apiRouter = express.Router();
|
|
app.use("/api", rate, apiRouter);
|
|
|
|
apiRouter.use("/admin", router.admin);
|
|
apiRouter.use("/options", router.option);
|
|
apiRouter.use("/conferences", router.conference);
|
|
apiRouter.use("/user", router.user);
|
|
apiRouter.use("/repo", router.repositoryPublic);
|
|
apiRouter.use("/repo", speedLimiter, router.file);
|
|
apiRouter.use("/repo", speedLimiter, router.repositoryPrivate);
|
|
apiRouter.use("/pr", speedLimiter, router.pullRequestPrivate);
|
|
apiRouter.use("/pr", speedLimiter, router.pullRequestPublic);
|
|
|
|
apiRouter.get("/message", async (_, res) => {
|
|
if (ofs.existsSync("./message.txt")) {
|
|
return res.sendFile(path.resolve(__dirname, "..", "message.txt"));
|
|
}
|
|
res.sendStatus(404);
|
|
});
|
|
|
|
apiRouter.get("/stat", async (_, res) => {
|
|
const [nbRepositories, users, nbPageViews, nbPullRequests] =
|
|
await Promise.all([
|
|
AnonymizedRepositoryModel.estimatedDocumentCount(),
|
|
AnonymizedRepositoryModel.distinct("owner"),
|
|
AnonymizedRepositoryModel.collection
|
|
.aggregate([
|
|
{
|
|
$group: { _id: null, total: { $sum: "$pageView" } },
|
|
},
|
|
])
|
|
.toArray(),
|
|
AnonymizedPullRequestModel.estimatedDocumentCount(),
|
|
]);
|
|
|
|
res.json({
|
|
nbRepositories,
|
|
nbUsers: users.length,
|
|
nbPageViews: nbPageViews[0].total,
|
|
nbPullRequests,
|
|
});
|
|
});
|
|
|
|
// web view
|
|
app.use("/w/", rate, speedLimiter, router.webview);
|
|
|
|
app
|
|
.get("/", indexResponse)
|
|
.get("/404", indexResponse)
|
|
.get("/anonymize", indexResponse)
|
|
.get("/r/:repoId/?*", indexResponse)
|
|
.get("/repository/:repoId/?*", indexResponse);
|
|
|
|
app.use(
|
|
express.static(path.join(__dirname, "..", "public"), {
|
|
etag: true,
|
|
lastModified: true,
|
|
maxAge: 3600, // 1h
|
|
})
|
|
);
|
|
|
|
app.get("*", indexResponse);
|
|
|
|
// start schedules
|
|
conferenceStatusCheck();
|
|
repositoryStatusCheck();
|
|
|
|
await db.connect();
|
|
app.listen(config.PORT);
|
|
console.log("Database connected and Server started on port: " + config.PORT);
|
|
}
|