103 lines
3.0 KiB
JavaScript
103 lines
3.0 KiB
JavaScript
|
|
import express from "express";
|
||
|
|
import bodyParser from "body-parser";
|
||
|
|
import crypto from "crypto";
|
||
|
|
|
||
|
|
const app = express();
|
||
|
|
app.use(bodyParser.json());
|
||
|
|
|
||
|
|
// In-memory stores
|
||
|
|
const users = {}; // { userId: username }
|
||
|
|
const sessions = {}; // { token: userId }
|
||
|
|
|
||
|
|
// Basic HTML UI
|
||
|
|
const HTML_PAGE = `
|
||
|
|
<!DOCTYPE html>
|
||
|
|
<html>
|
||
|
|
<head>
|
||
|
|
<title>Fake Auth API (Express)</title>
|
||
|
|
<style>
|
||
|
|
body { font-family: sans-serif; max-width: 500px; margin: 2rem auto; }
|
||
|
|
input, button { margin: .3rem 0; padding: .3rem; }
|
||
|
|
pre { background: #f5f5f5; padding: 1rem; border-radius: 5px; }
|
||
|
|
</style>
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
<h2>Fake Auth API</h2>
|
||
|
|
<form id="userForm">
|
||
|
|
<input id="uid" placeholder="User ID" required><br>
|
||
|
|
<input id="uname" placeholder="Username" required><br>
|
||
|
|
<button type="submit">Add User</button>
|
||
|
|
</form>
|
||
|
|
<h3>Users</h3>
|
||
|
|
<div id="users"></div>
|
||
|
|
|
||
|
|
<script>
|
||
|
|
async function refresh() {
|
||
|
|
const res = await fetch('/api/users');
|
||
|
|
const data = await res.json();
|
||
|
|
const div = document.getElementById('users');
|
||
|
|
div.innerHTML = '';
|
||
|
|
for (const [id, name] of Object.entries(data)) {
|
||
|
|
const btn = document.createElement('button');
|
||
|
|
btn.textContent = 'Create token';
|
||
|
|
btn.onclick = async () => {
|
||
|
|
const res = await fetch('/api/create_token/' + id, {method:'POST'});
|
||
|
|
const tok = await res.json();
|
||
|
|
alert('Token for ' + name + ': ' + tok.token);
|
||
|
|
};
|
||
|
|
div.append(\`\${id}: \${name} \`, btn, document.createElement('br'));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
document.getElementById('userForm').onsubmit = async (e) => {
|
||
|
|
e.preventDefault();
|
||
|
|
const id = uid.value.trim();
|
||
|
|
const name = uname.value.trim();
|
||
|
|
await fetch('/api/users', {
|
||
|
|
method: 'POST',
|
||
|
|
headers: {'Content-Type':'application/json'},
|
||
|
|
body: JSON.stringify({id, name})
|
||
|
|
});
|
||
|
|
uid.value = uname.value = '';
|
||
|
|
refresh();
|
||
|
|
};
|
||
|
|
refresh();
|
||
|
|
</script>
|
||
|
|
</body>
|
||
|
|
</html>
|
||
|
|
`;
|
||
|
|
|
||
|
|
// === Routes ===
|
||
|
|
|
||
|
|
// UI page
|
||
|
|
app.get("/", (req, res) => res.send(HTML_PAGE));
|
||
|
|
|
||
|
|
// Get users
|
||
|
|
app.get("/api/users", (req, res) => res.json(users));
|
||
|
|
|
||
|
|
// Add user
|
||
|
|
app.post("/api/users", (req, res) => {
|
||
|
|
const { id, name } = req.body;
|
||
|
|
if (!id || !name) return res.status(400).json({ error: "Missing id or name" });
|
||
|
|
users[id] = name;
|
||
|
|
res.json({ status: "ok" });
|
||
|
|
});
|
||
|
|
|
||
|
|
// Create token
|
||
|
|
app.post("/api/create_token/:uid", (req, res) => {
|
||
|
|
const uid = req.params.uid;
|
||
|
|
if (!users[uid]) return res.status(404).json({ error: "User not found" });
|
||
|
|
const token = crypto.randomBytes(8).toString("hex");
|
||
|
|
sessions[token] = uid;
|
||
|
|
res.json({ token });
|
||
|
|
});
|
||
|
|
|
||
|
|
// Verify token
|
||
|
|
app.get("/api/verify/:token", (req, res) => {
|
||
|
|
const uid = sessions[req.params.token];
|
||
|
|
if (!uid) return res.status(404).json({ error: "Invalid token" });
|
||
|
|
res.json({ id: uid, name: users[uid] });
|
||
|
|
});
|
||
|
|
|
||
|
|
const PORT = process.env.PORT || 5000;
|
||
|
|
app.listen(PORT, () => console.log(`[FakeAuth] Running on http://localhost:${PORT}`));
|