100 lines
6.2 KiB
HTML
100 lines
6.2 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Setup 2FA - FINA{% endblock %}
|
|
|
|
{% block body %}
|
|
<div class="min-h-screen flex items-center justify-center p-4 bg-background-light dark:bg-background-dark">
|
|
<div class="max-w-md w-full">
|
|
<!-- Header -->
|
|
<div class="text-center mb-8">
|
|
<div class="inline-flex items-center justify-center w-16 h-16 bg-primary/10 rounded-full mb-4">
|
|
<span class="material-symbols-outlined text-primary text-[32px]">lock</span>
|
|
</div>
|
|
<h1 class="text-2xl font-bold text-text-main dark:text-white mb-2" data-translate="twofa.setupTitle">Setup Two-Factor Authentication</h1>
|
|
<p class="text-text-muted dark:text-[#92adc9]" data-translate="twofa.setupDesc">Scan the QR code with your authenticator app</p>
|
|
</div>
|
|
|
|
<div class="bg-card-light dark:bg-card-dark border border-border-light dark:border-[#233648] rounded-2xl p-6 md:p-8 shadow-sm">
|
|
<!-- Instructions -->
|
|
<div class="mb-6">
|
|
<h3 class="text-sm font-semibold text-text-main dark:text-white mb-3" data-translate="twofa.step1">Step 1: Scan QR Code</h3>
|
|
<p class="text-sm text-text-muted dark:text-[#92adc9] mb-4" data-translate="twofa.step1Desc">Open your authenticator app (Google Authenticator, Authy, etc.) and scan this QR code:</p>
|
|
|
|
<!-- QR Code -->
|
|
<div class="bg-white p-4 rounded-xl flex justify-center border border-border-light">
|
|
<img src="data:image/png;base64,{{ qr_code }}" alt="2FA QR Code" class="max-w-full h-auto" style="max-width: 200px;">
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Manual Entry -->
|
|
<div class="mb-6">
|
|
<details class="group">
|
|
<summary class="cursor-pointer list-none flex items-center justify-between text-sm font-medium text-text-main dark:text-white mb-2">
|
|
<span data-translate="twofa.manualEntry">Can't scan? Enter code manually</span>
|
|
<span class="material-symbols-outlined text-[20px] group-open:rotate-180 transition-transform">expand_more</span>
|
|
</summary>
|
|
<div class="mt-3 bg-background-light dark:bg-background-dark border border-border-light dark:border-[#233648] rounded-lg p-4">
|
|
<p class="text-xs text-text-muted dark:text-[#92adc9] mb-2" data-translate="twofa.enterManually">Enter this code in your authenticator app:</p>
|
|
<div class="flex items-center gap-2">
|
|
<code id="secret-code" class="flex-1 text-primary font-mono text-sm break-all">{{ secret }}</code>
|
|
<button onclick="copySecret()" class="p-2 text-text-muted dark:text-[#92adc9] hover:text-primary transition-colors" title="Copy">
|
|
<span class="material-symbols-outlined text-[20px]">content_copy</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</details>
|
|
</div>
|
|
|
|
<!-- Verification -->
|
|
<form method="POST" class="space-y-4">
|
|
<div>
|
|
<h3 class="text-sm font-semibold text-text-main dark:text-white mb-3" data-translate="twofa.step2">Step 2: Verify Code</h3>
|
|
<p class="text-sm text-text-muted dark:text-[#92adc9] mb-3" data-translate="twofa.step2Desc">Enter the 6-digit code from your authenticator app:</p>
|
|
<input type="text" name="code" maxlength="6" pattern="[0-9]{6}" required
|
|
class="w-full bg-background-light dark:bg-background-dark border border-border-light dark:border-[#233648] rounded-lg px-4 py-3 text-text-main dark:text-white text-center text-2xl tracking-widest font-mono focus:border-primary focus:ring-2 focus:ring-primary/20 outline-none transition-all"
|
|
placeholder="000000"
|
|
autocomplete="off">
|
|
</div>
|
|
|
|
<button type="submit" class="w-full bg-primary hover:bg-primary/90 text-white py-3 rounded-lg font-semibold transition-colors flex items-center justify-center gap-2">
|
|
<span class="material-symbols-outlined text-[20px]">verified_user</span>
|
|
<span data-translate="twofa.enable">Enable 2FA</span>
|
|
</button>
|
|
</form>
|
|
|
|
<div class="mt-6 text-center">
|
|
<a href="{{ url_for('main.settings') }}" class="text-text-muted dark:text-[#92adc9] hover:text-primary transition-colors text-sm" data-translate="actions.cancel">Cancel</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Info -->
|
|
<div class="mt-6 bg-blue-50 dark:bg-blue-500/10 border border-blue-200 dark:border-blue-500/30 rounded-lg p-4">
|
|
<div class="flex gap-3">
|
|
<span class="material-symbols-outlined text-blue-600 dark:text-blue-400 text-[20px] flex-shrink-0">info</span>
|
|
<p class="text-sm text-blue-700 dark:text-blue-300" data-translate="twofa.infoText">After enabling 2FA, you'll receive backup codes that you can use if you lose access to your authenticator app. Keep them in a safe place!</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function copySecret() {
|
|
const secretCode = document.getElementById('secret-code').textContent;
|
|
navigator.clipboard.writeText(secretCode).then(() => {
|
|
// Show success notification
|
|
const notification = document.createElement('div');
|
|
notification.className = 'fixed top-4 right-4 z-50 px-4 py-3 rounded-lg shadow-lg flex items-center gap-3 bg-green-500 text-white animate-slideIn';
|
|
notification.innerHTML = `
|
|
<span class="material-symbols-outlined text-[20px]">check_circle</span>
|
|
<span class="text-sm font-medium">Secret code copied!</span>
|
|
`;
|
|
document.body.appendChild(notification);
|
|
|
|
setTimeout(() => {
|
|
notification.classList.add('animate-slideOut');
|
|
setTimeout(() => document.body.removeChild(notification), 300);
|
|
}, 2000);
|
|
});
|
|
}
|
|
</script>
|
|
{% endblock %}
|