import * as plugins from './plugins.js'; import { isCodexCreationToken, isCodexThreadId } from './functions.codexidentity.js'; export interface IControllerCodexOrigin { version: 2; profileId: string; rawThreadId: string; remoteDirectory: string; } export const codexOriginsEqual = (leftArg: IControllerCodexOrigin | undefined, rightArg: IControllerCodexOrigin | undefined): boolean => ( leftArg === undefined || rightArg === undefined ? leftArg === rightArg : leftArg.version === rightArg.version && leftArg.profileId === rightArg.profileId && leftArg.rawThreadId === rightArg.rawThreadId && leftArg.remoteDirectory === rightArg.remoteDirectory ); export interface IControllerCodexProfileDocument { id: string; issuerId: string; profileName: string; mode: 'local' | 'remote'; serverUrl?: string; credentialCiphertext?: string; credentialRevision: number; state: 'active' | 'retired'; createdAt: Date; updatedAt: Date; updateId: string; } export interface IControllerCodexMappingDocument { id: string; issuerId: string; projectId: string; profileId: string; remoteDirectory: string; createdAt: Date; updatedAt: Date; updateId: string; } const record = (valueArg: unknown): valueArg is Record => ( typeof valueArg === 'object' && valueArg !== null && !Array.isArray(valueArg) && [Object.prototype, null].includes(Object.getPrototypeOf(valueArg)) ); const keys = (valueArg: Record, requiredArg: string[], optionalArg: string[] = []): boolean => ( requiredArg.every((key) => Object.hasOwn(valueArg, key)) && Object.keys(valueArg).every((key) => requiredArg.includes(key) || optionalArg.includes(key)) ); const date = (valueArg: unknown): valueArg is Date => ( valueArg instanceof Date && Number.isSafeInteger(valueArg.getTime()) && valueArg.getTime() >= 0 ); export const isCodexRemoteDirectory = (valueArg: unknown): valueArg is string => ( typeof valueArg === 'string' && valueArg.length > 0 && Buffer.byteLength(valueArg, 'utf8') <= 4096 && !/[\u0000-\u001f\u007f]/.test(valueArg) && (/^\//.test(valueArg) || /^[A-Za-z]:[\\/]/.test(valueArg)) && !valueArg.split(/[\\/]/).some((part) => part === '.' || part === '..') ); export const validateCodexServerUrl = (valueArg: unknown): string => { if (typeof valueArg !== 'string' || valueArg.length > 2048 || /[\u0000-\u0020\u007f]/.test(valueArg)) { throw new Error('A Codex connection requires a valid server URL.'); } let url: URL; try { url = new URL(valueArg); } catch { throw new Error('A Codex connection requires a valid server URL.'); } const loopback = ['localhost', '127.0.0.1', '[::1]'].includes(url.hostname); if ((url.protocol !== 'wss:' && !(url.protocol === 'ws:' && loopback)) || url.username || url.password || url.hash || url.search) { throw new Error('Use a wss:// Codex URL, or ws:// on loopback, without embedded credentials, query or fragment.'); } return url.href; }; export const codexMappingDocumentId = (issuerIdArg: string, projectIdArg: string): string => { if (!isCodexCreationToken(issuerIdArg, 32) || !isCodexCreationToken(projectIdArg, 16)) throw new Error('Invalid Codex project mapping identity.'); return plugins.crypto.createHash('sha256').update(JSON.stringify(['codex-mapping-v1', issuerIdArg, projectIdArg])).digest('base64url'); }; export const assertCodexOrigin: (valueArg: unknown) => asserts valueArg is IControllerCodexOrigin = (valueArg) => { if (!record(valueArg) || !keys(valueArg, ['version', 'profileId', 'rawThreadId', 'remoteDirectory']) || valueArg.version !== 2 || !isCodexCreationToken(valueArg.profileId, 32) || !isCodexThreadId(valueArg.rawThreadId) || !isCodexRemoteDirectory(valueArg.remoteDirectory)) { throw new Error('Invalid Codex conversation origin.'); } }; export const assertCodexProfileDocument: (valueArg: unknown) => asserts valueArg is IControllerCodexProfileDocument = (valueArg) => { if (!record(valueArg) || !keys(valueArg, ['id', 'issuerId', 'profileName', 'mode', 'credentialRevision', 'state', 'createdAt', 'updatedAt', 'updateId'], ['serverUrl', 'credentialCiphertext']) || !isCodexCreationToken(valueArg.id, 32) || !isCodexCreationToken(valueArg.issuerId, 32) || !isCodexCreationToken(valueArg.updateId, 32) || typeof valueArg.profileName !== 'string' || valueArg.profileName.trim() !== valueArg.profileName || valueArg.profileName.length < 1 || valueArg.profileName.length > 128 || /[\u0000-\u001f\u007f]/.test(valueArg.profileName) || !['local', 'remote'].includes(String(valueArg.mode)) || !['active', 'retired'].includes(String(valueArg.state)) || !Number.isSafeInteger(valueArg.credentialRevision) || Number(valueArg.credentialRevision) < 0 || !date(valueArg.createdAt) || !date(valueArg.updatedAt) || valueArg.updatedAt < valueArg.createdAt) { throw new Error('Invalid Codex connection profile.'); } if (valueArg.mode === 'remote') { if (validateCodexServerUrl(valueArg.serverUrl) !== valueArg.serverUrl) throw new Error('Codex server URLs must be canonical.'); } else if (Object.hasOwn(valueArg, 'serverUrl') || Object.hasOwn(valueArg, 'credentialCiphertext')) { throw new Error('Local Codex profiles cannot contain remote credentials.'); } if (Object.hasOwn(valueArg, 'credentialCiphertext')) { const ciphertext = valueArg.credentialCiphertext; if (typeof ciphertext !== 'string' || ciphertext.length < 1 || ciphertext.length > 87382 || !/^[A-Za-z0-9_-]+$/.test(ciphertext) || Buffer.from(ciphertext, 'base64url').toString('base64url') !== ciphertext) { throw new Error('Invalid sealed Codex credential.'); } } }; export const assertCodexMappingDocument: (valueArg: unknown) => asserts valueArg is IControllerCodexMappingDocument = (valueArg) => { if (!record(valueArg) || !keys(valueArg, ['id', 'issuerId', 'projectId', 'profileId', 'remoteDirectory', 'createdAt', 'updatedAt', 'updateId']) || !isCodexCreationToken(valueArg.issuerId, 32) || !isCodexCreationToken(valueArg.projectId, 16) || valueArg.id !== codexMappingDocumentId(valueArg.issuerId, valueArg.projectId) || !isCodexCreationToken(valueArg.profileId, 32) || !isCodexCreationToken(valueArg.updateId, 32) || !isCodexRemoteDirectory(valueArg.remoteDirectory) || !date(valueArg.createdAt) || !date(valueArg.updatedAt) || valueArg.updatedAt < valueArg.createdAt) { throw new Error('Invalid Codex project mapping.'); } }; @plugins.smartdata.compoundIndex({ name: 'controller_codex_profiles', key: { issuerId: 1, state: 1, id: 1 } }) @plugins.smartdata.managed({ collectionName: 'agl_controller_codex_profiles' }) @plugins.smartdata.exactPersistence({ assertDocument: assertCodexProfileDocument }) export class ControllerCodexProfileModel extends plugins.smartdata.SmartDataDbDoc { declare static exact: plugins.smartdata.TExact; @plugins.smartdata.unI() public id!: string; @plugins.smartdata.svDb() public issuerId!: string; @plugins.smartdata.svDb() public profileName!: string; @plugins.smartdata.svDb() public mode!: 'local' | 'remote'; @plugins.smartdata.svDb() public serverUrl?: string; @plugins.smartdata.svDb() public credentialCiphertext?: string; @plugins.smartdata.svDb() public credentialRevision!: number; @plugins.smartdata.svDb() public state!: 'active' | 'retired'; @plugins.smartdata.svDb() public createdAt!: Date; @plugins.smartdata.svDb() public updatedAt!: Date; @plugins.smartdata.svDb() public updateId!: string; } @plugins.smartdata.compoundIndex({ name: 'controller_codex_mapping_profiles', key: { issuerId: 1, profileId: 1, id: 1 } }) @plugins.smartdata.managed({ collectionName: 'agl_controller_codex_mappings' }) @plugins.smartdata.exactPersistence({ assertDocument: assertCodexMappingDocument }) export class ControllerCodexMappingModel extends plugins.smartdata.SmartDataDbDoc { declare static exact: plugins.smartdata.TExact; @plugins.smartdata.unI() public id!: string; @plugins.smartdata.svDb() public issuerId!: string; @plugins.smartdata.svDb() public projectId!: string; @plugins.smartdata.svDb() public profileId!: string; @plugins.smartdata.svDb() public remoteDirectory!: string; @plugins.smartdata.svDb() public createdAt!: Date; @plugins.smartdata.svDb() public updatedAt!: Date; @plugins.smartdata.svDb() public updateId!: string; }