| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- import { differenceInMinutes, subMinutes } from "date-fns";
- import { Handler } from "express";
- import passport from "passport";
- import axios from "axios";
- import { isAdmin, CustomError } from "../utils";
- import knex from "../knex";
- const authenticate = (
- type: "jwt" | "local" | "localapikey",
- error: string,
- isStrict = true
- ) =>
- async function auth(req, res, next) {
- if (req.user) return next();
- return passport.authenticate(type, (err, user) => {
- if (err) {
- throw new CustomError("An error occurred");
- }
- if (!user && isStrict) {
- throw new CustomError(error, 401);
- }
- if (user && isStrict && !user.verified) {
- throw new CustomError(
- "Your email address is not verified. " +
- "Click on signup to get the verification link again.",
- 400
- );
- }
- if (user && user.banned) {
- throw new CustomError("Your are banned from using this website.", 403);
- }
- if (user) {
- req.user = {
- ...user,
- admin: isAdmin(user.email)
- };
- return next();
- }
- return next();
- })(req, res, next);
- };
- export const local = authenticate("local", "Login credentials are wrong.");
- export const jwt = authenticate("jwt", "Unauthorized.");
- export const jwtLoose = authenticate("jwt", "Unauthorized.", false);
- export const apikey = authenticate(
- "localapikey",
- "API key is not correct.",
- false
- );
- export const cooldown: Handler = async (req, res, next) => {
- const cooldownConfig = Number(process.env.NON_USER_COOLDOWN);
- if (req.user || !cooldownConfig) return next();
- const ip = await knex<IP>("ips")
- .where({ ip: req.realIP.toLowerCase() })
- .andWhere(
- "created_at",
- ">",
- subMinutes(new Date(), cooldownConfig).toISOString()
- )
- .first();
- if (ip) {
- const timeToWait =
- cooldownConfig - differenceInMinutes(new Date(), new Date(ip.created_at));
- throw new CustomError(
- `Non-logged in users are limited. Wait ${timeToWait} minutes or log in.`,
- 400
- );
- }
- next();
- };
- export const recaptcha: Handler = async (req, res, next) => {
- if (process.env.NODE_ENV !== "production") return next();
- if (!req.user) return next();
- const isReCaptchaValid = await axios({
- method: "post",
- url: "https://www.google.com/recaptcha/api/siteverify",
- headers: {
- "Content-type": "application/x-www-form-urlencoded"
- },
- params: {
- secret: process.env.RECAPTCHA_SECRET_KEY,
- response: req.body.reCaptchaToken,
- remoteip: req.realIP
- }
- });
- if (!isReCaptchaValid.data.success) {
- throw new CustomError("reCAPTCHA is not valid. Try again.", 401);
- }
- return next();
- };
|