Refactor: Initial code split into includes directory for modularity
- Reorganized backend logic by moving API, authentication, Docker, status, and WebSocket handling into separate modules (api.js, auth.js, docker.js, status.js, websocket.js) within ./includes/ - Converted codebase to ES modules with import/export syntax for modern JavaScript - Updated index.js to serve as main entry point, importing from ./includes/ - Reduced code duplication and improved readability with modularized functions - Ensured full functionality preservation, including Docker stats and WebSocket communication - Updated README to reflect new folder structure and ES module setup
This commit is contained in:
88
includes/auth.js
Normal file
88
includes/auth.js
Normal file
@ -0,0 +1,88 @@
|
||||
import unirest from 'unirest';
|
||||
import { randomBytes } from 'crypto';
|
||||
|
||||
const temporaryLinks = new Map();
|
||||
|
||||
setInterval(() => {
|
||||
const now = Date.now();
|
||||
for (const [linkId, linkData] of temporaryLinks.entries()) {
|
||||
if (linkData.expiresAt < now) temporaryLinks.delete(linkId);
|
||||
}
|
||||
}, parseInt(process.env.TEMP_LINKS_CLEANUP_INTERVAL_MS, 10));
|
||||
|
||||
export async function generateLoginLink(req, res) {
|
||||
try {
|
||||
const { secretKey, username } = req.body;
|
||||
if (secretKey !== process.env.ADMIN_SECRET_KEY) return res.status(401).json({ error: 'Invalid secret key' });
|
||||
if (!username) return res.status(400).json({ error: 'Username is required' });
|
||||
|
||||
const tokenResponse = await unirest
|
||||
.post(process.env.AUTH_ENDPOINT)
|
||||
.headers({ 'Accept': 'application/json', 'Content-Type': 'application/json' })
|
||||
.send({ username, password: process.env.AUTH_PASSWORD });
|
||||
|
||||
if (!tokenResponse.body.token) return res.status(500).json({ error: 'Failed to generate API key' });
|
||||
|
||||
const apiKey = tokenResponse.body.token;
|
||||
const linkId = randomBytes(parseInt(process.env.LINK_ID_BYTES, 10)).toString('hex');
|
||||
const loginLink = `${process.env.AUTO_LOGIN_LINK_PREFIX}${linkId}`;
|
||||
|
||||
temporaryLinks.set(linkId, {
|
||||
apiKey,
|
||||
username,
|
||||
expiresAt: Date.now() + parseInt(process.env.LINK_EXPIRY_SECONDS, 10) * 1000
|
||||
});
|
||||
|
||||
setTimeout(() => temporaryLinks.delete(linkId), parseInt(process.env.LINK_EXPIRY_SECONDS, 10) * 1000);
|
||||
res.json({ loginLink });
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
}
|
||||
|
||||
export function handleAutoLogin(req, res) {
|
||||
const { linkId } = req.params;
|
||||
const linkData = temporaryLinks.get(linkId);
|
||||
|
||||
if (!linkData || linkData.expiresAt < Date.now()) {
|
||||
temporaryLinks.delete(linkId);
|
||||
return res.send(`
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="3;url=${process.env.AUTO_LOGIN_REDIRECT_URL}">
|
||||
<style>
|
||||
body { display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background-color: #111827; font-family: 'Arial', sans-serif; }
|
||||
.notification { background-color: #1f2937; color: white; padding: 16px; border-radius: 8px; display: flex; flex-direction: column; align-items: center; gap: 12px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); max-width: 400px; width: 100%; }
|
||||
h1 { font-size: 2.25em; color: white; text-align: center; margin: 0; }
|
||||
.spinner { border: 4px solid rgba(255, 255, 255, 0.3); border-top: 4px solid #ffffff; border-radius: 50%; width: 24px; height: 24px; animation: spin 1s linear infinite; }
|
||||
@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="notification">
|
||||
<span class="spinner"></span>
|
||||
<h1>Login Expired.</h1>
|
||||
<h1>Redirecting...</h1>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
}
|
||||
|
||||
temporaryLinks.delete(linkId);
|
||||
res.send(`
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Auto Login</title>
|
||||
<script>
|
||||
localStorage.setItem('apiKey', '${linkData.apiKey}');
|
||||
window.location.href = '/';
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<p>Logging in...</p>
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
}
|
Reference in New Issue
Block a user