51 lines
2.1 KiB
TypeScript
51 lines
2.1 KiB
TypeScript
import {CONTROL_EVENTS} from '../types.ts';
|
|
import type {ControlTransport, ForwardSessionStatus, RelayLogger} from '../types.ts';
|
|
import type {RelaySessionStore} from './session_store.ts';
|
|
import {error_ack, fail, success} from '../utils/relay_validation.ts';
|
|
|
|
export function install_control_routes(
|
|
transport: ControlTransport,
|
|
store: RelaySessionStore,
|
|
logger?: RelayLogger,
|
|
): () => void {
|
|
let active = true;
|
|
const handlers = {
|
|
forward_open_session: (value: unknown) => store.open(value),
|
|
forward_authorize_grant: (value: unknown) => store.authorize(value),
|
|
forward_revoke_session: (value: unknown) => store.revoke_session(value),
|
|
forward_revoke_grant: (value: unknown) => store.revoke_grant(value),
|
|
};
|
|
const listeners = new Map<string, (...args: unknown[]) => void>();
|
|
for (const event of CONTROL_EVENTS) {
|
|
const listener = (value: unknown, callback: unknown) => {
|
|
if (!active || typeof callback !== 'function') return;
|
|
let ack;
|
|
try {
|
|
if (!store.control_available) fail('RELAY_UNAVAILABLE', 'Control channel is disconnected', true);
|
|
ack = success(handlers[event](value));
|
|
} catch (error) { ack = error_ack(error); }
|
|
try { callback(ack); }
|
|
catch { logger?.log('Relay control ACK delivery failed'); }
|
|
};
|
|
transport.on(event, listener);
|
|
listeners.set(event, listener);
|
|
}
|
|
const disconnected = () => {
|
|
store.set_control_available(false);
|
|
logger?.log('Relay control channel disconnected');
|
|
};
|
|
transport.on('disconnect', disconnected);
|
|
store.set_control_available(true);
|
|
return () => {
|
|
if (!active) return;
|
|
active = false;
|
|
for (const [event, listener] of listeners) transport.off(event, listener);
|
|
transport.off('disconnect', disconnected);
|
|
store.set_control_available(false);
|
|
};
|
|
}
|
|
|
|
export function report_status(transport: ControlTransport | undefined, status: ForwardSessionStatus): void {
|
|
transport?.emit('forward_session_status', status);
|
|
}
|