Feat: implement callback for TwitterAPI linking

This commit is contained in:
kittentm 2026-03-22 21:00:40 +01:00
commit 67933ec76a
No known key found for this signature in database
GPG key ID: AC43DFDBC1F44A91
3 changed files with 76 additions and 0 deletions

17
callback/index.html Normal file
View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Linking Twitter...</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="status">
<h2>Linking your Twitter account...</h2>
<div class="loader"></div>
</div>
<script src="twitter.js"></script>
</body>
</html>

22
callback/styles.css Normal file
View file

@ -0,0 +1,22 @@
body {
font-family: sans-serif;
text-align: center;
padding-top: 50px;
background: #1a1a1a;
color: white;
}
.loader {
border: 4px solid #f3f3f3;
border-top: 4px solid #1DA1F2;
border-radius: 50%;
width: 40px;
height: 40px;
animation: spin 2s linear infinite;
margin: 20px auto;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

37
callback/twitter.js Normal file
View file

@ -0,0 +1,37 @@
async function finalizeLink() {
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
const state = urlParams.get('state');
const statusDiv = document.getElementById('status');
if (!code || !state) {
statusDiv.innerHTML = "<h2>Error: Missing data from Twitter</h2>";
return;
}
try {
const response = await fetch(`/api/v1/me/twitter/confirm?state=${state}&code=${code}`, {
method: 'GET',
});
const data = await response.json();
if (response.ok) {
statusDiv.innerHTML = `
<h2>Success!</h2>
<p>Linked as @${data.handle}</p>
<p>Redirecting you back...</p>
`;
setTimeout(() => {
window.location.href = '/';
}, 2000);
} else {
statusDiv.innerHTML = `<h2>Error: ${data.detail || 'Failed to link'}</h2>`;
}
} catch (err) {
statusDiv.innerHTML = "<h2>Failed to connect to backend</h2>";
}
}
finalizeLink();