updating templates to have dedicated wordpress login page, updated phpmyadmin page to be more correct

This commit is contained in:
Phillip Tarrant
2025-12-25 13:35:42 -06:00
parent 9128d2759f
commit 47a49b03be
5 changed files with 516 additions and 19 deletions

View File

@@ -249,18 +249,19 @@ class Handler(BaseHTTPRequestHandler):
self.wfile.write(api_response('/api/config').encode()) self.wfile.write(api_response('/api/config').encode())
return True return True
if path in ['/admin', '/admin/', '/admin/login', '/login', '/wp-login.php']: if path in ['/admin', '/admin/', '/admin/login', '/login']:
self.send_response(200) self.send_response(200)
self.send_header('Content-type', 'text/html') self.send_header('Content-type', 'text/html')
self.end_headers() self.end_headers()
self.wfile.write(html_templates.login_form().encode()) self.wfile.write(html_templates.login_form().encode())
return True return True
if path == '/wp-admin' or path == '/wp-admin/': # WordPress login page
if path in ['/wp-login.php', '/wp-login', '/wp-admin', '/wp-admin/']:
self.send_response(200) self.send_response(200)
self.send_header('Content-type', 'text/html') self.send_header('Content-type', 'text/html')
self.end_headers() self.end_headers()
self.wfile.write(html_templates.login_form().encode()) self.wfile.write(html_templates.wp_login().encode())
return True return True
if path in ['/wp-content/', '/wp-includes/'] or 'wordpress' in path.lower(): if path in ['/wp-content/', '/wp-includes/'] or 'wordpress' in path.lower():

View File

