diff --git a/app/Console/Commands/DeleteExpiredOneTimeSecrets.php b/app/Console/Commands/DeleteExpiredOneTimeSecrets.php new file mode 100644 index 0000000..f5f1d17 --- /dev/null +++ b/app/Console/Commands/DeleteExpiredOneTimeSecrets.php @@ -0,0 +1,19 @@ +delete(); + } +} diff --git a/app/Enums/OneTimeSecretDuration.php b/app/Enums/OneTimeSecretDuration.php new file mode 100644 index 0000000..f2e10b8 --- /dev/null +++ b/app/Enums/OneTimeSecretDuration.php @@ -0,0 +1,25 @@ + '30 Minutes', + self::OneHour => '1 Hour', + self::SixHours => '6 Hours', + self::OneDay => '1 Day', + self::ThreeDays => '3 Days', + self::OneWeek => '1 Week', + }; + } +} diff --git a/app/Http/Controllers/OTSController.php b/app/Http/Controllers/OTSController.php index 600c054..4229b6a 100644 --- a/app/Http/Controllers/OTSController.php +++ b/app/Http/Controllers/OTSController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers; +use App\Enums\OneTimeSecretDuration; use App\Http\Requests\StoreOTSRequest; use App\Models\OneTimeSecret; use Illuminate\Http\JsonResponse; @@ -29,7 +30,10 @@ class OTSController extends Controller { $validated = $request->validated(); - $ots = OneTimeSecret::create(($validated + ['expires_at' => now()->addMinutes(30)])); + $ots = OneTimeSecret::create([ + 'secret' => $validated['secret'], + 'expires_at' => now()->addSeconds($validated['duration']), + ]); $otsLink = route('ots.show', ['oneTimeSecret' => $ots->id]); return redirect()->route('ots.created')->with(['otsLink' => $otsLink]); @@ -37,19 +41,31 @@ class OTSController extends Controller public function create(): Response { - return Inertia::render('ots/Create', []); + return Inertia::render('ots/Create', [ + 'durations' => array_map( + fn (OneTimeSecretDuration $duration): array => [ + 'value' => $duration->value, + 'label' => $duration->label(), + ], + OneTimeSecretDuration::cases(), + ), + ]); } - public function show(OneTimeSecret $oneTimeSecret): Response + public function show(OneTimeSecret $oneTimeSecret): Response|RedirectResponse { + if ($oneTimeSecret->expires_at->isPast()) { + $oneTimeSecret->delete(); + return redirect()->route('ots.create'); + } return Inertia::render('ots/Show', ['oneTimeSecretId' => $oneTimeSecret->id]); } - public function reveal(OneTimeSecret $oneTimeSecret): JsonResponse + public function reveal(OneTimeSecret $oneTimeSecret): JsonResponse|RedirectResponse { $oneTimeSecret->delete(); if ($oneTimeSecret->expires_at->isPast()) { - abort(404); + return redirect()->route('ots.create'); } return response()->json(['secret' => $oneTimeSecret->secret]); diff --git a/app/Http/Requests/StoreOTSRequest.php b/app/Http/Requests/StoreOTSRequest.php index ce8ddb4..b78e678 100644 --- a/app/Http/Requests/StoreOTSRequest.php +++ b/app/Http/Requests/StoreOTSRequest.php @@ -2,8 +2,10 @@ namespace App\Http\Requests; +use App\Enums\OneTimeSecretDuration; use Illuminate\Contracts\Validation\ValidationRule; use Illuminate\Foundation\Http\FormRequest; +use Illuminate\Validation\Rule; class StoreOTSRequest extends FormRequest { @@ -16,6 +18,7 @@ class StoreOTSRequest extends FormRequest { return [ 'secret' => 'required|string', + 'duration' => ['required', 'integer', Rule::enum(OneTimeSecretDuration::class)], ]; } } diff --git a/app/Models/OneTimeSecret.php b/app/Models/OneTimeSecret.php index 8ec94d2..cda5101 100644 --- a/app/Models/OneTimeSecret.php +++ b/app/Models/OneTimeSecret.php @@ -6,7 +6,6 @@ use Carbon\CarbonImmutable; use Database\Factories\OneTimeSecretFactory; use Illuminate\Database\Eloquent\Attributes\Fillable; use Illuminate\Database\Eloquent\Concerns\HasUuids; -use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\MorphTo; @@ -23,7 +22,6 @@ use Illuminate\Database\Eloquent\Relations\MorphTo; * @property-read User|Team|null $recipient * @property-read Team|null $team * - * @method static \Database\Factories\OneTimeSecretFactory factory($count = null, $state = []) * @method static \Illuminate\Database\Eloquent\Builder|OneTimeSecret newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|OneTimeSecret newQuery() * @method static \Illuminate\Database\Eloquent\Builder|OneTimeSecret query() @@ -41,8 +39,7 @@ use Illuminate\Database\Eloquent\Relations\MorphTo; #[Fillable(['secret', 'expires_at'])] class OneTimeSecret extends Model { - /** @use HasFactory */ - use HasFactory, HasUuids; + use HasUuids; public function team(): BelongsTo { diff --git a/resources/js/pages/ots/Create.vue b/resources/js/pages/ots/Create.vue index b894b15..6abd6af 100644 --- a/resources/js/pages/ots/Create.vue +++ b/resources/js/pages/ots/Create.vue @@ -1,15 +1,24 @@