mirror of
https://github.com/BigBodyCobain/Shadowbroker.git
synced 2026-07-17 09:17:28 +02:00
v0.9.6: InfoNet hashchain, Wormhole gate encryption, mesh reputation, 16 community contributors
Gate messages now propagate via the Infonet hashchain as encrypted blobs — every node syncs them through normal chain sync while only Gate members with MLS keys can decrypt. Added mesh reputation system, peer push workers, voluntary Wormhole opt-in for node participation, fork recovery, killwormhole scripts, obfuscated terminology, and hardened the self-updater to protect encryption keys and chain state during updates. New features: Shodan search, train tracking, Sentinel Hub imagery, 8 new intelligence layers, CCTV expansion to 11,000+ cameras across 6 countries, Mesh Terminal CLI, prediction markets, desktop-shell scaffold, and comprehensive mesh test suite (215 frontend + backend tests passing). Community contributors: @wa1id, @AlborzNazari, @adust09, @Xpirix, @imqdcr, @csysp, @suranyami, @chr0n1x, @johan-martensson, @singularfailure, @smithbh, @OrfeoTerkuci, @deuza, @tm-const, @Elhard1, @ttulttul
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import { API_BASE } from '@/lib/api';
|
||||
|
||||
let hasPrimedSessionHint = false;
|
||||
|
||||
function takeLegacyAdminKey(): string {
|
||||
if (typeof window === 'undefined') return '';
|
||||
const sessionValue = sessionStorage.getItem('sb_admin_key') || '';
|
||||
const legacyValue = localStorage.getItem('sb_admin_key') || '';
|
||||
const candidate = sessionValue || legacyValue;
|
||||
try {
|
||||
sessionStorage.removeItem('sb_admin_key');
|
||||
localStorage.removeItem('sb_admin_key');
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
export async function hasAdminSession(): Promise<boolean> {
|
||||
try {
|
||||
const existing = await fetch(`${API_BASE}/api/admin/session`, { cache: 'no-store' });
|
||||
const existingData = await existing.json().catch(() => ({}));
|
||||
return Boolean(existing.ok && existingData?.hasSession);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export async function primeAdminSession(adminKey?: string): Promise<void> {
|
||||
if (!adminKey) {
|
||||
if (await hasAdminSession()) return;
|
||||
}
|
||||
const candidate = String(adminKey || takeLegacyAdminKey() || '').trim();
|
||||
if (!candidate) throw new Error('admin_session_required');
|
||||
if (hasPrimedSessionHint && (await hasAdminSession())) return;
|
||||
const res = await fetch(`${API_BASE}/api/admin/session`, {
|
||||
method: 'POST',
|
||||
cache: 'no-store',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ adminKey: candidate }),
|
||||
});
|
||||
const data = await res.json().catch(() => ({}));
|
||||
if (!res.ok || data?.ok === false) {
|
||||
throw new Error(data?.detail || data?.message || 'admin_session_failed');
|
||||
}
|
||||
hasPrimedSessionHint = true;
|
||||
}
|
||||
|
||||
export async function clearAdminSession(): Promise<void> {
|
||||
hasPrimedSessionHint = false;
|
||||
if (typeof window !== 'undefined') {
|
||||
try {
|
||||
sessionStorage.removeItem('sb_admin_key');
|
||||
localStorage.removeItem('sb_admin_key');
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
await fetch(`${API_BASE}/api/admin/session`, {
|
||||
method: 'DELETE',
|
||||
cache: 'no-store',
|
||||
}).catch(() => null);
|
||||
}
|
||||
Reference in New Issue
Block a user