ci: fix pipeline, update readme and anonymize ZT references

This commit is contained in:
2026-06-12 12:30:18 +02:00
commit d1bd1a9ba9
68 changed files with 10353 additions and 0 deletions
+81
View File
@@ -0,0 +1,81 @@
// Helper functions for password toggles and validation shared between login, setup, and overlay
window.AuthHelpers = {
/**
* Initializes password visibility toggles.
* @param {HTMLElement} rootEl
*/
initPasswordToggles(rootEl = document) {
rootEl.querySelectorAll('.toggle-password').forEach(btn => {
if (btn.dataset.initialized) return;
btn.dataset.initialized = 'true';
btn.addEventListener('click', () => {
const input = btn.parentElement.querySelector('input');
if (!input) return;
const isPassword = input.type === 'password';
input.type = isPassword ? 'text' : 'password';
btn.innerHTML = isPassword
? '<i data-lucide="eye-off" class="eye-icon"></i>'
: '<i data-lucide="eye" class="eye-icon"></i>';
if (typeof lucide !== 'undefined') {
lucide.createIcons({ root: btn });
}
});
});
},
/**
* Performs client-side password validation against complexity rules.
* @param {string} val
* @param {string} confirmVal
* @returns {Object}
*/
validateComplexity(val, confirmVal) {
const hasLength = val.length >= 8;
const hasUpper = /[A-Z]/.test(val);
const hasNumber = /[0-9]/.test(val);
const hasSpecial = /[^a-zA-Z0-9]/.test(val);
const matches = val === confirmVal && val.length > 0;
return {
hasLength,
hasUpper,
hasNumber,
hasSpecial,
matches,
allValid: hasLength && hasUpper && hasNumber && hasSpecial && matches
};
},
/**
* Updates requirements list checklist UI.
* @param {HTMLElement} rootEl
* @param {Object} statuses
*/
updateRequirementsUI(rootEl, statuses) {
const updateReq = (id, isValid) => {
const li = rootEl.querySelector(`#${id}`);
if (!li) return;
li.className = isValid ? 'valid' : 'invalid';
const holder = li.querySelector('.icon-holder');
if (holder) {
holder.innerHTML = isValid
? '<i data-lucide="check" style="width:14px;height:14px;"></i>'
: '<i data-lucide="x" style="width:14px;height:14px;"></i>';
if (typeof lucide !== 'undefined') {
lucide.createIcons({ root: holder });
}
}
};
updateReq('req-length', statuses.hasLength);
updateReq('req-upper', statuses.hasUpper);
updateReq('req-number', statuses.hasNumber);
updateReq('req-special', statuses.hasSpecial);
updateReq('req-match', statuses.matches);
}
};
+1733
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 620 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 620 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

+12
View File
File diff suppressed because one or more lines are too long
+21
View File
@@ -0,0 +1,21 @@
{
"name": "Hydr'Hacked",
"short_name": "Hydr'Hacked",
"start_url": "/",
"display": "standalone",
"orientation": "portrait",
"background_color": "#1a1a1a",
"theme_color": "#1a1a1a",
"icons": [
{
"src": "images/icone-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "images/icone-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
+2
View File
@@ -0,0 +1,2 @@
User-agent: *
Disallow: /
+1173
View File
File diff suppressed because it is too large Load Diff
+68
View File
@@ -0,0 +1,68 @@
const CACHE_NAME = 'hydrhacked-v4.8';
const STATIC_ASSETS = [
'/style.css',
'/app.auth.js',
'/app.js',
'/manifest.json',
'/images/icone-192.png',
'/images/icone-512.png',
'/images/logo_transparent.png',
'/lucide.min.js'
];
// 1. INSTALLATION
self.addEventListener('install', event => {
self.skipWaiting();
event.waitUntil(
caches.open(CACHE_NAME).then(cache => {
console.log('[SW] Mise en cache des fichiers statiques');
return cache.addAll(STATIC_ASSETS);
})
);
});
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cache => {
if (cache !== CACHE_NAME) {
console.log('[SW] Suppression ancien cache:', cache);
return caches.delete(cache);
}
})
);
})
);
return self.clients.claim();
});
self.addEventListener('fetch', event => {
const url = new URL(event.request.url);
const isStaticAsset = url.pathname.endsWith('.css') ||
url.pathname.endsWith('.js') ||
url.pathname.endsWith('.png') ||
url.pathname.endsWith('.json');
if (!isStaticAsset || event.request.method !== 'GET') {
return;
}
// Stratégie Network-First : on tente le réseau, et on met à jour le cache. Sinon, fallback sur le cache.
event.respondWith(
fetch(event.request)
.then(response => {
if (response && response.status === 200) {
const responseCopy = response.clone();
caches.open(CACHE_NAME).then(cache => {
cache.put(event.request, responseCopy);
});
}
return response;
})
.catch(() => {
return caches.match(event.request);
})
);
});