Initial commit

This commit is contained in:
root
2025-12-23 13:18:58 +02:00
commit 2ef7528ee9
36 changed files with 5983 additions and 0 deletions

View File

@@ -0,0 +1,96 @@
<?php
declare(strict_types=1);
require __DIR__ . '/../../includes/bootstrap.php';
require_admin_login();
function h(string $s): string { return htmlspecialchars($s, ENT_QUOTES, 'UTF-8'); }
if (!empty($_GET['error'])) {
echo "<pre>Spotify error: " . h((string)$_GET['error']) . "</pre>";
exit;
}
$code = (string)($_GET['code'] ?? '');
$state = (string)($_GET['state'] ?? '');
if ($code === '' || $state === '') {
echo "<pre>Missing code/state.\n\nGET:\n"; print_r($_GET); echo "</pre>";
exit;
}
$expected = (string)($_SESSION['sp_state'] ?? '');
unset($_SESSION['sp_state']);
if ($expected === '' || !hash_equals($expected, $state)) {
echo "<pre>State mismatch.\nExpected: ".h($expected)."\nGot: ".h($state)."</pre>";
echo "<p>Use the SAME host everywhere (127.0.0.1 vs localhost) or cookies wont match.</p>";
exit;
}
if (SPOTIFY_CLIENT_ID === '' || SPOTIFY_CLIENT_SECRET === '' || SPOTIFY_REDIRECT_URI === '') {
http_response_code(500);
echo "<pre>Missing Spotify config.</pre>";
exit;
}
$ch = curl_init('https://accounts.spotify.com/api/token');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Basic ' . base64_encode(SPOTIFY_CLIENT_ID . ':' . SPOTIFY_CLIENT_SECRET),
'Content-Type: application/x-www-form-urlencoded',
],
CURLOPT_POSTFIELDS => http_build_query([
'grant_type' => 'authorization_code',
'code' => $code,
'redirect_uri' => SPOTIFY_REDIRECT_URI,
]),
CURLOPT_TIMEOUT => 15,
]);
$raw = curl_exec($ch);
$http = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
$err = curl_error($ch);
curl_close($ch);
$data = is_string($raw) ? json_decode($raw, true) : null;
if ($raw === false || $http < 200 || $http >= 300 || !is_array($data)) {
echo "<pre>Token exchange failed.\nHTTP: {$http}\nCurl: ".h($err ?: 'none')."\nRaw:\n".h((string)$raw)."\n</pre>";
exit;
}
$access = (string)($data['access_token'] ?? '');
$refresh = (string)($data['refresh_token'] ?? '');
$expires = time() + (int)($data['expires_in'] ?? 3600);
if ($access === '') {
echo "<pre>No access_token returned.\n"; print_r($data); echo "</pre>";
exit;
}
pdo()->exec("
CREATE TABLE IF NOT EXISTS spotify_tokens (
id INT PRIMARY KEY,
refresh_token TEXT NULL,
access_token TEXT NULL,
access_expires INT NULL,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
");
pdo()->exec("INSERT IGNORE INTO spotify_tokens (id) VALUES (1)");
if ($refresh !== '') {
pdo()->prepare("UPDATE spotify_tokens SET refresh_token=?, access_token=?, access_expires=? WHERE id=1")
->execute([$refresh, $access, $expires]);
flash_set('success', 'Spotify connected. Refresh token saved.');
} else {
pdo()->prepare("UPDATE spotify_tokens SET access_token=?, access_expires=? WHERE id=1")
->execute([$access, $expires]);
flash_set('warning', 'Connected, but no refresh token returned (already authorized before). Revoke access in Spotify account settings and try again.');
}
header('Location: ' . url_path('/public/admin/dashboard.php'));
exit;