// src/integrations/mdmcorp/client.js import axios from 'axios'; import { logger } from '../../utils/logger.js'; let accessToken = null; let tokenExpiresAt = 0; const mdmcorpAxios = axios.create({ baseURL: process.env.CORP_WS1_API_BASE, timeout: 15000, headers: { 'Accept': 'application/json', }, }); // Get OAuth token using client_credentials flow (for CORP MDM) async function getMDMCorpToken() { const now = Date.now(); if (accessToken && now < tokenExpiresAt) { return accessToken; } logger('mdmcorp:auth', 'Requesting new CORP MDM token'); try { const response = await axios.post( 'https://na.uemauth.workspaceone.com/connect/token', // Workspace ONE auth endpoint new URLSearchParams({ grant_type: 'client_credentials', client_id: process.env.CORP_WS1_CLIENT_ID, client_secret: process.env.CORP_WS1_CLIENT_SECRET, }), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, } ); accessToken = response.data.access_token; tokenExpiresAt = now + (response.data.expires_in * 1000) - 300000; // 5 min buffer logger('mdmcorp:auth', 'CORP MDM token acquired successfully'); return accessToken; } catch (err) { logger('mdmcorp:auth', `Token request failed: ${err.message}`, 'error'); throw new Error('Failed to obtain CORP MDM token'); } } // Add token to every request mdmcorpAxios.interceptors.request.use(async (cfg) => { const token = await getMDMCorpToken(); cfg.headers.Authorization = `Bearer ${token}`; cfg.headers['aw-tenant-code'] = process.env.CORP_WS1_TENANT_CODE; logger('mdmcorp:request', `${cfg.method.toUpperCase()} ${cfg.url}`); return cfg; }); mdmcorpAxios.interceptors.response.use( res => res, err => { const msg = err.response ? `${err.response.status} - ${JSON.stringify(err.response.data?.message || err.response.data)}` : err.message; logger('mdmcorp:error', msg, 'error'); return Promise.reject(err); } ); /** * Search devices by email in the CORP MDM instance * Uses only the username part (before @) as required by this tenant */ export async function findDevicesByEmail(fullEmail) { if (!fullEmail) return []; // Extract username only (e.g. "bollandd" from "bollandd@ae.com") const username = fullEmail.split('@')[0].trim(); if (!username) return []; logger('mdmcorp:device', `Searching CORP MDM for username: ${username} (from ${fullEmail})`); try { const response = await mdmcorpAxios.get('/api/mdm/devices/search', { params: { user: username } }); const devices = response.data?.Devices || response.data || []; logger('mdmcorp:device', `Found ${devices.length} devices for username ${username}`); // Optional: log first device for debugging if (devices.length > 0) { logger('mdmcorp:device', `First device: ${JSON.stringify(devices[0], null, 2)}`, 'debug'); } return devices; } catch (err) { logger('mdmcorp:device', `Search failed for ${username}: ${err.response?.status || err.message}`, 'error'); return []; } } /** * Perform Enterprise Wipe on a device */ export async function enterpriseWipe(deviceId) { if (!deviceId) throw new Error('Device ID is required'); try { const response = await mdmcorpAxios.post(`/api/mdm/devices/${deviceId}/commands/enterpriseWipe`); logger('mdmcorp:wipe', `Enterprise wipe initiated for device ${deviceId}`); return response.data; } catch (err) { logger('mdmcorp:wipe', `Failed to wipe device ${deviceId}: ${err.message}`, 'error'); throw err; } } export default mdmcorpAxios;