@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.
@@ -0,0 +1,899 @@
1
+ /**
2
+ * OpenMDM Core Types
3
+ *
4
+ * These types define the core data structures for the MDM system.
5
+ * Designed to be database-agnostic and framework-agnostic.
6
+ */
7
+ type DeviceStatus = 'pending' | 'enrolled' | 'unenrolled' | 'blocked';
8
+ interface Device {
9
+ id: string;
10
+ externalId?: string | null;
11
+ enrollmentId: string;
12
+ status: DeviceStatus;
13
+ model?: string | null;
14
+ manufacturer?: string | null;
15
+ osVersion?: string | null;
16
+ serialNumber?: string | null;
17
+ imei?: string | null;
18
+ macAddress?: string | null;
19
+ androidId?: string | null;
20
+ policyId?: string | null;
21
+ lastHeartbeat?: Date | null;
22
+ lastSync?: Date | null;
23
+ batteryLevel?: number | null;
24
+ storageUsed?: number | null;
25
+ storageTotal?: number | null;
26
+ location?: DeviceLocation | null;
27
+ installedApps?: InstalledApp[] | null;
28
+ tags?: Record<string, string> | null;
29
+ metadata?: Record<string, unknown> | null;
30
+ createdAt: Date;
31
+ updatedAt: Date;
32
+ }
33
+ interface DeviceLocation {
34
+ latitude: number;
35
+ longitude: number;
36
+ accuracy?: number;
37
+ timestamp: Date;
38
+ }
39
+ interface InstalledApp {
40
+ packageName: string;
41
+ version: string;
42
+ versionCode?: number;
43
+ installedAt?: Date;
44
+ }
45
+ interface CreateDeviceInput {
46
+ enrollmentId: string;
47
+ externalId?: string;
48
+ model?: string;
49
+ manufacturer?: string;
50
+ osVersion?: string;
51
+ serialNumber?: string;
52
+ imei?: string;
53
+ macAddress?: string;
54
+ androidId?: string;
55
+ policyId?: string;
56
+ tags?: Record<string, string>;
57
+ metadata?: Record<string, unknown>;
58
+ }
59
+ interface UpdateDeviceInput {
60
+ externalId?: string | null;
61
+ status?: DeviceStatus;
62
+ policyId?: string | null;
63
+ model?: string;
64
+ manufacturer?: string;
65
+ osVersion?: string;
66
+ batteryLevel?: number | null;
67
+ storageUsed?: number | null;
68
+ storageTotal?: number | null;
69
+ lastHeartbeat?: Date;
70
+ lastSync?: Date;
71
+ installedApps?: InstalledApp[];
72
+ location?: DeviceLocation;
73
+ tags?: Record<string, string>;
74
+ metadata?: Record<string, unknown>;
75
+ }
76
+ interface DeviceFilter {
77
+ status?: DeviceStatus | DeviceStatus[];
78
+ policyId?: string;
79
+ groupId?: string;
80
+ search?: string;
81
+ tags?: Record<string, string>;
82
+ limit?: number;
83
+ offset?: number;
84
+ }
85
+ interface DeviceListResult {
86
+ devices: Device[];
87
+ total: number;
88
+ limit: number;
89
+ offset: number;
90
+ }
91
+ interface Policy {
92
+ id: string;
93
+ name: string;
94
+ description?: string | null;
95
+ isDefault: boolean;
96
+ settings: PolicySettings;
97
+ createdAt: Date;
98
+ updatedAt: Date;
99
+ }
100
+ interface PolicySettings {
101
+ kioskMode?: boolean;
102
+ mainApp?: string;
103
+ allowedApps?: string[];
104
+ kioskExitPassword?: string;
105
+ lockStatusBar?: boolean;
106
+ lockNavigationBar?: boolean;
107
+ lockSettings?: boolean;
108
+ lockPowerButton?: boolean;
109
+ blockInstall?: boolean;
110
+ blockUninstall?: boolean;
111
+ bluetooth?: HardwareControl;
112
+ wifi?: HardwareControl;
113
+ gps?: HardwareControl;
114
+ mobileData?: HardwareControl;
115
+ camera?: HardwareControl;
116
+ microphone?: HardwareControl;
117
+ usb?: HardwareControl;
118
+ nfc?: HardwareControl;
119
+ systemUpdatePolicy?: SystemUpdatePolicy;
120
+ updateWindow?: TimeWindow;
121
+ passwordPolicy?: PasswordPolicy;
122
+ encryptionRequired?: boolean;
123
+ factoryResetProtection?: boolean;
124
+ safeBootDisabled?: boolean;
125
+ heartbeatInterval?: number;
126
+ locationReportInterval?: number;
127
+ locationEnabled?: boolean;
128
+ wifiConfigs?: WifiConfig[];
129
+ vpnConfig?: VpnConfig;
130
+ applications?: PolicyApplication[];
131
+ custom?: Record<string, unknown>;
132
+ }
133
+ type HardwareControl = 'on' | 'off' | 'user';
134
+ type SystemUpdatePolicy = 'auto' | 'windowed' | 'postpone' | 'manual';
135
+ interface TimeWindow {
136
+ start: string;
137
+ end: string;
138
+ }
139
+ interface PasswordPolicy {
140
+ required: boolean;
141
+ minLength?: number;
142
+ complexity?: 'none' | 'numeric' | 'alphanumeric' | 'complex';
143
+ maxFailedAttempts?: number;
144
+ expirationDays?: number;
145
+ historyLength?: number;
146
+ }
147
+ interface WifiConfig {
148
+ ssid: string;
149
+ securityType: 'none' | 'wep' | 'wpa' | 'wpa2' | 'wpa3';
150
+ password?: string;
151
+ hidden?: boolean;
152
+ autoConnect?: boolean;
153
+ }
154
+ interface VpnConfig {
155
+ type: 'pptp' | 'l2tp' | 'ipsec' | 'openvpn' | 'wireguard';
156
+ server: string;
157
+ username?: string;
158
+ password?: string;
159
+ certificate?: string;
160
+ config?: Record<string, unknown>;
161
+ }
162
+ interface PolicyApplication {
163
+ packageName: string;
164
+ action: 'install' | 'update' | 'uninstall';
165
+ version?: string;
166
+ required?: boolean;
167
+ autoUpdate?: boolean;
168
+ }
169
+ interface CreatePolicyInput {
170
+ name: string;
171
+ description?: string;
172
+ isDefault?: boolean;
173
+ settings: PolicySettings;
174
+ }
175
+ interface UpdatePolicyInput {
176
+ name?: string;
177
+ description?: string | null;
178
+ isDefault?: boolean;
179
+ settings?: PolicySettings;
180
+ }
181
+ interface Application {
182
+ id: string;
183
+ name: string;
184
+ packageName: string;
185
+ version: string;
186
+ versionCode: number;
187
+ url: string;
188
+ hash?: string | null;
189
+ size?: number | null;
190
+ minSdkVersion?: number | null;
191
+ showIcon: boolean;
192
+ runAfterInstall: boolean;
193
+ runAtBoot: boolean;
194
+ isSystem: boolean;
195
+ isActive: boolean;
196
+ metadata?: Record<string, unknown> | null;
197
+ createdAt: Date;
198
+ updatedAt: Date;
199
+ }
200
+ interface CreateApplicationInput {
201
+ name: string;
202
+ packageName: string;
203
+ version: string;
204
+ versionCode: number;
205
+ url: string;
206
+ hash?: string;
207
+ size?: number;
208
+ minSdkVersion?: number;
209
+ showIcon?: boolean;
210
+ runAfterInstall?: boolean;
211
+ runAtBoot?: boolean;
212
+ isSystem?: boolean;
213
+ metadata?: Record<string, unknown>;
214
+ }
215
+ interface UpdateApplicationInput {
216
+ name?: string;
217
+ version?: string;
218
+ versionCode?: number;
219
+ url?: string;
220
+ hash?: string | null;
221
+ size?: number | null;
222
+ minSdkVersion?: number | null;
223
+ showIcon?: boolean;
224
+ runAfterInstall?: boolean;
225
+ runAtBoot?: boolean;
226
+ isActive?: boolean;
227
+ metadata?: Record<string, unknown> | null;
228
+ }
229
+ interface DeployTarget {
230
+ devices?: string[];
231
+ policies?: string[];
232
+ groups?: string[];
233
+ }
234
+ interface AppVersion {
235
+ id: string;
236
+ applicationId: string;
237
+ packageName: string;
238
+ version: string;
239
+ versionCode: number;
240
+ url: string;
241
+ hash?: string | null;
242
+ size?: number | null;
243
+ releaseNotes?: string | null;
244
+ isMinimumVersion: boolean;
245
+ createdAt: Date;
246
+ }
247
+ interface AppRollback {
248
+ id: string;
249
+ deviceId: string;
250
+ packageName: string;
251
+ fromVersion: string;
252
+ fromVersionCode: number;
253
+ toVersion: string;
254
+ toVersionCode: number;
255
+ reason?: string | null;
256
+ status: 'pending' | 'in_progress' | 'completed' | 'failed';
257
+ error?: string | null;
258
+ initiatedBy?: string | null;
259
+ createdAt: Date;
260
+ completedAt?: Date | null;
261
+ }
262
+ interface CreateAppRollbackInput {
263
+ deviceId: string;
264
+ packageName: string;
265
+ toVersionCode: number;
266
+ reason?: string;
267
+ initiatedBy?: string;
268
+ }
269
+ type CommandType = 'reboot' | 'shutdown' | 'sync' | 'lock' | 'unlock' | 'wipe' | 'factoryReset' | 'installApp' | 'uninstallApp' | 'updateApp' | 'runApp' | 'clearAppData' | 'clearAppCache' | 'shell' | 'setPolicy' | 'grantPermissions' | 'exitKiosk' | 'enterKiosk' | 'setWifi' | 'screenshot' | 'getLocation' | 'setVolume' | 'sendNotification' | 'whitelistBattery' | 'enablePermissiveMode' | 'setTimeZone' | 'enableAdb' | 'rollbackApp' | 'custom';
270
+ type CommandStatus = 'pending' | 'sent' | 'acknowledged' | 'completed' | 'failed' | 'cancelled';
271
+ interface Command {
272
+ id: string;
273
+ deviceId: string;
274
+ type: CommandType;
275
+ payload?: Record<string, unknown> | null;
276
+ status: CommandStatus;
277
+ result?: CommandResult | null;
278
+ error?: string | null;
279
+ createdAt: Date;
280
+ sentAt?: Date | null;
281
+ acknowledgedAt?: Date | null;
282
+ completedAt?: Date | null;
283
+ }
284
+ interface CommandResult {
285
+ success: boolean;
286
+ message?: string;
287
+ data?: unknown;
288
+ }
289
+ interface SendCommandInput {
290
+ deviceId: string;
291
+ type: CommandType;
292
+ payload?: Record<string, unknown>;
293
+ }
294
+ interface CommandFilter {
295
+ deviceId?: string;
296
+ status?: CommandStatus | CommandStatus[];
297
+ type?: CommandType | CommandType[];
298
+ limit?: number;
299
+ offset?: number;
300
+ }
301
+ type EventType = 'device.enrolled' | 'device.unenrolled' | 'device.blocked' | 'device.heartbeat' | 'device.locationUpdated' | 'device.statusChanged' | 'device.policyChanged' | 'app.installed' | 'app.uninstalled' | 'app.updated' | 'app.crashed' | 'app.started' | 'app.stopped' | 'policy.applied' | 'policy.failed' | 'command.received' | 'command.acknowledged' | 'command.completed' | 'command.failed' | 'security.tamper' | 'security.rootDetected' | 'security.screenLocked' | 'security.screenUnlocked' | 'custom';
302
+ interface MDMEvent<T = unknown> {
303
+ id: string;
304
+ deviceId: string;
305
+ type: EventType;
306
+ payload: T;
307
+ createdAt: Date;
308
+ }
309
+ interface EventFilter {
310
+ deviceId?: string;
311
+ type?: EventType | EventType[];
312
+ startDate?: Date;
313
+ endDate?: Date;
314
+ limit?: number;
315
+ offset?: number;
316
+ }
317
+ interface Group {
318
+ id: string;
319
+ name: string;
320
+ description?: string | null;
321
+ policyId?: string | null;
322
+ parentId?: string | null;
323
+ metadata?: Record<string, unknown> | null;
324
+ createdAt: Date;
325
+ updatedAt: Date;
326
+ }
327
+ interface CreateGroupInput {
328
+ name: string;
329
+ description?: string;
330
+ policyId?: string;
331
+ parentId?: string;
332
+ metadata?: Record<string, unknown>;
333
+ }
334
+ interface UpdateGroupInput {
335
+ name?: string;
336
+ description?: string | null;
337
+ policyId?: string | null;
338
+ parentId?: string | null;
339
+ metadata?: Record<string, unknown> | null;
340
+ }
341
+ type EnrollmentMethod = 'qr' | 'nfc' | 'zero-touch' | 'knox' | 'manual' | 'app-only' | 'adb';
342
+ interface EnrollmentRequest {
343
+ macAddress?: string;
344
+ serialNumber?: string;
345
+ imei?: string;
346
+ androidId?: string;
347
+ model: string;
348
+ manufacturer: string;
349
+ osVersion: string;
350
+ sdkVersion?: number;
351
+ agentVersion?: string;
352
+ agentPackage?: string;
353
+ method: EnrollmentMethod;
354
+ timestamp: string;
355
+ signature: string;
356
+ policyId?: string;
357
+ groupId?: string;
358
+ }
359
+ interface EnrollmentResponse {
360
+ deviceId: string;
361
+ enrollmentId: string;
362
+ policyId?: string;
363
+ policy?: Policy;
364
+ serverUrl: string;
365
+ pushConfig: PushConfig;
366
+ token: string;
367
+ refreshToken?: string;
368
+ tokenExpiresAt?: Date;
369
+ }
370
+ interface PushConfig {
371
+ provider: 'fcm' | 'mqtt' | 'websocket' | 'polling';
372
+ fcmSenderId?: string;
373
+ mqttUrl?: string;
374
+ mqttTopic?: string;
375
+ mqttUsername?: string;
376
+ mqttPassword?: string;
377
+ wsUrl?: string;
378
+ pollingInterval?: number;
379
+ }
380
+ interface Heartbeat {
381
+ deviceId: string;
382
+ timestamp: Date;
383
+ batteryLevel: number;
384
+ isCharging: boolean;
385
+ batteryHealth?: 'good' | 'overheat' | 'dead' | 'cold' | 'unknown';
386
+ storageUsed: number;
387
+ storageTotal: number;
388
+ memoryUsed: number;
389
+ memoryTotal: number;
390
+ networkType?: 'wifi' | 'cellular' | 'ethernet' | 'none';
391
+ networkName?: string;
392
+ signalStrength?: number;
393
+ ipAddress?: string;
394
+ location?: DeviceLocation;
395
+ installedApps: InstalledApp[];
396
+ runningApps?: string[];
397
+ isRooted?: boolean;
398
+ isEncrypted?: boolean;
399
+ screenLockEnabled?: boolean;
400
+ agentVersion?: string;
401
+ policyVersion?: string;
402
+ lastPolicySync?: Date;
403
+ }
404
+ interface PushToken {
405
+ id: string;
406
+ deviceId: string;
407
+ provider: 'fcm' | 'mqtt' | 'websocket';
408
+ token: string;
409
+ isActive: boolean;
410
+ createdAt: Date;
411
+ updatedAt: Date;
412
+ }
413
+ interface RegisterPushTokenInput {
414
+ deviceId: string;
415
+ provider: 'fcm' | 'mqtt' | 'websocket';
416
+ token: string;
417
+ }
418
+ interface MDMConfig {
419
+ /** Database adapter for persistence */
420
+ database: DatabaseAdapter;
421
+ /** Authentication/authorization configuration */
422
+ auth?: AuthConfig;
423
+ /** Push notification provider configuration */
424
+ push?: PushProviderConfig;
425
+ /** Device enrollment configuration */
426
+ enrollment?: EnrollmentConfig;
427
+ /** Server URL (used in enrollment responses) */
428
+ serverUrl?: string;
429
+ /** APK/file storage configuration */
430
+ storage?: StorageConfig;
431
+ /** Outbound webhook configuration */
432
+ webhooks?: WebhookConfig;
433
+ /** Plugins to extend functionality */
434
+ plugins?: MDMPlugin[];
435
+ /** Event handlers */
436
+ onDeviceEnrolled?: (device: Device) => Promise<void>;
437
+ onDeviceUnenrolled?: (device: Device) => Promise<void>;
438
+ onDeviceBlocked?: (device: Device) => Promise<void>;
439
+ onHeartbeat?: (device: Device, heartbeat: Heartbeat) => Promise<void>;
440
+ onCommand?: (command: Command) => Promise<void>;
441
+ onEvent?: (event: MDMEvent) => Promise<void>;
442
+ }
443
+ interface StorageConfig {
444
+ /** Storage provider (s3, local, custom) */
445
+ provider: 's3' | 'local' | 'custom';
446
+ /** S3 configuration */
447
+ s3?: {
448
+ bucket: string;
449
+ region: string;
450
+ accessKeyId?: string;
451
+ secretAccessKey?: string;
452
+ endpoint?: string;
453
+ presignedUrlExpiry?: number;
454
+ };
455
+ /** Local storage path */
456
+ localPath?: string;
457
+ /** Custom storage adapter */
458
+ customAdapter?: {
459
+ upload: (file: Buffer, key: string) => Promise<string>;
460
+ getUrl: (key: string) => Promise<string>;
461
+ delete: (key: string) => Promise<void>;
462
+ };
463
+ }
464
+ interface WebhookConfig {
465
+ /** Webhook endpoints to notify */
466
+ endpoints?: WebhookEndpoint[];
467
+ /** Retry configuration */
468
+ retry?: {
469
+ maxRetries?: number;
470
+ initialDelay?: number;
471
+ maxDelay?: number;
472
+ };
473
+ /** Sign webhooks with HMAC secret */
474
+ signingSecret?: string;
475
+ }
476
+ interface WebhookEndpoint {
477
+ /** Unique identifier */
478
+ id: string;
479
+ /** Webhook URL */
480
+ url: string;
481
+ /** Events to trigger this webhook */
482
+ events: (EventType | '*')[];
483
+ /** Custom headers */
484
+ headers?: Record<string, string>;
485
+ /** Whether endpoint is active */
486
+ enabled: boolean;
487
+ }
488
+ interface AuthConfig {
489
+ /** Get current user from request context */
490
+ getUser: <T = unknown>(context: unknown) => Promise<T | null>;
491
+ /** Check if user has admin privileges */
492
+ isAdmin?: (user: unknown) => Promise<boolean>;
493
+ /** Check if user can access specific device */
494
+ canAccessDevice?: (user: unknown, deviceId: string) => Promise<boolean>;
495
+ /** Device JWT secret (for device auth tokens) */
496
+ deviceTokenSecret?: string;
497
+ /** Device token expiration in seconds (default: 365 days) */
498
+ deviceTokenExpiration?: number;
499
+ }
500
+ interface PushProviderConfig {
501
+ provider: 'fcm' | 'mqtt' | 'websocket' | 'polling';
502
+ fcmCredentials?: string | Record<string, unknown>;
503
+ fcmProjectId?: string;
504
+ mqttUrl?: string;
505
+ mqttUsername?: string;
506
+ mqttPassword?: string;
507
+ mqttTopicPrefix?: string;
508
+ wsPath?: string;
509
+ wsPingInterval?: number;
510
+ pollingInterval?: number;
511
+ }
512
+ interface EnrollmentConfig {
513
+ /** Auto-enroll devices with valid signature */
514
+ autoEnroll?: boolean;
515
+ /** HMAC secret for device signature verification */
516
+ deviceSecret: string;
517
+ /** Allowed enrollment methods */
518
+ allowedMethods?: EnrollmentMethod[];
519
+ /** Default policy for new devices */
520
+ defaultPolicyId?: string;
521
+ /** Default group for new devices */
522
+ defaultGroupId?: string;
523
+ /** Require manual approval for enrollment */
524
+ requireApproval?: boolean;
525
+ /** Custom enrollment validation */
526
+ validate?: (request: EnrollmentRequest) => Promise<boolean>;
527
+ }
528
+ interface DatabaseAdapter {
529
+ findDevice(id: string): Promise<Device | null>;
530
+ findDeviceByEnrollmentId(enrollmentId: string): Promise<Device | null>;
531
+ listDevices(filter?: DeviceFilter): Promise<DeviceListResult>;
532
+ createDevice(data: CreateDeviceInput): Promise<Device>;
533
+ updateDevice(id: string, data: UpdateDeviceInput): Promise<Device>;
534
+ deleteDevice(id: string): Promise<void>;
535
+ countDevices(filter?: DeviceFilter): Promise<number>;
536
+ findPolicy(id: string): Promise<Policy | null>;
537
+ findDefaultPolicy(): Promise<Policy | null>;
538
+ listPolicies(): Promise<Policy[]>;
539
+ createPolicy(data: CreatePolicyInput): Promise<Policy>;
540
+ updatePolicy(id: string, data: UpdatePolicyInput): Promise<Policy>;
541
+ deletePolicy(id: string): Promise<void>;
542
+ findApplication(id: string): Promise<Application | null>;
543
+ findApplicationByPackage(packageName: string, version?: string): Promise<Application | null>;
544
+ listApplications(activeOnly?: boolean): Promise<Application[]>;
545
+ createApplication(data: CreateApplicationInput): Promise<Application>;
546
+ updateApplication(id: string, data: UpdateApplicationInput): Promise<Application>;
547
+ deleteApplication(id: string): Promise<void>;
548
+ findCommand(id: string): Promise<Command | null>;
549
+ listCommands(filter?: CommandFilter): Promise<Command[]>;
550
+ createCommand(data: SendCommandInput): Promise<Command>;
551
+ updateCommand(id: string, data: Partial<Command>): Promise<Command>;
552
+ getPendingCommands(deviceId: string): Promise<Command[]>;
553
+ createEvent(event: Omit<MDMEvent, 'id' | 'createdAt'>): Promise<MDMEvent>;
554
+ listEvents(filter?: EventFilter): Promise<MDMEvent[]>;
555
+ findGroup(id: string): Promise<Group | null>;
556
+ listGroups(): Promise<Group[]>;
557
+ createGroup(data: CreateGroupInput): Promise<Group>;
558
+ updateGroup(id: string, data: UpdateGroupInput): Promise<Group>;
559
+ deleteGroup(id: string): Promise<void>;
560
+ listDevicesInGroup(groupId: string): Promise<Device[]>;
561
+ addDeviceToGroup(deviceId: string, groupId: string): Promise<void>;
562
+ removeDeviceFromGroup(deviceId: string, groupId: string): Promise<void>;
563
+ getDeviceGroups(deviceId: string): Promise<Group[]>;
564
+ findPushToken(deviceId: string, provider: string): Promise<PushToken | null>;
565
+ upsertPushToken(data: RegisterPushTokenInput): Promise<PushToken>;
566
+ deletePushToken(deviceId: string, provider?: string): Promise<void>;
567
+ listAppVersions?(packageName: string): Promise<AppVersion[]>;
568
+ createAppVersion?(data: Omit<AppVersion, 'id' | 'createdAt'>): Promise<AppVersion>;
569
+ setMinimumVersion?(packageName: string, versionCode: number): Promise<void>;
570
+ getMinimumVersion?(packageName: string): Promise<AppVersion | null>;
571
+ createRollback?(data: CreateAppRollbackInput): Promise<AppRollback>;
572
+ updateRollback?(id: string, data: Partial<AppRollback>): Promise<AppRollback>;
573
+ listRollbacks?(filter?: {
574
+ deviceId?: string;
575
+ packageName?: string;
576
+ }): Promise<AppRollback[]>;
577
+ transaction?<T>(fn: () => Promise<T>): Promise<T>;
578
+ }
579
+ interface PushAdapter {
580
+ /** Send push message to a device */
581
+ send(deviceId: string, message: PushMessage): Promise<PushResult>;
582
+ /** Send push message to multiple devices */
583
+ sendBatch(deviceIds: string[], message: PushMessage): Promise<PushBatchResult>;
584
+ /** Register device push token */
585
+ registerToken?(deviceId: string, token: string): Promise<void>;
586
+ /** Unregister device push token */
587
+ unregisterToken?(deviceId: string): Promise<void>;
588
+ /** Subscribe device to topic */
589
+ subscribe?(deviceId: string, topic: string): Promise<void>;
590
+ /** Unsubscribe device from topic */
591
+ unsubscribe?(deviceId: string, topic: string): Promise<void>;
592
+ }
593
+ interface PushMessage {
594
+ type: string;
595
+ payload?: Record<string, unknown>;
596
+ priority?: 'high' | 'normal';
597
+ ttl?: number;
598
+ collapseKey?: string;
599
+ }
600
+ interface PushResult {
601
+ success: boolean;
602
+ messageId?: string;
603
+ error?: string;
604
+ }
605
+ interface PushBatchResult {
606
+ successCount: number;
607
+ failureCount: number;
608
+ results: Array<{
609
+ deviceId: string;
610
+ result: PushResult;
611
+ }>;
612
+ }
613
+ interface MDMPlugin {
614
+ /** Unique plugin name */
615
+ name: string;
616
+ /** Plugin version */
617
+ version: string;
618
+ /** Called when MDM is initialized */
619
+ onInit?(mdm: MDMInstance): Promise<void>;
620
+ /** Called when MDM is destroyed */
621
+ onDestroy?(): Promise<void>;
622
+ /** Additional routes to mount */
623
+ routes?: PluginRoute[];
624
+ /** Middleware to apply to all routes */
625
+ middleware?: PluginMiddleware[];
626
+ /** Extend enrollment process */
627
+ onEnroll?(device: Device, request: EnrollmentRequest): Promise<void>;
628
+ /** Extend device processing */
629
+ onDeviceEnrolled?(device: Device): Promise<void>;
630
+ onDeviceUnenrolled?(device: Device): Promise<void>;
631
+ onHeartbeat?(device: Device, heartbeat: Heartbeat): Promise<void>;
632
+ /** Extend policy processing */
633
+ policySchema?: Record<string, unknown>;
634
+ validatePolicy?(settings: PolicySettings): Promise<{
635
+ valid: boolean;
636
+ errors?: string[];
637
+ }>;
638
+ applyPolicy?(device: Device, policy: Policy): Promise<void>;
639
+ /** Extend command processing */
640
+ commandTypes?: CommandType[];
641
+ executeCommand?(device: Device, command: Command): Promise<CommandResult>;
642
+ }
643
+ interface PluginRoute {
644
+ method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
645
+ path: string;
646
+ handler: (context: unknown) => Promise<unknown>;
647
+ auth?: boolean;
648
+ admin?: boolean;
649
+ }
650
+ type PluginMiddleware = (context: unknown, next: () => Promise<unknown>) => Promise<unknown>;
651
+ interface WebhookManager {
652
+ /** Deliver an event to all matching webhook endpoints */
653
+ deliver<T>(event: MDMEvent<T>): Promise<WebhookDeliveryResult[]>;
654
+ /** Add a webhook endpoint at runtime */
655
+ addEndpoint(endpoint: WebhookEndpoint): void;
656
+ /** Remove a webhook endpoint */
657
+ removeEndpoint(endpointId: string): void;
658
+ /** Update a webhook endpoint */
659
+ updateEndpoint(endpointId: string, updates: Partial<WebhookEndpoint>): void;
660
+ /** Get all configured endpoints */
661
+ getEndpoints(): WebhookEndpoint[];
662
+ /** Test a webhook endpoint with a test payload */
663
+ testEndpoint(endpointId: string): Promise<WebhookDeliveryResult>;
664
+ }
665
+ interface WebhookDeliveryResult {
666
+ endpointId: string;
667
+ success: boolean;
668
+ statusCode?: number;
669
+ error?: string;
670
+ retryCount: number;
671
+ deliveredAt?: Date;
672
+ }
673
+ interface MDMInstance {
674
+ /** Device management */
675
+ devices: DeviceManager;
676
+ /** Policy management */
677
+ policies: PolicyManager;
678
+ /** Application management */
679
+ apps: ApplicationManager;
680
+ /** Command management */
681
+ commands: CommandManager;
682
+ /** Group management */
683
+ groups: GroupManager;
684
+ /** Push notification service */
685
+ push: PushAdapter;
686
+ /** Webhook delivery (if configured) */
687
+ webhooks?: WebhookManager;
688
+ /** Database adapter */
689
+ db: DatabaseAdapter;
690
+ /** Configuration */
691
+ config: MDMConfig;
692
+ /** Subscribe to events */
693
+ on<T extends EventType>(event: T, handler: EventHandler<T>): () => void;
694
+ /** Emit an event */
695
+ emit<T extends EventType>(event: T, data: EventPayloadMap[T]): Promise<void>;
696
+ /** Process device enrollment */
697
+ enroll(request: EnrollmentRequest): Promise<EnrollmentResponse>;
698
+ /** Process device heartbeat */
699
+ processHeartbeat(deviceId: string, heartbeat: Heartbeat): Promise<void>;
700
+ /** Verify device token */
701
+ verifyDeviceToken(token: string): Promise<{
702
+ deviceId: string;
703
+ } | null>;
704
+ /** Get loaded plugins */
705
+ getPlugins(): MDMPlugin[];
706
+ /** Get plugin by name */
707
+ getPlugin(name: string): MDMPlugin | undefined;
708
+ }
709
+ interface DeviceManager {
710
+ get(id: string): Promise<Device | null>;
711
+ getByEnrollmentId(enrollmentId: string): Promise<Device | null>;
712
+ list(filter?: DeviceFilter): Promise<DeviceListResult>;
713
+ create(data: CreateDeviceInput): Promise<Device>;
714
+ update(id: string, data: UpdateDeviceInput): Promise<Device>;
715
+ delete(id: string): Promise<void>;
716
+ assignPolicy(deviceId: string, policyId: string | null): Promise<Device>;
717
+ addToGroup(deviceId: string, groupId: string): Promise<void>;
718
+ removeFromGroup(deviceId: string, groupId: string): Promise<void>;
719
+ getGroups(deviceId: string): Promise<Group[]>;
720
+ sendCommand(deviceId: string, input: Omit<SendCommandInput, 'deviceId'>): Promise<Command>;
721
+ sync(deviceId: string): Promise<Command>;
722
+ reboot(deviceId: string): Promise<Command>;
723
+ lock(deviceId: string, message?: string): Promise<Command>;
724
+ wipe(deviceId: string, preserveData?: boolean): Promise<Command>;
725
+ }
726
+ interface PolicyManager {
727
+ get(id: string): Promise<Policy | null>;
728
+ getDefault(): Promise<Policy | null>;
729
+ list(): Promise<Policy[]>;
730
+ create(data: CreatePolicyInput): Promise<Policy>;
731
+ update(id: string, data: UpdatePolicyInput): Promise<Policy>;
732
+ delete(id: string): Promise<void>;
733
+ setDefault(id: string): Promise<Policy>;
734
+ getDevices(policyId: string): Promise<Device[]>;
735
+ applyToDevice(policyId: string, deviceId: string): Promise<void>;
736
+ }
737
+ interface ApplicationManager {
738
+ get(id: string): Promise<Application | null>;
739
+ getByPackage(packageName: string, version?: string): Promise<Application | null>;
740
+ list(activeOnly?: boolean): Promise<Application[]>;
741
+ register(data: CreateApplicationInput): Promise<Application>;
742
+ update(id: string, data: UpdateApplicationInput): Promise<Application>;
743
+ delete(id: string): Promise<void>;
744
+ activate(id: string): Promise<Application>;
745
+ deactivate(id: string): Promise<Application>;
746
+ deploy(packageName: string, target: DeployTarget): Promise<void>;
747
+ installOnDevice(packageName: string, deviceId: string, version?: string): Promise<Command>;
748
+ uninstallFromDevice(packageName: string, deviceId: string): Promise<Command>;
749
+ }
750
+ interface CommandManager {
751
+ get(id: string): Promise<Command | null>;
752
+ list(filter?: CommandFilter): Promise<Command[]>;
753
+ send(input: SendCommandInput): Promise<Command>;
754
+ cancel(id: string): Promise<Command>;
755
+ acknowledge(id: string): Promise<Command>;
756
+ complete(id: string, result: CommandResult): Promise<Command>;
757
+ fail(id: string, error: string): Promise<Command>;
758
+ getPending(deviceId: string): Promise<Command[]>;
759
+ }
760
+ interface GroupManager {
761
+ get(id: string): Promise<Group | null>;
762
+ list(): Promise<Group[]>;
763
+ create(data: CreateGroupInput): Promise<Group>;
764
+ update(id: string, data: UpdateGroupInput): Promise<Group>;
765
+ delete(id: string): Promise<void>;
766
+ getDevices(groupId: string): Promise<Device[]>;
767
+ addDevice(groupId: string, deviceId: string): Promise<void>;
768
+ removeDevice(groupId: string, deviceId: string): Promise<void>;
769
+ getChildren(groupId: string): Promise<Group[]>;
770
+ }
771
+ type EventHandler<T extends EventType> = (event: MDMEvent<EventPayloadMap[T]>) => Promise<void> | void;
772
+ interface EventPayloadMap {
773
+ 'device.enrolled': {
774
+ device: Device;
775
+ };
776
+ 'device.unenrolled': {
777
+ device: Device;
778
+ reason?: string;
779
+ };
780
+ 'device.blocked': {
781
+ device: Device;
782
+ reason: string;
783
+ };
784
+ 'device.heartbeat': {
785
+ device: Device;
786
+ heartbeat: Heartbeat;
787
+ };
788
+ 'device.locationUpdated': {
789
+ device: Device;
790
+ location: DeviceLocation;
791
+ };
792
+ 'device.statusChanged': {
793
+ device: Device;
794
+ oldStatus: DeviceStatus;
795
+ newStatus: DeviceStatus;
796
+ };
797
+ 'device.policyChanged': {
798
+ device: Device;
799
+ oldPolicyId?: string;
800
+ newPolicyId?: string;
801
+ };
802
+ 'app.installed': {
803
+ device: Device;
804
+ app: InstalledApp;
805
+ };
806
+ 'app.uninstalled': {
807
+ device: Device;
808
+ packageName: string;
809
+ };
810
+ 'app.updated': {
811
+ device: Device;
812
+ app: InstalledApp;
813
+ oldVersion: string;
814
+ };
815
+ 'app.crashed': {
816
+ device: Device;
817
+ packageName: string;
818
+ error?: string;
819
+ };
820
+ 'app.started': {
821
+ device: Device;
822
+ packageName: string;
823
+ };
824
+ 'app.stopped': {
825
+ device: Device;
826
+ packageName: string;
827
+ };
828
+ 'policy.applied': {
829
+ device: Device;
830
+ policy: Policy;
831
+ };
832
+ 'policy.failed': {
833
+ device: Device;
834
+ policy: Policy;
835
+ error: string;
836
+ };
837
+ 'command.received': {
838
+ device: Device;
839
+ command: Command;
840
+ };
841
+ 'command.acknowledged': {
842
+ device: Device;
843
+ command: Command;
844
+ };
845
+ 'command.completed': {
846
+ device: Device;
847
+ command: Command;
848
+ result: CommandResult;
849
+ };
850
+ 'command.failed': {
851
+ device: Device;
852
+ command: Command;
853
+ error: string;
854
+ };
855
+ 'security.tamper': {
856
+ device: Device;
857
+ type: string;
858
+ details?: unknown;
859
+ };
860
+ 'security.rootDetected': {
861
+ device: Device;
862
+ };
863
+ 'security.screenLocked': {
864
+ device: Device;
865
+ };
866
+ 'security.screenUnlocked': {
867
+ device: Device;
868
+ };
869
+ custom: Record<string, unknown>;
870
+ }
871
+ declare class MDMError extends Error {
872
+ code: string;
873
+ statusCode: number;
874
+ details?: unknown | undefined;
875
+ constructor(message: string, code: string, statusCode?: number, details?: unknown | undefined);
876
+ }
877
+ declare class DeviceNotFoundError extends MDMError {
878
+ constructor(deviceId: string);
879
+ }
880
+ declare class PolicyNotFoundError extends MDMError {
881
+ constructor(policyId: string);
882
+ }
883
+ declare class ApplicationNotFoundError extends MDMError {
884
+ constructor(identifier: string);
885
+ }
886
+ declare class EnrollmentError extends MDMError {
887
+ constructor(message: string, details?: unknown);
888
+ }
889
+ declare class AuthenticationError extends MDMError {
890
+ constructor(message?: string);
891
+ }
892
+ declare class AuthorizationError extends MDMError {
893
+ constructor(message?: string);
894
+ }
895
+ declare class ValidationError extends MDMError {
896
+ constructor(message: string, details?: unknown);
897
+ }
898
+
899
+ export { type AppRollback, type AppVersion, type Application, type ApplicationManager, ApplicationNotFoundError, type AuthConfig, AuthenticationError, AuthorizationError, type Command, type CommandFilter, type CommandManager, type CommandResult, type CommandStatus, type CommandType, type CreateAppRollbackInput, type CreateApplicationInput, type CreateDeviceInput, type CreateGroupInput, type CreatePolicyInput, type DatabaseAdapter, type DeployTarget, type Device, type DeviceFilter, type DeviceListResult, type DeviceLocation, type DeviceManager, DeviceNotFoundError, type DeviceStatus, type EnrollmentConfig, EnrollmentError, type EnrollmentMethod, type EnrollmentRequest, type EnrollmentResponse, type EventFilter, type EventHandler, type EventPayloadMap, type EventType, type Group, type GroupManager, type HardwareControl, type Heartbeat, type InstalledApp, type MDMConfig, MDMError, type MDMEvent, type MDMInstance, type MDMPlugin, type PasswordPolicy, type PluginMiddleware, type PluginRoute, type Policy, type PolicyApplication, type PolicyManager, PolicyNotFoundError, type PolicySettings, type PushAdapter, type PushBatchResult, type PushConfig, type PushMessage, type PushProviderConfig, type PushResult, type PushToken, type RegisterPushTokenInput, type SendCommandInput, type StorageConfig, type SystemUpdatePolicy, type TimeWindow, type UpdateApplicationInput, type UpdateDeviceInput, type UpdateGroupInput, type UpdatePolicyInput, ValidationError, type VpnConfig, type WebhookConfig, type WebhookDeliveryResult, type WebhookEndpoint, type WebhookManager, type WifiConfig };