67 lines
1.6 KiB
PHP
Executable File
67 lines
1.6 KiB
PHP
Executable File
<?php
|
|
|
|
namespace App\Libraries;
|
|
|
|
/**
|
|
* Generates and validates signed tokens for staff time-off approval links.
|
|
*/
|
|
class StaffTimeOffLinkService
|
|
{
|
|
private const TOKEN_CONTEXT = 'timeoff_notify';
|
|
private const DEFAULT_TTL = 1209600; // 14 days
|
|
|
|
private string $secret;
|
|
private int $ttl;
|
|
|
|
public function __construct(?string $secret = null, ?int $ttlSeconds = null)
|
|
{
|
|
helper('jwt');
|
|
|
|
$this->secret = $secret ?: (string)env('JWT_SECRET', 'change-me-in-env');
|
|
$this->ttl = ($ttlSeconds !== null && $ttlSeconds > 0) ? $ttlSeconds : self::DEFAULT_TTL;
|
|
}
|
|
|
|
/**
|
|
* Create a signed token embedding request metadata.
|
|
*
|
|
* @param array $payload
|
|
*/
|
|
public function createToken(array $payload): string
|
|
{
|
|
$now = time();
|
|
$data = array_merge($payload, [
|
|
'iat' => $now,
|
|
'exp' => $now + $this->ttl,
|
|
'ctx' => self::TOKEN_CONTEXT,
|
|
]);
|
|
|
|
return jwt_encode($data, $this->secret);
|
|
}
|
|
|
|
/**
|
|
* Validate a token and return its payload if valid.
|
|
*/
|
|
public function parseToken(?string $token): ?array
|
|
{
|
|
if (!is_string($token) || $token === '') {
|
|
return null;
|
|
}
|
|
|
|
$payload = jwt_decode($token, $this->secret);
|
|
if (!is_array($payload)) {
|
|
return null;
|
|
}
|
|
|
|
if (($payload['ctx'] ?? null) !== self::TOKEN_CONTEXT) {
|
|
return null;
|
|
}
|
|
|
|
$exp = (int)($payload['exp'] ?? 0);
|
|
if ($exp > 0 && $exp < time()) {
|
|
return null;
|
|
}
|
|
|
|
return $payload;
|
|
}
|
|
}
|