░▒▓████████████████████████████████▓▒░ ░▒▓█ ▓▒░ ░▒▓█ ~ S W A M P ~ ▓▒░ ░▒▓█ ▓▒░ ░▒▓████████████████████████████████▓▒░
lon105.truehost.cloud
LOCATION:
/home/ilrtztmy/floraandcreations.com/api/Controllers/AuthApi
☗ ROOT
↻ REFRESH
✎ CARVE FLESH
EDITING: AuthController.php
<?php /** * Flora and Creations — Auth Controller * * Handles user registration, login, logout, password reset. * Uses bcrypt for password hashing and JWT for session tokens. */ namespace App\Controllers\AuthApi; use App\Database; use App\Auth; use App\Utils\Response; use App\Utils\Request; use App\Utils\Validator; use App\Utils\RateLimiter; use App\Utils\Email; class AuthController { /** * POST /api/auth/register * Register a new customer account. */ public function register(array $params): void { $db = Database::getConnection(); $body = Request::body(); $errors = Validator::make($body, [ 'name' => 'required|min:2|max:255', 'email' => 'required|email', 'phone' => 'required', 'password' => 'required|min:8', ]); if ($errors) { Response::validationError($errors); } // Check email uniqueness $stmt = $db->prepare("SELECT id FROM users WHERE email = :email"); $stmt->execute([':email' => $body['email']]); if ($stmt->fetch()) { Response::validationError(['email' => 'Email already registered.']); } // Insert user $hash = password_hash($body['password'], PASSWORD_BCRYPT); $stmt = $db->prepare("INSERT INTO users (name, email, phone, password_hash, role) VALUES (:name, :email, :phone, :hash, 'customer')"); $stmt->execute([ ':name' => trim($body['name']), ':email' => strtolower($body['email']), ':phone' => trim($body['phone']), ':hash' => $hash, ]); $userId = $db->lastInsertId(); // Generate token $token = Auth::generateToken([ 'id' => $userId, 'role' => 'customer', 'email' => strtolower($body['email']), 'name' => trim($body['name']), ]); Response::created([ 'token' => $token, 'user' => [ 'id' => $userId, 'name' => trim($body['name']), 'email' => strtolower($body['email']), 'phone' => trim($body['phone']), 'role' => 'customer', ], 'message' => 'Account created successfully.', ]); } /** * POST /api/auth/login * Authenticate and return JWT token. */ public function login(array $params): void { $db = Database::getConnection(); $body = Request::body(); // Rate limit login attempts $clientIp = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1'; if (!RateLimiter::check("login_$clientIp", 5, 60)) { Response::tooManyRequests('Too many login attempts. Please try again in a minute.'); } $errors = Validator::make($body, [ 'email' => 'required|email', 'password' => 'required', ]); if ($errors) { Response::validationError($errors); } // Find user $stmt = $db->prepare("SELECT * FROM users WHERE email = :email LIMIT 1"); $stmt->execute([':email' => strtolower($body['email'])]); $user = $stmt->fetch(); if (!$user || !$user['password_hash']) { Response::unauthorized('Invalid email or password.'); } // Verify password if (!password_verify($body['password'], $user['password_hash'])) { Response::unauthorized('Invalid email or password.'); } // Generate token $token = Auth::generateToken([ 'id' => $user['id'], 'role' => $user['role'], 'email' => $user['email'], 'name' => $user['name'], ]); Response::ok([ 'token' => $token, 'user' => [ 'id' => $user['id'], 'name' => $user['name'], 'email' => $user['email'], 'phone' => $user['phone'], 'role' => $user['role'], ], ]); } /** * POST /api/auth/logout * In a JWT system, logout is client-side (discard token). * We still provide this endpoint for consistency. */ public function logout(array $params): void { // In a stateless JWT system, logout means the client discards the token. // Optionally, you could add a token blacklist in a future version. Response::ok(['message' => 'Logged out. Please discard your token.']); } /** * POST /api/auth/forgot-password * Send password reset link via email. */ public function forgotPassword(array $params): void { $db = Database::getConnection(); $body = Request::body(); $errors = Validator::make($body, [ 'email' => 'required|email', ]); if ($errors) { Response::validationError($errors); } $stmt = $db->prepare("SELECT id, name, email FROM users WHERE email = :email LIMIT 1"); $stmt->execute([':email' => strtolower($body['email'])]); $user = $stmt->fetch(); if (!$user) { // Don't reveal whether the email exists Response::ok(['message' => 'If an account with that email exists, a reset link has been sent.']); } // Generate reset token $resetToken = bin2hex(random_bytes(32)); $expiry = date('Y-m-d H:i:s', strtotime('+1 hour')); // Store reset token (add expires_at column or use a separate table) $ri = $db->prepare("UPDATE users SET password_reset_token = :token, password_reset_expires = :expiry WHERE id = :id"); $ri->execute([ ':token' => $resetToken, ':expiry' => $expiry, ':id' => $user['id'], ]); // Build reset link $cfg = require __DIR__ . '/../../../config/config.php'; $resetLink = "{$cfg['app']['url']}/reset-password?token=$resetToken&email=" . urlencode($user['email']); // Send email Email::sendPasswordReset($user['email'], $user['name'], $resetLink); Response::ok(['message' => 'If an account with that email exists, a reset link has been sent.']); } /** * POST /api/auth/reset-password * Reset password using the token from forgot-password. */ public function resetPassword(array $params): void { $db = Database::getConnection(); $body = Request::body(); $errors = Validator::make($body, [ 'email' => 'required|email', 'token' => 'required', 'password' => 'required|min:8', ]); if ($errors) { Response::validationError($errors); } $stmt = $db->prepare("SELECT id, password_reset_token, password_reset_expires FROM users WHERE email = :email"); $stmt->execute([':email' => strtolower($body['email'])]); $user = $stmt->fetch(); if (!$user) { Response::badRequest('Invalid reset link.'); } if ($user['password_reset_token'] !== $body['token']) { Response::badRequest('Invalid reset token.'); } if (strtotime($user['password_reset_expires']) < time()) { Response::badRequest('Reset token has expired.'); } // Update password $hash = password_hash($body['password'], PASSWORD_BCRYPT); $stmt = $db->prepare("UPDATE users SET password_hash = :hash, password_reset_token = NULL, password_reset_expires = NULL WHERE id = :id"); $stmt->execute([':hash' => $hash, ':id' => $user['id']]); Response::ok(['message' => 'Password reset successfully.']); } /** * GET /api/auth/me * Return current authenticated user's profile. */ public function me(array $params): void { $authUser = $_SERVER['AUTH_USER'] ?? null; if (!$authUser) { Response::unauthorized(); } $db = Database::getConnection(); $stmt = $db->prepare("SELECT id, name, email, phone, role, created_at, updated_at FROM users WHERE id = :id"); $stmt->execute([':id' => $authUser['id']]); $user = $stmt->fetch(); if (!$user) { Response::unauthorized('User no longer exists.'); } Response::ok($user); } }
CANCEL
Name
Type
Size
Modified
Actions
↩ ..
DIR
—
—
📄 AuthController.php
PHP
8.3 KB
2026-07-15 09:17
EDIT