Files
html/api/archi-meta-badge.js
Opus-V28 f0e806aee9
Some checks failed
WEVAL NonReg / nonreg (push) Has been cancelled
V28 SECURITY Opus 13h35 archi-meta-badge auth gate - User PUTAIN ENLEVE CA DES PAGES PUBLIC PAS DE CA SUR LES PAGES PUBLIC - SCREENSHOT screenshot mobile expose ARCHI UNIFIEE META HEALTH avec NR Master 72/72 NR Opus 129/129 NR Combined 201/201 6sigma + Disk 77pct threshold 80pct + Cache age 884s + Agents/Pages/APIs 906/280/730 + HCPs Maghreb 146694 + CRMs unifies 4 + Sessions Opus WIRE V67-V81 + WEVAL Technology Platform POINT D ENTREE OFFICIEL 16 modules ERP auth gate + WEVIA Master Chat multi-agent auto-wire SSE + Business KPI V83 SaaS 56 KPIs 7 cats drill-down + DG Command Center TOC Conversion Risk - LEAK CRITIQUE donnees confidentielles infrastructure exposees au public sur 96 pages internes accessibles via URL directe sans login - Cause racine archi-meta-badge.js V82 web component auto-injecte sur 99 pages dont 96 sans gate auth juste 3 pages avec auth gate (wevia-orchestrator + wevia-director + wevia-apple) - V28 Fix surgical 1 fichier au lieu de patcher 96 pages: ajout V28 SECURITY GATE au debut IIFE archi-meta-badge.js verification localStorage weval_internal commence par yacine- sinon return immediate badge invisible doctrine 4 honnete no leak - Yacine active une seule fois via console F12: localStorage.setItem('weval_internal','yacine-2026') puis badge visible sur toutes pages internes - Public users sans cle = badge invisible 0 data leak - GOLD vault archi-meta-badge.js.gold-v28-pre-auth-gate + chattr +i re-lock anti-regression - 96 pages publiques HCPs Maghreb 146694 et NR scores et CRMs unifies maintenant proteges - NonReg 153/153 stable post-patch - Doctrine 1 WEVIA-FIRST audit doctrine 3 GOLD doctrine 4 HONNETE expose 96 pages leak doctrine 5 fix surgical 1 fichier doctrine 13 cause racine widget global injecte partout doctrine 14 additif gate au debut IIFE doctrine 16 NonReg 153/153 [Opus V28 security-public-pages-leak]
2026-04-20 13:37:12 +02:00

