feat: ✨ display remaining time on ratelimits
This commit is contained in:
parent
8a45d25912
commit
7ca519560f
|
@ -0,0 +1,17 @@
|
||||||
|
export function convertMilliseconds(ms: number) {
|
||||||
|
let seconds = Math.round(ms / 1000);
|
||||||
|
let minutes = Math.round(seconds / 60);
|
||||||
|
let hours = Math.round(minutes / 60);
|
||||||
|
const days = Math.round(hours / 24);
|
||||||
|
seconds %= 60;
|
||||||
|
minutes %= 60;
|
||||||
|
hours %= 24;
|
||||||
|
|
||||||
|
const result = [];
|
||||||
|
if (days > 0) result.push(`${days} day(s)`);
|
||||||
|
if (hours > 0) result.push(`${hours} hour(s)`);
|
||||||
|
if (minutes > 0) result.push(`${minutes} minute(s)`);
|
||||||
|
if (seconds > 0) result.push(`${seconds} second(s)`);
|
||||||
|
|
||||||
|
return result.join(", ");
|
||||||
|
}
|
|
@ -66,8 +66,11 @@ export default async (
|
||||||
limit as IEndpointMeta["limit"] & { key: NonNullable<string> },
|
limit as IEndpointMeta["limit"] & { key: NonNullable<string> },
|
||||||
limitActor,
|
limitActor,
|
||||||
).catch((e) => {
|
).catch((e) => {
|
||||||
|
const remainingTime = e.remainingTime
|
||||||
|
? `Please try again in ${e.remainingTime}.`
|
||||||
|
: "Please try again later.";
|
||||||
throw new ApiError({
|
throw new ApiError({
|
||||||
message: "Rate limit exceeded. Please try again later.",
|
message: `Rate limit exceeded. ${remainingTime}`,
|
||||||
code: "RATE_LIMIT_EXCEEDED",
|
code: "RATE_LIMIT_EXCEEDED",
|
||||||
id: "d5826d14-3982-4d2e-8011-b9e9f02499ef",
|
id: "d5826d14-3982-4d2e-8011-b9e9f02499ef",
|
||||||
httpStatusCode: 429,
|
httpStatusCode: 429,
|
||||||
|
@ -94,7 +97,7 @@ export default async (
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ep.meta.requireAdmin && !user!.isAdmin) {
|
if (ep.meta.requireAdmin && !user!.isAdmin) {
|
||||||
throw new ApiError(accessDenied, { reason: "You are not the admin." });
|
throw new ApiError(accessDenied, { reason: "You are not an admin." });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ep.meta.requireModerator && !isModerator) {
|
if (ep.meta.requireModerator && !isModerator) {
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { CacheableLocalUser, User } from "@/models/entities/user.js";
|
||||||
import Logger from "@/services/logger.js";
|
import Logger from "@/services/logger.js";
|
||||||
import { redisClient } from "../../db/redis.js";
|
import { redisClient } from "../../db/redis.js";
|
||||||
import type { IEndpointMeta } from "./endpoints.js";
|
import type { IEndpointMeta } from "./endpoints.js";
|
||||||
|
import { convertMilliseconds } from "@/misc/convert-milliseconds.js";
|
||||||
|
|
||||||
const logger = new Logger("limiter");
|
const logger = new Logger("limiter");
|
||||||
|
|
||||||
|
@ -76,7 +77,10 @@ export const limiter = (
|
||||||
);
|
);
|
||||||
|
|
||||||
if (info.remaining === 0) {
|
if (info.remaining === 0) {
|
||||||
reject("RATE_LIMIT_EXCEEDED");
|
reject({
|
||||||
|
message: "RATE_LIMIT_EXCEEDED",
|
||||||
|
remainingTime: convertMilliseconds(info.resetMs),
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
ok();
|
ok();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ export const errors = {
|
||||||
INVALID_PARAM: {
|
INVALID_PARAM: {
|
||||||
value: {
|
value: {
|
||||||
error: {
|
error: {
|
||||||
message: "Invalid param.",
|
message: "Invalid parameter.",
|
||||||
code: "INVALID_PARAM",
|
code: "INVALID_PARAM",
|
||||||
id: "3d81ceae-475f-4600-b2a8-2bc116157532",
|
id: "3d81ceae-475f-4600-b2a8-2bc116157532",
|
||||||
},
|
},
|
||||||
|
@ -25,8 +25,7 @@ export const errors = {
|
||||||
AUTHENTICATION_FAILED: {
|
AUTHENTICATION_FAILED: {
|
||||||
value: {
|
value: {
|
||||||
error: {
|
error: {
|
||||||
message:
|
message: "Authentication failed.",
|
||||||
"Authentication failed. Please ensure your token is correct.",
|
|
||||||
code: "AUTHENTICATION_FAILED",
|
code: "AUTHENTICATION_FAILED",
|
||||||
id: "b0a7f5f8-dc2f-4171-b91f-de88ad238e14",
|
id: "b0a7f5f8-dc2f-4171-b91f-de88ad238e14",
|
||||||
},
|
},
|
||||||
|
@ -38,7 +37,7 @@ export const errors = {
|
||||||
value: {
|
value: {
|
||||||
error: {
|
error: {
|
||||||
message:
|
message:
|
||||||
"You sent a request to Calc, Calckey's resident stoner furry, instead of the server.",
|
"You sent a request to Calc instead of the server. How did this happen?",
|
||||||
code: "I_AM_CALC",
|
code: "I_AM_CALC",
|
||||||
id: "60c46cd1-f23a-46b1-bebe-5d2b73951a84",
|
id: "60c46cd1-f23a-46b1-bebe-5d2b73951a84",
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue