Modernize UI/UX with Bootstrap 5.3 and contemporary design
Complete UI overhaul bringing RailsGoat into 2024 with a professional, modern interface while maintaining all security vulnerabilities for educational purposes. ## Design System - Modern color palette with CSS variables - Primary: #e63946 (red), Secondary: #457b9d (blue) - Professional sans-serif typography - Consistent spacing and shadows - Bootstrap Icons for modern iconography - Responsive design with mobile-first approach ## Layout Changes - Fixed header with clean navigation (60px height) - Dark sidebar with modern icons and section headers (250px width) - Proper spacing and padding throughout - Responsive breakpoints for mobile/tablet/desktop - Modern card-based content areas ## Header Modernization - Clean white header with subtle shadow - RailsGoat branding with shield icon - Modern dropdown user menu with avatar - Improved font size controls - Better button styling and spacing - Modal-based credentials display (Bootstrap 5) ## Sidebar Improvements - Dark navy background (#1d3557) - Bootstrap Icons instead of custom fonts - Section headers (Admin, Employee) - Active state highlighting - Smooth hover transitions - Version info in footer ## Login Page Redesign - Beautiful gradient background - Centered card with shadow - Modern form inputs with icons - Clear call-to-action buttons - Security training notice banner - Responsive design ## Components Updated - Modern alerts with icons and proper dismiss buttons - Footer with OWASP links and copyright - Scroll-to-top button (vanilla JS, no jQuery) - Form controls with proper Bootstrap 5 classes ## Technical Improvements - Bootstrap 5.3 properly implemented (not just CDN reference) - Bootstrap Icons 1.11.1 for modern iconography - Removed jQuery dependencies where possible - Modern JavaScript (vanilla, no jQuery for new features) - Proper Bootstrap 5 data attributes (data-bs-*) - Semantic HTML5 structure ## Security Vulnerabilities Preserved - XSS via html_safe in user welcome (header) - XSS via cookie font-size (application layout) - XSS via URL hash parameter (login page) - Missing SRI on CDN assets (A03:2025) - All educational vulnerabilities intact ## Files Modified - app/views/layouts/application.html.erb - Complete redesign with CSS variables - app/views/layouts/shared/_header.html.erb - Modern navigation - app/views/layouts/shared/_sidebar.html.erb - Dark sidebar with icons - app/views/layouts/shared/_footer.html.erb - Modern footer with links - app/views/layouts/shared/_messages.html.erb - Bootstrap 5 alerts - app/views/sessions/new.html.erb - Beautiful login page This modernization makes RailsGoat visually appealing and professional while maintaining its core educational purpose. The application now looks like a modern web app security professionals want to use. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,142 +1,90 @@
|
||||
<% if current_user %>
|
||||
<div id="mainnav" class="hidden-phone hidden-tablet">
|
||||
<ul style="display: block;">
|
||||
<li id="home">
|
||||
<%= link_to home_dashboard_index_path do %>
|
||||
<div class="icon">
|
||||
<span class="fs1" aria-hidden="true" data-icon=""></span>
|
||||
</div>
|
||||
Dashboard
|
||||
<% end %>
|
||||
</li>
|
||||
<% if is_admin? %>
|
||||
<li class="submenu" id='admin'>
|
||||
<a href="#">
|
||||
<div class="icon">
|
||||
<span class="fs1" aria-hidden="true" data-icon=""></span>
|
||||
</div>
|
||||
Admin
|
||||
</a>
|
||||
<ul>
|
||||
<li>
|
||||
<%= link_to admin_dashboard_path(:admin_id => "1") do %>
|
||||
Manage Users
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to admin_analytics_path(:admin_id => "1") do %>
|
||||
View Analytics
|
||||
<% end %>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<% end %>
|
||||
<li id="benefit_forms">
|
||||
<%= link_to user_benefit_forms_path(user_id: current_user.id) do %>
|
||||
<div class="icon">
|
||||
<span class="fs1" aria-hidden="true" data-icon=""></span>
|
||||
</div>
|
||||
Benefit Forms
|
||||
<% end %>
|
||||
</li>
|
||||
<li id="retirement">
|
||||
<%= link_to user_retirement_index_path(user_id: current_user.id) do %>
|
||||
<div class="icon">
|
||||
<span class="fs1" aria-hidden="true" data-icon=""></span>
|
||||
</div>
|
||||
401k Info
|
||||
<% end %>
|
||||
</li>
|
||||
<li id="pto">
|
||||
<%= link_to user_paid_time_off_index_path(user_id: current_user.id) do %>
|
||||
<div class="icon">
|
||||
<span class="fs1" aria-hidden="true" data-icon=""></span>
|
||||
</div>
|
||||
PTO
|
||||
<% end %>
|
||||
</li>
|
||||
<li id="employee_info">
|
||||
<%= link_to user_work_info_index_path(user_id: current_user.id) do %>
|
||||
<div class="icon">
|
||||
<span class="fs1" aria-hidden="true" data-icon=""></span>
|
||||
</div>
|
||||
Work Info
|
||||
<% end %>
|
||||
</li>
|
||||
<li id="performance">
|
||||
<%= link_to user_performance_index_path(user_id: current_user.id) do %>
|
||||
<div class="icon">
|
||||
<span class="fs1" aria-hidden="true" data-icon=""></span>
|
||||
</div>
|
||||
Performance
|
||||
<% end %>
|
||||
</li>
|
||||
<li id="messages">
|
||||
<%= link_to user_messages_path(user_id: current_user.id) do %>
|
||||
<div class="icon">
|
||||
<span class="fs1" aria-hidden="true" data-icon=""></span>
|
||||
</div>
|
||||
Messages
|
||||
<% end %>
|
||||
</li>
|
||||
<li id="pay">
|
||||
<%= link_to user_pay_index_path(user_id: current_user.id) do %>
|
||||
<div class="icon">
|
||||
<span class="fs1" aria-hidden="true" data-icon=""></span>
|
||||
</div>
|
||||
Pay
|
||||
<% end %>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<nav class="rg-sidebar">
|
||||
<ul class="rg-sidebar-nav">
|
||||
<li>
|
||||
<%= link_to home_dashboard_index_path, class: "#{controller_name == 'dashboard' ? 'active' : ''}" do %>
|
||||
<i class="bi bi-speedometer2"></i>
|
||||
<span>Dashboard</span>
|
||||
<% end %>
|
||||
</li>
|
||||
|
||||
<script type="text/javascript">
|
||||
//Main menu navigation
|
||||
<% if is_admin? %>
|
||||
<li class="mt-3">
|
||||
<div class="px-4 py-2 text-white-50 text-uppercase small fw-bold">Admin</div>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to admin_dashboard_path(admin_id: "1"), class: "#{controller_name == 'admin' && action_name == 'dashboard' ? 'active' : ''}" do %>
|
||||
<i class="bi bi-people"></i>
|
||||
<span>Manage Users</span>
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to admin_analytics_path(admin_id: "1"), class: "#{controller_name == 'admin' && action_name == 'analytics' ? 'active' : ''}" do %>
|
||||
<i class="bi bi-graph-up"></i>
|
||||
<span>View Analytics</span>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
$('.submenu > a').click(function(e){
|
||||
e.preventDefault();
|
||||
var submenu = $(this).siblings('ul');
|
||||
var li = $(this).parents('li');
|
||||
var submenus = $('#mainnav li.submenu ul');
|
||||
var submenus_parents = $('#mainnav li.submenu');
|
||||
if(li.hasClass('open'))
|
||||
{
|
||||
if(($(window).width() > 768) || ($(window).width() < 479)) {
|
||||
submenu.slideUp();
|
||||
} else {
|
||||
submenu.fadeOut(250);
|
||||
}
|
||||
li.removeClass('open');
|
||||
} else
|
||||
{
|
||||
if(($(window).width() > 768) || ($(window).width() < 479)) {
|
||||
submenus.slideUp();
|
||||
submenu.slideDown();
|
||||
} else {
|
||||
submenus.fadeOut(250);
|
||||
submenu.fadeIn(250);
|
||||
}
|
||||
submenus_parents.removeClass('open');
|
||||
li.addClass('open');
|
||||
}
|
||||
});
|
||||
<li class="mt-3">
|
||||
<div class="px-4 py-2 text-white-50 text-uppercase small fw-bold">Employee</div>
|
||||
</li>
|
||||
|
||||
var ul = $('#mainnav > ul');
|
||||
<li>
|
||||
<%= link_to user_benefit_forms_path(user_id: current_user.id), class: "#{controller_name == 'benefit_forms' ? 'active' : ''}" do %>
|
||||
<i class="bi bi-file-earmark-text"></i>
|
||||
<span>Benefit Forms</span>
|
||||
<% end %>
|
||||
</li>
|
||||
|
||||
$('#mainnav > a').click(function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
var mainnav = $('#mainnav');
|
||||
if(mainnav.hasClass('open'))
|
||||
{
|
||||
mainnav.removeClass('open');
|
||||
ul.slideUp(250);
|
||||
} else
|
||||
{
|
||||
mainnav.addClass('open');
|
||||
ul.slideDown(250);
|
||||
}
|
||||
});
|
||||
<li>
|
||||
<%= link_to user_retirement_index_path(user_id: current_user.id), class: "#{controller_name == 'retirement' ? 'active' : ''}" do %>
|
||||
<i class="bi bi-piggy-bank"></i>
|
||||
<span>401k Info</span>
|
||||
<% end %>
|
||||
</li>
|
||||
|
||||
</script>
|
||||
<li>
|
||||
<%= link_to user_paid_time_off_index_path(user_id: current_user.id), class: "#{controller_name == 'paid_time_off' ? 'active' : ''}" do %>
|
||||
<i class="bi bi-calendar-check"></i>
|
||||
<span>PTO</span>
|
||||
<% end %>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<%= link_to user_work_info_index_path(user_id: current_user.id), class: "#{controller_name == 'work_info' ? 'active' : ''}" do %>
|
||||
<i class="bi bi-briefcase"></i>
|
||||
<span>Work Info</span>
|
||||
<% end %>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<%= link_to user_performance_index_path(user_id: current_user.id), class: "#{controller_name == 'performance' ? 'active' : ''}" do %>
|
||||
<i class="bi bi-bar-chart"></i>
|
||||
<span>Performance</span>
|
||||
<% end %>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<%= link_to user_messages_path(user_id: current_user.id), class: "#{controller_name == 'messages' ? 'active' : ''}" do %>
|
||||
<i class="bi bi-envelope"></i>
|
||||
<span>Messages</span>
|
||||
<% end %>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<%= link_to user_pay_index_path(user_id: current_user.id), class: "#{controller_name == 'pay' ? 'active' : ''}" do %>
|
||||
<i class="bi bi-credit-card"></i>
|
||||
<span>Pay</span>
|
||||
<% end %>
|
||||
</li>
|
||||
|
||||
<li class="mt-4 pt-4 border-top border-secondary">
|
||||
<div class="px-4 py-2 text-white-50 small">
|
||||
<i class="bi bi-shield-exclamation"></i>
|
||||
OWASP RailsGoat <%= Rails::VERSION::STRING %>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<% end %>
|
||||
|
||||
Reference in New Issue
Block a user