mirror of
https://github.com/fosrl/pangolin.git
synced 2025-08-20 01:08:41 +02:00
add strict rate limit to endpoints that send email
This commit is contained in:
parent
58a084426b
commit
3c7025a327
2 changed files with 46 additions and 5 deletions
|
@ -8,10 +8,8 @@ import { db } from "@server/db";
|
||||||
import { passwordResetTokens, users } from "@server/db/schema";
|
import { passwordResetTokens, users } from "@server/db/schema";
|
||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
import { alphabet, generateRandomString, sha256 } from "oslo/crypto";
|
import { alphabet, generateRandomString, sha256 } from "oslo/crypto";
|
||||||
import { encodeHex } from "oslo/encoding";
|
|
||||||
import { createDate } from "oslo";
|
import { createDate } from "oslo";
|
||||||
import logger from "@server/logger";
|
import logger from "@server/logger";
|
||||||
import { generateIdFromEntropySize } from "@server/auth/sessions/app";
|
|
||||||
import { TimeSpan } from "oslo";
|
import { TimeSpan } from "oslo";
|
||||||
import config from "@server/lib/config";
|
import config from "@server/lib/config";
|
||||||
import { sendEmail } from "@server/emails";
|
import { sendEmail } from "@server/emails";
|
||||||
|
@ -85,7 +83,9 @@ export async function requestPasswordReset(
|
||||||
const url = `${config.getRawConfig().app.dashboard_url}/auth/reset-password?email=${email}&token=${token}`;
|
const url = `${config.getRawConfig().app.dashboard_url}/auth/reset-password?email=${email}&token=${token}`;
|
||||||
|
|
||||||
if (!config.getRawConfig().email) {
|
if (!config.getRawConfig().email) {
|
||||||
logger.info(`Password reset requested for ${email}. Token: ${token}.`);
|
logger.info(
|
||||||
|
`Password reset requested for ${email}. Token: ${token}.`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await sendEmail(
|
await sendEmail(
|
||||||
|
|
|
@ -27,6 +27,8 @@ import { verifyUserHasAction } from "../middlewares/verifyUserHasAction";
|
||||||
import { ActionsEnum } from "@server/auth/actions";
|
import { ActionsEnum } from "@server/auth/actions";
|
||||||
import { verifyUserIsOrgOwner } from "../middlewares/verifyUserIsOrgOwner";
|
import { verifyUserIsOrgOwner } from "../middlewares/verifyUserIsOrgOwner";
|
||||||
import { createNewt, getToken } from "./newt";
|
import { createNewt, getToken } from "./newt";
|
||||||
|
import rateLimit from "express-rate-limit";
|
||||||
|
import createHttpError from "http-errors";
|
||||||
|
|
||||||
// Root routes
|
// Root routes
|
||||||
export const unauthenticated = Router();
|
export const unauthenticated = Router();
|
||||||
|
@ -452,22 +454,61 @@ authRouter.post(
|
||||||
);
|
);
|
||||||
authRouter.post("/2fa/disable", verifySessionUserMiddleware, auth.disable2fa);
|
authRouter.post("/2fa/disable", verifySessionUserMiddleware, auth.disable2fa);
|
||||||
authRouter.post("/verify-email", verifySessionMiddleware, auth.verifyEmail);
|
authRouter.post("/verify-email", verifySessionMiddleware, auth.verifyEmail);
|
||||||
|
|
||||||
authRouter.post(
|
authRouter.post(
|
||||||
"/verify-email/request",
|
"/verify-email/request",
|
||||||
verifySessionMiddleware,
|
verifySessionMiddleware,
|
||||||
|
rateLimit({
|
||||||
|
windowMs: 15 * 60 * 1000,
|
||||||
|
max: 3,
|
||||||
|
keyGenerator: (req) => `requestEmailVerificationCode:${req.body.email}`,
|
||||||
|
handler: (req, res, next) => {
|
||||||
|
const message = `You can only request an email verification code ${3} times every ${15} minutes. Please try again later.`;
|
||||||
|
return next(createHttpError(HttpCode.TOO_MANY_REQUESTS, message));
|
||||||
|
}
|
||||||
|
}),
|
||||||
auth.requestEmailVerificationCode
|
auth.requestEmailVerificationCode
|
||||||
);
|
);
|
||||||
|
|
||||||
// authRouter.post(
|
// authRouter.post(
|
||||||
// "/change-password",
|
// "/change-password",
|
||||||
// verifySessionUserMiddleware,
|
// verifySessionUserMiddleware,
|
||||||
// auth.changePassword
|
// auth.changePassword
|
||||||
// );
|
// );
|
||||||
authRouter.post("/reset-password/request", auth.requestPasswordReset);
|
|
||||||
|
authRouter.post(
|
||||||
|
"/reset-password/request",
|
||||||
|
rateLimit({
|
||||||
|
windowMs: 15 * 60 * 1000,
|
||||||
|
max: 3,
|
||||||
|
keyGenerator: (req) => `requestPasswordReset:${req.body.email}`,
|
||||||
|
handler: (req, res, next) => {
|
||||||
|
const message = `You can only request a password reset ${3} times every ${15} minutes. Please try again later.`;
|
||||||
|
return next(createHttpError(HttpCode.TOO_MANY_REQUESTS, message));
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
auth.requestPasswordReset
|
||||||
|
);
|
||||||
|
|
||||||
authRouter.post("/reset-password/", auth.resetPassword);
|
authRouter.post("/reset-password/", auth.resetPassword);
|
||||||
|
|
||||||
authRouter.post("/resource/:resourceId/password", resource.authWithPassword);
|
authRouter.post("/resource/:resourceId/password", resource.authWithPassword);
|
||||||
authRouter.post("/resource/:resourceId/pincode", resource.authWithPincode);
|
authRouter.post("/resource/:resourceId/pincode", resource.authWithPincode);
|
||||||
authRouter.post("/resource/:resourceId/whitelist", resource.authWithWhitelist);
|
|
||||||
|
authRouter.post(
|
||||||
|
"/resource/:resourceId/whitelist",
|
||||||
|
rateLimit({
|
||||||
|
windowMs: 15 * 60 * 1000,
|
||||||
|
max: 10,
|
||||||
|
keyGenerator: (req) => `authWithWhitelist:${req.body.email}`,
|
||||||
|
handler: (req, res, next) => {
|
||||||
|
const message = `You can only request an email OTP ${10} times every ${15} minutes. Please try again later.`;
|
||||||
|
return next(createHttpError(HttpCode.TOO_MANY_REQUESTS, message));
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
resource.authWithWhitelist
|
||||||
|
);
|
||||||
|
|
||||||
authRouter.post(
|
authRouter.post(
|
||||||
"/resource/:resourceId/access-token",
|
"/resource/:resourceId/access-token",
|
||||||
resource.authWithAccessToken
|
resource.authWithAccessToken
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue