feat(api): add rate-limiting and /clear-guild-cache (#198)

This commit is contained in:
41666 2021-03-23 22:14:33 -04:00 committed by GitHub
parent 57d83699d5
commit a4fd37d71c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 138 additions and 12 deletions

View file

@ -10,6 +10,7 @@ import {
import { AuthType, cacheLayer, discordFetch } from './api-tools';
import { botClientID, botToken } from './config';
import { GuildData, Guilds } from './kv';
import { useRateLimiter } from './rate-limiting';
type APIGuild = {
// Only relevant stuff
@ -161,3 +162,14 @@ const calculateRoleSafety = (role: Role | APIRole, highestBotRolePosition: numbe
return safety;
};
export enum GuildRateLimiterKey {
legacyImport = 'legacyImport',
cacheClear = 'cacheClear',
}
export const useGuildRateLimiter = (
guildID: string,
key: GuildRateLimiterKey,
timeoutSeconds: number
) => useRateLimiter(Guilds, `guilds/${guildID}/rate-limit/${key}`, timeoutSeconds);

View file

@ -0,0 +1,15 @@
import { WrappedKVNamespace } from './kv';
export const useRateLimiter = (
kv: WrappedKVNamespace,
key: string,
timeoutSeconds: number
) => async (): Promise<boolean> => {
const value = await kv.get<boolean>(key);
if (value) {
return true;
}
await kv.put(key, true, timeoutSeconds);
return false;
};

View file

@ -0,0 +1,16 @@
import { respond } from './api-tools';
export const ok = () => respond({ ok: true });
export const missingParameters = () =>
respond({ error: 'missing parameters' }, { status: 400 });
export const lowPermissions = () =>
respond({ error: 'no permissions for this action' }, { status: 403 });
export const notFound = () => respond({ error: 'not found' }, { status: 404 });
export const conflict = () => respond({ error: 'conflict' }, { status: 409 });
export const rateLimited = () =>
respond({ error: 'rate limit hit, enhance your calm' }, { status: 419 });