@@ -1,24 +1,286 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html lang="en" dir="ltr">
<head> <head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex,nofollow">
<title>phpMyAdmin</title> <title>phpMyAdmin</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><rect fill='%236c78af' width='32' height='32' rx='4'/><text x='16' y='22' font-size='18' fill='white' text-anchor='middle' font-family='sans-serif' font-weight='bold'>pma</text></svg>">
<style> <style>
body {{ font-family: 'Segoe UI', Tahoma, sans-serif; margin: 0; background: #f0f0f0; }} * {{
.header {{ background: #2979ff; color: white; padding: 10px 20px; }} box-sizing: border-box;
.login {{ background: white; width: 400px; margin: 100px auto; padding: 30px; border-radius: 4px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }} }}
input {{ width: 100%; padding: 8px; margin: 8px 0; border: 1px solid #ddd; }} body {{
button {{ padding: 10px 20px; background: #2979ff; color: white; border: none; cursor: pointer; }} font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
font-size: 14px;
background: #fffffc;
margin: 0;
padding: 0;
color: #444;
}}
#page_content {{
margin: 0 auto;
max-width: 960px;
padding: 20px;
}}
.container-fluid {{
display: flex;
min-height: 100vh;
}}
#pma_navigation {{
width: 240px;
background: #f3f3f3;
border-right: 1px solid #ddd;
padding: 10px;
}}
#pma_navigation_header {{
text-align: center;
padding: 15px 10px;
border-bottom: 1px solid #ddd;
margin-bottom: 10px;
}}
#pma_navigation_header img {{
max-width: 160px;
}}
.logo-text {{
font-size: 24px;
font-weight: bold;
color: #6c78af;
}}
.logo-text span {{
color: #f89c0e;
}}
#pma_main {{
flex: 1;
padding: 20px;
background: #fff;
}}
.login_form {{
max-width: 500px;
margin: 40px auto;
background: #fff;
border: 1px solid #ddd;
border-radius: 4px;
box-shadow: 0 1px 3px rgba(0,0,0,0.08);
}}
.login_form h1 {{
background: #f3f3f3;
margin: 0;
padding: 15px 20px;
font-size: 16px;
font-weight: normal;
border-bottom: 1px solid #ddd;
color: #333;
}}
.login_form h1 img {{
vertical-align: middle;
margin-right: 8px;
}}
.login_form form {{
padding: 20px;
}}
.item {{
margin-bottom: 15px;
}}
.item label {{
display: block;
margin-bottom: 5px;
font-weight: 500;
color: #333;
}}
.item input[type="text"],
.item input[type="password"],
.item select {{
width: 100%;
padding: 8px 10px;
border: 1px solid #aaa;
border-radius: 2px;
font-size: 14px;
background: #fff;
}}
.item input:focus,
.item select:focus {{
border-color: #6c78af;
outline: none;
box-shadow: 0 0 0 2px rgba(108, 120, 175, 0.2);
}}
.item select {{
cursor: pointer;
}}
.checkbox-item {{
display: flex;
align-items: center;
gap: 8px;
}}
.checkbox-item input {{
margin: 0;
}}
fieldset {{
border: 1px solid #ddd;
border-radius: 2px;
padding: 15px;
margin: 0 0 15px 0;
}}
legend {{
font-weight: 500;
padding: 0 8px;
color: #333;
}}
.btn {{
display: inline-block;
padding: 8px 20px;
background: #6c78af;
color: #fff;
border: none;
border-radius: 2px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
}}
.btn:hover {{
background: #5a6699;
}}
.server-choice {{
display: flex;
gap: 10px;
margin-bottom: 15px;
}}
.server-choice label {{
display: flex;
align-items: center;
gap: 5px;
cursor: pointer;
}}
.footer {{
text-align: center;
margin-top: 20px;
padding-top: 15px;
border-top: 1px solid #ddd;
font-size: 12px;
color: #888;
}}
.footer a {{
color: #6c78af;
text-decoration: none;
}}
.footer a:hover {{
text-decoration: underline;
}}
.lang-select {{
margin-top: 15px;
padding-top: 15px;
border-top: 1px solid #eee;
}}
.lang-select label {{
display: inline;
margin-right: 10px;
}}
.lang-select select {{
width: auto;
padding: 5px 10px;
}}
.nav-item {{
padding: 8px 12px;
color: #333;
text-decoration: none;
display: block;
border-radius: 2px;
}}
.nav-item:hover {{
background: #e8e8e8;
}}
.error-message {{
display: none;
}}
@media (max-width: 768px) {{
.container-fluid {{
flex-direction: column;
}}
#pma_navigation {{
width: 100%;
border-right: none;
border-bottom: 1px solid #ddd;
}}
.login_form {{
margin: 20px;
}}
}}
</style> </style>
</head> </head>
<body> <body>
<div class="header"><h1>phpMyAdmin</h1></div> <div class="container-fluid">
<div class="login"> <div id="pma_navigation">
<h2>MySQL Server Login</h2> <div id="pma_navigation_header">
<form action="/phpMyAdmin/index.php" method="post"> <div class="logo-text">php<span>My</span>Admin</div>
<input type="text" name="pma_username" placeholder="Username"> </div>
<input type="password" name="pma_password" placeholder="Password"> <nav>
<button type="submit">Go</button> <a href="#" class="nav-item">Databases</a>
</form> <a href="#" class="nav-item">SQL</a>
<a href="#" class="nav-item">Status</a>
<a href="#" class="nav-item">User accounts</a>
<a href="#" class="nav-item">Export</a>
<a href="#" class="nav-item">Import</a>
<a href="#" class="nav-item">Settings</a>
</nav>
</div>
<div id="pma_main">
<div class="login_form">
<h1>
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#6c78af" stroke-width="2" style="vertical-align: middle; margin-right: 8px;">
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect>
<path d="M7 11V7a5 5 0 0 1 10 0v4"></path>
</svg>
Log in
</h1>
<form method="post" action="/phpmyadmin/index.php" name="login_form" autocomplete="off">
<fieldset>
<legend>Log in</legend>
<div class="item">
<label for="input_servername">Server Choice:</label>
<select name="server" id="input_servername">
<option value="1">127.0.0.1</option>
<option value="2">localhost</option>
</select>
</div>
<div class="item">
<label for="input_username">Username:</label>
<input type="text" name="pma_username" id="input_username" value="" autocomplete="username" autofocus>
</div>
<div class="item">
<label for="input_password">Password:</label>
<input type="password" name="pma_password" id="input_password" value="" autocomplete="current-password">
</div>
</fieldset>
<input type="hidden" name="token" value="a1b2c3d4e5f6g7h8i9j0">
<input type="hidden" name="set_session" value="1">
<button type="submit" class="btn" id="input_go" value="Log in">Log in</button>
<div class="lang-select">
<label for="lang_select">Language:</label>
<select name="lang" id="lang_select">
<option value="en" selected>English</option>
<option value="de">Deutsch</option>
<option value="es">Español</option>
<option value="fr">Français</option>
<option value="it">Italiano</option>
<option value="ja">日本語</option>
<option value="ko">한국어</option>
<option value="nl">Nederlands</option>
<option value="pl">Polski</option>
<option value="pt">Português</option>
<option value="ru">Русский</option>
<option value="zh">中文</option>
</select>
</div>
</form>
<div class="footer">
<a href="https://www.phpmyadmin.net/docs/" target="_blank">Documentation</a> |
<a href="https://www.phpmyadmin.net/" target="_blank">Official Homepage</a> |
<a href="https://github.com/phpmyadmin/phpmyadmin" target="_blank">Contribute</a>
<br><br>
phpMyAdmin 5.2.1
</div>
</div>
</div>
</div> </div>
</body> </body>
</html> </html>

