nhance/app/Helpers/JWTToken.php

252 lines
8.0 KiB
PHP
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Helpers;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Firebase\JWT\ExpiredException;
use Firebase\JWT\BeforeValidException;
use Firebase\JWT\SignatureInvalidException;
// use Psr\Http\Message\RequestInterface;
use CodeIgniter\HTTP\RequestInterface;
use ReflectionClass;
use Exception;
use App\Models\EmployeeModel;
use App\Models\LevelContactModel;
class JWTToken
{
private const ALLOWED_ALG = 'HS512';
public static function encode($data =null)
{
$secret_Key = env('JWT_SECRET');
$request_data = (array)$data;
try{
$token = JWT::encode($request_data ,$secret_Key,'HS512');
$id = $request_data['id'];
$update["token_time_out"] = time() + getenv('TOKENTIMEOUT');
if(isset($data['emp_code'])){
$model = new EmployeeModel();
$model->update($id, $update);
}else{
$models = new LevelContactModel();
$id = $request_data['post_hr_id'];
$models->update($id, $update);
}
return $token;
}
catch (Exception $e) {
return ['status' => false,'message' => $e->getMessage()];
}
}
// public static function validateJWT($jwt)
// {
// $jwtParts = explode(' ', $jwt);
// // print_r($jwtParts);
// if (count($jwtParts) != 2 || $jwtParts[0] == 'Bearer') {
// return false;
// }
// $token = $jwtParts[1];
// try {
// $decoded = JWT::decode($token, new Key(env('JWT_SECRET'), 'HS512'));
// return json_encode(['status' => true, 'message' => 'Token is valid', 'decoded' => (array) $decoded]);
// } catch (ExpiredException $e) {
// return json_encode(['status' => false, 'message' => 'Token has expired']);
// } catch (BeforeValidException $e) {
// return json_encode(['status' => false, 'message' => 'Token is not yet valid']);
// } catch (SignatureInvalidException $e) {
// return json_encode(['status' => false, 'message' => 'Token signature is invalid']);
// } catch (\Exception $e) {
// return json_encode(['status' => false, 'message' => 'An error occurred while decoding the token']);
// }
// }
public static function validateJWT(string $authHeader)
{
// 1⃣ Validate Authorization header
if (!preg_match('/^Bearer\s(\S+)$/', $authHeader, $matches)) {
return ['status' => false, 'message' => 'Invalid Authorization header'];
}
$token = $matches[1];
// 2⃣ Decode JWT header manually
$jwtParts = explode('.', $token);
if (count($jwtParts) !== 3) {
return ['status' => false, 'message' => 'Malformed JWT'];
}
$header = json_decode(base64_decode(strtr($jwtParts[0], '-_', '+/')), true);
// 3⃣ Reject missing or NONE algorithm
if (
empty($header['alg']) ||
$header['alg'] === 'none' ||
$header['alg'] !== self::ALLOWED_ALG
) {
return ['status' => false, 'message' => 'Invalid or unsupported JWT algorithm'];
}
// 4⃣ Enforce signature validation
try {
$decoded = JWT::decode(
$token,
new Key(env('JWT_SECRET'), self::ALLOWED_ALG)
);
return [
'status' => true,
'decoded' => (array) $decoded
];
} catch (ExpiredException $e) {
return ['status' => false, 'message' => 'Token expired'];
} catch (BeforeValidException $e) {
return ['status' => false, 'message' => 'Token not yet valid'];
} catch (SignatureInvalidException $e) {
return ['status' => false, 'message' => 'Invalid token signature'];
} catch (\Exception $e) {
return ['status' => false, 'message' => 'Token validation failed'];
}
}
public static function getIdFromToken($jwt)
{
$jwtParts = explode(' ', $jwt);
$token = $jwtParts[0];
try {
$decoded = JWT::decode($token, new Key(env('JWT_SECRET'), 'HS512'));
return json_encode(['status' => true, 'message' => 'Token is valid', 'data' =>$decoded->data->id ]);
} catch (ExpiredException $e) {
return json_encode(['status' => false, 'message' => 'Token has expired']);
} catch (BeforeValidException $e) {
return json_encode(['status' => false, 'message' => 'Token is not yet valid']);
} catch (SignatureInvalidException $e) {
return json_encode(['status' => false, 'message' => 'Token signature is invalid']);
} catch (\Exception $e) {
return json_encode(['status' => false, 'message' => 'An error occurred while decoding the token']);
}
}
public static function getUserIdFromToken()
{
$request = \Config\Services::request();
$jwt = $request->getHeader('Authorization');
$jwtParts = explode(' ', $jwt);
$token = $jwtParts[1];
$decoded = JWT::decode($token, new Key(env('JWT_SECRET'), 'HS512'));
return $decoded->id;
}
public static function getUserRoleFromToken()
{
$request = \Config\Services::request();
$jwt = $request->getHeader('Authorization');
$jwtParts = explode(' ', $jwt);
$token = $jwtParts[1];
$decoded = JWT::decode($token, new Key(env('JWT_SECRET'), 'HS512'));
return $decoded->role;
}
public static function decodeToken()
{
$request = \Config\Services::request();
$jwt = $request->getHeader('Authorization');
$jwtParts = explode(' ', $jwt);
$token = $jwtParts[1];
$decoded = JWT::decode($token, new Key(env('JWT_SECRET'), 'HS512'));
return $decoded;
}
/**
* Decode Authorization Bearer JWT into an associative array.
* Returns null when header is missing or token is invalid.
*/
public static function getDecodedTokenArray(?RequestInterface $request = null): ?array
{
$request = $request ?? \Config\Services::request();
$authHeader = $request->getHeaderLine('Authorization');
if ($authHeader === '' || empty(env('JWT_SECRET'))) {
return null;
}
try {
$result = self::validateJWT($authHeader);
} catch (\Throwable $e) {
return null;
}
if (($result['status'] ?? false) !== true) {
return null;
}
return isset($result['decoded']) && is_array($result['decoded'])
? $result['decoded']
: null;
}
/**
* Get any claim value from the request Authorization JWT by key.
*
* Usage:
* JWTToken::getValueFromToken($this->request, 'allowed_active_policies', []);
* JWTToken::getValueFromToken($this->request, 'post_hr_id');
*
* JSON-encoded string claims (e.g. "[1,2]" / '{"a":1}') are decoded to arrays.
*
* @param mixed $default Returned when token/key is missing or invalid
* @return mixed
*/
public static function getValueFromToken(RequestInterface $request, string $key, $default = null)
{
$decoded = self::getDecodedTokenArray($request);
if ($decoded === null || ! array_key_exists($key, $decoded)) {
return $default;
}
$value = $decoded[$key];
if (is_string($value)) {
$trimmed = trim($value);
if ($trimmed !== '' && ($trimmed[0] === '{' || $trimmed[0] === '[')) {
$parsed = json_decode($trimmed, true);
if (json_last_error() === JSON_ERROR_NONE) {
return $parsed;
}
}
}
return $value;
}
}