feat: Implement secure email/password authentication with user registration, API rate limiting, and dynamic homepage navigation.

This commit is contained in:
Yusuf İpek
2026-02-07 06:43:09 +03:00
parent d38e8b8749
commit 5b436fff2d
11 changed files with 707 additions and 166 deletions
+31
View File
@@ -0,0 +1,31 @@
-- Rate Limiting Table (UNLOGGED for performance)
-- Run this migration manually: psql $DATABASE_URL -f prisma/migrations/rate_limit.sql
-- Drop if exists (for re-running)
DROP TABLE IF EXISTS rate_limits;
-- Create UNLOGGED table for rate limiting
-- UNLOGGED = no WAL writes = faster, but data lost on crash (acceptable for rate limits)
CREATE UNLOGGED TABLE rate_limits (
id SERIAL PRIMARY KEY,
key VARCHAR(255) NOT NULL, -- e.g., "register:192.168.1.1" or "login:[email protected]"
action VARCHAR(50) NOT NULL, -- e.g., "register", "login", "api"
count INTEGER NOT NULL DEFAULT 1,
window_start TIMESTAMP NOT NULL DEFAULT NOW(),
-- Unique constraint for upsert operations
UNIQUE(key, action)
);
-- Index for fast lookups
CREATE INDEX idx_rate_limits_key_action ON rate_limits(key, action);
-- Index for cleanup operations
CREATE INDEX idx_rate_limits_window_start ON rate_limits(window_start);
-- Auto-cleanup function: removes expired entries
CREATE OR REPLACE FUNCTION cleanup_rate_limits() RETURNS void AS $$
BEGIN
DELETE FROM rate_limits WHERE window_start < NOW() - INTERVAL '1 hour';
END;
$$ LANGUAGE plpgsql;
+2 -1
View File
@@ -18,6 +18,7 @@ model User {
email String? @unique
emailVerified DateTime?
image String?
password String? // Hashed password for email/password auth
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -248,7 +249,7 @@ model ShareLink {
expiresAt DateTime? // Link expiration
maxUses Int? // Maximum number of uses
useCount Int @default(0)
password String? // Optional password protection
passwordHash String? // Bcrypt hash of optional password protection
// Settings
allowGuests Boolean @default(true) // Allow comments without account