/** * Connection token utilities for RemoteIngress edge connections. * A token is a base64url-encoded compact JSON object carrying hub connection details. */ export interface IConnectionTokenData { hubHost: string; hubPort: number; edgeId: string; secret: string; } /** * Encode connection data into a single opaque token string (base64url). */ export function encodeConnectionToken(data: IConnectionTokenData): string { const compact = JSON.stringify({ h: data.hubHost, p: data.hubPort, e: data.edgeId, s: data.secret, }); // base64url: standard base64 with + → -, / → _, trailing = stripped return Buffer.from(compact, 'utf-8') .toString('base64') .replace(/\+/g, '-') .replace(/\//g, '_') .replace(/=+$/, ''); } /** * Decode a connection token back into its constituent fields. * Throws on malformed or incomplete tokens. */ export function decodeConnectionToken(token: string): IConnectionTokenData { let parsed: { h?: unknown; p?: unknown; e?: unknown; s?: unknown }; try { // Restore standard base64 from base64url let base64 = token.replace(/-/g, '+').replace(/_/g, '/'); // Re-add padding const remainder = base64.length % 4; if (remainder === 2) base64 += '=='; else if (remainder === 3) base64 += '='; const json = Buffer.from(base64, 'base64').toString('utf-8'); parsed = JSON.parse(json); } catch { throw new Error('Invalid connection token'); } if ( typeof parsed.h !== 'string' || typeof parsed.p !== 'number' || typeof parsed.e !== 'string' || typeof parsed.s !== 'string' ) { throw new Error('Invalid connection token: missing required fields'); } return { hubHost: parsed.h, hubPort: parsed.p, edgeId: parsed.e, secret: parsed.s, }; }