freeleaps-ops/apps/gitea-webhook-ambassador-python/app/templates/login.html
Nicolas f6c515157c feat: 添加 Python 版本的 Gitea Webhook Ambassador
- 新增完整的 Python 实现,替代 Go 版本
- 添加 Web 登录界面和仪表板
- 实现 JWT 认证和 API 密钥管理
- 添加数据库存储功能
- 保持与 Go 版本一致的目录结构和启动脚本
- 包含完整的文档和测试脚本
2025-07-20 21:17:10 +08:00

174 lines
6.1 KiB
HTML

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>登录 - Gitea Webhook Ambassador</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
.login-container {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.login-form {
width: 100%;
max-width: 400px;
padding: 2rem;
margin: auto;
background: white;
border-radius: 12px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
}
.login-header {
text-align: center;
margin-bottom: 2rem;
}
.login-header h1 {
color: #333;
font-weight: 600;
margin-bottom: 0.5rem;
}
.login-header p {
color: #666;
margin: 0;
}
.form-floating {
margin-bottom: 1rem;
}
.btn-login {
width: 100%;
padding: 0.75rem;
font-weight: 600;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border: none;
border-radius: 8px;
}
.btn-login:hover {
background: linear-gradient(135deg, #5a6fd8 0%, #6a4190 100%);
transform: translateY(-1px);
}
.alert {
border-radius: 8px;
border: none;
}
</style>
</head>
<body>
<div class="login-container">
<div class="login-form">
<div class="login-header">
<h1>🔗 Gitea Webhook Ambassador</h1>
<p>高性能的 Gitea 到 Jenkins 的 Webhook 服务</p>
</div>
<form id="loginForm">
<div class="alert alert-danger" role="alert" id="loginError" style="display: none;">
</div>
<div class="form-floating">
<input type="password" class="form-control" id="secret_key" name="secret_key"
placeholder="管理员密钥" required>
<label for="secret_key">管理员密钥</label>
</div>
<button class="btn btn-primary btn-login" type="submit">
<span id="loginBtnText">登录</span>
<span id="loginBtnSpinner" class="spinner-border spinner-border-sm" style="display: none;"></span>
</button>
</form>
<div class="text-center mt-3">
<small class="text-muted">
使用管理员密钥进行身份验证
</small>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script>
$(document).ready(function() {
// 检查是否已登录
const token = localStorage.getItem('auth_token');
if (token) {
window.location.href = '/dashboard';
return;
}
// 检查 URL 参数中的 secret_key
const urlParams = new URLSearchParams(window.location.search);
const secretKeyFromUrl = urlParams.get('secret_key');
if (secretKeyFromUrl) {
$('#secret_key').val(secretKeyFromUrl);
// 自动提交登录
$('#loginForm').submit();
return;
}
// 处理登录表单提交
$('#loginForm').on('submit', function(e) {
e.preventDefault();
const secretKey = $('#secret_key').val();
if (!secretKey) {
showError('请输入管理员密钥');
return;
}
// 显示加载状态
$('#loginBtnText').hide();
$('#loginBtnSpinner').show();
$('#loginError').hide();
// 发送登录请求
$.ajax({
url: '/api/auth/login',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify({ secret_key: secretKey }),
success: function(response) {
if (response && response.token) {
// 保存令牌并跳转
localStorage.setItem('auth_token', response.token);
window.location.href = '/dashboard';
} else {
showError('服务器响应无效');
}
},
error: function(xhr) {
console.error('登录错误:', xhr);
let errorMsg = '登录失败,请重试';
if (xhr.responseJSON && xhr.responseJSON.detail) {
errorMsg = xhr.responseJSON.detail;
}
showError(errorMsg);
$('#secret_key').val('').focus();
},
complete: function() {
// 恢复按钮状态
$('#loginBtnText').show();
$('#loginBtnSpinner').hide();
}
});
});
function showError(message) {
$('#loginError').text(message).show();
}
// 回车键提交
$('#secret_key').on('keypress', function(e) {
if (e.which === 13) {
$('#loginForm').submit();
}
});
});
</script>
</body>
</html>