Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions apps/api/src/device-agent/device-agent.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,8 @@ export class DeviceAgentController {
@AuthContext() authContext: AuthContextType,
@Response({ passthrough: true }) res: ExpressResponse,
) {
// Use the authenticated user's ID as the employee ID
const employeeId = authContext.userId || 'unknown-user';

const { stream, filename, contentType } =
await this.deviceAgentService.downloadWindowsAgent(
organizationId,
employeeId,
);
await this.deviceAgentService.downloadWindowsAgent();

// Set headers for file download
res.set({
Expand Down
91 changes: 18 additions & 73 deletions apps/api/src/device-agent/device-agent.service.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
import { Injectable, NotFoundException, Logger } from '@nestjs/common';
import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3';
import { Readable, PassThrough } from 'stream';
import archiver from 'archiver';
import { generateWindowsScript } from './scripts/windows';
import {
getPackageFilename,
getReadmeContent,
getScriptFilename,
} from './scripts/common';
import { Readable } from 'stream';

@Injectable()
export class DeviceAgentService {
Expand Down Expand Up @@ -73,56 +66,12 @@ export class DeviceAgentService {
}
}

async downloadWindowsAgent(
organizationId: string,
employeeId: string,
): Promise<{ stream: Readable; filename: string; contentType: string }> {
async downloadWindowsAgent(): Promise<{ stream: Readable; filename: string; contentType: string }> {
try {
this.logger.log(
`Creating Windows agent zip for org ${organizationId}, employee ${employeeId}`,
);

// Hardcoded device marker paths used by the setup scripts
const fleetDevicePathWindows = 'C:\\ProgramData\\CompAI\\Fleet';

// Generate the Windows setup script
const script = generateWindowsScript({
orgId: organizationId,
employeeId: employeeId,
fleetDevicePath: fleetDevicePathWindows,
});

// Create a passthrough stream for the response
const passThrough = new PassThrough();
const archive = archiver('zip', { zlib: { level: 9 } });

// Pipe archive to passthrough
archive.pipe(passThrough);

// Error handling for the archive
archive.on('error', (err) => {
this.logger.error('Archive error:', err);
passThrough.destroy(err);
});

archive.on('warning', (warn) => {
this.logger.warn('Archive warning:', warn);
});

// Add script file
const scriptFilename = getScriptFilename('windows');
archive.append(script, { name: scriptFilename, mode: 0o755 });

// Add README
const readmeContent = getReadmeContent('windows');
archive.append(readmeContent, { name: 'README.txt' });

// Get MSI package from S3 and stream it into the zip
const windowsPackageFilename = 'fleet-osquery.msi';
const windowsPackageFilename = 'Comp AI Agent 1.0.0.exe';
const packageKey = `windows/${windowsPackageFilename}`;
const packageFilename = getPackageFilename('windows');

this.logger.log(`Downloading Windows MSI from S3: ${packageKey}`);
this.logger.log(`Downloading Windows agent from S3: ${packageKey}`);

const getObjectCommand = new GetObjectCommand({
Bucket: this.fleetBucketName,
Expand All @@ -131,31 +80,27 @@ export class DeviceAgentService {

const s3Response = await this.s3Client.send(getObjectCommand);

if (s3Response.Body) {
const s3Stream = s3Response.Body as Readable;
s3Stream.on('error', (err) => {
this.logger.error('S3 stream error:', err);
passThrough.destroy(err);
});
archive.append(s3Stream, { name: packageFilename, store: true });
} else {
this.logger.warn(
'Windows MSI file not found in S3, creating zip without MSI',
);
if (!s3Response.Body) {
throw new NotFoundException('Windows agent executable file not found in S3');
}

// Finalize the archive
archive.finalize();
// Use S3 stream directly as Node.js Readable
const s3Stream = s3Response.Body as Readable;

this.logger.log('Successfully created Windows agent zip');
this.logger.log(
`Successfully retrieved Windows agent: ${windowsPackageFilename}`,
);

return {
stream: passThrough,
filename: `compai-device-agent-windows.zip`,
contentType: 'application/zip',
stream: s3Stream,
filename: windowsPackageFilename,
contentType: 'application/octet-stream',
};
} catch (error) {
this.logger.error('Failed to create Windows agent zip:', error);
if (error instanceof NotFoundException) {
throw error;
}
this.logger.error('Failed to download Windows agent from S3:', error);
throw error;
}
}
Expand Down
35 changes: 0 additions & 35 deletions apps/api/src/device-agent/scripts/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,3 @@ export function getScriptFilename(os: SupportedOS): string {
export function getPackageFilename(os: SupportedOS): string {
return os === 'macos' ? 'compai-device-agent.pkg' : 'compai-device-agent.msi';
}

export function getReadmeContent(os: SupportedOS): string {
if (os === 'macos') {
return `Installation Instructions for macOS:

1. First, run the setup script by double-clicking "run_me_first.command"
- This will create the necessary organization markers for device management
- You may need to allow the script to run in System Preferences > Security & Privacy

2. Then, install the agent by double-clicking "compai-device-agent.pkg"
- Follow the installation wizard
- You may need to allow the installer in System Preferences > Security & Privacy

3. The agent will start automatically after installation
`;
}

return `Installation Instructions for Windows:

1. First, run the setup script:
- Right-click on "run_me_first.bat" and select "Run as administrator" (required)
- This writes organization markers to the device and registry
- If prompted by SmartScreen, click "More info" -> "Run anyway"

2. Then, install the agent:
- Double-click "compai-device-agent.msi" and follow the wizard

3. Troubleshooting:
- If setup fails, open the log at: %ProgramData%\\CompAI\\Fleet or %Public%\\CompAI\\Fleet -> setup.log
- Ensure your antivirus or endpoint protection allows running local .bat files
- If you cannot run as administrator, ask IT to assist or install both files and registry keys manually

4. After installation, the agent will start automatically.
`;
}
222 changes: 0 additions & 222 deletions apps/api/src/device-agent/scripts/windows.ts

This file was deleted.

Loading
Loading