<!DOCTYPE html>
<html lang="ro">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login - Academia de Poliție MCP</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.login-container {
background: white;
border-radius: 12px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
max-width: 420px;
width: 100%;
padding: 40px;
}
.logo {
text-align: center;
margin-bottom: 30px;
}
.logo img {
max-width: 150px;
height: auto;
}
.logo h2 {
color: #333;
margin-top: 15px;
font-size: 24px;
}
.info-box {
background: #f8f9fa;
border-left: 4px solid #667eea;
padding: 15px;
margin-bottom: 25px;
border-radius: 4px;
}
.info-box p {
color: #555;
font-size: 14px;
line-height: 1.5;
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
margin-bottom: 8px;
color: #333;
font-weight: 500;
font-size: 14px;
}
.form-group input {
width: 100%;
padding: 12px 15px;
border: 1px solid #ddd;
border-radius: 6px;
font-size: 16px;
transition: all 0.3s;
}
.form-group input:focus {
outline: none;
border-color: #667eea;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
.remember-me {
display: flex;
align-items: center;
margin-bottom: 20px;
}
.remember-me input {
margin-right: 8px;
}
.remember-me label {
color: #666;
font-size: 14px;
cursor: pointer;
}
.btn-login {
width: 100%;
padding: 14px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
border-radius: 6px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: transform 0.2s, box-shadow 0.2s;
}
.btn-login:hover {
transform: translateY(-2px);
box-shadow: 0 10px 20px rgba(102, 126, 234, 0.3);
}
.btn-login:active {
transform: translateY(0);
}
.btn-login:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.error-message {
background: #fee;
border: 1px solid #fcc;
color: #c33;
padding: 12px;
border-radius: 6px;
margin-bottom: 20px;
display: none;
font-size: 14px;
}
.success-message {
background: #efe;
border: 1px solid #cfc;
color: #3c3;
padding: 12px;
border-radius: 6px;
margin-bottom: 20px;
display: none;
font-size: 14px;
}
.loading {
display: none;
text-align: center;
margin-top: 20px;
}
.spinner {
display: inline-block;
width: 20px;
height: 20px;
border: 3px solid rgba(102, 126, 234, 0.3);
border-radius: 50%;
border-top-color: #667eea;
animation: spin 1s ease-in-out infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.footer-links {
margin-top: 30px;
text-align: center;
padding-top: 20px;
border-top: 1px solid #eee;
}
.footer-links a {
color: #667eea;
text-decoration: none;
font-size: 14px;
margin: 0 10px;
}
.footer-links a:hover {
text-decoration: underline;
}
.mcp-badge {
display: inline-flex;
align-items: center;
background: #f0f4ff;
color: #667eea;
padding: 4px 10px;
border-radius: 20px;
font-size: 12px;
font-weight: 600;
margin-top: 10px;
}
.mcp-badge svg {
width: 16px;
height: 16px;
margin-right: 5px;
}
</style>
</head>
<body>
<div class="login-container">
<div class="logo">
<h2>Academia de Poliție</h2>
<div class="mcp-badge">
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2L2 7v10c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V7l-10-5z"/>
</svg>
MCP Authentication
</div>
</div>
<div class="info-box">
<p>🔒 Autentificare securizată pentru accesul la Remote MCP Server. Folosește credențialele tale de pe academiadepolitie.com</p>
</div>
<div class="error-message" id="errorMessage"></div>
<div class="success-message" id="successMessage"></div>
<form id="loginForm">
<div class="form-group">
<label for="username">Username sau Email:</label>
<input type="text" id="username" name="username" required autofocus>
</div>
<div class="form-group">
<label for="password">Parolă:</label>
<input type="password" id="password" name="password" required>
</div>
<div class="remember-me">
<input type="checkbox" id="remember" name="remember">
<label for="remember">Ține-mă minte 30 zile</label>
</div>
<button type="submit" class="btn-login" id="loginBtn">
Autentificare
</button>
<div class="loading" id="loading">
<div class="spinner"></div>
<p style="margin-top: 10px; color: #666;">Se verifică credențialele...</p>
</div>
</form>
<div class="footer-links">
<a href="https://www.academiadepolitie.com/resetare_parola" target="_blank">Am uitat parola</a>
<a href="https://www.academiadepolitie.com/inregistrare" target="_blank">Înregistrare</a>
</div>
</div>
<script>
// Extrage parametrii OAuth din URL
const urlParams = new URLSearchParams(window.location.search);
const clientId = urlParams.get('client_id');
const redirectUri = urlParams.get('redirect_uri');
const state = urlParams.get('state');
const codeChallenge = urlParams.get('code_challenge');
// Verifică dacă avem parametrii OAuth necesari
if (!clientId || !redirectUri) {
document.getElementById('errorMessage').textContent = 'Parametri OAuth lipsă. Încearcă din nou din Claude.';
document.getElementById('errorMessage').style.display = 'block';
document.getElementById('loginForm').style.display = 'none';
}
// Handler pentru form submit
document.getElementById('loginForm').addEventListener('submit', async (e) => {
e.preventDefault();
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
const remember = document.getElementById('remember').checked;
// Reset messages
document.getElementById('errorMessage').style.display = 'none';
document.getElementById('successMessage').style.display = 'none';
// Show loading
document.getElementById('loginBtn').disabled = true;
document.getElementById('loading').style.display = 'block';
try {
// Trimite credențialele la server
const response = await fetch('/oauth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
username,
password,
remember,
client_id: clientId,
redirect_uri: redirectUri,
state: state,
code_challenge: codeChallenge
})
});
const result = await response.json();
if (response.ok && result.redirect_url) {
// Success - redirect cu authorization code
document.getElementById('successMessage').textContent = '✓ Autentificare reușită! Redirectare...';
document.getElementById('successMessage').style.display = 'block';
setTimeout(() => {
window.location.href = result.redirect_url;
}, 1000);
} else {
// Error
document.getElementById('errorMessage').textContent = result.error || 'Credențiale invalide. Încearcă din nou.';
document.getElementById('errorMessage').style.display = 'block';
// Reset form
document.getElementById('loginBtn').disabled = false;
document.getElementById('loading').style.display = 'none';
}
} catch (error) {
console.error('Login error:', error);
document.getElementById('errorMessage').textContent = 'Eroare de conexiune. Încearcă din nou.';
document.getElementById('errorMessage').style.display = 'block';
// Reset form
document.getElementById('loginBtn').disabled = false;
document.getElementById('loading').style.display = 'none';
}
});
</script>
</body>
</html>