@openmdm/core 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/index.d.ts +90 -0
- package/dist/index.js +1368 -0
- package/dist/index.js.map +1 -0
- package/dist/schema.d.ts +78 -0
- package/dist/schema.js +415 -0
- package/dist/schema.js.map +1 -0
- package/dist/types.d.ts +899 -0
- package/dist/types.js +49 -0
- package/dist/types.js.map +1 -0
- package/package.json +67 -0
- package/src/index.ts +1145 -0
- package/src/schema.ts +533 -0
- package/src/types.ts +1161 -0
- package/src/webhooks.ts +314 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/webhooks.ts","../src/schema.ts","../src/index.ts"],"names":["randomUUID","policy","createHmac"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * OpenMDM Core Types\n *\n * These types define the core data structures for the MDM system.\n * Designed to be database-agnostic and framework-agnostic.\n */\n\n// ============================================\n// Device Types\n// ============================================\n\nexport type DeviceStatus = 'pending' | 'enrolled' | 'unenrolled' | 'blocked';\n\nexport interface Device {\n id: string;\n externalId?: string | null;\n enrollmentId: string;\n status: DeviceStatus;\n\n // Device Info\n model?: string | null;\n manufacturer?: string | null;\n osVersion?: string | null;\n serialNumber?: string | null;\n imei?: string | null;\n macAddress?: string | null;\n androidId?: string | null;\n\n // MDM State\n policyId?: string | null;\n lastHeartbeat?: Date | null;\n lastSync?: Date | null;\n\n // Telemetry\n batteryLevel?: number | null;\n storageUsed?: number | null;\n storageTotal?: number | null;\n location?: DeviceLocation | null;\n installedApps?: InstalledApp[] | null;\n\n // Metadata\n tags?: Record<string, string> | null;\n metadata?: Record<string, unknown> | null;\n\n // Timestamps\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface DeviceLocation {\n latitude: number;\n longitude: number;\n accuracy?: number;\n timestamp: Date;\n}\n\nexport interface InstalledApp {\n packageName: string;\n version: string;\n versionCode?: number;\n installedAt?: Date;\n}\n\nexport interface CreateDeviceInput {\n enrollmentId: string;\n externalId?: string;\n model?: string;\n manufacturer?: string;\n osVersion?: string;\n serialNumber?: string;\n imei?: string;\n macAddress?: string;\n androidId?: string;\n policyId?: string;\n tags?: Record<string, string>;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateDeviceInput {\n externalId?: string | null;\n status?: DeviceStatus;\n policyId?: string | null;\n model?: string;\n manufacturer?: string;\n osVersion?: string;\n batteryLevel?: number | null;\n storageUsed?: number | null;\n storageTotal?: number | null;\n lastHeartbeat?: Date;\n lastSync?: Date;\n installedApps?: InstalledApp[];\n location?: DeviceLocation;\n tags?: Record<string, string>;\n metadata?: Record<string, unknown>;\n}\n\nexport interface DeviceFilter {\n status?: DeviceStatus | DeviceStatus[];\n policyId?: string;\n groupId?: string;\n search?: string;\n tags?: Record<string, string>;\n limit?: number;\n offset?: number;\n}\n\nexport interface DeviceListResult {\n devices: Device[];\n total: number;\n limit: number;\n offset: number;\n}\n\n// ============================================\n// Policy Types\n// ============================================\n\nexport interface Policy {\n id: string;\n name: string;\n description?: string | null;\n isDefault: boolean;\n settings: PolicySettings;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface PolicySettings {\n // Kiosk Mode\n kioskMode?: boolean;\n mainApp?: string;\n allowedApps?: string[];\n kioskExitPassword?: string;\n\n // Lock Features\n lockStatusBar?: boolean;\n lockNavigationBar?: boolean;\n lockSettings?: boolean;\n lockPowerButton?: boolean;\n blockInstall?: boolean;\n blockUninstall?: boolean;\n\n // Hardware Controls\n bluetooth?: HardwareControl;\n wifi?: HardwareControl;\n gps?: HardwareControl;\n mobileData?: HardwareControl;\n camera?: HardwareControl;\n microphone?: HardwareControl;\n usb?: HardwareControl;\n nfc?: HardwareControl;\n\n // Update Settings\n systemUpdatePolicy?: SystemUpdatePolicy;\n updateWindow?: TimeWindow;\n\n // Security\n passwordPolicy?: PasswordPolicy;\n encryptionRequired?: boolean;\n factoryResetProtection?: boolean;\n safeBootDisabled?: boolean;\n\n // Telemetry\n heartbeatInterval?: number;\n locationReportInterval?: number;\n locationEnabled?: boolean;\n\n // Network\n wifiConfigs?: WifiConfig[];\n vpnConfig?: VpnConfig;\n\n // Applications\n applications?: PolicyApplication[];\n\n // Custom settings (for plugins)\n custom?: Record<string, unknown>;\n}\n\nexport type HardwareControl = 'on' | 'off' | 'user';\nexport type SystemUpdatePolicy = 'auto' | 'windowed' | 'postpone' | 'manual';\n\nexport interface TimeWindow {\n start: string; // \"HH:MM\"\n end: string; // \"HH:MM\"\n}\n\nexport interface PasswordPolicy {\n required: boolean;\n minLength?: number;\n complexity?: 'none' | 'numeric' | 'alphanumeric' | 'complex';\n maxFailedAttempts?: number;\n expirationDays?: number;\n historyLength?: number;\n}\n\nexport interface WifiConfig {\n ssid: string;\n securityType: 'none' | 'wep' | 'wpa' | 'wpa2' | 'wpa3';\n password?: string;\n hidden?: boolean;\n autoConnect?: boolean;\n}\n\nexport interface VpnConfig {\n type: 'pptp' | 'l2tp' | 'ipsec' | 'openvpn' | 'wireguard';\n server: string;\n username?: string;\n password?: string;\n certificate?: string;\n config?: Record<string, unknown>;\n}\n\nexport interface PolicyApplication {\n packageName: string;\n action: 'install' | 'update' | 'uninstall';\n version?: string;\n required?: boolean;\n autoUpdate?: boolean;\n}\n\nexport interface CreatePolicyInput {\n name: string;\n description?: string;\n isDefault?: boolean;\n settings: PolicySettings;\n}\n\nexport interface UpdatePolicyInput {\n name?: string;\n description?: string | null;\n isDefault?: boolean;\n settings?: PolicySettings;\n}\n\n// ============================================\n// Application Types\n// ============================================\n\nexport interface Application {\n id: string;\n name: string;\n packageName: string;\n version: string;\n versionCode: number;\n url: string;\n hash?: string | null;\n size?: number | null;\n minSdkVersion?: number | null;\n\n // Deployment settings\n showIcon: boolean;\n runAfterInstall: boolean;\n runAtBoot: boolean;\n isSystem: boolean;\n\n // State\n isActive: boolean;\n\n // Metadata\n metadata?: Record<string, unknown> | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateApplicationInput {\n name: string;\n packageName: string;\n version: string;\n versionCode: number;\n url: string;\n hash?: string;\n size?: number;\n minSdkVersion?: number;\n showIcon?: boolean;\n runAfterInstall?: boolean;\n runAtBoot?: boolean;\n isSystem?: boolean;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateApplicationInput {\n name?: string;\n version?: string;\n versionCode?: number;\n url?: string;\n hash?: string | null;\n size?: number | null;\n minSdkVersion?: number | null;\n showIcon?: boolean;\n runAfterInstall?: boolean;\n runAtBoot?: boolean;\n isActive?: boolean;\n metadata?: Record<string, unknown> | null;\n}\n\nexport interface DeployTarget {\n devices?: string[];\n policies?: string[];\n groups?: string[];\n}\n\n// ============================================\n// App Version & Rollback Types\n// ============================================\n\nexport interface AppVersion {\n id: string;\n applicationId: string;\n packageName: string;\n version: string;\n versionCode: number;\n url: string;\n hash?: string | null;\n size?: number | null;\n releaseNotes?: string | null;\n isMinimumVersion: boolean;\n createdAt: Date;\n}\n\nexport interface AppRollback {\n id: string;\n deviceId: string;\n packageName: string;\n fromVersion: string;\n fromVersionCode: number;\n toVersion: string;\n toVersionCode: number;\n reason?: string | null;\n status: 'pending' | 'in_progress' | 'completed' | 'failed';\n error?: string | null;\n initiatedBy?: string | null;\n createdAt: Date;\n completedAt?: Date | null;\n}\n\nexport interface CreateAppRollbackInput {\n deviceId: string;\n packageName: string;\n toVersionCode: number;\n reason?: string;\n initiatedBy?: string;\n}\n\n// ============================================\n// Command Types\n// ============================================\n\nexport type CommandType =\n | 'reboot'\n | 'shutdown'\n | 'sync'\n | 'lock'\n | 'unlock'\n | 'wipe'\n | 'factoryReset'\n | 'installApp'\n | 'uninstallApp'\n | 'updateApp'\n | 'runApp'\n | 'clearAppData'\n | 'clearAppCache'\n | 'shell'\n | 'setPolicy'\n | 'grantPermissions'\n | 'exitKiosk'\n | 'enterKiosk'\n | 'setWifi'\n | 'screenshot'\n | 'getLocation'\n | 'setVolume'\n | 'sendNotification'\n | 'whitelistBattery' // Whitelist app from battery optimization (Doze)\n | 'enablePermissiveMode' // Enable permissive mode for debugging\n | 'setTimeZone' // Set device timezone\n | 'enableAdb' // Enable/disable ADB debugging\n | 'rollbackApp' // Rollback to previous app version\n | 'custom';\n\nexport type CommandStatus =\n | 'pending'\n | 'sent'\n | 'acknowledged'\n | 'completed'\n | 'failed'\n | 'cancelled';\n\nexport interface Command {\n id: string;\n deviceId: string;\n type: CommandType;\n payload?: Record<string, unknown> | null;\n status: CommandStatus;\n result?: CommandResult | null;\n error?: string | null;\n createdAt: Date;\n sentAt?: Date | null;\n acknowledgedAt?: Date | null;\n completedAt?: Date | null;\n}\n\nexport interface CommandResult {\n success: boolean;\n message?: string;\n data?: unknown;\n}\n\nexport interface SendCommandInput {\n deviceId: string;\n type: CommandType;\n payload?: Record<string, unknown>;\n}\n\nexport interface CommandFilter {\n deviceId?: string;\n status?: CommandStatus | CommandStatus[];\n type?: CommandType | CommandType[];\n limit?: number;\n offset?: number;\n}\n\n// ============================================\n// Event Types\n// ============================================\n\nexport type EventType =\n | 'device.enrolled'\n | 'device.unenrolled'\n | 'device.blocked'\n | 'device.heartbeat'\n | 'device.locationUpdated'\n | 'device.statusChanged'\n | 'device.policyChanged'\n | 'app.installed'\n | 'app.uninstalled'\n | 'app.updated'\n | 'app.crashed'\n | 'app.started'\n | 'app.stopped'\n | 'policy.applied'\n | 'policy.failed'\n | 'command.received'\n | 'command.acknowledged'\n | 'command.completed'\n | 'command.failed'\n | 'security.tamper'\n | 'security.rootDetected'\n | 'security.screenLocked'\n | 'security.screenUnlocked'\n | 'custom';\n\nexport interface MDMEvent<T = unknown> {\n id: string;\n deviceId: string;\n type: EventType;\n payload: T;\n createdAt: Date;\n}\n\nexport interface EventFilter {\n deviceId?: string;\n type?: EventType | EventType[];\n startDate?: Date;\n endDate?: Date;\n limit?: number;\n offset?: number;\n}\n\n// ============================================\n// Group Types\n// ============================================\n\nexport interface Group {\n id: string;\n name: string;\n description?: string | null;\n policyId?: string | null;\n parentId?: string | null;\n metadata?: Record<string, unknown> | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateGroupInput {\n name: string;\n description?: string;\n policyId?: string;\n parentId?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateGroupInput {\n name?: string;\n description?: string | null;\n policyId?: string | null;\n parentId?: string | null;\n metadata?: Record<string, unknown> | null;\n}\n\n// ============================================\n// Enrollment Types\n// ============================================\n\nexport type EnrollmentMethod =\n | 'qr'\n | 'nfc'\n | 'zero-touch'\n | 'knox'\n | 'manual'\n | 'app-only'\n | 'adb';\n\nexport interface EnrollmentRequest {\n // Device identifiers (at least one required)\n macAddress?: string;\n serialNumber?: string;\n imei?: string;\n androidId?: string;\n\n // Device info\n model: string;\n manufacturer: string;\n osVersion: string;\n sdkVersion?: number;\n\n // Agent info\n agentVersion?: string;\n agentPackage?: string;\n\n // Enrollment details\n method: EnrollmentMethod;\n timestamp: string;\n signature: string;\n\n // Optional pre-assigned policy/group\n policyId?: string;\n groupId?: string;\n}\n\nexport interface EnrollmentResponse {\n deviceId: string;\n enrollmentId: string;\n policyId?: string;\n policy?: Policy;\n serverUrl: string;\n pushConfig: PushConfig;\n token: string;\n refreshToken?: string;\n tokenExpiresAt?: Date;\n}\n\nexport interface PushConfig {\n provider: 'fcm' | 'mqtt' | 'websocket' | 'polling';\n fcmSenderId?: string;\n mqttUrl?: string;\n mqttTopic?: string;\n mqttUsername?: string;\n mqttPassword?: string;\n wsUrl?: string;\n pollingInterval?: number;\n}\n\n// ============================================\n// Telemetry Types\n// ============================================\n\nexport interface Heartbeat {\n deviceId: string;\n timestamp: Date;\n\n // Battery\n batteryLevel: number;\n isCharging: boolean;\n batteryHealth?: 'good' | 'overheat' | 'dead' | 'cold' | 'unknown';\n\n // Storage\n storageUsed: number;\n storageTotal: number;\n\n // Memory\n memoryUsed: number;\n memoryTotal: number;\n\n // Network\n networkType?: 'wifi' | 'cellular' | 'ethernet' | 'none';\n networkName?: string; // SSID or carrier\n signalStrength?: number;\n ipAddress?: string;\n\n // Location\n location?: DeviceLocation;\n\n // Apps\n installedApps: InstalledApp[];\n runningApps?: string[];\n\n // Security\n isRooted?: boolean;\n isEncrypted?: boolean;\n screenLockEnabled?: boolean;\n\n // Agent status\n agentVersion?: string;\n policyVersion?: string;\n lastPolicySync?: Date;\n}\n\n// ============================================\n// Push Token Types\n// ============================================\n\nexport interface PushToken {\n id: string;\n deviceId: string;\n provider: 'fcm' | 'mqtt' | 'websocket';\n token: string;\n isActive: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface RegisterPushTokenInput {\n deviceId: string;\n provider: 'fcm' | 'mqtt' | 'websocket';\n token: string;\n}\n\n// ============================================\n// Configuration Types\n// ============================================\n\nexport interface MDMConfig {\n /** Database adapter for persistence */\n database: DatabaseAdapter;\n\n /** Authentication/authorization configuration */\n auth?: AuthConfig;\n\n /** Push notification provider configuration */\n push?: PushProviderConfig;\n\n /** Device enrollment configuration */\n enrollment?: EnrollmentConfig;\n\n /** Server URL (used in enrollment responses) */\n serverUrl?: string;\n\n /** APK/file storage configuration */\n storage?: StorageConfig;\n\n /** Outbound webhook configuration */\n webhooks?: WebhookConfig;\n\n /** Plugins to extend functionality */\n plugins?: MDMPlugin[];\n\n /** Event handlers */\n onDeviceEnrolled?: (device: Device) => Promise<void>;\n onDeviceUnenrolled?: (device: Device) => Promise<void>;\n onDeviceBlocked?: (device: Device) => Promise<void>;\n onHeartbeat?: (device: Device, heartbeat: Heartbeat) => Promise<void>;\n onCommand?: (command: Command) => Promise<void>;\n onEvent?: (event: MDMEvent) => Promise<void>;\n}\n\nexport interface StorageConfig {\n /** Storage provider (s3, local, custom) */\n provider: 's3' | 'local' | 'custom';\n\n /** S3 configuration */\n s3?: {\n bucket: string;\n region: string;\n accessKeyId?: string;\n secretAccessKey?: string;\n endpoint?: string; // For S3-compatible services\n presignedUrlExpiry?: number; // Seconds, default 3600\n };\n\n /** Local storage path */\n localPath?: string;\n\n /** Custom storage adapter */\n customAdapter?: {\n upload: (file: Buffer, key: string) => Promise<string>;\n getUrl: (key: string) => Promise<string>;\n delete: (key: string) => Promise<void>;\n };\n}\n\nexport interface WebhookConfig {\n /** Webhook endpoints to notify */\n endpoints?: WebhookEndpoint[];\n\n /** Retry configuration */\n retry?: {\n maxRetries?: number;\n initialDelay?: number;\n maxDelay?: number;\n };\n\n /** Sign webhooks with HMAC secret */\n signingSecret?: string;\n}\n\nexport interface WebhookEndpoint {\n /** Unique identifier */\n id: string;\n /** Webhook URL */\n url: string;\n /** Events to trigger this webhook */\n events: (EventType | '*')[];\n /** Custom headers */\n headers?: Record<string, string>;\n /** Whether endpoint is active */\n enabled: boolean;\n}\n\nexport interface AuthConfig {\n /** Get current user from request context */\n getUser: <T = unknown>(context: unknown) => Promise<T | null>;\n /** Check if user has admin privileges */\n isAdmin?: (user: unknown) => Promise<boolean>;\n /** Check if user can access specific device */\n canAccessDevice?: (user: unknown, deviceId: string) => Promise<boolean>;\n /** Device JWT secret (for device auth tokens) */\n deviceTokenSecret?: string;\n /** Device token expiration in seconds (default: 365 days) */\n deviceTokenExpiration?: number;\n}\n\nexport interface PushProviderConfig {\n provider: 'fcm' | 'mqtt' | 'websocket' | 'polling';\n\n // FCM configuration\n fcmCredentials?: string | Record<string, unknown>;\n fcmProjectId?: string;\n\n // MQTT configuration\n mqttUrl?: string;\n mqttUsername?: string;\n mqttPassword?: string;\n mqttTopicPrefix?: string;\n\n // WebSocket configuration\n wsPath?: string;\n wsPingInterval?: number;\n\n // Polling fallback\n pollingInterval?: number;\n}\n\nexport interface EnrollmentConfig {\n /** Auto-enroll devices with valid signature */\n autoEnroll?: boolean;\n /** HMAC secret for device signature verification */\n deviceSecret: string;\n /** Allowed enrollment methods */\n allowedMethods?: EnrollmentMethod[];\n /** Default policy for new devices */\n defaultPolicyId?: string;\n /** Default group for new devices */\n defaultGroupId?: string;\n /** Require manual approval for enrollment */\n requireApproval?: boolean;\n /** Custom enrollment validation */\n validate?: (request: EnrollmentRequest) => Promise<boolean>;\n}\n\n// ============================================\n// Adapter Interfaces\n// ============================================\n\nexport interface DatabaseAdapter {\n // Devices\n findDevice(id: string): Promise<Device | null>;\n findDeviceByEnrollmentId(enrollmentId: string): Promise<Device | null>;\n listDevices(filter?: DeviceFilter): Promise<DeviceListResult>;\n createDevice(data: CreateDeviceInput): Promise<Device>;\n updateDevice(id: string, data: UpdateDeviceInput): Promise<Device>;\n deleteDevice(id: string): Promise<void>;\n countDevices(filter?: DeviceFilter): Promise<number>;\n\n // Policies\n findPolicy(id: string): Promise<Policy | null>;\n findDefaultPolicy(): Promise<Policy | null>;\n listPolicies(): Promise<Policy[]>;\n createPolicy(data: CreatePolicyInput): Promise<Policy>;\n updatePolicy(id: string, data: UpdatePolicyInput): Promise<Policy>;\n deletePolicy(id: string): Promise<void>;\n\n // Applications\n findApplication(id: string): Promise<Application | null>;\n findApplicationByPackage(packageName: string, version?: string): Promise<Application | null>;\n listApplications(activeOnly?: boolean): Promise<Application[]>;\n createApplication(data: CreateApplicationInput): Promise<Application>;\n updateApplication(id: string, data: UpdateApplicationInput): Promise<Application>;\n deleteApplication(id: string): Promise<void>;\n\n // Commands\n findCommand(id: string): Promise<Command | null>;\n listCommands(filter?: CommandFilter): Promise<Command[]>;\n createCommand(data: SendCommandInput): Promise<Command>;\n updateCommand(id: string, data: Partial<Command>): Promise<Command>;\n getPendingCommands(deviceId: string): Promise<Command[]>;\n\n // Events\n createEvent(event: Omit<MDMEvent, 'id' | 'createdAt'>): Promise<MDMEvent>;\n listEvents(filter?: EventFilter): Promise<MDMEvent[]>;\n\n // Groups\n findGroup(id: string): Promise<Group | null>;\n listGroups(): Promise<Group[]>;\n createGroup(data: CreateGroupInput): Promise<Group>;\n updateGroup(id: string, data: UpdateGroupInput): Promise<Group>;\n deleteGroup(id: string): Promise<void>;\n listDevicesInGroup(groupId: string): Promise<Device[]>;\n addDeviceToGroup(deviceId: string, groupId: string): Promise<void>;\n removeDeviceFromGroup(deviceId: string, groupId: string): Promise<void>;\n getDeviceGroups(deviceId: string): Promise<Group[]>;\n\n // Push Tokens\n findPushToken(deviceId: string, provider: string): Promise<PushToken | null>;\n upsertPushToken(data: RegisterPushTokenInput): Promise<PushToken>;\n deletePushToken(deviceId: string, provider?: string): Promise<void>;\n\n // App Versions (optional - for version tracking)\n listAppVersions?(packageName: string): Promise<AppVersion[]>;\n createAppVersion?(data: Omit<AppVersion, 'id' | 'createdAt'>): Promise<AppVersion>;\n setMinimumVersion?(packageName: string, versionCode: number): Promise<void>;\n getMinimumVersion?(packageName: string): Promise<AppVersion | null>;\n\n // Rollback History (optional)\n createRollback?(data: CreateAppRollbackInput): Promise<AppRollback>;\n updateRollback?(id: string, data: Partial<AppRollback>): Promise<AppRollback>;\n listRollbacks?(filter?: { deviceId?: string; packageName?: string }): Promise<AppRollback[]>;\n\n // Transactions (optional)\n transaction?<T>(fn: () => Promise<T>): Promise<T>;\n}\n\nexport interface PushAdapter {\n /** Send push message to a device */\n send(deviceId: string, message: PushMessage): Promise<PushResult>;\n /** Send push message to multiple devices */\n sendBatch(deviceIds: string[], message: PushMessage): Promise<PushBatchResult>;\n /** Register device push token */\n registerToken?(deviceId: string, token: string): Promise<void>;\n /** Unregister device push token */\n unregisterToken?(deviceId: string): Promise<void>;\n /** Subscribe device to topic */\n subscribe?(deviceId: string, topic: string): Promise<void>;\n /** Unsubscribe device from topic */\n unsubscribe?(deviceId: string, topic: string): Promise<void>;\n}\n\nexport interface PushMessage {\n type: string;\n payload?: Record<string, unknown>;\n priority?: 'high' | 'normal';\n ttl?: number;\n collapseKey?: string;\n}\n\nexport interface PushResult {\n success: boolean;\n messageId?: string;\n error?: string;\n}\n\nexport interface PushBatchResult {\n successCount: number;\n failureCount: number;\n results: Array<{ deviceId: string; result: PushResult }>;\n}\n\n// ============================================\n// Plugin Interface\n// ============================================\n\nexport interface MDMPlugin {\n /** Unique plugin name */\n name: string;\n /** Plugin version */\n version: string;\n\n /** Called when MDM is initialized */\n onInit?(mdm: MDMInstance): Promise<void>;\n\n /** Called when MDM is destroyed */\n onDestroy?(): Promise<void>;\n\n /** Additional routes to mount */\n routes?: PluginRoute[];\n\n /** Middleware to apply to all routes */\n middleware?: PluginMiddleware[];\n\n /** Extend enrollment process */\n onEnroll?(device: Device, request: EnrollmentRequest): Promise<void>;\n\n /** Extend device processing */\n onDeviceEnrolled?(device: Device): Promise<void>;\n onDeviceUnenrolled?(device: Device): Promise<void>;\n onHeartbeat?(device: Device, heartbeat: Heartbeat): Promise<void>;\n\n /** Extend policy processing */\n policySchema?: Record<string, unknown>;\n validatePolicy?(settings: PolicySettings): Promise<{ valid: boolean; errors?: string[] }>;\n applyPolicy?(device: Device, policy: Policy): Promise<void>;\n\n /** Extend command processing */\n commandTypes?: CommandType[];\n executeCommand?(device: Device, command: Command): Promise<CommandResult>;\n}\n\nexport interface PluginRoute {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n path: string;\n handler: (context: unknown) => Promise<unknown>;\n auth?: boolean;\n admin?: boolean;\n}\n\nexport type PluginMiddleware = (\n context: unknown,\n next: () => Promise<unknown>\n) => Promise<unknown>;\n\n// ============================================\n// MDM Instance Interface\n// ============================================\n\nexport interface WebhookManager {\n /** Deliver an event to all matching webhook endpoints */\n deliver<T>(event: MDMEvent<T>): Promise<WebhookDeliveryResult[]>;\n /** Add a webhook endpoint at runtime */\n addEndpoint(endpoint: WebhookEndpoint): void;\n /** Remove a webhook endpoint */\n removeEndpoint(endpointId: string): void;\n /** Update a webhook endpoint */\n updateEndpoint(endpointId: string, updates: Partial<WebhookEndpoint>): void;\n /** Get all configured endpoints */\n getEndpoints(): WebhookEndpoint[];\n /** Test a webhook endpoint with a test payload */\n testEndpoint(endpointId: string): Promise<WebhookDeliveryResult>;\n}\n\nexport interface WebhookDeliveryResult {\n endpointId: string;\n success: boolean;\n statusCode?: number;\n error?: string;\n retryCount: number;\n deliveredAt?: Date;\n}\n\nexport interface MDMInstance {\n /** Device management */\n devices: DeviceManager;\n /** Policy management */\n policies: PolicyManager;\n /** Application management */\n apps: ApplicationManager;\n /** Command management */\n commands: CommandManager;\n /** Group management */\n groups: GroupManager;\n\n /** Push notification service */\n push: PushAdapter;\n\n /** Webhook delivery (if configured) */\n webhooks?: WebhookManager;\n\n /** Database adapter */\n db: DatabaseAdapter;\n\n /** Configuration */\n config: MDMConfig;\n\n /** Subscribe to events */\n on<T extends EventType>(event: T, handler: EventHandler<T>): () => void;\n /** Emit an event */\n emit<T extends EventType>(event: T, data: EventPayloadMap[T]): Promise<void>;\n\n /** Process device enrollment */\n enroll(request: EnrollmentRequest): Promise<EnrollmentResponse>;\n /** Process device heartbeat */\n processHeartbeat(deviceId: string, heartbeat: Heartbeat): Promise<void>;\n /** Verify device token */\n verifyDeviceToken(token: string): Promise<{ deviceId: string } | null>;\n\n /** Get loaded plugins */\n getPlugins(): MDMPlugin[];\n /** Get plugin by name */\n getPlugin(name: string): MDMPlugin | undefined;\n}\n\n// ============================================\n// Manager Interfaces\n// ============================================\n\nexport interface DeviceManager {\n get(id: string): Promise<Device | null>;\n getByEnrollmentId(enrollmentId: string): Promise<Device | null>;\n list(filter?: DeviceFilter): Promise<DeviceListResult>;\n create(data: CreateDeviceInput): Promise<Device>;\n update(id: string, data: UpdateDeviceInput): Promise<Device>;\n delete(id: string): Promise<void>;\n assignPolicy(deviceId: string, policyId: string | null): Promise<Device>;\n addToGroup(deviceId: string, groupId: string): Promise<void>;\n removeFromGroup(deviceId: string, groupId: string): Promise<void>;\n getGroups(deviceId: string): Promise<Group[]>;\n sendCommand(deviceId: string, input: Omit<SendCommandInput, 'deviceId'>): Promise<Command>;\n sync(deviceId: string): Promise<Command>;\n reboot(deviceId: string): Promise<Command>;\n lock(deviceId: string, message?: string): Promise<Command>;\n wipe(deviceId: string, preserveData?: boolean): Promise<Command>;\n}\n\nexport interface PolicyManager {\n get(id: string): Promise<Policy | null>;\n getDefault(): Promise<Policy | null>;\n list(): Promise<Policy[]>;\n create(data: CreatePolicyInput): Promise<Policy>;\n update(id: string, data: UpdatePolicyInput): Promise<Policy>;\n delete(id: string): Promise<void>;\n setDefault(id: string): Promise<Policy>;\n getDevices(policyId: string): Promise<Device[]>;\n applyToDevice(policyId: string, deviceId: string): Promise<void>;\n}\n\nexport interface ApplicationManager {\n get(id: string): Promise<Application | null>;\n getByPackage(packageName: string, version?: string): Promise<Application | null>;\n list(activeOnly?: boolean): Promise<Application[]>;\n register(data: CreateApplicationInput): Promise<Application>;\n update(id: string, data: UpdateApplicationInput): Promise<Application>;\n delete(id: string): Promise<void>;\n activate(id: string): Promise<Application>;\n deactivate(id: string): Promise<Application>;\n deploy(packageName: string, target: DeployTarget): Promise<void>;\n installOnDevice(packageName: string, deviceId: string, version?: string): Promise<Command>;\n uninstallFromDevice(packageName: string, deviceId: string): Promise<Command>;\n}\n\nexport interface CommandManager {\n get(id: string): Promise<Command | null>;\n list(filter?: CommandFilter): Promise<Command[]>;\n send(input: SendCommandInput): Promise<Command>;\n cancel(id: string): Promise<Command>;\n acknowledge(id: string): Promise<Command>;\n complete(id: string, result: CommandResult): Promise<Command>;\n fail(id: string, error: string): Promise<Command>;\n getPending(deviceId: string): Promise<Command[]>;\n}\n\nexport interface GroupManager {\n get(id: string): Promise<Group | null>;\n list(): Promise<Group[]>;\n create(data: CreateGroupInput): Promise<Group>;\n update(id: string, data: UpdateGroupInput): Promise<Group>;\n delete(id: string): Promise<void>;\n getDevices(groupId: string): Promise<Device[]>;\n addDevice(groupId: string, deviceId: string): Promise<void>;\n removeDevice(groupId: string, deviceId: string): Promise<void>;\n getChildren(groupId: string): Promise<Group[]>;\n}\n\n// ============================================\n// Event Handler Types\n// ============================================\n\nexport type EventHandler<T extends EventType> = (\n event: MDMEvent<EventPayloadMap[T]>\n) => Promise<void> | void;\n\nexport interface EventPayloadMap {\n 'device.enrolled': { device: Device };\n 'device.unenrolled': { device: Device; reason?: string };\n 'device.blocked': { device: Device; reason: string };\n 'device.heartbeat': { device: Device; heartbeat: Heartbeat };\n 'device.locationUpdated': { device: Device; location: DeviceLocation };\n 'device.statusChanged': { device: Device; oldStatus: DeviceStatus; newStatus: DeviceStatus };\n 'device.policyChanged': { device: Device; oldPolicyId?: string; newPolicyId?: string };\n 'app.installed': { device: Device; app: InstalledApp };\n 'app.uninstalled': { device: Device; packageName: string };\n 'app.updated': { device: Device; app: InstalledApp; oldVersion: string };\n 'app.crashed': { device: Device; packageName: string; error?: string };\n 'app.started': { device: Device; packageName: string };\n 'app.stopped': { device: Device; packageName: string };\n 'policy.applied': { device: Device; policy: Policy };\n 'policy.failed': { device: Device; policy: Policy; error: string };\n 'command.received': { device: Device; command: Command };\n 'command.acknowledged': { device: Device; command: Command };\n 'command.completed': { device: Device; command: Command; result: CommandResult };\n 'command.failed': { device: Device; command: Command; error: string };\n 'security.tamper': { device: Device; type: string; details?: unknown };\n 'security.rootDetected': { device: Device };\n 'security.screenLocked': { device: Device };\n 'security.screenUnlocked': { device: Device };\n custom: Record<string, unknown>;\n}\n\n// ============================================\n// Error Types\n// ============================================\n\nexport class MDMError extends Error {\n constructor(\n message: string,\n public code: string,\n public statusCode: number = 500,\n public details?: unknown\n ) {\n super(message);\n this.name = 'MDMError';\n }\n}\n\nexport class DeviceNotFoundError extends MDMError {\n constructor(deviceId: string) {\n super(`Device not found: ${deviceId}`, 'DEVICE_NOT_FOUND', 404);\n }\n}\n\nexport class PolicyNotFoundError extends MDMError {\n constructor(policyId: string) {\n super(`Policy not found: ${policyId}`, 'POLICY_NOT_FOUND', 404);\n }\n}\n\nexport class ApplicationNotFoundError extends MDMError {\n constructor(identifier: string) {\n super(`Application not found: ${identifier}`, 'APPLICATION_NOT_FOUND', 404);\n }\n}\n\nexport class EnrollmentError extends MDMError {\n constructor(message: string, details?: unknown) {\n super(message, 'ENROLLMENT_ERROR', 400, details);\n }\n}\n\nexport class AuthenticationError extends MDMError {\n constructor(message: string = 'Authentication required') {\n super(message, 'AUTHENTICATION_ERROR', 401);\n }\n}\n\nexport class AuthorizationError extends MDMError {\n constructor(message: string = 'Access denied') {\n super(message, 'AUTHORIZATION_ERROR', 403);\n }\n}\n\nexport class ValidationError extends MDMError {\n constructor(message: string, details?: unknown) {\n super(message, 'VALIDATION_ERROR', 400, details);\n }\n}\n","/**\n * OpenMDM Webhook Delivery System\n *\n * Handles outbound webhook delivery with HMAC signing and retry logic.\n */\n\nimport { createHmac, randomUUID } from 'crypto';\nimport type {\n WebhookConfig,\n WebhookEndpoint,\n EventType,\n MDMEvent,\n} from './types';\n\n// ============================================\n// Types\n// ============================================\n\nexport interface WebhookDeliveryResult {\n endpointId: string;\n success: boolean;\n statusCode?: number;\n error?: string;\n retryCount: number;\n deliveredAt?: Date;\n}\n\nexport interface WebhookPayload<T = unknown> {\n id: string;\n event: EventType;\n timestamp: string;\n data: T;\n}\n\nexport interface WebhookManager {\n /**\n * Deliver an event to all matching webhook endpoints\n */\n deliver<T>(event: MDMEvent<T>): Promise<WebhookDeliveryResult[]>;\n\n /**\n * Add a webhook endpoint at runtime\n */\n addEndpoint(endpoint: WebhookEndpoint): void;\n\n /**\n * Remove a webhook endpoint\n */\n removeEndpoint(endpointId: string): void;\n\n /**\n * Update a webhook endpoint\n */\n updateEndpoint(endpointId: string, updates: Partial<WebhookEndpoint>): void;\n\n /**\n * Get all configured endpoints\n */\n getEndpoints(): WebhookEndpoint[];\n\n /**\n * Test a webhook endpoint with a test payload\n */\n testEndpoint(endpointId: string): Promise<WebhookDeliveryResult>;\n}\n\n// ============================================\n// Implementation\n// ============================================\n\nconst DEFAULT_RETRY_CONFIG = {\n maxRetries: 3,\n initialDelay: 1000,\n maxDelay: 30000,\n};\n\n/**\n * Create a webhook manager instance\n */\nexport function createWebhookManager(config: WebhookConfig): WebhookManager {\n const endpoints = new Map<string, WebhookEndpoint>();\n const retryConfig = { ...DEFAULT_RETRY_CONFIG, ...config.retry };\n\n // Initialize with configured endpoints\n if (config.endpoints) {\n for (const endpoint of config.endpoints) {\n endpoints.set(endpoint.id, endpoint);\n }\n }\n\n /**\n * Sign a webhook payload with HMAC-SHA256\n */\n function signPayload(payload: string, secret: string): string {\n return createHmac('sha256', secret).update(payload).digest('hex');\n }\n\n /**\n * Calculate exponential backoff delay\n */\n function getBackoffDelay(retryCount: number): number {\n const delay = retryConfig.initialDelay * Math.pow(2, retryCount);\n return Math.min(delay, retryConfig.maxDelay);\n }\n\n /**\n * Check if an endpoint should receive this event\n */\n function shouldDeliverToEndpoint(\n endpoint: WebhookEndpoint,\n eventType: EventType\n ): boolean {\n if (!endpoint.enabled) {\n return false;\n }\n\n // Wildcard matches all events\n if (endpoint.events.includes('*')) {\n return true;\n }\n\n return endpoint.events.includes(eventType);\n }\n\n /**\n * Deliver payload to a single endpoint with retry logic\n */\n async function deliverToEndpoint(\n endpoint: WebhookEndpoint,\n payload: WebhookPayload\n ): Promise<WebhookDeliveryResult> {\n const payloadString = JSON.stringify(payload);\n let lastError: string | undefined;\n let lastStatusCode: number | undefined;\n\n for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {\n try {\n // Prepare headers\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-OpenMDM-Event': payload.event,\n 'X-OpenMDM-Delivery': payload.id,\n 'X-OpenMDM-Timestamp': payload.timestamp,\n ...endpoint.headers,\n };\n\n // Add signature if signing secret is configured\n if (config.signingSecret) {\n const signature = signPayload(payloadString, config.signingSecret);\n headers['X-OpenMDM-Signature'] = `sha256=${signature}`;\n }\n\n // Make the request\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers,\n body: payloadString,\n signal: AbortSignal.timeout(30000), // 30 second timeout\n });\n\n lastStatusCode = response.status;\n\n // 2xx is success\n if (response.ok) {\n return {\n endpointId: endpoint.id,\n success: true,\n statusCode: response.status,\n retryCount: attempt,\n deliveredAt: new Date(),\n };\n }\n\n // 4xx errors (except 429) should not be retried\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n return {\n endpointId: endpoint.id,\n success: false,\n statusCode: response.status,\n error: `HTTP ${response.status}: ${response.statusText}`,\n retryCount: attempt,\n };\n }\n\n // 5xx and 429 should be retried\n lastError = `HTTP ${response.status}: ${response.statusText}`;\n } catch (error) {\n lastError = error instanceof Error ? error.message : String(error);\n }\n\n // Wait before retry (unless this was the last attempt)\n if (attempt < retryConfig.maxRetries) {\n const delay = getBackoffDelay(attempt);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n return {\n endpointId: endpoint.id,\n success: false,\n statusCode: lastStatusCode,\n error: lastError || 'Max retries exceeded',\n retryCount: retryConfig.maxRetries,\n };\n }\n\n return {\n async deliver<T>(event: MDMEvent<T>): Promise<WebhookDeliveryResult[]> {\n const matchingEndpoints = Array.from(endpoints.values()).filter((ep) =>\n shouldDeliverToEndpoint(ep, event.type)\n );\n\n if (matchingEndpoints.length === 0) {\n return [];\n }\n\n // Prepare webhook payload\n const payload: WebhookPayload<T> = {\n id: randomUUID(),\n event: event.type,\n timestamp: new Date().toISOString(),\n data: event.payload,\n };\n\n // Deliver to all matching endpoints in parallel\n const deliveryPromises = matchingEndpoints.map((endpoint) =>\n deliverToEndpoint(endpoint, payload as WebhookPayload)\n );\n\n const results = await Promise.all(deliveryPromises);\n\n // Log failures\n for (const result of results) {\n if (!result.success) {\n console.error(\n `[OpenMDM] Webhook delivery failed to endpoint ${result.endpointId}:`,\n result.error\n );\n }\n }\n\n return results;\n },\n\n addEndpoint(endpoint: WebhookEndpoint): void {\n endpoints.set(endpoint.id, endpoint);\n },\n\n removeEndpoint(endpointId: string): void {\n endpoints.delete(endpointId);\n },\n\n updateEndpoint(endpointId: string, updates: Partial<WebhookEndpoint>): void {\n const existing = endpoints.get(endpointId);\n if (existing) {\n endpoints.set(endpointId, { ...existing, ...updates });\n }\n },\n\n getEndpoints(): WebhookEndpoint[] {\n return Array.from(endpoints.values());\n },\n\n async testEndpoint(endpointId: string): Promise<WebhookDeliveryResult> {\n const endpoint = endpoints.get(endpointId);\n if (!endpoint) {\n return {\n endpointId,\n success: false,\n error: 'Endpoint not found',\n retryCount: 0,\n };\n }\n\n const testPayload: WebhookPayload = {\n id: randomUUID(),\n event: 'device.heartbeat',\n timestamp: new Date().toISOString(),\n data: {\n test: true,\n message: 'OpenMDM webhook test',\n },\n };\n\n return deliverToEndpoint(endpoint, testPayload);\n },\n };\n}\n\n/**\n * Verify a webhook signature from incoming requests\n * (Utility for consumers to verify our webhooks)\n */\nexport function verifyWebhookSignature(\n payload: string,\n signature: string,\n secret: string\n): boolean {\n const expectedSignature = `sha256=${createHmac('sha256', secret)\n .update(payload)\n .digest('hex')}`;\n\n // Constant-time comparison\n if (signature.length !== expectedSignature.length) {\n return false;\n }\n\n let result = 0;\n for (let i = 0; i < signature.length; i++) {\n result |= signature.charCodeAt(i) ^ expectedSignature.charCodeAt(i);\n }\n\n return result === 0;\n}\n","/**\n * OpenMDM Database Schema Definition\n *\n * This schema defines the structure for MDM data storage.\n * Database adapters implement this schema for their specific ORM/database.\n *\n * Tables:\n * - mdm_devices: Enrolled devices and their state\n * - mdm_policies: Device policies and configurations\n * - mdm_applications: Registered applications for deployment\n * - mdm_commands: Command queue for device operations\n * - mdm_events: Event log for device activities\n * - mdm_groups: Device grouping for bulk operations\n * - mdm_device_groups: Many-to-many device-group relationships\n * - mdm_push_tokens: FCM/MQTT push notification tokens\n * - mdm_app_deployments: App-to-policy/group deployment mappings\n * - mdm_app_versions: App version history for rollback support\n * - mdm_rollbacks: Rollback operation history and status\n * - mdm_webhook_endpoints: Outbound webhook configuration\n * - mdm_webhook_deliveries: Webhook delivery history\n */\n\n// ============================================\n// Schema Column Types\n// ============================================\n\nexport type ColumnType =\n | 'string'\n | 'text'\n | 'integer'\n | 'bigint'\n | 'boolean'\n | 'datetime'\n | 'json'\n | 'enum';\n\nexport interface ColumnDefinition {\n type: ColumnType;\n nullable?: boolean;\n primaryKey?: boolean;\n unique?: boolean;\n default?: unknown;\n enumValues?: string[];\n references?: {\n table: string;\n column: string;\n onDelete?: 'cascade' | 'set null' | 'restrict';\n };\n}\n\nexport interface IndexDefinition {\n columns: string[];\n unique?: boolean;\n name?: string;\n}\n\nexport interface TableDefinition {\n columns: Record<string, ColumnDefinition>;\n indexes?: IndexDefinition[];\n}\n\nexport interface SchemaDefinition {\n tables: Record<string, TableDefinition>;\n}\n\n// ============================================\n// OpenMDM Schema\n// ============================================\n\nexport const mdmSchema: SchemaDefinition = {\n tables: {\n // ----------------------------------------\n // Devices Table\n // ----------------------------------------\n mdm_devices: {\n columns: {\n id: { type: 'string', primaryKey: true },\n external_id: { type: 'string', nullable: true },\n enrollment_id: { type: 'string', unique: true },\n status: {\n type: 'enum',\n enumValues: ['pending', 'enrolled', 'unenrolled', 'blocked'],\n default: 'pending',\n },\n\n // Device Info\n model: { type: 'string', nullable: true },\n manufacturer: { type: 'string', nullable: true },\n os_version: { type: 'string', nullable: true },\n serial_number: { type: 'string', nullable: true },\n imei: { type: 'string', nullable: true },\n mac_address: { type: 'string', nullable: true },\n android_id: { type: 'string', nullable: true },\n\n // MDM State\n policy_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_policies', column: 'id', onDelete: 'set null' },\n },\n last_heartbeat: { type: 'datetime', nullable: true },\n last_sync: { type: 'datetime', nullable: true },\n\n // Telemetry (denormalized for quick access)\n battery_level: { type: 'integer', nullable: true },\n storage_used: { type: 'bigint', nullable: true },\n storage_total: { type: 'bigint', nullable: true },\n latitude: { type: 'string', nullable: true }, // Stored as string for precision\n longitude: { type: 'string', nullable: true },\n location_timestamp: { type: 'datetime', nullable: true },\n\n // JSON fields\n installed_apps: { type: 'json', nullable: true },\n tags: { type: 'json', nullable: true },\n metadata: { type: 'json', nullable: true },\n\n // Timestamps\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['enrollment_id'], unique: true },\n { columns: ['status'] },\n { columns: ['policy_id'] },\n { columns: ['last_heartbeat'] },\n { columns: ['mac_address'] },\n { columns: ['serial_number'] },\n ],\n },\n\n // ----------------------------------------\n // Policies Table\n // ----------------------------------------\n mdm_policies: {\n columns: {\n id: { type: 'string', primaryKey: true },\n name: { type: 'string' },\n description: { type: 'text', nullable: true },\n is_default: { type: 'boolean', default: false },\n settings: { type: 'json' },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['name'] },\n { columns: ['is_default'] },\n ],\n },\n\n // ----------------------------------------\n // Applications Table\n // ----------------------------------------\n mdm_applications: {\n columns: {\n id: { type: 'string', primaryKey: true },\n name: { type: 'string' },\n package_name: { type: 'string' },\n version: { type: 'string' },\n version_code: { type: 'integer' },\n url: { type: 'string' },\n hash: { type: 'string', nullable: true }, // SHA-256\n size: { type: 'bigint', nullable: true },\n min_sdk_version: { type: 'integer', nullable: true },\n\n // Deployment settings\n show_icon: { type: 'boolean', default: true },\n run_after_install: { type: 'boolean', default: false },\n run_at_boot: { type: 'boolean', default: false },\n is_system: { type: 'boolean', default: false },\n\n // State\n is_active: { type: 'boolean', default: true },\n\n // Metadata\n metadata: { type: 'json', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['package_name'] },\n { columns: ['package_name', 'version'], unique: true },\n { columns: ['is_active'] },\n ],\n },\n\n // ----------------------------------------\n // Commands Table\n // ----------------------------------------\n mdm_commands: {\n columns: {\n id: { type: 'string', primaryKey: true },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n type: { type: 'string' },\n payload: { type: 'json', nullable: true },\n status: {\n type: 'enum',\n enumValues: ['pending', 'sent', 'acknowledged', 'completed', 'failed', 'cancelled'],\n default: 'pending',\n },\n result: { type: 'json', nullable: true },\n error: { type: 'text', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n sent_at: { type: 'datetime', nullable: true },\n acknowledged_at: { type: 'datetime', nullable: true },\n completed_at: { type: 'datetime', nullable: true },\n },\n indexes: [\n { columns: ['device_id'] },\n { columns: ['status'] },\n { columns: ['device_id', 'status'] },\n { columns: ['created_at'] },\n ],\n },\n\n // ----------------------------------------\n // Events Table\n // ----------------------------------------\n mdm_events: {\n columns: {\n id: { type: 'string', primaryKey: true },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n type: { type: 'string' },\n payload: { type: 'json' },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['device_id'] },\n { columns: ['type'] },\n { columns: ['device_id', 'type'] },\n { columns: ['created_at'] },\n ],\n },\n\n // ----------------------------------------\n // Groups Table\n // ----------------------------------------\n mdm_groups: {\n columns: {\n id: { type: 'string', primaryKey: true },\n name: { type: 'string' },\n description: { type: 'text', nullable: true },\n policy_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_policies', column: 'id', onDelete: 'set null' },\n },\n parent_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_groups', column: 'id', onDelete: 'set null' },\n },\n metadata: { type: 'json', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['name'] },\n { columns: ['policy_id'] },\n { columns: ['parent_id'] },\n ],\n },\n\n // ----------------------------------------\n // Device Groups (Many-to-Many)\n // ----------------------------------------\n mdm_device_groups: {\n columns: {\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n group_id: {\n type: 'string',\n references: { table: 'mdm_groups', column: 'id', onDelete: 'cascade' },\n },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['device_id', 'group_id'], unique: true },\n { columns: ['group_id'] },\n ],\n },\n\n // ----------------------------------------\n // Push Tokens (for FCM/MQTT registration)\n // ----------------------------------------\n mdm_push_tokens: {\n columns: {\n id: { type: 'string', primaryKey: true },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n provider: {\n type: 'enum',\n enumValues: ['fcm', 'mqtt', 'websocket'],\n },\n token: { type: 'string' },\n is_active: { type: 'boolean', default: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['device_id'] },\n { columns: ['provider', 'token'], unique: true },\n { columns: ['is_active'] },\n ],\n },\n\n // ----------------------------------------\n // Application Deployments (Which apps go to which policies/groups)\n // ----------------------------------------\n mdm_app_deployments: {\n columns: {\n id: { type: 'string', primaryKey: true },\n application_id: {\n type: 'string',\n references: { table: 'mdm_applications', column: 'id', onDelete: 'cascade' },\n },\n // Target can be policy or group\n target_type: {\n type: 'enum',\n enumValues: ['policy', 'group'],\n },\n target_id: { type: 'string' },\n action: {\n type: 'enum',\n enumValues: ['install', 'update', 'uninstall'],\n default: 'install',\n },\n is_required: { type: 'boolean', default: false },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['application_id'] },\n { columns: ['target_type', 'target_id'] },\n ],\n },\n\n // ----------------------------------------\n // App Versions (Version history for rollback support)\n // ----------------------------------------\n mdm_app_versions: {\n columns: {\n id: { type: 'string', primaryKey: true },\n application_id: {\n type: 'string',\n references: { table: 'mdm_applications', column: 'id', onDelete: 'cascade' },\n },\n package_name: { type: 'string' },\n version: { type: 'string' },\n version_code: { type: 'integer' },\n url: { type: 'string' },\n hash: { type: 'string', nullable: true },\n size: { type: 'bigint', nullable: true },\n release_notes: { type: 'text', nullable: true },\n is_minimum_version: { type: 'boolean', default: false },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['application_id'] },\n { columns: ['package_name'] },\n { columns: ['package_name', 'version_code'], unique: true },\n { columns: ['is_minimum_version'] },\n ],\n },\n\n // ----------------------------------------\n // App Rollbacks (Rollback history and status)\n // ----------------------------------------\n mdm_rollbacks: {\n columns: {\n id: { type: 'string', primaryKey: true },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n package_name: { type: 'string' },\n from_version: { type: 'string' },\n from_version_code: { type: 'integer' },\n to_version: { type: 'string' },\n to_version_code: { type: 'integer' },\n reason: { type: 'text', nullable: true },\n status: {\n type: 'enum',\n enumValues: ['pending', 'in_progress', 'completed', 'failed'],\n default: 'pending',\n },\n error: { type: 'text', nullable: true },\n initiated_by: { type: 'string', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n completed_at: { type: 'datetime', nullable: true },\n },\n indexes: [\n { columns: ['device_id'] },\n { columns: ['package_name'] },\n { columns: ['device_id', 'package_name'] },\n { columns: ['status'] },\n { columns: ['created_at'] },\n ],\n },\n\n // ----------------------------------------\n // Webhook Endpoints (For outbound webhook configuration storage)\n // ----------------------------------------\n mdm_webhook_endpoints: {\n columns: {\n id: { type: 'string', primaryKey: true },\n url: { type: 'string' },\n events: { type: 'json' }, // Array of event types or ['*']\n headers: { type: 'json', nullable: true },\n enabled: { type: 'boolean', default: true },\n description: { type: 'text', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['enabled'] },\n ],\n },\n\n // ----------------------------------------\n // Webhook Deliveries (Delivery history and status)\n // ----------------------------------------\n mdm_webhook_deliveries: {\n columns: {\n id: { type: 'string', primaryKey: true },\n endpoint_id: {\n type: 'string',\n references: { table: 'mdm_webhook_endpoints', column: 'id', onDelete: 'cascade' },\n },\n event_id: { type: 'string' },\n event_type: { type: 'string' },\n payload: { type: 'json' },\n status: {\n type: 'enum',\n enumValues: ['pending', 'success', 'failed'],\n default: 'pending',\n },\n status_code: { type: 'integer', nullable: true },\n error: { type: 'text', nullable: true },\n retry_count: { type: 'integer', default: 0 },\n created_at: { type: 'datetime', default: 'now' },\n delivered_at: { type: 'datetime', nullable: true },\n },\n indexes: [\n { columns: ['endpoint_id'] },\n { columns: ['event_type'] },\n { columns: ['status'] },\n { columns: ['created_at'] },\n ],\n },\n },\n};\n\n// ============================================\n// Schema Helper Functions\n// ============================================\n\n/**\n * Get all table names from the schema\n */\nexport function getTableNames(): string[] {\n return Object.keys(mdmSchema.tables);\n}\n\n/**\n * Get column names for a table\n */\nexport function getColumnNames(tableName: string): string[] {\n const table = mdmSchema.tables[tableName];\n if (!table) throw new Error(`Table ${tableName} not found in schema`);\n return Object.keys(table.columns);\n}\n\n/**\n * Get the primary key column for a table\n */\nexport function getPrimaryKey(tableName: string): string | null {\n const table = mdmSchema.tables[tableName];\n if (!table) throw new Error(`Table ${tableName} not found in schema`);\n\n for (const [name, def] of Object.entries(table.columns)) {\n if (def.primaryKey) return name;\n }\n return null;\n}\n\n/**\n * Convert snake_case column name to camelCase\n */\nexport function snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n}\n\n/**\n * Convert camelCase to snake_case\n */\nexport function camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/**\n * Transform object keys from snake_case to camelCase\n */\nexport function transformToCamelCase<T extends Record<string, unknown>>(\n obj: T\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[snakeToCamel(key)] = value;\n }\n return result;\n}\n\n/**\n * Transform object keys from camelCase to snake_case\n */\nexport function transformToSnakeCase<T extends Record<string, unknown>>(\n obj: T\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[camelToSnake(key)] = value;\n }\n return result;\n}\n","/**\n * OpenMDM Core\n *\n * A flexible, embeddable MDM (Mobile Device Management) SDK.\n * Inspired by better-auth's design philosophy.\n *\n * @example\n * ```typescript\n * import { createMDM } from '@openmdm/core';\n * import { drizzleAdapter } from '@openmdm/drizzle-adapter';\n *\n * const mdm = createMDM({\n * database: drizzleAdapter(db),\n * enrollment: {\n * deviceSecret: process.env.DEVICE_HMAC_SECRET!,\n * autoEnroll: true,\n * },\n * });\n *\n * // Use in your routes\n * const devices = await mdm.devices.list();\n * ```\n */\n\nimport { createHmac, timingSafeEqual, randomUUID } from 'crypto';\nimport type {\n MDMConfig,\n MDMInstance,\n Device,\n Policy,\n Application,\n Command,\n Group,\n Heartbeat,\n EnrollmentRequest,\n EnrollmentResponse,\n DeviceFilter,\n DeviceListResult,\n CreateDeviceInput,\n UpdateDeviceInput,\n CreatePolicyInput,\n UpdatePolicyInput,\n CreateApplicationInput,\n UpdateApplicationInput,\n SendCommandInput,\n CommandFilter,\n CreateGroupInput,\n UpdateGroupInput,\n DeployTarget,\n DeviceManager,\n PolicyManager,\n ApplicationManager,\n CommandManager,\n GroupManager,\n PushAdapter,\n PushResult,\n PushBatchResult,\n PushMessage,\n EventType,\n EventHandler,\n EventPayloadMap,\n MDMEvent,\n MDMPlugin,\n CommandResult,\n InstalledApp,\n WebhookManager,\n} from './types';\nimport {\n DeviceNotFoundError,\n ApplicationNotFoundError,\n EnrollmentError,\n} from './types';\nimport { createWebhookManager } from './webhooks';\n\n// Re-export all types\nexport * from './types';\nexport * from './schema';\nexport { createWebhookManager, verifyWebhookSignature } from './webhooks';\nexport type { WebhookPayload } from './webhooks';\n\n/**\n * Create an MDM instance with the given configuration.\n */\nexport function createMDM(config: MDMConfig): MDMInstance {\n const { database, push, enrollment, webhooks: webhooksConfig, plugins = [] } = config;\n\n // Event handlers registry\n const eventHandlers = new Map<EventType, Set<EventHandler<EventType>>>();\n\n // Create push adapter\n const pushAdapter: PushAdapter = push\n ? createPushAdapter(push, database)\n : createStubPushAdapter();\n\n // Create webhook manager if configured\n const webhookManager: WebhookManager | undefined = webhooksConfig\n ? createWebhookManager(webhooksConfig)\n : undefined;\n\n // Event subscription\n const on = <T extends EventType>(\n event: T,\n handler: EventHandler<T>\n ): (() => void) => {\n if (!eventHandlers.has(event)) {\n eventHandlers.set(event, new Set());\n }\n const handlers = eventHandlers.get(event)!;\n handlers.add(handler as EventHandler<EventType>);\n\n // Return unsubscribe function\n return () => {\n handlers.delete(handler as EventHandler<EventType>);\n };\n };\n\n // Event emission\n const emit = async <T extends EventType>(\n event: T,\n data: EventPayloadMap[T]\n ): Promise<void> => {\n const handlers = eventHandlers.get(event);\n\n // Create event record\n const eventRecord: MDMEvent<EventPayloadMap[T]> = {\n id: randomUUID(),\n deviceId: (data as any).device?.id || (data as any).deviceId || '',\n type: event,\n payload: data,\n createdAt: new Date(),\n };\n\n // Persist event\n try {\n await database.createEvent({\n deviceId: eventRecord.deviceId,\n type: eventRecord.type,\n payload: eventRecord.payload as Record<string, unknown>,\n });\n } catch (error) {\n console.error('[OpenMDM] Failed to persist event:', error);\n }\n\n // Deliver webhooks (async, don't wait)\n if (webhookManager) {\n webhookManager.deliver(eventRecord).catch((error) => {\n console.error('[OpenMDM] Webhook delivery error:', error);\n });\n }\n\n // Call handlers\n if (handlers) {\n for (const handler of handlers) {\n try {\n await handler(eventRecord);\n } catch (error) {\n console.error(`[OpenMDM] Event handler error for ${event}:`, error);\n }\n }\n }\n\n // Call config hook if defined\n if (config.onEvent) {\n try {\n await config.onEvent(eventRecord);\n } catch (error) {\n console.error('[OpenMDM] onEvent hook error:', error);\n }\n }\n };\n\n // ============================================\n // Device Manager\n // ============================================\n\n const devices: DeviceManager = {\n async get(id: string): Promise<Device | null> {\n return database.findDevice(id);\n },\n\n async getByEnrollmentId(enrollmentId: string): Promise<Device | null> {\n return database.findDeviceByEnrollmentId(enrollmentId);\n },\n\n async list(filter?: DeviceFilter): Promise<DeviceListResult> {\n return database.listDevices(filter);\n },\n\n async create(data: CreateDeviceInput): Promise<Device> {\n const device = await database.createDevice(data);\n\n await emit('device.enrolled', { device });\n\n if (config.onDeviceEnrolled) {\n await config.onDeviceEnrolled(device);\n }\n\n return device;\n },\n\n async update(id: string, data: UpdateDeviceInput): Promise<Device> {\n const oldDevice = await database.findDevice(id);\n if (!oldDevice) {\n throw new DeviceNotFoundError(id);\n }\n\n const device = await database.updateDevice(id, data);\n\n // Emit status change event if status changed\n if (data.status && data.status !== oldDevice.status) {\n await emit('device.statusChanged', {\n device,\n oldStatus: oldDevice.status,\n newStatus: data.status,\n });\n }\n\n // Emit policy change event if policy changed\n if (data.policyId !== undefined && data.policyId !== oldDevice.policyId) {\n await emit('device.policyChanged', {\n device,\n oldPolicyId: oldDevice.policyId || undefined,\n newPolicyId: data.policyId || undefined,\n });\n }\n\n return device;\n },\n\n async delete(id: string): Promise<void> {\n const device = await database.findDevice(id);\n if (device) {\n await database.deleteDevice(id);\n await emit('device.unenrolled', { device });\n\n if (config.onDeviceUnenrolled) {\n await config.onDeviceUnenrolled(device);\n }\n }\n },\n\n async assignPolicy(\n deviceId: string,\n policyId: string | null\n ): Promise<Device> {\n const device = await this.update(deviceId, { policyId });\n\n // Notify device of policy change\n await pushAdapter.send(deviceId, {\n type: 'policy.updated',\n payload: { policyId },\n priority: 'high',\n });\n\n return device;\n },\n\n async addToGroup(deviceId: string, groupId: string): Promise<void> {\n await database.addDeviceToGroup(deviceId, groupId);\n },\n\n async removeFromGroup(deviceId: string, groupId: string): Promise<void> {\n await database.removeDeviceFromGroup(deviceId, groupId);\n },\n\n async getGroups(deviceId: string): Promise<Group[]> {\n return database.getDeviceGroups(deviceId);\n },\n\n async sendCommand(\n deviceId: string,\n input: Omit<SendCommandInput, 'deviceId'>\n ): Promise<Command> {\n const command = await database.createCommand({\n ...input,\n deviceId,\n });\n\n // Send via push\n const pushResult = await pushAdapter.send(deviceId, {\n type: `command.${input.type}`,\n payload: {\n commandId: command.id,\n type: input.type,\n ...input.payload,\n },\n priority: 'high',\n });\n\n // Update command status\n if (pushResult.success) {\n await database.updateCommand(command.id, {\n status: 'sent',\n sentAt: new Date(),\n });\n }\n\n if (config.onCommand) {\n await config.onCommand(command);\n }\n\n return database.findCommand(command.id) as Promise<Command>;\n },\n\n async sync(deviceId: string): Promise<Command> {\n return this.sendCommand(deviceId, { type: 'sync' });\n },\n\n async reboot(deviceId: string): Promise<Command> {\n return this.sendCommand(deviceId, { type: 'reboot' });\n },\n\n async lock(deviceId: string, message?: string): Promise<Command> {\n return this.sendCommand(deviceId, {\n type: 'lock',\n payload: message ? { message } : undefined,\n });\n },\n\n async wipe(deviceId: string, preserveData?: boolean): Promise<Command> {\n return this.sendCommand(deviceId, {\n type: preserveData ? 'wipe' : 'factoryReset',\n payload: { preserveData },\n });\n },\n };\n\n // ============================================\n // Policy Manager\n // ============================================\n\n const policies: PolicyManager = {\n async get(id: string): Promise<Policy | null> {\n return database.findPolicy(id);\n },\n\n async getDefault(): Promise<Policy | null> {\n return database.findDefaultPolicy();\n },\n\n async list(): Promise<Policy[]> {\n return database.listPolicies();\n },\n\n async create(data: CreatePolicyInput): Promise<Policy> {\n // If this is being set as default, clear other defaults first\n if (data.isDefault) {\n const existingPolicies = await database.listPolicies();\n for (const policy of existingPolicies) {\n if (policy.isDefault) {\n await database.updatePolicy(policy.id, { isDefault: false });\n }\n }\n }\n\n return database.createPolicy(data);\n },\n\n async update(id: string, data: UpdatePolicyInput): Promise<Policy> {\n // If setting as default, clear other defaults first\n if (data.isDefault) {\n const existingPolicies = await database.listPolicies();\n for (const policy of existingPolicies) {\n if (policy.isDefault && policy.id !== id) {\n await database.updatePolicy(policy.id, { isDefault: false });\n }\n }\n }\n\n const policy = await database.updatePolicy(id, data);\n\n // Notify all devices with this policy\n const devicesResult = await database.listDevices({ policyId: id });\n if (devicesResult.devices.length > 0) {\n const deviceIds = devicesResult.devices.map((d) => d.id);\n await pushAdapter.sendBatch(deviceIds, {\n type: 'policy.updated',\n payload: { policyId: id },\n priority: 'high',\n });\n }\n\n return policy;\n },\n\n async delete(id: string): Promise<void> {\n // Check if any devices use this policy\n const devicesResult = await database.listDevices({ policyId: id });\n if (devicesResult.devices.length > 0) {\n // Remove policy from devices first\n for (const device of devicesResult.devices) {\n await database.updateDevice(device.id, { policyId: null });\n }\n }\n\n await database.deletePolicy(id);\n },\n\n async setDefault(id: string): Promise<Policy> {\n return this.update(id, { isDefault: true });\n },\n\n async getDevices(policyId: string): Promise<Device[]> {\n const result = await database.listDevices({ policyId });\n return result.devices;\n },\n\n async applyToDevice(policyId: string, deviceId: string): Promise<void> {\n await devices.assignPolicy(deviceId, policyId);\n },\n };\n\n // ============================================\n // Application Manager\n // ============================================\n\n const apps: ApplicationManager = {\n async get(id: string): Promise<Application | null> {\n return database.findApplication(id);\n },\n\n async getByPackage(\n packageName: string,\n version?: string\n ): Promise<Application | null> {\n return database.findApplicationByPackage(packageName, version);\n },\n\n async list(activeOnly?: boolean): Promise<Application[]> {\n return database.listApplications(activeOnly);\n },\n\n async register(data: CreateApplicationInput): Promise<Application> {\n return database.createApplication(data);\n },\n\n async update(id: string, data: UpdateApplicationInput): Promise<Application> {\n return database.updateApplication(id, data);\n },\n\n async delete(id: string): Promise<void> {\n await database.deleteApplication(id);\n },\n\n async activate(id: string): Promise<Application> {\n return database.updateApplication(id, { isActive: true });\n },\n\n async deactivate(id: string): Promise<Application> {\n return database.updateApplication(id, { isActive: false });\n },\n\n async deploy(packageName: string, target: DeployTarget): Promise<void> {\n const app = await database.findApplicationByPackage(packageName);\n if (!app) {\n throw new ApplicationNotFoundError(packageName);\n }\n\n const deviceIds: string[] = [];\n\n // Collect target devices\n if (target.devices) {\n deviceIds.push(...target.devices);\n }\n\n if (target.groups) {\n for (const groupId of target.groups) {\n const groupDevices = await database.listDevicesInGroup(groupId);\n deviceIds.push(...groupDevices.map((d) => d.id));\n }\n }\n\n if (target.policies) {\n for (const policyId of target.policies) {\n const result = await database.listDevices({ policyId });\n deviceIds.push(...result.devices.map((d) => d.id));\n }\n }\n\n // Deduplicate\n const uniqueDeviceIds = [...new Set(deviceIds)];\n\n // Send install command to all devices\n if (uniqueDeviceIds.length > 0) {\n await pushAdapter.sendBatch(uniqueDeviceIds, {\n type: 'command.installApp',\n payload: {\n packageName: app.packageName,\n version: app.version,\n versionCode: app.versionCode,\n url: app.url,\n hash: app.hash,\n },\n priority: 'high',\n });\n\n // Create command records for each device\n for (const deviceId of uniqueDeviceIds) {\n await database.createCommand({\n deviceId,\n type: 'installApp',\n payload: {\n packageName: app.packageName,\n version: app.version,\n url: app.url,\n },\n });\n }\n }\n },\n\n async installOnDevice(\n packageName: string,\n deviceId: string,\n version?: string\n ): Promise<Command> {\n const app = await database.findApplicationByPackage(packageName, version);\n if (!app) {\n throw new ApplicationNotFoundError(packageName);\n }\n\n return devices.sendCommand(deviceId, {\n type: 'installApp',\n payload: {\n packageName: app.packageName,\n version: app.version,\n versionCode: app.versionCode,\n url: app.url,\n hash: app.hash,\n },\n });\n },\n\n async uninstallFromDevice(\n packageName: string,\n deviceId: string\n ): Promise<Command> {\n return devices.sendCommand(deviceId, {\n type: 'uninstallApp',\n payload: { packageName },\n });\n },\n };\n\n // ============================================\n // Command Manager\n // ============================================\n\n const commands: CommandManager = {\n async get(id: string): Promise<Command | null> {\n return database.findCommand(id);\n },\n\n async list(filter?: CommandFilter): Promise<Command[]> {\n return database.listCommands(filter);\n },\n\n async send(input: SendCommandInput): Promise<Command> {\n return devices.sendCommand(input.deviceId, {\n type: input.type,\n payload: input.payload,\n });\n },\n\n async cancel(id: string): Promise<Command> {\n return database.updateCommand(id, { status: 'cancelled' });\n },\n\n async acknowledge(id: string): Promise<Command> {\n const command = await database.updateCommand(id, {\n status: 'acknowledged',\n acknowledgedAt: new Date(),\n });\n\n const device = await database.findDevice(command.deviceId);\n if (device) {\n await emit('command.acknowledged', { device, command });\n }\n\n return command;\n },\n\n async complete(id: string, result: CommandResult): Promise<Command> {\n const command = await database.updateCommand(id, {\n status: 'completed',\n result,\n completedAt: new Date(),\n });\n\n const device = await database.findDevice(command.deviceId);\n if (device) {\n await emit('command.completed', { device, command, result });\n }\n\n return command;\n },\n\n async fail(id: string, error: string): Promise<Command> {\n const command = await database.updateCommand(id, {\n status: 'failed',\n error,\n completedAt: new Date(),\n });\n\n const device = await database.findDevice(command.deviceId);\n if (device) {\n await emit('command.failed', { device, command, error });\n }\n\n return command;\n },\n\n async getPending(deviceId: string): Promise<Command[]> {\n return database.getPendingCommands(deviceId);\n },\n };\n\n // ============================================\n // Group Manager\n // ============================================\n\n const groups: GroupManager = {\n async get(id: string): Promise<Group | null> {\n return database.findGroup(id);\n },\n\n async list(): Promise<Group[]> {\n return database.listGroups();\n },\n\n async create(data: CreateGroupInput): Promise<Group> {\n return database.createGroup(data);\n },\n\n async update(id: string, data: UpdateGroupInput): Promise<Group> {\n return database.updateGroup(id, data);\n },\n\n async delete(id: string): Promise<void> {\n await database.deleteGroup(id);\n },\n\n async getDevices(groupId: string): Promise<Device[]> {\n return database.listDevicesInGroup(groupId);\n },\n\n async addDevice(groupId: string, deviceId: string): Promise<void> {\n await database.addDeviceToGroup(deviceId, groupId);\n },\n\n async removeDevice(groupId: string, deviceId: string): Promise<void> {\n await database.removeDeviceFromGroup(deviceId, groupId);\n },\n\n async getChildren(groupId: string): Promise<Group[]> {\n const allGroups = await database.listGroups();\n return allGroups.filter((g) => g.parentId === groupId);\n },\n };\n\n // ============================================\n // Enrollment\n // ============================================\n\n const enroll = async (\n request: EnrollmentRequest\n ): Promise<EnrollmentResponse> => {\n // Validate method if restricted\n if (\n enrollment?.allowedMethods &&\n !enrollment.allowedMethods.includes(request.method)\n ) {\n throw new EnrollmentError(\n `Enrollment method '${request.method}' is not allowed`\n );\n }\n\n // Verify signature if secret is configured\n if (enrollment?.deviceSecret) {\n const isValid = verifyEnrollmentSignature(\n request,\n enrollment.deviceSecret\n );\n if (!isValid) {\n throw new EnrollmentError('Invalid enrollment signature');\n }\n }\n\n // Custom validation\n if (enrollment?.validate) {\n const isValid = await enrollment.validate(request);\n if (!isValid) {\n throw new EnrollmentError('Enrollment validation failed');\n }\n }\n\n // Determine enrollment ID\n const enrollmentId =\n request.macAddress ||\n request.serialNumber ||\n request.imei ||\n request.androidId;\n\n if (!enrollmentId) {\n throw new EnrollmentError(\n 'Device must provide at least one identifier (macAddress, serialNumber, imei, or androidId)'\n );\n }\n\n // Check if device already exists\n let device = await database.findDeviceByEnrollmentId(enrollmentId);\n\n if (device) {\n // Device re-enrolling\n device = await database.updateDevice(device.id, {\n status: 'enrolled',\n model: request.model,\n manufacturer: request.manufacturer,\n osVersion: request.osVersion,\n lastSync: new Date(),\n });\n } else if (enrollment?.autoEnroll) {\n // Auto-create device\n device = await database.createDevice({\n enrollmentId,\n model: request.model,\n manufacturer: request.manufacturer,\n osVersion: request.osVersion,\n serialNumber: request.serialNumber,\n imei: request.imei,\n macAddress: request.macAddress,\n androidId: request.androidId,\n policyId: request.policyId || enrollment.defaultPolicyId,\n });\n\n // Add to default group if configured\n if (enrollment.defaultGroupId) {\n await database.addDeviceToGroup(device.id, enrollment.defaultGroupId);\n }\n } else if (enrollment?.requireApproval) {\n // Create pending device\n device = await database.createDevice({\n enrollmentId,\n model: request.model,\n manufacturer: request.manufacturer,\n osVersion: request.osVersion,\n serialNumber: request.serialNumber,\n imei: request.imei,\n macAddress: request.macAddress,\n androidId: request.androidId,\n });\n // Status remains 'pending'\n } else {\n throw new EnrollmentError(\n 'Device not registered and auto-enroll is disabled'\n );\n }\n\n // Get policy\n let policy: Policy | null = null;\n if (device.policyId) {\n policy = await database.findPolicy(device.policyId);\n }\n if (!policy) {\n policy = await database.findDefaultPolicy();\n }\n\n // Generate JWT token for device auth\n const tokenSecret =\n config.auth?.deviceTokenSecret || enrollment?.deviceSecret || '';\n const tokenExpiration = config.auth?.deviceTokenExpiration || 365 * 24 * 60 * 60;\n const token = generateDeviceToken(device.id, tokenSecret, tokenExpiration);\n\n // Emit enrollment event\n await emit('device.enrolled', { device });\n\n // Call config hook if defined\n if (config.onDeviceEnrolled) {\n await config.onDeviceEnrolled(device);\n }\n\n // Call plugin hooks\n for (const plugin of plugins) {\n if (plugin.onEnroll) {\n await plugin.onEnroll(device, request);\n }\n if (plugin.onDeviceEnrolled) {\n await plugin.onDeviceEnrolled(device);\n }\n }\n\n return {\n deviceId: device.id,\n enrollmentId: device.enrollmentId,\n policyId: policy?.id,\n policy: policy || undefined,\n serverUrl: config.serverUrl || '',\n pushConfig: {\n provider: push?.provider || 'polling',\n fcmSenderId: (push?.fcmCredentials as any)?.project_id,\n mqttUrl: push?.mqttUrl,\n mqttTopic: push?.mqttTopicPrefix\n ? `${push.mqttTopicPrefix}/${device.id}`\n : `openmdm/devices/${device.id}`,\n pollingInterval: push?.pollingInterval || 60,\n },\n token,\n tokenExpiresAt: new Date(Date.now() + tokenExpiration * 1000),\n };\n };\n\n // ============================================\n // Heartbeat Processing\n // ============================================\n\n const processHeartbeat = async (\n deviceId: string,\n heartbeat: Heartbeat\n ): Promise<void> => {\n const device = await database.findDevice(deviceId);\n if (!device) {\n throw new DeviceNotFoundError(deviceId);\n }\n\n // Update device with heartbeat data\n const updateData: UpdateDeviceInput = {\n lastHeartbeat: heartbeat.timestamp,\n batteryLevel: heartbeat.batteryLevel,\n storageUsed: heartbeat.storageUsed,\n storageTotal: heartbeat.storageTotal,\n installedApps: heartbeat.installedApps,\n };\n\n if (heartbeat.location) {\n updateData.location = heartbeat.location;\n }\n\n const updatedDevice = await database.updateDevice(deviceId, updateData);\n\n // Emit heartbeat event\n await emit('device.heartbeat', { device: updatedDevice, heartbeat });\n\n // Emit location event if location changed\n if (heartbeat.location) {\n await emit('device.locationUpdated', {\n device: updatedDevice,\n location: heartbeat.location,\n });\n }\n\n // Check for app changes\n if (device.installedApps && heartbeat.installedApps) {\n const oldApps = new Map(\n device.installedApps.map((a) => [a.packageName, a])\n );\n const newApps = new Map(\n heartbeat.installedApps.map((a) => [a.packageName, a])\n );\n\n // Check for new installs\n for (const [pkg, app] of newApps) {\n const oldApp = oldApps.get(pkg);\n if (!oldApp) {\n await emit('app.installed', { device: updatedDevice, app });\n } else if (oldApp.version !== app.version) {\n await emit('app.updated', {\n device: updatedDevice,\n app,\n oldVersion: oldApp.version,\n });\n }\n }\n\n // Check for uninstalls\n for (const [pkg] of oldApps) {\n if (!newApps.has(pkg)) {\n await emit('app.uninstalled', {\n device: updatedDevice,\n packageName: pkg,\n });\n }\n }\n }\n\n // Call config hook if defined\n if (config.onHeartbeat) {\n await config.onHeartbeat(updatedDevice, heartbeat);\n }\n\n // Call plugin hooks\n for (const plugin of plugins) {\n if (plugin.onHeartbeat) {\n await plugin.onHeartbeat(updatedDevice, heartbeat);\n }\n }\n };\n\n // ============================================\n // Token Verification\n // ============================================\n\n const verifyDeviceToken = async (\n token: string\n ): Promise<{ deviceId: string } | null> => {\n try {\n const tokenSecret =\n config.auth?.deviceTokenSecret || enrollment?.deviceSecret || '';\n\n const parts = token.split('.');\n if (parts.length !== 3) {\n return null;\n }\n\n const [header, payload, signature] = parts;\n\n // Verify signature\n const expectedSignature = createHmac('sha256', tokenSecret)\n .update(`${header}.${payload}`)\n .digest('base64url');\n\n if (signature !== expectedSignature) {\n return null;\n }\n\n // Decode payload\n const decoded = JSON.parse(\n Buffer.from(payload, 'base64url').toString('utf-8')\n );\n\n // Check expiration\n if (decoded.exp && decoded.exp < Math.floor(Date.now() / 1000)) {\n return null;\n }\n\n return { deviceId: decoded.sub };\n } catch {\n return null;\n }\n };\n\n // ============================================\n // Plugin Management\n // ============================================\n\n const getPlugins = (): MDMPlugin[] => plugins;\n\n const getPlugin = (name: string): MDMPlugin | undefined => {\n return plugins.find((p) => p.name === name);\n };\n\n // ============================================\n // Create Instance\n // ============================================\n\n const instance: MDMInstance = {\n devices,\n policies,\n apps,\n commands,\n groups,\n push: pushAdapter,\n webhooks: webhookManager,\n db: database,\n config,\n on,\n emit,\n enroll,\n processHeartbeat,\n verifyDeviceToken,\n getPlugins,\n getPlugin,\n };\n\n // Initialize plugins\n (async () => {\n for (const plugin of plugins) {\n if (plugin.onInit) {\n try {\n await plugin.onInit(instance);\n console.log(`[OpenMDM] Plugin initialized: ${plugin.name}`);\n } catch (error) {\n console.error(\n `[OpenMDM] Failed to initialize plugin ${plugin.name}:`,\n error\n );\n }\n }\n }\n })();\n\n return instance;\n}\n\n// ============================================\n// Push Adapter Factory\n// ============================================\n\nfunction createPushAdapter(\n config: MDMConfig['push'],\n database: MDMConfig['database']\n): PushAdapter {\n if (!config) {\n return createStubPushAdapter();\n }\n\n // The actual implementations will be provided by separate packages\n // This is a base implementation that logs and stores tokens\n return {\n async send(deviceId: string, message: PushMessage): Promise<PushResult> {\n console.log(\n `[OpenMDM] Push to ${deviceId}: ${message.type}`,\n message.payload\n );\n\n // In production, this would be replaced by FCM/MQTT adapter\n return { success: true, messageId: randomUUID() };\n },\n\n async sendBatch(\n deviceIds: string[],\n message: PushMessage\n ): Promise<PushBatchResult> {\n console.log(\n `[OpenMDM] Push to ${deviceIds.length} devices: ${message.type}`\n );\n\n const results = deviceIds.map((deviceId) => ({\n deviceId,\n result: { success: true, messageId: randomUUID() },\n }));\n\n return {\n successCount: deviceIds.length,\n failureCount: 0,\n results,\n };\n },\n\n async registerToken(deviceId: string, token: string): Promise<void> {\n // Polling doesn't use push tokens\n if (config.provider === 'polling') {\n return;\n }\n await database.upsertPushToken({\n deviceId,\n provider: config.provider,\n token,\n });\n },\n\n async unregisterToken(deviceId: string): Promise<void> {\n // Polling doesn't use push tokens\n if (config.provider === 'polling') {\n return;\n }\n await database.deletePushToken(deviceId, config.provider);\n },\n };\n}\n\nfunction createStubPushAdapter(): PushAdapter {\n return {\n async send(deviceId: string, message: PushMessage): Promise<PushResult> {\n console.log(`[OpenMDM] Push (stub): ${deviceId} <- ${message.type}`);\n return { success: true, messageId: 'stub' };\n },\n\n async sendBatch(\n deviceIds: string[],\n message: PushMessage\n ): Promise<PushBatchResult> {\n console.log(\n `[OpenMDM] Push (stub): ${deviceIds.length} devices <- ${message.type}`\n );\n return {\n successCount: deviceIds.length,\n failureCount: 0,\n results: deviceIds.map((deviceId) => ({\n deviceId,\n result: { success: true, messageId: 'stub' },\n })),\n };\n },\n };\n}\n\n// ============================================\n// Utility Functions\n// ============================================\n\nfunction verifyEnrollmentSignature(\n request: EnrollmentRequest,\n secret: string\n): boolean {\n const { signature, ...data } = request;\n\n if (!signature) {\n return false;\n }\n\n // Reconstruct the message that was signed\n // Format: identifier:timestamp\n const identifier =\n data.macAddress || data.serialNumber || data.imei || data.androidId || '';\n const message = `${identifier}:${data.timestamp}`;\n\n const expectedSignature = createHmac('sha256', secret)\n .update(message)\n .digest('hex');\n\n try {\n return timingSafeEqual(\n Buffer.from(signature, 'hex'),\n Buffer.from(expectedSignature, 'hex')\n );\n } catch {\n return false;\n }\n}\n\nfunction generateDeviceToken(\n deviceId: string,\n secret: string,\n expirationSeconds: number\n): string {\n const header = Buffer.from(\n JSON.stringify({ alg: 'HS256', typ: 'JWT' })\n ).toString('base64url');\n\n const now = Math.floor(Date.now() / 1000);\n const payload = Buffer.from(\n JSON.stringify({\n sub: deviceId,\n iat: now,\n exp: now + expirationSeconds,\n iss: 'openmdm',\n })\n ).toString('base64url');\n\n const signature = createHmac('sha256', secret)\n .update(`${header}.${payload}`)\n .digest('base64url');\n\n return `${header}.${payload}.${signature}`;\n}\n"]}
|
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenMDM Database Schema Definition
|
|
3
|
+
*
|
|
4
|
+
* This schema defines the structure for MDM data storage.
|
|
5
|
+
* Database adapters implement this schema for their specific ORM/database.
|
|
6
|
+
*
|
|
7
|
+
* Tables:
|
|
8
|
+
* - mdm_devices: Enrolled devices and their state
|
|
9
|
+
* - mdm_policies: Device policies and configurations
|
|
10
|
+
* - mdm_applications: Registered applications for deployment
|
|
11
|
+
* - mdm_commands: Command queue for device operations
|
|
12
|
+
* - mdm_events: Event log for device activities
|
|
13
|
+
* - mdm_groups: Device grouping for bulk operations
|
|
14
|
+
* - mdm_device_groups: Many-to-many device-group relationships
|
|
15
|
+
* - mdm_push_tokens: FCM/MQTT push notification tokens
|
|
16
|
+
* - mdm_app_deployments: App-to-policy/group deployment mappings
|
|
17
|
+
* - mdm_app_versions: App version history for rollback support
|
|
18
|
+
* - mdm_rollbacks: Rollback operation history and status
|
|
19
|
+
* - mdm_webhook_endpoints: Outbound webhook configuration
|
|
20
|
+
* - mdm_webhook_deliveries: Webhook delivery history
|
|
21
|
+
*/
|
|
22
|
+
type ColumnType = 'string' | 'text' | 'integer' | 'bigint' | 'boolean' | 'datetime' | 'json' | 'enum';
|
|
23
|
+
interface ColumnDefinition {
|
|
24
|
+
type: ColumnType;
|
|
25
|
+
nullable?: boolean;
|
|
26
|
+
primaryKey?: boolean;
|
|
27
|
+
unique?: boolean;
|
|
28
|
+
default?: unknown;
|
|
29
|
+
enumValues?: string[];
|
|
30
|
+
references?: {
|
|
31
|
+
table: string;
|
|
32
|
+
column: string;
|
|
33
|
+
onDelete?: 'cascade' | 'set null' | 'restrict';
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
interface IndexDefinition {
|
|
37
|
+
columns: string[];
|
|
38
|
+
unique?: boolean;
|
|
39
|
+
name?: string;
|
|
40
|
+
}
|
|
41
|
+
interface TableDefinition {
|
|
42
|
+
columns: Record<string, ColumnDefinition>;
|
|
43
|
+
indexes?: IndexDefinition[];
|
|
44
|
+
}
|
|
45
|
+
interface SchemaDefinition {
|
|
46
|
+
tables: Record<string, TableDefinition>;
|
|
47
|
+
}
|
|
48
|
+
declare const mdmSchema: SchemaDefinition;
|
|
49
|
+
/**
|
|
50
|
+
* Get all table names from the schema
|
|
51
|
+
*/
|
|
52
|
+
declare function getTableNames(): string[];
|
|
53
|
+
/**
|
|
54
|
+
* Get column names for a table
|
|
55
|
+
*/
|
|
56
|
+
declare function getColumnNames(tableName: string): string[];
|
|
57
|
+
/**
|
|
58
|
+
* Get the primary key column for a table
|
|
59
|
+
*/
|
|
60
|
+
declare function getPrimaryKey(tableName: string): string | null;
|
|
61
|
+
/**
|
|
62
|
+
* Convert snake_case column name to camelCase
|
|
63
|
+
*/
|
|
64
|
+
declare function snakeToCamel(str: string): string;
|
|
65
|
+
/**
|
|
66
|
+
* Convert camelCase to snake_case
|
|
67
|
+
*/
|
|
68
|
+
declare function camelToSnake(str: string): string;
|
|
69
|
+
/**
|
|
70
|
+
* Transform object keys from snake_case to camelCase
|
|
71
|
+
*/
|
|
72
|
+
declare function transformToCamelCase<T extends Record<string, unknown>>(obj: T): Record<string, unknown>;
|
|
73
|
+
/**
|
|
74
|
+
* Transform object keys from camelCase to snake_case
|
|
75
|
+
*/
|
|
76
|
+
declare function transformToSnakeCase<T extends Record<string, unknown>>(obj: T): Record<string, unknown>;
|
|
77
|
+
|
|
78
|
+
export { type ColumnDefinition, type ColumnType, type IndexDefinition, type SchemaDefinition, type TableDefinition, camelToSnake, getColumnNames, getPrimaryKey, getTableNames, mdmSchema, snakeToCamel, transformToCamelCase, transformToSnakeCase };
|