clqms-be/app/Controllers/AuthController.php
mahdahar 425595f5c0 feat: Implement custom ResponseTrait with automatic empty string to null conversion
- Create App\Traits\ResponseTrait that wraps CodeIgniter\API\ResponseTrait
- Add json_helper with convert_empty_strings_to_null() and prepare_json_response() functions
- Replace all imports of CodeIgniter\API\ResponseTrait with App\Traits\ResponseTrait across all controllers
- Add 'json' helper to BaseController helpers array
- Ensure consistent API response formatting across the application
2026-02-18 10:15:47 +07:00

330 lines
11 KiB
PHP

<?php
namespace App\Controllers;
use App\Traits\ResponseTrait;
use CodeIgniter\Controller;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Firebase\JWT\ExpiredException;
use Firebase\JWT\SignatureInvalidException;
use Firebase\JWT\BeforeValidException;
use CodeIgniter\Cookie\Cookie;
class AuthController extends Controller
{
use ResponseTrait;
protected $db;
// ok
public function __construct()
{
$this->db = \Config\Database::connect();
}
// ok
public function checkAuth()
{
$token = $this->request->getCookie('token');
$key = getenv('JWT_SECRET');
// Jika token FE tidak ada langsung kabarkan failed
if (!$token) {
return $this->respond([
'status' => 'failed',
'message' => 'No token found'
], 401);
}
try {
// Decode Token dengan Key yg ada di .env
$decodedPayload = JWT::decode($token, new Key($key, 'HS256'));
return $this->respond([
'status' => 'success',
'message' => 'Authenticated',
'data' => $decodedPayload
], 200);
} catch (ExpiredException $e) {
return $this->respond([
'status' => 'failed',
'message' => 'Token expired',
'data' => []
], 401);
} catch (SignatureInvalidException $e) {
return $this->respond([
'status' => 'failed',
'message' => 'Invalid token signature',
'data' => []
], 401);
} catch (BeforeValidException $e) {
return $this->respond([
'status' => 'failed',
'message' => 'Token not valid yet',
'data' => []
], 401);
} catch (\Exception $e) {
return $this->respond([
'status' => 'failed',
'message' => 'Invalid token: ' . $e->getMessage(),
'data' => []
], 401);
}
}
// ok
// public function login() {
// // Ambil dari JSON Form dan Key .env
// $username = $this->request->getVar('username');
// $password = $this->request->getVar('password');
// $key = getenv('JWT_SECRET');
// if (!$username) {
// return $this->fail('Username required.', 400);
// }
// $sql = "SELECT * FROM users WHERE username=" . $this->db->escape($username);
// $query = $this->db->query($sql);
// $row = $query->getResultArray();
// if (!$row) { return $this->fail('User not found.', 401); }
// $row = $row[0];
// if (!password_verify($password, $row['password'])) {
// return $this->fail('Invalid password.', 401);
// }
// // Buat JWT payload
// $exp = time() + 864000;
// $payload = [
// 'userid' => $row['id'],
// 'roleid' => $row['role_id'],
// 'username' => $row['username'],
// 'exp' => $exp
// ];
// try {
// // Melakukan Hash terhadap Payload dengan Kunci .env menggunakan Algortima HMAC + SHA-256
// $jwt = JWT::encode($payload, $key, 'HS256');
// } catch (Exception $e) {
// return $this->fail('Error generating JWT: ' . $e->getMessage(), 500);
// }
// // Kirim Respon ke HttpOnly yg akan disimpan di browser dan tidak akan dapat diakses oleh siapapun
// // $isSecure = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on';
// $this->response->setCookie([
// // 'name' => 'token', // nama token
// // 'value' => $jwt, // value dari jwt yg sudah di hash
// // 'expire' => 864000, // 10 hari
// // 'path' => '/', // valid untuk semua path
// // 'secure' => $isSecure, // true for HTTPS, false for HTTP (localhost)
// // 'httponly' => true, // dipakai agar cookie berikut tidak dapat diakses oleh javascript
// // 'samesite' => $isSecure ? Cookie::SAMESITE_NONE : Cookie::SAMESITE_LAX
// ]);
// // Response tanpa token di body
// return $this->respond([
// 'status' => 'success',
// 'code' => 200,
// 'message' => 'Login successful'
// ], 200);
// }
public function login()
{
// Ambil dari JSON Form dan Key .env
$username = $this->request->getVar('username');
$password = $this->request->getVar('password');
$key = getenv('JWT_SECRET');
if (!$username) {
return $this->fail('Username required.', 400);
}
$sql = "SELECT * FROM users WHERE username=" . $this->db->escape($username);
$query = $this->db->query($sql);
$row = $query->getResultArray();
if (!$row) {
return $this->fail('User not found.', 401);
}
$row = $row[0];
if (!password_verify($password, $row['password'])) {
return $this->fail('Invalid password.', 401);
}
// Buat JWT payload
$exp = time() + 864000;
$payload = [
'userid' => $row['id'],
'roleid' => $row['role_id'],
'username' => $row['username'],
'exp' => $exp
];
try {
// Melakukan Hash terhadap Payload dengan Kunci .env menggunakan Algortima HMAC + SHA-256
$jwt = JWT::encode($payload, $key, 'HS256');
} catch (\Exception $e) {
return $this->fail('Error generating JWT: ' . $e->getMessage(), 500);
}
// Detect if HTTPS is being used
$isSecure = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on';
// Kirim Respon ke HttpOnly yg akan disimpan di browser dan tidak akan dapat diakses oleh siapapun
$this->response->setCookie([
'name' => 'token', // nama token
'value' => $jwt, // value dari jwt yg sudah di hash
'expire' => 864000, // 10 hari
'path' => '/', // valid untuk semua path
'secure' => $isSecure,
'httponly' => true, // dipakai agar cookie berikut tidak dapat diakses oleh javascript
'samesite' => $isSecure ? Cookie::SAMESITE_NONE : Cookie::SAMESITE_LAX
]);
// Response tanpa token di body
return $this->respond([
'status' => 'success',
'code' => 200,
'message' => 'Login successful'
], 200);
}
// ok
// public function logout() {
// // Definisikan ini pada cookies browser, harus sama dengan cookies login
// // $isSecure = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on';
// return $this->response->setCookie([
// 'name' => 'token',
// 'value' => '',
// 'expire' => time() - 3600,
// 'path' => '/',
// 'secure' => $isSecure,
// 'httponly' => true,
// 'samesite' => $isSecure ? Cookie::SAMESITE_NONE : Cookie::SAMESITE_LAX
// ])->setJSON([
// 'status' => 'success',
// 'code' => 200,
// 'message' => 'Logout successful'
// ], 200);
// }
public function logout()
{
// Detect if HTTPS is being used
$isSecure = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on';
// Definisikan ini pada cookies browser, harus sama dengan cookies login
return $this->response->setCookie([
'name' => 'token',
'value' => '',
'expire' => time() - 3600,
'path' => '/',
'secure' => $isSecure,
'httponly' => true,
'samesite' => $isSecure ? Cookie::SAMESITE_NONE : Cookie::SAMESITE_LAX
])->setJSON([
'status' => 'success',
'code' => 200,
'message' => 'Logout successful'
], 200);
}
// ok
public function register()
{
$username = strtolower($this->request->getJsonVar('username'));
$password = $this->request->getJsonVar('password');
// Validasi Awal Dari BE
if (empty($username) || empty($password)) {
return $this->respond([
'status' => 'failed',
'code' => 400,
'message' => 'Username and password are required'
], 400); // Gunakan 400 Bad Request
}
// Cek Duplikasi Username
$exists = $this->db->query("SELECT id FROM users WHERE username = ?", [$username])->getRow();
if ($exists) {
return $this->respond(['status' => 'failed', 'code' => 409, 'message' => 'Username already exists'], 409);
}
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
// Mulai transaksi Insert
$this->db->transStart();
$this->db->query(
"INSERT INTO users(username, password, role_id) VALUES(?, ?, ?)",
[$username, $hashedPassword, 1]
);
$this->db->transComplete();
// Cek status transaksi
if ($this->db->transStatus() === false) {
return $this->respond([
'status' => 'error',
'code' => 500,
'message' => 'Failed to create user. Please try again later.'
], 500);
}
// Respon sukses jika kueri berhasil
return $this->respond([
'status' => 'success',
'code' => 201,
'message' => 'User ' . $username . ' successfully created.'
], 201);
}
// public function change_pass() {
// $db = \Config\Database::connect();
// $username = $this->request->getJsonVar('username');
// $password = $this->request->getJsonVar('password');
// $password = password_hash($password, PASSWORD_DEFAULT);
// $master = $this->request->getJsonVar('master');
// $masterkey = getenv('masterkey');
// if($master != $masterkey) {
// return $this->fail('Invalid master key.', 401);
// }
// $sql = "update users set password='$password' where username='$username'";
// $query = $db->query($sql);
// $response = [
// 'message' => "Password Changed for $username"
// ];
// return $this->respond($response);
// }
public function coba()
{
$token = $this->request->getCookie('token');
$key = getenv('JWT_SECRET');
// Decode Token dengan Key yg ada di .env
$decodedPayload = JWT::decode($token, new Key($key, 'HS256'));
return $this->respond([
'status' => 'success',
'message' => 'Authenticated',
'data' => $decodedPayload
], 200);
}
}