JRNET / web /templates /profile.html
Factor Studios
Upload 96 files
6a5b8d8 verified
{% extends "base.html" %}
{% block title %}User Profile - Outline VPN{% endblock %}
{% block content %}
<div class="dashboard-container">
{% include 'sidebar.html' %}
<main class="main-content">
<div class="container">
<h1 class="h3 mb-4">User Profile</h1>
<div class="row">
<!-- Profile Information -->
<div class="col-lg-8">
<div class="dashboard-card">
<div class="d-flex justify-content-between align-items-center mb-4">
<h2 class="h5 mb-0">Profile Information</h2>
<button class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#editProfileModal">
<i class="bi bi-pencil me-2"></i>Edit Profile
</button>
</div>
<div class="row">
<div class="col-md-6">
<p class="text-muted mb-1">Username</p>
<p class="h6">{{ current_user.username }}</p>
</div>
<div class="col-md-6">
<p class="text-muted mb-1">Role</p>
<p class="h6">{{ current_user.role.value|title }}</p>
</div>
<div class="col-md-6 mt-3">
<p class="text-muted mb-1">Account Status</p>
<p class="h6">
<span class="status-indicator status-{{ current_user.status.value }}"></span>
{{ current_user.status.value|title }}
</p>
</div>
<div class="col-md-6 mt-3">
<p class="text-muted mb-1">Member Since</p>
<p class="h6">{{ current_user.created_at.strftime('%B %d, %Y') }}</p>
</div>
</div>
</div>
<!-- Security Settings -->
<div class="dashboard-card mt-4">
<h2 class="h5 mb-4">Security Settings</h2>
<!-- Change Password -->
<div class="mb-4">
<div class="d-flex justify-content-between align-items-center mb-3">
<div>
<h3 class="h6 mb-1">Password</h3>
<p class="text-muted small mb-0">Last changed {{ current_user.password_changed_at.strftime('%B %d, %Y') if current_user.password_changed_at else 'Never' }}</p>
</div>
<button class="btn btn-outline-primary btn-sm" data-bs-toggle="modal" data-bs-target="#changePasswordModal">
Change Password
</button>
</div>
</div>
<!-- Two-Factor Authentication -->
<div class="mb-4">
<div class="d-flex justify-content-between align-items-center mb-3">
<div>
<h3 class="h6 mb-1">Two-Factor Authentication</h3>
<p class="text-muted small mb-0">Add an extra layer of security to your account</p>
</div>
<button class="btn btn-outline-primary btn-sm" data-bs-toggle="modal" data-bs-target="#setup2FAModal">
{% if current_user.two_factor_enabled %}Manage 2FA{% else %}Enable 2FA{% endif %}
</button>
</div>
</div>
</div>
</div>
<!-- Active Sessions -->
<div class="col-lg-4">
<div class="dashboard-card">
<h2 class="h5 mb-4">Active Sessions</h2>
<div class="active-sessions">
{% for session in user_sessions %}
<div class="session-item mb-3 p-3 border rounded">
<div class="d-flex justify-content-between align-items-start mb-2">
<div>
<h6 class="mb-1">{{ session.device_info }}</h6>
<small class="text-muted">{{ session.ip_address }}</small>
</div>
{% if session.is_current %}
<span class="badge bg-success">Current</span>
{% endif %}
</div>
<div class="small text-muted mb-2">
Last active: {{ session.last_active.strftime('%B %d, %Y %H:%M') }}
</div>
{% if not session.is_current %}
<button class="btn btn-danger btn-sm" onclick="terminateSession('{{ session.id }}')">
<i class="bi bi-x-circle me-1"></i>Terminate
</button>
{% endif %}
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</main>
</div>
<!-- Edit Profile Modal -->
<div class="modal fade" id="editProfileModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Edit Profile</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form action="{{ url_for('update_profile') }}" method="POST">
<div class="modal-body">
<div class="mb-3">
<label class="form-label">Username</label>
<input type="text" class="form-control" name="username" value="{{ current_user.username }}" required>
</div>
<div class="mb-3">
<label class="form-label">Email</label>
<input type="email" class="form-control" name="email" value="{{ current_user.email }}" required>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Save Changes</button>
</div>
</form>
</div>
</div>
</div>
<!-- Change Password Modal -->
<div class="modal fade" id="changePasswordModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Change Password</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form action="{{ url_for('change_password') }}" method="POST">
<div class="modal-body">
<div class="mb-3">
<label class="form-label">Current Password</label>
<input type="password" class="form-control" name="current_password" required>
</div>
<div class="mb-3">
<label class="form-label">New Password</label>
<input type="password" class="form-control" name="new_password" required minlength="8">
</div>
<div class="mb-3">
<label class="form-label">Confirm New Password</label>
<input type="password" class="form-control" name="confirm_password" required minlength="8">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Change Password</button>
</div>
</form>
</div>
</div>
</div>
<!-- Setup 2FA Modal -->
<div class="modal fade" id="setup2FAModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Two-Factor Authentication</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
{% if not current_user.two_factor_enabled %}
<div class="text-center mb-4">
<img src="{{ qr_code_url }}" alt="2FA QR Code" class="img-fluid mb-3">
<p class="mb-1">Scan this QR code with your authenticator app</p>
<p class="text-muted small">or enter this code manually: <code>{{ setup_code }}</code></p>
</div>
<form action="{{ url_for('enable_2fa') }}" method="POST">
<div class="mb-3">
<label class="form-label">Verification Code</label>
<input type="text" class="form-control" name="verification_code" required>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary">Enable 2FA</button>
</div>
</form>
{% else %}
<div class="text-center mb-4">
<i class="bi bi-shield-check text-success" style="font-size: 3rem;"></i>
<h6 class="mt-3">Two-Factor Authentication is Enabled</h6>
</div>
<form action="{{ url_for('disable_2fa') }}" method="POST">
<div class="mb-3">
<label class="form-label">Enter your password to disable 2FA</label>
<input type="password" class="form-control" name="password" required>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-danger">Disable 2FA</button>
</div>
</form>
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script>
function terminateSession(sessionId) {
if (confirm('Are you sure you want to terminate this session?')) {
fetch(`/api/sessions/${sessionId}/terminate`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
}).then(response => {
if (response.ok) {
location.reload();
}
});
}
}
</script>
{% endblock %}