mirror of
https://github.com/exchanges-lab/view.git
synced 2026-08-05 05:36:06 +08:00
190 lines
5.9 KiB
HTML
190 lines
5.9 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Login - TradingView</title>
|
|
<style>
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
}
|
|
|
|
#auth-background {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background-image: url('https://img.cathiefish.art/tradingview/large.jpg');
|
|
background-size: cover;
|
|
background-position: center;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
#auth-background {
|
|
background-image: url('https://img.cathiefish.art/tradingview/small.jpg');
|
|
}
|
|
|
|
#auth-card {
|
|
padding: 30px 20px !important;
|
|
max-width: 90% !important;
|
|
}
|
|
|
|
#auth-title {
|
|
font-size: 20px !important;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 769px) and (max-width: 1200px) {
|
|
#auth-background {
|
|
background-image: url('https://img.cathiefish.art/tradingview/medium.jpg');
|
|
}
|
|
}
|
|
|
|
.overlay {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: rgba(15, 15, 15, 0.05);
|
|
}
|
|
|
|
#auth-card {
|
|
position: relative;
|
|
background: rgba(250, 248, 245, 0.95);
|
|
padding: 50px 40px;
|
|
border-radius: 16px;
|
|
box-shadow: 0 16px 48px rgba(0, 0, 0, 0.6);
|
|
text-align: center;
|
|
max-width: 420px;
|
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
backdrop-filter: blur(10px);
|
|
}
|
|
|
|
#auth-title {
|
|
color: #2c3e50;
|
|
margin-bottom: 12px;
|
|
font-size: 28px;
|
|
font-weight: 600;
|
|
letter-spacing: -0.5px;
|
|
}
|
|
|
|
#auth-subtitle {
|
|
color: #5a6c7d;
|
|
margin-bottom: 35px;
|
|
font-size: 15px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
#error-msg {
|
|
color: #e74c3c;
|
|
margin-top: 15px;
|
|
font-size: 14px;
|
|
display: none;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<div id="auth-background">
|
|
<div class="overlay"></div>
|
|
<div id="auth-card">
|
|
<h1 id="auth-title">TradingView</h1>
|
|
<p id="auth-subtitle">Sign in with your authorized Google account to continue</p>
|
|
<div id="google-signin-button"></div>
|
|
<p id="error-msg"></p>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="auth-config.js"></script>
|
|
<script src="https://accounts.google.com/gsi/client" async defer></script>
|
|
<script>
|
|
const REDIRECT_URL = './index.html';
|
|
|
|
function parseJwt(token) {
|
|
const base64Url = token.split('.')[1];
|
|
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
|
|
const jsonPayload = decodeURIComponent(atob(base64).split('').map(c =>
|
|
'%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
|
|
).join(''));
|
|
return JSON.parse(jsonPayload);
|
|
}
|
|
|
|
function handleCredentialResponse(response) {
|
|
try {
|
|
const credential = response.credential;
|
|
const userData = parseJwt(credential);
|
|
|
|
const user = {
|
|
email: userData.email,
|
|
name: userData.name,
|
|
picture: userData.picture,
|
|
sub: userData.sub
|
|
};
|
|
|
|
localStorage.setItem('auth_user', JSON.stringify(user));
|
|
localStorage.setItem('auth_token', credential);
|
|
localStorage.setItem('auth_login_time', Date.now().toString());
|
|
|
|
console.log('Login successful:', user.email);
|
|
window.location.href = REDIRECT_URL;
|
|
|
|
} catch (error) {
|
|
console.error('Login failed:', error);
|
|
document.getElementById('error-msg').textContent = 'Authentication failed. Please try again.';
|
|
document.getElementById('error-msg').style.display = 'block';
|
|
}
|
|
}
|
|
|
|
function checkExistingSession() {
|
|
const savedUser = localStorage.getItem('auth_user');
|
|
const savedToken = localStorage.getItem('auth_token');
|
|
|
|
if (savedUser && savedToken) {
|
|
try {
|
|
const tokenData = parseJwt(savedToken);
|
|
// 144 hours = 144 * 60 * 60 * 1000 ms
|
|
const loginTime = localStorage.getItem('auth_login_time');
|
|
const maxAge = 144 * 60 * 60 * 1000;
|
|
if (loginTime && (Date.now() - parseInt(loginTime)) < maxAge) {
|
|
// Already logged in, redirect
|
|
window.location.href = REDIRECT_URL;
|
|
return true;
|
|
}
|
|
} catch (e) {
|
|
localStorage.removeItem('auth_user');
|
|
localStorage.removeItem('auth_token');
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
window.onload = function () {
|
|
if (checkExistingSession()) return;
|
|
|
|
google.accounts.id.initialize({
|
|
client_id: window.AUTH_CONFIG.clientId,
|
|
callback: handleCredentialResponse,
|
|
auto_select: true
|
|
});
|
|
|
|
google.accounts.id.renderButton(
|
|
document.getElementById('google-signin-button'),
|
|
{ theme: 'filled_blue', size: 'large', text: 'signin_with', shape: 'rectangular', width: 300 }
|
|
);
|
|
};
|
|
</script>
|
|
</body>
|
|
|
|
</html> |