mirror of
https://github.com/fergalmoran/snapp.git
synced 2025-12-22 09:41:45 +00:00
Fixes on api rate limits
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
# .dockerignore
|
||||
|
||||
.vscode
|
||||
node_modules
|
||||
.env
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
AUTH_SECRET=lFNiU7T98/44Qlqb4hMUkVcLOpijEI7z722Kxhv4O2Y=
|
||||
AUTH_SECRET= ## openssl rand -base64 32
|
||||
DB_HOST=
|
||||
DB_PASS=
|
||||
DB_PORT=6379
|
||||
|
||||
@@ -25,7 +25,7 @@ import isWhiteListed from './users/isWhiteListed';
|
||||
import isBlackListed from './users/isBlackListed';
|
||||
import isBlackListedEmail from './users/isEmailBlackListed';
|
||||
import trackMaxURLs from './settings/trackMaxURLs';
|
||||
import trackRPDandRPM from './settings/trackRDPandRPM';
|
||||
import trackRPDandRPM from './settings/trackRPDandRPM';
|
||||
import hasWhiteList from './snapps/has_whitelist';
|
||||
|
||||
export const domainZList = 'settings:app:banlists:website' as const;
|
||||
|
||||
@@ -10,7 +10,6 @@ export default async function checkRPDLimit(this: Database, userId: string, rpdL
|
||||
|
||||
// Check if the user has already made a request on the current date
|
||||
const count = await this.redis.get(key);
|
||||
|
||||
if (count && parseInt(count) >= rpdLimit) {
|
||||
// User has exceeded the RPD limit
|
||||
return false;
|
||||
|
||||
@@ -4,12 +4,12 @@ import { error } from '@sveltejs/kit';
|
||||
import type { Database } from '..';
|
||||
|
||||
export default async function trackMaxURLs(this: Database, apiKey: DBAPIKey, _EN?: Translation) {
|
||||
if (apiKey.roles.includes('admin') || apiKey.roles.includes('superadmin')) return true;
|
||||
if (apiKey.roles.includes('admin') || apiKey.roles.includes('superadmin')) return false;
|
||||
|
||||
const is_limited = await this.getSetting('settings:app:limits:enabled').then(
|
||||
(res) => res === 'true' || false
|
||||
);
|
||||
if (!is_limited) return true;
|
||||
if (!is_limited) return false;
|
||||
|
||||
const EN = _EN ? _EN : await getLanguage();
|
||||
|
||||
@@ -28,6 +28,6 @@ export default async function trackMaxURLs(this: Database, apiKey: DBAPIKey, _EN
|
||||
const limit = user_limit?.urls ?? global_limit_urls;
|
||||
|
||||
if (!limit || urls_by_this_user <= limit) {
|
||||
return true;
|
||||
} else throw error(401, { message: EN['api:error:too:many:shorturl'] });
|
||||
return false;
|
||||
} else true;
|
||||
}
|
||||
|
||||
@@ -4,14 +4,13 @@ import { error } from 'console';
|
||||
import type { Database } from '..';
|
||||
|
||||
export default async function trackRPDandRPM(this: Database, apiKey: DBAPIKey, _EN?: Translation) {
|
||||
if (apiKey.roles.includes('admin') || apiKey.roles.includes('superadmin')) return true;
|
||||
if (apiKey.roles.includes('admin') || apiKey.roles.includes('superadmin')) return false;
|
||||
|
||||
const is_limited = await this.getSetting('settings:app:limits:enabled').then(
|
||||
(res) => res === 'true' || false
|
||||
);
|
||||
if (!is_limited) return true;
|
||||
if (!is_limited) return false;
|
||||
|
||||
const EN = _EN ? _EN : await getLanguage();
|
||||
const global_limit_rpm = await parseNumber(this.getSetting('settings:app:limits:max:rpm'));
|
||||
const global_limit_rpd = await parseNumber(this.getSetting('settings:app:limits:max:rpd'));
|
||||
const user_limit = (
|
||||
@@ -23,5 +22,6 @@ export default async function trackRPDandRPM(this: Database, apiKey: DBAPIKey, _
|
||||
|
||||
const under_the_max_request_limit =
|
||||
(await this.rpm(apiKey.user_id, rpm)) && (await this.rpd(apiKey.user_id, rpd));
|
||||
if (!under_the_max_request_limit) throw error(429, { message: EN['api:error:too:many:request'] });
|
||||
if (!under_the_max_request_limit) return true;
|
||||
return false
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
import type { SubmitFunction } from './$types';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import { signIn } from '@auth/sveltekit/client';
|
||||
import { invalidateAll } from '$app/navigation';
|
||||
import { goto, invalidateAll } from '$app/navigation';
|
||||
import EyeIcon from 'lucide-svelte/icons/eye';
|
||||
import EyeOffIcon from 'lucide-svelte/icons/eye-off';
|
||||
let show_password = false;
|
||||
@@ -51,6 +51,7 @@
|
||||
callbackUrl: '/'
|
||||
});
|
||||
await invalidateAll();
|
||||
goto('/');
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -59,7 +60,6 @@
|
||||
show_password = !show_password;
|
||||
}
|
||||
function handle_submit_enter(e: KeyboardEvent) {
|
||||
|
||||
const keyEvent = e as KeyboardEvent;
|
||||
if (keyEvent.code !== 'Enter' && keyEvent.code !== 'NumpadEnter') return;
|
||||
e.preventDefault();
|
||||
|
||||
@@ -110,7 +110,7 @@ export const actions = {
|
||||
emailForm.set('email_footer', EMAIL_FOOTER);
|
||||
emailForm.set('outer_text', OUT_TEXT);
|
||||
|
||||
const send_mail = await fetch('/api/smtp/send', {
|
||||
await fetch('/api/smtp/send', {
|
||||
headers: {
|
||||
authorization: 'Bearer ' + token.id
|
||||
},
|
||||
|
||||
@@ -3,8 +3,6 @@ import type SnappError from '$lib/db/utils/snappError.js';
|
||||
import { error, fail, redirect, type NumericRange } from '@sveltejs/kit';
|
||||
import { randomUUID } from 'crypto';
|
||||
import type { Actions } from './$types';
|
||||
import { generateRandomString } from '$lib/utils/randomString';
|
||||
import { createTransport, type TransportOptions } from 'nodemailer';
|
||||
import { env } from '$env/dynamic/public';
|
||||
import getLanguage from '$lib/api/utils/getLanguage';
|
||||
|
||||
@@ -124,7 +122,7 @@ export const actions: Actions = {
|
||||
const APP_NAME = EN['global:appname'];
|
||||
const EMAIL_OBJECT = EN['emails:invited:object'].replace('{app_name}', APP_NAME);
|
||||
const EMAIL_DESCRIPTION = EN['emails:invited:text']
|
||||
.replace('{url}', `${env.PUBLIC_URL}/auth/recover-password?token=${token}`)
|
||||
.replace('{url}', `${env.PUBLIC_URL}/auth/recover-password?token=${token.id}`)
|
||||
.replace('{username}', user.username);
|
||||
const EMAIL_FOOTER = EN['emails:invited:footer'].replace('{url}', url.origin);
|
||||
|
||||
|
||||
@@ -10,11 +10,11 @@ import { extractDomain } from '$lib/db/snapps/shorten.js';
|
||||
import { randomUUID } from 'crypto';
|
||||
|
||||
export async function GET({ request, url }) {
|
||||
console.log('get');
|
||||
const EN = await getLanguage();
|
||||
const apiKey = await authenticate(request, EN);
|
||||
|
||||
await db.trackRPDandRPM(apiKey, EN);
|
||||
const isLimited = await db.trackRPDandRPM(apiKey, EN);
|
||||
if (isLimited) throw error(429, { message: EN['api:error:too:many:request'] });
|
||||
|
||||
const { page, limit, search, sort, sortDir, offset } = getUrlParams(url);
|
||||
let query = db.snapps.search();
|
||||
@@ -40,7 +40,7 @@ export async function GET({ request, url }) {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'cache-control': 'max-age=' + 60 * 60,
|
||||
'Access-Control-Allowed-Origins':"*"
|
||||
'Access-Control-Allowed-Origins': '*'
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -53,8 +53,10 @@ export async function POST({ request, fetch }) {
|
||||
const EN = await getLanguage();
|
||||
const apiKey = await authenticate(request, EN);
|
||||
|
||||
await db.trackRPDandRPM(apiKey, EN);
|
||||
await db.trackMaxURLs(apiKey, EN);
|
||||
const isLimited = await db.trackRPDandRPM(apiKey, EN);
|
||||
if (isLimited) throw error(429, { message: EN['api:error:too:many:request'] });
|
||||
const hasReachedMaxLimit = await db.trackMaxURLs(apiKey, EN);
|
||||
if (hasReachedMaxLimit) throw error(401, { message: EN['api:error:too:many:shorturl'] });
|
||||
|
||||
const form = await request.formData();
|
||||
const { user_id } = apiKey;
|
||||
@@ -107,7 +109,8 @@ export async function PATCH({ request, fetch }) {
|
||||
const EN = await getLanguage();
|
||||
const apiKey = await authenticate(request, EN);
|
||||
|
||||
await db.trackRPDandRPM(apiKey, EN);
|
||||
const isLimited = await db.trackRPDandRPM(apiKey, EN);
|
||||
if (isLimited) throw error(429, { message: EN['api:error:too:many:request'] });
|
||||
|
||||
const form = await request.formData();
|
||||
const id = form.get('id')?.toString();
|
||||
@@ -171,7 +174,8 @@ export async function DELETE({ request, url }) {
|
||||
const EN = await getLanguage();
|
||||
const apiKey = await authenticate(request, EN);
|
||||
|
||||
await db.trackRPDandRPM(apiKey, EN);
|
||||
const isLimited = await db.trackRPDandRPM(apiKey, EN);
|
||||
if (isLimited) throw error(429, { message: EN['api:error:too:many:request'] });
|
||||
|
||||
const { user_id } = apiKey;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user