mirror of
https://github.com/BigBodyCobain/Shadowbroker.git
synced 2026-06-08 23:33:57 +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,50 @@
|
||||
import type { NativeControlHandlerMap } from '../types';
|
||||
|
||||
export function createSettingsHandlers(): Pick<
|
||||
NativeControlHandlerMap,
|
||||
| 'settings.wormhole.get'
|
||||
| 'settings.wormhole.set'
|
||||
| 'settings.privacy.get'
|
||||
| 'settings.privacy.set'
|
||||
| 'settings.api_keys.get'
|
||||
| 'settings.api_keys.set'
|
||||
| 'settings.news.get'
|
||||
| 'settings.news.set'
|
||||
| 'settings.news.reset'
|
||||
> {
|
||||
return {
|
||||
'settings.wormhole.get': async (_payload, _ctx, exec) => exec('/api/settings/wormhole'),
|
||||
'settings.wormhole.set': async (payload, _ctx, exec) =>
|
||||
exec('/api/settings/wormhole', {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
}),
|
||||
'settings.privacy.get': async (_payload, _ctx, exec) =>
|
||||
exec('/api/settings/privacy-profile'),
|
||||
'settings.privacy.set': async (payload, _ctx, exec) =>
|
||||
exec('/api/settings/privacy-profile', {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
}),
|
||||
'settings.api_keys.get': async (_payload, _ctx, exec) => exec('/api/settings/api-keys'),
|
||||
'settings.api_keys.set': async (payload, _ctx, exec) =>
|
||||
exec('/api/settings/api-keys', {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
}),
|
||||
'settings.news.get': async (_payload, _ctx, exec) => exec('/api/settings/news-feeds'),
|
||||
'settings.news.set': async (payload, _ctx, exec) =>
|
||||
exec('/api/settings/news-feeds', {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
}),
|
||||
'settings.news.reset': async (_payload, _ctx, exec) =>
|
||||
exec('/api/settings/news-feeds/reset', {
|
||||
method: 'POST',
|
||||
}),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import type { NativeControlHandlerMap } from '../types';
|
||||
|
||||
export function createUpdateHandlers(): Pick<NativeControlHandlerMap, 'system.update'> {
|
||||
return {
|
||||
'system.update': async (_payload, _ctx, exec) =>
|
||||
exec('/api/system/update', {
|
||||
method: 'POST',
|
||||
}),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
import type { NativeControlHandlerMap } from '../types';
|
||||
|
||||
export function createWormholeHandlers(): Pick<
|
||||
NativeControlHandlerMap,
|
||||
| 'wormhole.status'
|
||||
| 'wormhole.connect'
|
||||
| 'wormhole.disconnect'
|
||||
| 'wormhole.restart'
|
||||
| 'wormhole.gate.enter'
|
||||
| 'wormhole.gate.leave'
|
||||
| 'wormhole.gate.proof'
|
||||
| 'wormhole.gate.personas.get'
|
||||
| 'wormhole.gate.persona.create'
|
||||
| 'wormhole.gate.persona.activate'
|
||||
| 'wormhole.gate.persona.clear'
|
||||
| 'wormhole.gate.key.get'
|
||||
| 'wormhole.gate.key.rotate'
|
||||
| 'wormhole.gate.message.compose'
|
||||
| 'wormhole.gate.message.decrypt'
|
||||
| 'wormhole.gate.message.post'
|
||||
| 'wormhole.gate.messages.decrypt'
|
||||
> {
|
||||
return {
|
||||
'wormhole.status': async (_payload, _ctx, exec) => exec('/api/wormhole/status'),
|
||||
'wormhole.connect': async (_payload, _ctx, exec) =>
|
||||
exec('/api/wormhole/connect', { method: 'POST' }),
|
||||
'wormhole.disconnect': async (_payload, _ctx, exec) =>
|
||||
exec('/api/wormhole/disconnect', { method: 'POST' }),
|
||||
'wormhole.restart': async (_payload, _ctx, exec) =>
|
||||
exec('/api/wormhole/restart', { method: 'POST' }),
|
||||
'wormhole.gate.personas.get': async (payload, _ctx, exec) =>
|
||||
exec(`/api/wormhole/gate/${encodeURIComponent(String(payload?.gate_id || ''))}/personas`),
|
||||
'wormhole.gate.persona.create': async (payload, _ctx, exec) =>
|
||||
exec('/api/wormhole/gate/persona/create', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
}),
|
||||
'wormhole.gate.persona.activate': async (payload, _ctx, exec) =>
|
||||
exec('/api/wormhole/gate/persona/activate', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
}),
|
||||
'wormhole.gate.persona.clear': async (payload, _ctx, exec) =>
|
||||
exec('/api/wormhole/gate/persona/clear', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
}),
|
||||
'wormhole.gate.key.get': async (payload, _ctx, exec) =>
|
||||
exec(`/api/wormhole/gate/${encodeURIComponent(String(payload?.gate_id || ''))}/key`),
|
||||
'wormhole.gate.key.rotate': async (payload, _ctx, exec) =>
|
||||
exec('/api/wormhole/gate/key/rotate', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
}),
|
||||
'wormhole.gate.message.compose': async (payload, _ctx, exec) =>
|
||||
exec('/api/wormhole/gate/message/compose', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
}),
|
||||
'wormhole.gate.message.decrypt': async (payload, _ctx, exec) =>
|
||||
exec('/api/wormhole/gate/message/decrypt', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
}),
|
||||
'wormhole.gate.enter': async (payload, _ctx, exec) =>
|
||||
exec('/api/wormhole/gate/enter', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
}),
|
||||
'wormhole.gate.leave': async (payload, _ctx, exec) =>
|
||||
exec('/api/wormhole/gate/leave', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
}),
|
||||
'wormhole.gate.proof': async (payload, _ctx, exec) =>
|
||||
exec('/api/wormhole/gate/proof', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
}),
|
||||
'wormhole.gate.message.post': async (payload, _ctx, exec) =>
|
||||
exec('/api/wormhole/gate/message/post', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
}),
|
||||
'wormhole.gate.messages.decrypt': async (payload, _ctx, exec) =>
|
||||
exec('/api/wormhole/gate/messages/decrypt', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
}),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export * from './nativeControlRouter';
|
||||
export * from './runtimeBridge';
|
||||
export * from './nativeControlAudit';
|
||||
export * from './types';
|
||||
@@ -0,0 +1,60 @@
|
||||
import type {
|
||||
DesktopControlAuditOutcome,
|
||||
DesktopControlAuditRecord,
|
||||
DesktopControlAuditReport,
|
||||
} from '../../frontend/src/lib/desktopControlContract';
|
||||
import type { NativeControlAuditEvent, NativeControlAuditTrail } from './types';
|
||||
|
||||
const DEFAULT_LIMIT = 100;
|
||||
|
||||
function incrementOutcome(
|
||||
counts: Partial<Record<DesktopControlAuditOutcome, number>>,
|
||||
outcome: DesktopControlAuditOutcome,
|
||||
) {
|
||||
counts[outcome] = (counts[outcome] || 0) + 1;
|
||||
}
|
||||
|
||||
export function createNativeControlAuditTrail(maxEntries: number = DEFAULT_LIMIT): NativeControlAuditTrail {
|
||||
const entries: DesktopControlAuditRecord[] = [];
|
||||
let totalRecorded = 0;
|
||||
|
||||
return {
|
||||
record(event: NativeControlAuditEvent) {
|
||||
totalRecorded += 1;
|
||||
entries.push({
|
||||
...event,
|
||||
recordedAt: Date.now(),
|
||||
});
|
||||
if (entries.length > maxEntries) {
|
||||
entries.splice(0, entries.length - maxEntries);
|
||||
}
|
||||
},
|
||||
snapshot(limit: number = 25): DesktopControlAuditReport {
|
||||
const recent = entries.slice(-Math.max(1, limit)).reverse();
|
||||
const byOutcome: Partial<Record<DesktopControlAuditOutcome, number>> = {};
|
||||
let lastProfileMismatch: DesktopControlAuditRecord | undefined;
|
||||
let lastDenied: DesktopControlAuditRecord | undefined;
|
||||
for (const entry of entries) {
|
||||
incrementOutcome(byOutcome, entry.outcome);
|
||||
if (entry.outcome === 'profile_warn' || entry.outcome === 'profile_denied') {
|
||||
lastProfileMismatch = entry;
|
||||
}
|
||||
if (entry.outcome === 'profile_denied' || entry.outcome === 'capability_denied') {
|
||||
lastDenied = entry;
|
||||
}
|
||||
}
|
||||
return {
|
||||
totalEvents: entries.length,
|
||||
totalRecorded,
|
||||
recent,
|
||||
byOutcome,
|
||||
lastProfileMismatch,
|
||||
lastDenied,
|
||||
};
|
||||
},
|
||||
clear() {
|
||||
totalRecorded = 0;
|
||||
entries.splice(0, entries.length);
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
import type {
|
||||
DesktopControlCommand,
|
||||
DesktopControlPayloadMap,
|
||||
} from '../../frontend/src/lib/desktopControlContract';
|
||||
import {
|
||||
controlCommandCapability as resolveCommandCapability,
|
||||
extractGateTargetRef,
|
||||
sessionProfileCapabilities as capabilitiesForProfile,
|
||||
} from '../../frontend/src/lib/desktopControlContract';
|
||||
import { createSettingsHandlers } from './handlers/settingsHandlers';
|
||||
import { createUpdateHandlers } from './handlers/updateHandlers';
|
||||
import { createWormholeHandlers } from './handlers/wormholeHandlers';
|
||||
import type {
|
||||
NativeControlExecutor,
|
||||
NativeControlHandlerContext,
|
||||
NativeControlHandlerMap,
|
||||
NativeControlInvokeMeta,
|
||||
} from './types';
|
||||
|
||||
function createHandlerMap(): NativeControlHandlerMap {
|
||||
return {
|
||||
...createWormholeHandlers(),
|
||||
...createSettingsHandlers(),
|
||||
...createUpdateHandlers(),
|
||||
};
|
||||
}
|
||||
|
||||
export function createNativeControlRouter(
|
||||
ctx: NativeControlHandlerContext,
|
||||
exec: NativeControlExecutor,
|
||||
) {
|
||||
const handlers = createHandlerMap();
|
||||
return {
|
||||
async invoke<C extends DesktopControlCommand>(
|
||||
command: C,
|
||||
payload: DesktopControlPayloadMap[C],
|
||||
meta?: NativeControlInvokeMeta,
|
||||
): Promise<unknown> {
|
||||
const handler = handlers[command];
|
||||
if (!handler) {
|
||||
throw new Error(`native_control_handler_missing:${command}`);
|
||||
}
|
||||
const expectedCapability = resolveCommandCapability(command);
|
||||
const profile = ctx.sessionProfile;
|
||||
const profileCapabilities = profile ? capabilitiesForProfile(profile) : [];
|
||||
const profileAllows =
|
||||
!profile || profileCapabilities.length === 0 || profileCapabilities.includes(expectedCapability);
|
||||
const profileEnforced = Boolean((ctx.enforceSessionProfile || meta?.enforceProfileHint) && profile);
|
||||
const allowedCapabilitiesConfigured =
|
||||
Array.isArray(ctx.allowedCapabilities) && ctx.allowedCapabilities.length > 0;
|
||||
const capabilityDenied =
|
||||
allowedCapabilitiesConfigured && !ctx.allowedCapabilities!.includes(expectedCapability);
|
||||
const targetRef = extractGateTargetRef(command, payload);
|
||||
const auditBase = {
|
||||
command,
|
||||
expectedCapability,
|
||||
declaredCapability: meta?.capability,
|
||||
...(targetRef ? { targetRef } : {}),
|
||||
sessionProfile: profile,
|
||||
sessionProfileHint: meta?.sessionProfileHint,
|
||||
enforceProfileHint: meta?.enforceProfileHint,
|
||||
profileAllows,
|
||||
allowedCapabilitiesConfigured,
|
||||
enforced: profileEnforced,
|
||||
} as const;
|
||||
if (meta?.capability && meta.capability !== expectedCapability) {
|
||||
ctx.auditControlUse?.({
|
||||
...auditBase,
|
||||
outcome: 'capability_mismatch',
|
||||
});
|
||||
throw new Error(
|
||||
`native_control_capability_mismatch:${meta.capability}:${expectedCapability}`,
|
||||
);
|
||||
}
|
||||
if (capabilityDenied) {
|
||||
ctx.auditControlUse?.({
|
||||
...auditBase,
|
||||
outcome: 'capability_denied',
|
||||
});
|
||||
throw new Error(`native_control_capability_denied:${expectedCapability}`);
|
||||
}
|
||||
if (!profileAllows) {
|
||||
const profileMessage = `native_control_profile_mismatch:${profile}:${expectedCapability}`;
|
||||
ctx.auditControlUse?.({
|
||||
...auditBase,
|
||||
outcome: profileEnforced ? 'profile_denied' : 'profile_warn',
|
||||
});
|
||||
if (profileEnforced) {
|
||||
throw new Error(profileMessage);
|
||||
}
|
||||
console.warn(profileMessage, {
|
||||
command,
|
||||
sessionProfileHint: meta?.sessionProfileHint,
|
||||
});
|
||||
}
|
||||
if (profileAllows) {
|
||||
ctx.auditControlUse?.({
|
||||
...auditBase,
|
||||
outcome: 'allowed',
|
||||
});
|
||||
}
|
||||
return handler(payload, ctx, exec);
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
import type {
|
||||
DesktopControlCommand,
|
||||
DesktopControlPayloadMap,
|
||||
LocalControlInvokeMeta,
|
||||
} from '../../frontend/src/lib/desktopControlContract';
|
||||
import { createNativeControlAuditTrail } from './nativeControlAudit';
|
||||
import { createNativeControlRouter } from './nativeControlRouter';
|
||||
import type {
|
||||
NativeControlAuditEvent,
|
||||
NativeControlExecutor,
|
||||
NativeControlHandlerContext,
|
||||
} from './types';
|
||||
|
||||
async function defaultExecutor<T = unknown>(baseUrl: string, path: string, init: RequestInit = {}): Promise<T> {
|
||||
const res = await fetch(`${baseUrl}${path}`, init);
|
||||
const data = await res.json().catch(() => ({}));
|
||||
if (!res.ok || data?.ok === false) {
|
||||
throw new Error(data?.detail || data?.message || 'native_control_request_failed');
|
||||
}
|
||||
return data as T;
|
||||
}
|
||||
|
||||
export function createRuntimeBridge(ctx: NativeControlHandlerContext) {
|
||||
const auditTrail = ctx.auditTrail || createNativeControlAuditTrail();
|
||||
const auditControlUse = (event: NativeControlAuditEvent) => {
|
||||
auditTrail.record(event);
|
||||
ctx.auditControlUse?.(event);
|
||||
};
|
||||
const exec: NativeControlExecutor = <T = unknown>(path: string, init: RequestInit = {}) => {
|
||||
const headers = new Headers(init.headers);
|
||||
if (ctx.adminKey && !headers.has('X-Admin-Key')) {
|
||||
headers.set('X-Admin-Key', ctx.adminKey);
|
||||
}
|
||||
return defaultExecutor<T>(ctx.backendBaseUrl, path, { ...init, headers });
|
||||
};
|
||||
function invocationContext(meta?: LocalControlInvokeMeta): NativeControlHandlerContext {
|
||||
const baseCtx: NativeControlHandlerContext = {
|
||||
...ctx,
|
||||
auditTrail,
|
||||
auditControlUse,
|
||||
};
|
||||
if (ctx.sessionProfile || !meta?.sessionProfileHint) {
|
||||
return baseCtx;
|
||||
}
|
||||
return {
|
||||
...baseCtx,
|
||||
sessionProfile: meta.sessionProfileHint,
|
||||
};
|
||||
}
|
||||
return {
|
||||
invokeLocalControl<C extends DesktopControlCommand>(
|
||||
command: C,
|
||||
payload: DesktopControlPayloadMap[C],
|
||||
meta?: LocalControlInvokeMeta,
|
||||
) {
|
||||
return createNativeControlRouter(invocationContext(meta), exec).invoke(command, payload, meta);
|
||||
},
|
||||
getNativeControlAuditReport(limit?: number) {
|
||||
return auditTrail.snapshot(limit);
|
||||
},
|
||||
clearNativeControlAuditReport() {
|
||||
auditTrail.clear();
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import type {
|
||||
DesktopControlAuditEvent,
|
||||
DesktopControlAuditReport,
|
||||
DesktopControlCapability,
|
||||
DesktopControlCommand,
|
||||
DesktopControlPayloadMap,
|
||||
DesktopControlSessionProfile,
|
||||
LocalControlInvokeMeta,
|
||||
} from '../../frontend/src/lib/desktopControlContract';
|
||||
|
||||
export type NativeControlHandlerContext = {
|
||||
backendBaseUrl: string;
|
||||
wormholeBaseUrl: string;
|
||||
adminKey?: string;
|
||||
allowedCapabilities?: DesktopControlCapability[];
|
||||
sessionProfile?: DesktopControlSessionProfile;
|
||||
enforceSessionProfile?: boolean;
|
||||
auditControlUse?: (event: NativeControlAuditEvent) => void;
|
||||
auditTrail?: NativeControlAuditTrail;
|
||||
};
|
||||
|
||||
export type NativeControlExecutor = <T = unknown>(
|
||||
path: string,
|
||||
init?: RequestInit,
|
||||
) => Promise<T>;
|
||||
|
||||
export type NativeControlHandlerMap = {
|
||||
[K in DesktopControlCommand]: (
|
||||
payload: DesktopControlPayloadMap[K],
|
||||
ctx: NativeControlHandlerContext,
|
||||
exec: NativeControlExecutor,
|
||||
) => Promise<unknown>;
|
||||
};
|
||||
|
||||
export type NativeControlInvokeMeta = LocalControlInvokeMeta;
|
||||
|
||||
export type NativeControlAuditEvent = DesktopControlAuditEvent;
|
||||
|
||||
export type NativeControlAuditTrail = {
|
||||
record: (event: NativeControlAuditEvent) => void;
|
||||
snapshot: (limit?: number) => DesktopControlAuditReport;
|
||||
clear: () => void;
|
||||
};
|
||||
Reference in New Issue
Block a user