View File

@@ -0,0 +1,227 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="robots" content="max-image-preview:large, noindex, noarchive">
<title>Log In &lsaquo; WordPress &mdash; WordPress</title>
<style>
html {{
background: #f0f0f1;
min-height: 100%;
}}
body {{
background: #f0f0f1;
min-height: 100%;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
font-size: 13px;
line-height: 1.4em;
color: #3c434a;
margin: 0;
padding: 0;
}}
a {{
color: #2271b1;
text-decoration: none;
}}
a:hover, a:active {{
color: #135e96;
}}
#login {{
width: 320px;
padding: 8% 0 0;
margin: auto;
}}
#login h1 {{
text-align: center;
}}
#login h1 a {{
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA4NCA4NCI+PHBhdGggZD0iTTQyIDBDMTguOCAwIDAgMTguOCAwIDQyczE4LjggNDIgNDIgNDIgNDItMTguOCA0Mi00MlM2NS4yIDAgNDIgMHptMCA3OC40QzIxLjggNzguNCA1LjYgNjIuMiA1LjYgNDJTMjEuOCA1LjYgNDIgNS42IDc4LjQgMjEuOCA3OC40IDQyIDYyLjIgNzguNCA0MiA3OC40ek0yMC4xIDQyYzAgNy42IDQuNSAxNC4yIDEwLjkgMTcuM2wtOS4yLTI1LjJjLTEuMSAyLjUtMS43IDUuMi0xLjcgNy45em0zNi44LTEuMWMwLTIuNC0uOS01LjYtMi40LTcuMi0xLjUtMi0zLTMuNC0zLTUuMiAwLTIgMS41LTMuOSAzLjctMy45aC4zYy00LjktNC42LTExLjQtNy40LTE4LjUtNy40LTkuNiAwLTE4IDQuOS0yMi45IDEyLjMuNiAwIDEuMiAwIDEuNyAwIDIuOCAwIDcuMi0uMyA3LjItLjNzLjItLjEuMi0uMi0xLjUtLjEtMS41LS4xYy45LTEuMSAxLjYtMy4xIDEuNi0zLjEuMiAwIDEuOS41IDIuNS41cy42LjEuNi4xYy0xLjMuOC0xLjUgMy4xLTEuNSAzLjFzMCAuNC40LjRjLjMgMCAuOC0uMy44LS4zLjguNCAxLjcgMi4xIDEuNyAyLjF2LS4yYy42IDEuNCAyLjMgNS4yIDIuMyA1LjIgMS4xIDMuMiAyLjggNS41IDQuMSA3LjIgMS4zIDEuNyAyLjggMy4xIDQuNCAzLjggNC4yLTEuMSA3LjItNC4zIDguNS03LjZsLjItLjVjLjEtLjMuMi0uNi40LTFsLTYuNi0xOGMtLjYtMS42LTEtMi43LTEuNC0zLjhoLS41Yy0uNCAwLS43LjEtLjcuMS0uMS4xLjIuMi4yLjJzMS40LjEgMi4yLjRjLjkuMiAyIC43IDIgLjcuMy4xLjcuMy43LjNzLjEgMCAuMS0uMWMwIDAgLjEtLjItLjQtLjQtLjMtLjEtMS0uMy0xLjYtLjUtLjUtLjEtLjktLjItMS0uMi0uMSAwLS4xLS4xLS4xLS4xdi0uMWMwIC4xLjEuMS4xLjFzMCAuMS0uMS4xYy0uMi4xLjEuMy41LjVzLjkuNSAxLjQuN2MuNi4zIDEuMS43IDEuNC45LjMuMy42LjkuOSAxLjIuMy40LjYgMS4xLjggMS43bDQuMSAxMy44YzIuNy0xLjEgNC42LTMuNyA0LjYtNi43eiIgZmlsbD0iIzMzMzMzMyIvPjwvc3ZnPg==');
background-size: 84px;
background-position: center top;
background-repeat: no-repeat;
color: #3c434a;
height: 84px;
font-size: 0;
display: block;
outline: 0;
}}
.login form {{
margin-top: 20px;
margin-left: 0;
padding: 26px 24px 34px;
font-weight: 400;
overflow: hidden;
background: #fff;
border: 1px solid #c3c4c7;
box-shadow: 0 1px 3px rgba(0, 0, 0, .04);
}}
.login form .input, .login input[type="text"], .login input[type="password"] {{
font-size: 24px;
width: 100%;
padding: 3px;
margin: 2px 6px 16px 0;
background: #fff;
border: 1px solid #8c8f94;
box-shadow: none;
color: #2c3338;
outline: none;
}}
.login form .input:focus {{
border-color: #2271b1;
box-shadow: 0 0 0 1px #2271b1;
}}
.login label {{
font-size: 14px;
line-height: 1.5;
display: inline-block;
margin-bottom: 3px;
}}
.login .forgetmenot {{
margin: 2px 0 24px;
}}
.login .forgetmenot label {{
font-size: 12px;
display: flex;
align-items: center;
}}
.login .forgetmenot input {{
margin: 0 4px 0 0;
}}
.wp-hide-pw {{
position: absolute;
right: 0;
top: 0;
bottom: 0;
padding: 0 15px;
background: transparent;
border: none;
color: #2271b1;
cursor: pointer;
}}
.wp-hide-pw:hover {{
color: #135e96;
}}
.user-pass-wrap {{
position: relative;
}}
.wp-pwd {{
position: relative;
}}
#wp-submit {{
float: right;
text-decoration: none;
font-size: 13px;
line-height: 2.15384615;
min-height: 32px;
margin: 0;
padding: 0 12px;
cursor: pointer;
border: 1px solid #2271b1;
border-radius: 3px;
white-space: nowrap;
box-sizing: border-box;
background: #2271b1;
color: #fff;
}}
#wp-submit:hover {{
background: #135e96;
border-color: #135e96;
color: #fff;
}}
p.submit {{
margin-bottom: 0;
}}
#nav {{
margin: 24px 0 0 0;
padding: 0;
text-align: center;
}}
#nav a {{
color: #50575e;
}}
#nav a:hover {{
color: #135e96;
}}
#backtoblog {{
margin: 16px 0 0 0;
padding: 0;
text-align: center;
}}
#backtoblog a {{
color: #50575e;
}}
#backtoblog a:hover {{
color: #135e96;
}}
.privacy-policy-page-link {{
text-align: center;
margin-top: 16px;
}}
.privacy-policy-page-link a {{
color: #50575e;
font-size: 12px;
}}
@media screen and (max-width: 400px) {{
#login {{
width: 100%;
padding: 20px;
box-sizing: border-box;
}}
}}
</style>
</head>
<body class="login js login-action-login wp-core-ui locale-en-us">
<div id="login">
<h1><a href="https://wordpress.org/">Powered by WordPress</a></h1>
<form name="loginform" id="loginform" action="/wp-login.php" method="post">
<p>
<label for="user_login">Username or Email Address</label>
<input type="text" name="log" id="user_login" class="input" value="" size="20" autocapitalize="off" autocomplete="username" required>
</p>
<div class="user-pass-wrap">
<label for="user_pass">Password</label>
<div class="wp-pwd">
<input type="password" name="pwd" id="user_pass" class="input password-input" value="" size="20" autocomplete="current-password" spellcheck="false" required>
<button type="button" class="wp-hide-pw hide-if-no-js" data-toggle="0" aria-label="Show password">
<span class="dashicons dashicons-visibility" aria-hidden="true"></span>
</button>
</div>
</div>
<p class="forgetmenot">
<label>
<input name="rememberme" type="checkbox" id="rememberme" value="forever">
Remember Me
</label>
</p>
<p class="submit">
<input type="submit" name="wp-submit" id="wp-submit" class="button button-primary button-large" value="Log In">
<input type="hidden" name="redirect_to" value="/wp-admin/">
<input type="hidden" name="testcookie" value="1">
</p>
</form>
<p id="nav">
<a href="/wp-login.php?action=lostpassword">Lost your password?</a>
</p>
<p id="backtoblog">
<a href="/">&larr; Go to WordPress</a>
</p>
<div class="privacy-policy-page-link">
<a href="/privacy-policy/">Privacy Policy</a>
</div>
</div>
<script>
// Toggle password visibility
document.querySelector('.wp-hide-pw').addEventListener('click', function() {{
var pwdInput = document.getElementById('user_pass');
if (pwdInput.type === 'password') {{
pwdInput.type = 'text';
this.setAttribute('aria-label', 'Hide password');
}} else {{
pwdInput.type = 'password';
this.setAttribute('aria-label', 'Show password');
}}
}});
</script>
</body>
</html>

