Commit 4540c726 authored by Arnolds's avatar Arnolds
Browse files

Added timestamp utility functions, enhanced secret metadata tracking, and...

Added timestamp utility functions, enhanced secret metadata tracking, and updated logic for secret retrieval and deletion in secret-api.php
parent 194127bb
Loading
Loading
Loading
Loading
+50 −9
Original line number Diff line number Diff line
@@ -12,6 +12,16 @@ use MongoDB\BSON\UTCDateTime;
use MongoDB\Client;
use Ramsey\Uuid\Uuid;

function utcNow(): UTCDateTime
{
    return new UTCDateTime((int)(microtime(true) * 1000));
}

function utcAfterSeconds(int $seconds): UTCDateTime
{
    return new UTCDateTime((int)(microtime(true) * 1000) + $seconds * 1000);
}

$dotenv = Dotenv::createImmutable(__DIR__);
$dotenv->load();

@@ -46,20 +56,20 @@ if ($method === 'POST' && isset($data['secret'])) {

    $id = Uuid::uuid4()->toString();
    $metaDataId = Uuid::uuid4()->toString();
    $now = new DateTimeImmutable('now', new DateTimeZone('UTC'));
    $ttlMinutes = isset($data['ttl_minutes']) ? (int)$data['ttl_minutes'] : 60 * 24 * 7;
    $expiresAt = $now->modify("+{$ttlMinutes} minutes");

    $collection->insertOne([
        '_id' => $id,
        'secret' => $data['secret'],
        'encrypted' => !!$data['encrypted'], // cast to bool - dubults neplīst 😂
        'createdAt' => new UTCDateTime($now),
        'expiresAt' => new UTCDateTime($expiresAt),
        'opened' => false,
        'openedAt' => null,
        'createdAt' => utcNow(),
        'expiresAt' => utcAfterSeconds($ttlMinutes * 60),
        'deleted' => false,
        'deletedAt' => null,
        'displayedAt' => null, // essentially this is same as deletedAt
        'firstRetrievedAt' => null,
        'retrievedCount' => 0,
        'lastRetrievedAt' => null,
        'displayToken' => null,
        'metaDataId' => $metaDataId,
    ]);

@@ -82,10 +92,41 @@ if ($method === 'POST' && isset($data['secret'])) {
        exit;
    }

    $collection->deleteOne(['_id' => $id]);
    // $collection->deleteOne(['_id' => $id]);
    $displayToken = Uuid::uuid4()->toString();
    $lastRetrievedAt = utcNow();
    if (!$doc['firstRetrievedAt']) {
        $firstRetrievedAt = $lastRetrievedAt;
    } else {
        $firstRetrievedAt = $doc['firstRetrievedAt'];
    }
    $retrievedCount = $doc['retrievedCount'] + 1;
    $collection->updateOne(['_id' => $id], ['$set' => ['displayToken' => $displayToken, 'lastRetrievedAt' => $lastRetrievedAt, 'retrievedCount' => $retrievedCount, 'firstRetrievedAt' => $firstRetrievedAt]]);

    echo json_encode(['secret' => $doc['secret'], 'encrypted' => $doc['encrypted']]);
    echo json_encode(['secret' => $doc['secret'], 'encrypted' => $doc['encrypted'], 'displayToken' => $displayToken]);
    /**
     * If two or more people open the same link at the same time, the last one will have correct displayToken.
     * Only last one will be allowed to delete the secret. If they fail to delete it, it will be deleted upon expiry.
     */

} else if ($method === 'GET' && isset($_GET['displayed'])) {
    $id = $_GET['id'] ?? null;
    $displayToken = $_GET['displayed'];
    if (!$id) {
        http_response_code(200);
        exit;
    }

    $doc = $collection->findOne(['_id' => $id]);
    if (!$doc || $doc['displayToken'] !== $displayToken) {
        http_response_code(200);
        exit;
    }

    $collection->updateOne(['_id' => $id], ['$set' => ['secret' => '', 'deleted' => 'true', 'displayToken' => null, 'displayedAt' => utcNow()]]);

    http_response_code(200);
    exit;
} else {
    http_response_code(405);
    echo json_encode(['error' => '<p class="mb-0">Šitā nedrīkst 😤! Mūsu glabātuve to neatzīst kā legālu gājienu.</p>']);