feat(sentinel): embed server UUID in encrypted sentinel token

Replace random string with encrypted JSON payload containing
server_uuid, binding token to its server for validation.
Remove double-encrypt test no longer relevant to new token format.
This commit is contained in:
Andras Bacsai 2026-04-30 08:21:30 +02:00
parent 3a42ceb67d
commit 4575106f53
2 changed files with 4 additions and 17 deletions

View file

@ -6,7 +6,6 @@
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use OpenApi\Attributes as OA;
#[OA\Schema(
@ -189,7 +188,10 @@ public function ensureValidSentinelToken(): string
public function generateSentinelToken(bool $save = true, bool $ignoreEvent = false): string
{
$token = Str::random(64);
$data = [
'server_uuid' => $this->server->uuid,
];
$token = encrypt(json_encode($data));
$this->sentinel_token = $token;
if ($save) {
if ($ignoreEvent) {

View file

@ -3,9 +3,7 @@
use App\Models\Server;
use App\Models\ServerSetting;
use App\Models\User;
use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;
uses(RefreshDatabase::class);
@ -158,19 +156,6 @@ public function generateSentinelToken(bool $save = true, bool $ignoreEvent = fal
expect(ServerSetting::isValidSentinelToken($token))->toBeTrue();
});
it('does not double-encrypt newly generated tokens', function () {
$settings = $this->server->settings;
$token = $settings->generateSentinelToken(save: true, ignoreEvent: true);
$raw = DB::table('server_settings')->where('id', $settings->id)->value('sentinel_token');
$once = Crypt::decryptString($raw);
expect($once)->toBe($token);
expect(fn () => Crypt::decryptString($once))
->toThrow(DecryptException::class);
});
it('returns the same value the cast reads back', function () {
$settings = $this->server->settings;
$returned = $settings->generateSentinelToken(save: true, ignoreEvent: true);