diff --git a/src/lib/protected/milka.jpg b/src/lib/protected/milka.jpg
new file mode 100644
index 0000000..4ba6ce0
Binary files /dev/null and b/src/lib/protected/milka.jpg differ
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index 12a38ca..7b4e691 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -320,7 +320,7 @@
flex-direction: column;
min-height: 100vh;
width: 100vw;
- background-color: #2d4f5a;
+ background-color: #385764;
color: #333;
position: absolute;
top: 0;
@@ -422,7 +422,7 @@
.form-input {
width: 100%;
- padding: clamp(0.7rem, 3vw, 0.8rem);
+ padding: 0.4rem 0.6rem;
border: 1px solid #ddd;
border-radius: 4px;
background-color: #f5f5f5;
@@ -501,7 +501,7 @@
color: white;
border: none;
border-radius: 4px;
- padding: clamp(0.6rem, 3vw, 0.8rem) clamp(1rem, 4vw, 1.2rem);
+ padding: clamp(0.4rem, 2vw, 0.5rem) clamp(0.8rem, 3vw, 1rem);
font-size: clamp(0.85rem, 3.5vw, 0.9rem);
cursor: pointer;
transition: background-color 0.2s;
@@ -565,9 +565,9 @@
color: white;
font-size: clamp(1.5rem, 5vw, 1.8rem);
cursor: pointer;
- padding: 0.5rem;
- width: 44px;
- height: 44px;
+ padding: 0.3rem;
+ width: 36px;
+ height: 36px;
display: flex;
align-items: center;
justify-content: center;
@@ -702,4 +702,18 @@
margin-top: 1rem;
}
}
+
+ .admin-button {
+ background-color: #30b0d5;
+ color: white;
+ border: none;
+ border-radius: 4px;
+ padding: clamp(0.4rem, 2vw, 0.5rem) clamp(0.8rem, 3vw, 1rem);
+ font-size: clamp(0.85rem, 3.5vw, 0.9rem);
+ cursor: pointer;
+ transition: background-color 0.2s;
+ text-align: center;
+ text-decoration: none;
+ display: block;
+ }
diff --git a/src/routes/api/login/+server.js b/src/routes/api/login/+server.js
index 13b29d1..e23a105 100644
--- a/src/routes/api/login/+server.js
+++ b/src/routes/api/login/+server.js
@@ -229,8 +229,15 @@ USE_SSL=false # majd ha lesz rá idő`
color: white;
font-size: 1.5rem;
cursor: pointer;
- padding: 0;
+ padding: 0.3rem;
line-height: 1;
+ width: 36px;
+ height: 36px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ touch-action: manipulation;
+ -webkit-tap-highlight-color: transparent;
}
.modal-body {
@@ -426,15 +433,13 @@ USE_SSL=false # majd ha lesz rá idő`
color: white;
border: none;
border-radius: 4px;
- padding: clamp(0.8rem, 3vw, 1rem);
- font-size: clamp(0.9rem, 3vw, 1rem);
+ padding: 1rem;
+ font-size: 1rem;
cursor: pointer;
transition: background-color 0.2s;
text-align: center;
text-decoration: none;
display: block;
- touch-action: manipulation;
- -webkit-tap-highlight-color: transparent;
}
.admin-button:hover {
@@ -484,10 +489,10 @@ USE_SSL=false # majd ha lesz rá idő`
color: white;
font-size: 1.5rem;
cursor: pointer;
- padding: 0.25rem;
+ padding: 0.3rem;
line-height: 1;
- width: 32px;
- height: 32px;
+ width: 36px;
+ height: 36px;
display: flex;
align-items: center;
justify-content: center;
@@ -723,6 +728,267 @@ USE_SSL=false # majd ha lesz rá idő`
});
}
+ // Wide gold storage silo case
+ if (username === 'wide_gold_storage_silo' && password === 'wide_gold_storage_silo') {
+ return json({
+ success: true,
+ type: 'admin',
+ content: {
+ html: `
+
+

+
+
+ `,
+ css: `
+ .logo-container {
+ margin-bottom: 2rem;
+ text-align: center;
+ padding: 0 1rem;
+ }
+
+ .logo {
+ max-width: 100%;
+ height: auto;
+ width: auto;
+ max-height: 120px;
+ }
+
+ .admin-panel {
+ background-color: white;
+ border-radius: 4px;
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
+ width: 100%;
+ max-width: 600px;
+ overflow: hidden;
+ margin: 0 1rem;
+ }
+
+ .login-header {
+ background-color: #30b0d5;
+ color: white;
+ padding: 1rem;
+ text-align: center;
+ }
+
+ .login-header h2 {
+ font-size: clamp(1rem, 4vw, 1.2rem);
+ font-weight: normal;
+ margin: 0;
+ line-height: 1.3;
+ }
+
+ .login-form {
+ padding: 1.5rem;
+ }
+
+ .admin-buttons {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ margin: 1rem 0;
+ }
+
+ .admin-button {
+ background-color: #30b0d5;
+ color: white;
+ border: none;
+ border-radius: 4px;
+ padding: 1rem;
+ font-size: 1rem;
+ cursor: pointer;
+ transition: background-color 0.2s;
+ text-align: center;
+ text-decoration: none;
+ display: block;
+ }
+
+ .admin-button:hover {
+ background-color: #2698bb;
+ }
+
+ .modal-backdrop {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.8);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 1000;
+ padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
+ }
+
+ .modal-content {
+ background-color: black;
+ border-radius: 4px;
+ width: min(800px, 95%);
+ height: min(600px, 90%);
+ max-width: none;
+ max-height: none;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+ position: relative;
+ }
+
+ .modal-header {
+ background-color: #30b0d5;
+ color: white;
+ padding: 0.5rem;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ min-height: 40px;
+ }
+
+ .modal-close {
+ background: none;
+ border: none;
+ color: white;
+ font-size: 1.5rem;
+ cursor: pointer;
+ padding: 0.3rem;
+ line-height: 1;
+ width: 36px;
+ height: 36px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ touch-action: manipulation;
+ -webkit-tap-highlight-color: transparent;
+ }
+
+ .modal-body {
+ flex: 1;
+ padding: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ overflow: hidden;
+ background-color: #000;
+ }
+
+ .modal-image {
+ max-width: 100%;
+ max-height: 100%;
+ width: auto;
+ height: auto;
+ object-fit: contain;
+ display: block;
+ }
+
+ @media (max-width: 640px) {
+ .logo-container {
+ margin-bottom: 1.5rem;
+ }
+
+ .admin-panel {
+ margin: 0 0.5rem;
+ }
+
+ .login-form {
+ padding: 1rem;
+ }
+
+ .modal-content {
+ width: 100%;
+ height: 100%;
+ border-radius: 0;
+ }
+
+ .modal-header {
+ padding: 0.5rem;
+ }
+
+ .modal-close {
+ font-size: 1.5rem;
+ }
+ }
+ `,
+ js: `
+ document.getElementById('showMilkaButton').addEventListener('click', async function() {
+ try {
+ const milkaModal = document.createElement('div');
+ milkaModal.className = 'modal-backdrop';
+ milkaModal.innerHTML = \`
+
+
+
+
![Milka]()
+
+
+ \`;
+
+ document.body.appendChild(milkaModal);
+
+ // Load image with authentication
+ const img = milkaModal.querySelector('.modal-image');
+ fetch('/api/protected-image?image=milka.jpg', {
+ headers: {
+ 'x-auth': 'milka-authenticated'
+ }
+ })
+ .then(response => response.blob())
+ .then(blob => {
+ img.src = URL.createObjectURL(blob);
+ })
+ .catch(error => {
+ console.error('Error loading image:', error);
+ img.style.display = 'none';
+ });
+
+ const closeModal = () => {
+ document.body.removeChild(milkaModal);
+ };
+
+ milkaModal.querySelector('.modal-close').addEventListener('click', closeModal);
+ milkaModal.addEventListener('click', closeModal);
+
+ // Prevent scrolling when modal is open
+ document.body.style.overflow = 'hidden';
+ milkaModal.addEventListener('click', () => {
+ document.body.style.overflow = '';
+ closeModal();
+ });
+
+ // Handle escape key
+ const handleEscape = (e) => {
+ if (e.key === 'Escape') {
+ document.body.style.overflow = '';
+ closeModal();
+ document.removeEventListener('keydown', handleEscape);
+ }
+ };
+ document.addEventListener('keydown', handleEscape);
+ } catch (error) {
+ console.error('Error loading Milka:', error);
+ }
+ });
+ `
+ }
+ });
+ }
+
// Pearoo case
if (username === 'pearoo' && password === 'pearoo') {
return json({
diff --git a/src/routes/api/plist/+server.js b/src/routes/api/plist/+server.js
new file mode 100644
index 0000000..be13ba6
--- /dev/null
+++ b/src/routes/api/plist/+server.js
@@ -0,0 +1,51 @@
+import { json } from '@sveltejs/kit';
+import fs from 'fs/promises';
+import path from 'path';
+
+const PLIST_PASSWORD = 'mivancicus';
+
+// Function to extract login pairs from the login handler code
+async function getLoginPairs() {
+ try {
+ // Read the login handler file
+ const loginHandlerPath = path.join(process.cwd(), 'src', 'routes', 'api', 'login', '+server.js');
+ const content = await fs.readFile(loginHandlerPath, 'utf-8');
+
+ const pairs = [];
+
+ // Extract username/password pairs using regex
+ const matches = content.matchAll(/if\s*\(username\s*===\s*['"]([^'"]+)['"]\s*&&\s*(?:password\s*===\s*['"]([^'"]+)['"]|hashedPassword\s*===\s*adminHash)/g);
+
+ for (const match of matches) {
+ const username = match[1];
+ // For admin, we use 'admin' as password since it's hashed in the code
+ const password = username === 'admin' ? 'admin' : match[2];
+
+ if (username && password) {
+ pairs.push({ username, password });
+ }
+ }
+
+ return pairs;
+ } catch (error) {
+ console.error('Error reading login pairs:', error);
+ return [];
+ }
+}
+
+export async function POST({ request }) {
+ const { password } = await request.json();
+
+ if (password === PLIST_PASSWORD) {
+ const pairs = await getLoginPairs();
+ return json({
+ success: true,
+ pairs
+ });
+ }
+
+ return json({
+ success: false,
+ message: 'Invalid password'
+ });
+}
\ No newline at end of file
diff --git a/src/routes/api/protected-image/+server.js b/src/routes/api/protected-image/+server.js
index 0414fa0..27336fd 100644
--- a/src/routes/api/protected-image/+server.js
+++ b/src/routes/api/protected-image/+server.js
@@ -7,17 +7,16 @@ export async function GET({ request, url }) {
const authHeader = request.headers.get('x-auth');
const imageName = url.searchParams.get('image');
- // Validate image name to prevent directory traversal
- if (!imageName || !['skelly.jpg', 'klima.png', 'p1.png', 'p2.png'].includes(imageName)) {
+ if (!imageName || !['skelly.jpg', 'klima.png', 'p1.png', 'p2.png', 'milka.jpg'].includes(imageName)) {
throw redirect(307, '/');
}
- // Check for proper authentication
const validAuth = {
'skelly.jpg': 'skelly-authenticated',
'klima.png': 'klima-authenticated',
'p1.png': 'pearoo-authenticated',
- 'p2.png': 'pearoo-authenticated'
+ 'p2.png': 'pearoo-authenticated',
+ 'milka.jpg': 'milka-authenticated'
};
if (!authHeader || authHeader !== validAuth[imageName]) {
@@ -25,16 +24,12 @@ export async function GET({ request, url }) {
}
try {
- // Construct the path to the protected image
const imagePath = path.join(process.cwd(), 'src', 'lib', 'protected', imageName);
- // Read the image file
const imageBuffer = await fs.readFile(imagePath);
- // Determine content type
const contentType = imageName.endsWith('.jpg') ? 'image/jpeg' : 'image/png';
- // Return the image with proper headers
return new Response(imageBuffer, {
headers: {
'Content-Type': contentType,
diff --git a/src/routes/plist/+page.svelte b/src/routes/plist/+page.svelte
new file mode 100644
index 0000000..fe937b6
--- /dev/null
+++ b/src/routes/plist/+page.svelte
@@ -0,0 +1,300 @@
+
+
+
+ KRETÉN - Password List
+
+
+
+
+
+

+
+
+
+
+
+ {#if !isAuthenticated}
+
+ {:else}
+
+ {/if}
+
+
+
+
+
+
+
\ No newline at end of file