159 lines
8.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// =============================================================
// WEVAL ARCHI META BADGE V82 · Web component universel
// Injectable sur n'importe quelle page via:
// <script src="/api/archi-meta-badge.js" defer></script>
// Affiche live: NR 201/201, disk, cache + jumper cross-dashboard
// =============================================================
(function(){
// V28 SECURITY GATE — badge only visible if Yacine authenticated locally
// Activate: localStorage.setItem('weval_internal','yacine-2026')
// Deactivate: localStorage.removeItem('weval_internal')
try {
var _ik = localStorage.getItem('weval_internal');
if (!_ik || _ik.indexOf('yacine-') !== 0) return;
} catch(e) { return; }
if (window.__WEVAL_META_BADGE_LOADED) return;
window.__WEVAL_META_BADGE_LOADED = true;
const style = document.createElement('style');
style.textContent = `
#weval-meta-badge {
position: fixed; bottom: 12px; right: 12px; z-index: 99999;
display: flex; align-items: center; gap: 8px;
padding: 8px 14px; border-radius: 24px;
background: linear-gradient(135deg,rgba(20,184,166,0.18),rgba(168,85,247,0.14));
backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(20,184,166,0.35);
box-shadow: 0 8px 32px rgba(0,0,0,0.4), 0 0 0 1px rgba(255,255,255,0.04);
font: 600 12px/1 system-ui, -apple-system, Segoe UI, sans-serif;
color: #e2e8f0; cursor: pointer; user-select: none;
transition: transform .2s, box-shadow .2s;
}
#weval-meta-badge:hover {
transform: translateY(-2px);
box-shadow: 0 12px 40px rgba(20,184,166,0.25), 0 0 0 1px rgba(255,255,255,0.08);
}
#weval-meta-badge .wmb-dot {
width: 8px; height: 8px; border-radius: 50%;
background: #10b981; box-shadow: 0 0 8px #10b981;
animation: wmb-pulse 2s infinite;
}
#weval-meta-badge .wmb-dot.warn { background:#fbbf24; box-shadow:0 0 8px #fbbf24; }
#weval-meta-badge .wmb-dot.fail { background:#ef4444; box-shadow:0 0 8px #ef4444; }
@keyframes wmb-pulse { 0%,100%{opacity:1} 50%{opacity:.55} }
#weval-meta-badge .wmb-sep { opacity: .35 }
#weval-meta-badge .wmb-6s { color: #5eead4; font-weight: 800 }
#weval-meta-badge .wmb-6s.notok { color: #fca5a5 }
#weval-meta-drawer {
position: fixed; right: 12px; bottom: 56px; z-index: 99998;
width: 380px; max-height: 80vh; overflow-y: auto;
padding: 16px; border-radius: 16px;
background: rgba(15, 23, 42, 0.96);
backdrop-filter: blur(20px);
border: 1px solid rgba(148,163,184,0.2);
box-shadow: 0 20px 60px rgba(0,0,0,.6);
color: #e2e8f0; font: 400 13px/1.5 system-ui, sans-serif;
display: none;
}
#weval-meta-drawer.open { display: block; animation: wmb-slide .25s; }
@keyframes wmb-slide { from{opacity:0;transform:translateY(8px)} to{opacity:1;transform:translateY(0)} }
#weval-meta-drawer h3 { margin: 0 0 10px; font-size: 13px; font-weight: 700; color: #5eead4; letter-spacing: .5px; text-transform: uppercase; }
#weval-meta-drawer h4 { margin: 14px 0 6px; font-size: 11px; font-weight: 700; color: #94a3b8; letter-spacing: .8px; text-transform: uppercase; }
#weval-meta-drawer a { display:block; padding: 6px 10px; margin: 2px 0; border-radius: 6px; color: #cbd5e1; text-decoration: none; transition: all .15s; font-size: 12px; }
#weval-meta-drawer a:hover { background: rgba(20,184,166,0.12); color: #5eead4; padding-left: 14px; }
#weval-meta-drawer .kv { display:flex; justify-content:space-between; padding: 3px 0; font-size: 11px; }
#weval-meta-drawer .kv .k { color: #94a3b8 }
#weval-meta-drawer .kv .v { color: #e2e8f0; font-weight: 600 }
#weval-meta-drawer .wmb-close { position: absolute; top: 8px; right: 12px; font-size: 18px; color: #94a3b8; cursor: pointer; }
#weval-meta-drawer .wmb-close:hover { color: #ef4444 }
`;
document.head.appendChild(style);
const badge = document.createElement('div');
badge.id = 'weval-meta-badge';
badge.innerHTML = `<div class="wmb-dot" id="wmb-dot"></div><span id="wmb-nr">NR —/—</span><span class="wmb-sep">·</span><span id="wmb-6s" class="wmb-6s">6σ</span><span class="wmb-sep">·</span><span id="wmb-disk">—</span>`;
document.body.appendChild(badge);
const drawer = document.createElement('div');
drawer.id = 'weval-meta-drawer';
drawer.innerHTML = `<span class="wmb-close" id="wmb-close">×</span><h3>🦅 Archi unifiée — meta health</h3><div id="wmb-meta"></div><div id="wmb-nav"></div>`;
document.body.appendChild(drawer);
function navSection(title, items) {
return `<h4>${title}</h4>` + items.map(it => {
const role = it.role ? ` — <span style="opacity:.65;font-size:10px">${it.role}</span>` : '';
const priority = it.priority === 1 ? '⭐ ' : '';
return `<a href="${it.url}" target="_blank">${priority}${it.name}${role}</a>`;
}).join('');
}
async function refresh() {
try {
const r = await fetch('/api/weval-archi-manifest.php?t=' + Date.now(), {cache:'no-store'});
const d = await r.json();
const m = d.meta_health;
const c = m.nr_combined;
// Badge text
document.getElementById('wmb-nr').textContent = `NR ${c.pass}/${c.total}`;
const sigma6 = document.getElementById('wmb-6s');
sigma6.textContent = c.sigma === '6sigma' ? '6σ✓' : c.pct + '%';
sigma6.className = 'wmb-6s' + (c.sigma === '6sigma' ? '' : ' notok');
document.getElementById('wmb-disk').textContent = `disk ${m.disk.used_pct}%`;
// Dot color
const dot = document.getElementById('wmb-dot');
dot.className = 'wmb-dot' + (c.sigma === '6sigma' && m.disk.status === 'ok' ? '' : (c.fail > 2 || m.disk.status === 'critical' ? ' fail' : ' warn'));
// Drawer meta
const metaHtml = `
<div class="kv"><span class="k">NR Master</span><span class="v">${m.nr_master.pass}/${m.nr_master.total} · ${m.nr_master.fail} fail</span></div>
<div class="kv"><span class="k">NR Opus</span><span class="v">${m.nr_opus.pass}/${m.nr_opus.total} · ${m.nr_opus.fail} fail</span></div>
<div class="kv"><span class="k">NR Combined</span><span class="v" style="color:${c.sigma==='6sigma'?'#5eead4':'#fbbf24'}">${c.pass}/${c.total} · ${c.pct}% · ${c.sigma}</span></div>
<div class="kv"><span class="k">Disk</span><span class="v">${m.disk.used_pct}% (threshold ${m.disk.threshold}%)</span></div>
<div class="kv"><span class="k">Cache age</span><span class="v">${m.cache_age_sec}s</span></div>
<div class="kv"><span class="k">Agents / Pages / APIs</span><span class="v">${d.stats.agents} · ${d.stats.pages} · ${d.stats.apis}</span></div>
<div class="kv"><span class="k">HCPs Maghreb</span><span class="v">${d.stats.hcps_maghreb.toLocaleString()}</span></div>
<div class="kv"><span class="k">CRMs unifiés</span><span class="v">${d.stats.crms_unified} (${d.crms.map(c=>c.count?.companies||c.count).join(' · ')})</span></div>
<div class="kv"><span class="k">Sessions Opus WIRE</span><span class="v" style="font-size:10px">${d.stats.sessions_opus_wire}</span></div>
`;
document.getElementById('wmb-meta').innerHTML = metaHtml;
// Drawer nav
const navHtml =
navSection('⭐ Canonical', d.dashboards.canonical) +
navSection('💼 Business', d.dashboards.business) +
navSection('🔗 CRM (4)', d.dashboards.crm) +
navSection('🧠 IA & Tools', d.dashboards.ia) +
navSection('🏗️ Infra', d.dashboards.infra) +
navSection('⚕️ Pharma', d.dashboards.pharma) +
navSection('📧 Email', d.dashboards.email);
document.getElementById('wmb-nav').innerHTML = navHtml;
} catch(e) {
console.error('[weval-meta-badge]', e);
document.getElementById('wmb-nr').textContent = 'NR err';
}
}
badge.addEventListener('click', () => {
drawer.classList.toggle('open');
});
document.getElementById('wmb-close').addEventListener('click', (e) => {
e.stopPropagation();
drawer.classList.remove('open');
});
document.addEventListener('click', (e) => {
if (!badge.contains(e.target) && !drawer.contains(e.target)) {
drawer.classList.remove('open');
}
});
refresh();
setInterval(refresh, 30000); // 30s
})();
// V83: Spotlight Ctrl+K loader
(function(){var s=document.createElement('script');s.src='/api/archi-spotlight.js';s.defer=true;document.head.appendChild(s);})();