diff --git a/.dockerignore b/.dockerignore index dd69234..cc2f16b 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,5 @@ # .dockerignore + .vscode node_modules .env diff --git a/.env.example b/.env.example index dc49371..8571074 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,4 @@ -AUTH_SECRET=lFNiU7T98/44Qlqb4hMUkVcLOpijEI7z722Kxhv4O2Y= +AUTH_SECRET= ## openssl rand -base64 32 DB_HOST= DB_PASS= DB_PORT=6379 diff --git a/src/lib/db/index.ts b/src/lib/db/index.ts index 56d9a22..dfb3b73 100644 --- a/src/lib/db/index.ts +++ b/src/lib/db/index.ts @@ -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; diff --git a/src/lib/db/rpd/index.ts b/src/lib/db/rpd/index.ts index 65e8c1f..cbfb5f0 100644 --- a/src/lib/db/rpd/index.ts +++ b/src/lib/db/rpd/index.ts @@ -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; diff --git a/src/lib/db/settings/trackMaxURLs.ts b/src/lib/db/settings/trackMaxURLs.ts index 63e4d67..0b47b02 100644 --- a/src/lib/db/settings/trackMaxURLs.ts +++ b/src/lib/db/settings/trackMaxURLs.ts @@ -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; } diff --git a/src/lib/db/settings/trackRDPandRPM.ts b/src/lib/db/settings/trackRPDandRPM.ts similarity index 83% rename from src/lib/db/settings/trackRDPandRPM.ts rename to src/lib/db/settings/trackRPDandRPM.ts index 23ea955..71bf62e 100644 --- a/src/lib/db/settings/trackRDPandRPM.ts +++ b/src/lib/db/settings/trackRPDandRPM.ts @@ -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 } diff --git a/src/routes/(frontend)/auth/sign-in/+page.svelte b/src/routes/(frontend)/auth/sign-in/+page.svelte index 5de1352..e99a66c 100644 --- a/src/routes/(frontend)/auth/sign-in/+page.svelte +++ b/src/routes/(frontend)/auth/sign-in/+page.svelte @@ -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(); diff --git a/src/routes/(frontend)/dashboard/users/[username]/+page.server.ts b/src/routes/(frontend)/dashboard/users/[username]/+page.server.ts index b19a57c..22b1a90 100644 --- a/src/routes/(frontend)/dashboard/users/[username]/+page.server.ts +++ b/src/routes/(frontend)/dashboard/users/[username]/+page.server.ts @@ -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 }, diff --git a/src/routes/(frontend)/dashboard/users/create/+page.server.ts b/src/routes/(frontend)/dashboard/users/create/+page.server.ts index 0331f07..ca82cb7 100644 --- a/src/routes/(frontend)/dashboard/users/create/+page.server.ts +++ b/src/routes/(frontend)/dashboard/users/create/+page.server.ts @@ -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); diff --git a/src/routes/api/snapps/+server.ts b/src/routes/api/snapps/+server.ts index 55a0768..e4bf2ab 100644 --- a/src/routes/api/snapps/+server.ts +++ b/src/routes/api/snapps/+server.ts @@ -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;