View File

@@ -28,6 +28,11 @@ def phpmyadmin() -> str:
return load_template("phpmyadmin") return load_template("phpmyadmin")
def wp_login() -> str:
"""Generate fake WordPress login page"""
return load_template("wp_login")
def robots_txt() -> str: def robots_txt() -> str:
"""Generate juicy robots.txt""" """Generate juicy robots.txt"""
return load_template("robots.txt") return load_template("robots.txt")

View File

@@ -40,6 +40,9 @@ def load_template(name: str, **kwargs) -> str:
>>> load_template("robots.txt") # Loads html/robots.txt >>> load_template("robots.txt") # Loads html/robots.txt
>>> load_template("directory_listing", path="/var/www", rows="<tr>...</tr>") >>> load_template("directory_listing", path="/var/www", rows="<tr>...</tr>")
""" """
# debug
# print(f"Loading Template: {name}")
# Check cache first # Check cache first
if name not in _template_cache: if name not in _template_cache:
# Determine file path based on whether name has an extension # Determine file path based on whether name has an extension
@@ -58,7 +61,6 @@ def load_template(name: str, **kwargs) -> str:
# Apply substitutions if kwargs provided # Apply substitutions if kwargs provided
if kwargs: if kwargs:
template = template.format(**kwargs) template = template.format(**kwargs)
return template return template