Implement lazy-cleanup for expired invoices with deadline-based deletion
This commit is contained in:
@@ -24,6 +24,7 @@ $dbFile = __DIR__ . '/../data/urls.json';
|
||||
$rawInput = file_get_contents('php://input');
|
||||
$input = is_string($rawInput) ? json_decode($rawInput, true) : null;
|
||||
$hash = is_array($input) && isset($input['hash']) && is_string($input['hash']) ? $input['hash'] : '';
|
||||
$expiryTs = is_array($input) && isset($input['expiry_ts']) ? intval($input['expiry_ts']) : 0;
|
||||
|
||||
if (empty($hash) || strlen($hash) > 500 || !preg_match('/^[a-zA-Z0-9%+_=&.-]{1,500}$/', $hash)) {
|
||||
http_response_code(400);
|
||||
@@ -69,6 +70,9 @@ while (isset($urls[$code])) {
|
||||
|
||||
$signature = hash_hmac('sha256', $hash, $secret);
|
||||
$urls[$code] = ['h' => $hash, 's' => $signature];
|
||||
if ($expiryTs > 0) {
|
||||
$urls[$code]['e'] = $expiryTs;
|
||||
}
|
||||
|
||||
write_json_locked($fp, $urls);
|
||||
|
||||
|
||||
@@ -31,8 +31,20 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
$decodedProofs = is_string($rawProofs) ? json_decode($rawProofs, true) : [];
|
||||
$proofs = is_array($decodedProofs) ? $decodedProofs : [];
|
||||
if (isset($proofs[$code])) {
|
||||
$response = ['verified' => true];
|
||||
$proofEntry = $proofs[$code];
|
||||
$proofExpiry = is_array($proofEntry) ? intval($proofEntry['e'] ?? 0) : 0;
|
||||
|
||||
// Check if proof has expired (lazy cleanup)
|
||||
if ($proofExpiry > 0 && time() > $proofExpiry) {
|
||||
unset($proofs[$code]);
|
||||
[$fp, $allProofs] = read_json_locked($dbFile);
|
||||
if (isset($allProofs[$code])) {
|
||||
unset($allProofs[$code]);
|
||||
write_json_locked($fp, $allProofs);
|
||||
}
|
||||
echo json_encode(['verified' => false]);
|
||||
} else {
|
||||
$response = ['verified' => true];
|
||||
if (is_array($proofEntry)) {
|
||||
foreach ($proofEntry as $k => $v) {
|
||||
if (is_string($k)) {
|
||||
@@ -41,6 +53,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
}
|
||||
}
|
||||
echo json_encode($response);
|
||||
}
|
||||
} else {
|
||||
echo json_encode(['verified' => false]);
|
||||
}
|
||||
@@ -132,6 +145,11 @@ $proofs[$code] = [
|
||||
'verified_at' => time()
|
||||
];
|
||||
|
||||
// Copy expiry timestamp from URL if it exists
|
||||
if (isset($urls[$code]) && is_array($urls[$code]) && isset($urls[$code]['e']) && $urls[$code]['e'] > 0) {
|
||||
$proofs[$code]['e'] = $urls[$code]['e'];
|
||||
}
|
||||
|
||||
write_json_locked($fp, $proofs);
|
||||
echo json_encode(['ok' => true]);
|
||||
|
||||
|
||||
7
app.js
7
app.js
@@ -282,10 +282,15 @@
|
||||
|
||||
async function shortenUrl(hash) {
|
||||
try {
|
||||
// Calculate expiry timestamp if deadline is set
|
||||
let expiryTs = null;
|
||||
if (selectedDays && selectedDays > 0) {
|
||||
expiryTs = Math.floor((Date.now() + selectedDays * 86400000) / 1000);
|
||||
}
|
||||
const res = await fetch('/api/shorten.php', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ hash: hash })
|
||||
body: JSON.stringify({ hash: hash, expiry_ts: expiryTs })
|
||||
});
|
||||
if (!res.ok) throw new Error('HTTP ' + res.status);
|
||||
const data = await res.json();
|
||||
|
||||
2
app.min.js
vendored
2
app.min.js
vendored
File diff suppressed because one or more lines are too long
15
s.php
15
s.php
@@ -31,6 +31,21 @@ $data = $urls[$code];
|
||||
$hash = is_array($data) ? ($data['h'] ?? '') : $data;
|
||||
$hash = is_string($hash) ? $hash : '';
|
||||
$signature = is_array($data) ? ($data['s'] ?? null) : null;
|
||||
$expiryTs = is_array($data) ? intval($data['e'] ?? 0) : 0;
|
||||
|
||||
// Check if URL has expired (lazy cleanup)
|
||||
if ($expiryTs > 0 && time() > $expiryTs) {
|
||||
require_once __DIR__ . '/api/_helpers.php';
|
||||
// Delete expired URL
|
||||
[$fp, $urls] = read_json_locked(__DIR__ . '/data/urls.json');
|
||||
if (isset($urls[$code])) {
|
||||
unset($urls[$code]);
|
||||
write_json_locked($fp, $urls);
|
||||
}
|
||||
http_response_code(410);
|
||||
echo 'Gone';
|
||||
exit;
|
||||
}
|
||||
|
||||
// Verify HMAC signature if present (detect server-side tampering)
|
||||
if (is_string($signature) && $signature !== '') {
|
||||
|
||||
Reference in New Issue
Block a user