|
1 | | -import { auth } from '@/app/lib/auth'; |
2 | 1 | import { logger } from '@/utils/logger'; |
3 | 2 | import { s3Client } from '@/utils/s3'; |
4 | 3 | import { GetObjectCommand } from '@aws-sdk/client-s3'; |
5 | 4 | import { client as kv } from '@comp/kv'; |
6 | 5 | import archiver from 'archiver'; |
7 | 6 | import { type NextRequest, NextResponse } from 'next/server'; |
8 | 7 | import { PassThrough, Readable } from 'stream'; |
9 | | -import { createFleetLabel } from './fleet-label'; |
10 | 8 | import { |
11 | 9 | generateMacScript, |
12 | 10 | generateWindowsScript, |
13 | 11 | getPackageFilename, |
14 | 12 | getReadmeContent, |
15 | 13 | getScriptFilename, |
16 | 14 | } from './scripts'; |
17 | | -import type { DownloadAgentRequest, SupportedOS } from './types'; |
18 | | -import { detectOSFromUserAgent, validateMemberAndOrg } from './utils'; |
19 | 15 |
|
20 | 16 | // GET handler for direct browser downloads using token |
21 | 17 | export async function GET(req: NextRequest) { |
@@ -110,132 +106,3 @@ export async function GET(req: NextRequest) { |
110 | 106 | return new NextResponse('Failed to create download', { status: 500 }); |
111 | 107 | } |
112 | 108 | } |
113 | | - |
114 | | -// POST handler remains the same for backward compatibility or direct API usage |
115 | | -export async function POST(req: NextRequest) { |
116 | | - // Authentication |
117 | | - const session = await auth.api.getSession({ |
118 | | - headers: req.headers, |
119 | | - }); |
120 | | - |
121 | | - if (!session?.user) { |
122 | | - return new NextResponse('Unauthorized', { status: 401 }); |
123 | | - } |
124 | | - |
125 | | - // Validate request body |
126 | | - const { orgId, employeeId }: DownloadAgentRequest = await req.json(); |
127 | | - |
128 | | - if (!orgId || !employeeId) { |
129 | | - return new NextResponse('Missing orgId or employeeId', { status: 400 }); |
130 | | - } |
131 | | - |
132 | | - // Auto-detect OS from User-Agent |
133 | | - const userAgent = req.headers.get('user-agent'); |
134 | | - const detectedOS = detectOSFromUserAgent(userAgent); |
135 | | - |
136 | | - if (!detectedOS) { |
137 | | - return new NextResponse( |
138 | | - 'Could not detect OS from User-Agent. Please use a standard browser on macOS or Windows.', |
139 | | - { status: 400 }, |
140 | | - ); |
141 | | - } |
142 | | - |
143 | | - const os = detectedOS; |
144 | | - logger('Auto-detected OS from User-Agent', { os, userAgent }); |
145 | | - |
146 | | - // Check environment configuration |
147 | | - const fleetDevicePathMac = process.env.FLEET_DEVICE_PATH_MAC; |
148 | | - const fleetDevicePathWindows = process.env.FLEET_DEVICE_PATH_WINDOWS; |
149 | | - const fleetBucketName = process.env.FLEET_AGENT_BUCKET_NAME; |
150 | | - |
151 | | - if (!fleetDevicePathMac || !fleetDevicePathWindows) { |
152 | | - logger( |
153 | | - 'FLEET_DEVICE_PATH_MAC or FLEET_DEVICE_PATH_WINDOWS not configured in environment variables', |
154 | | - ); |
155 | | - return new NextResponse( |
156 | | - 'Server configuration error: FLEET_DEVICE_PATH_MAC or FLEET_DEVICE_PATH_WINDOWS is missing.', |
157 | | - { |
158 | | - status: 500, |
159 | | - }, |
160 | | - ); |
161 | | - } |
162 | | - |
163 | | - if (!fleetBucketName) { |
164 | | - return new NextResponse('Server configuration error: Fleet bucket name is missing.', { |
165 | | - status: 500, |
166 | | - }); |
167 | | - } |
168 | | - |
169 | | - // Validate member and organization |
170 | | - const member = await validateMemberAndOrg(session.user.id, orgId); |
171 | | - if (!member) { |
172 | | - return new NextResponse('Member not found or organization invalid', { status: 404 }); |
173 | | - } |
174 | | - |
175 | | - // Generate OS-specific script |
176 | | - const fleetDevicePath = os === 'macos' ? fleetDevicePathMac : fleetDevicePathWindows; |
177 | | - const script = |
178 | | - os === 'macos' |
179 | | - ? generateMacScript({ orgId, employeeId, fleetDevicePath }) |
180 | | - : generateWindowsScript({ orgId, employeeId, fleetDevicePath }); |
181 | | - |
182 | | - try { |
183 | | - // Create Fleet label |
184 | | - await createFleetLabel({ |
185 | | - employeeId, |
186 | | - memberId: member.id, |
187 | | - os: os as SupportedOS, |
188 | | - fleetDevicePathMac, |
189 | | - fleetDevicePathWindows, |
190 | | - }); |
191 | | - |
192 | | - // Create a passthrough stream for the response |
193 | | - const passThrough = new PassThrough(); |
194 | | - const archive = archiver('zip', { zlib: { level: 9 } }); |
195 | | - |
196 | | - // Pipe archive to passthrough |
197 | | - archive.pipe(passThrough); |
198 | | - |
199 | | - // Add script file |
200 | | - const scriptFilename = getScriptFilename(os); |
201 | | - archive.append(script, { name: scriptFilename, mode: 0o755 }); |
202 | | - |
203 | | - // Add README |
204 | | - const readmeContent = getReadmeContent(os); |
205 | | - archive.append(readmeContent, { name: 'README.txt' }); |
206 | | - |
207 | | - // Get package from S3 and stream it |
208 | | - const packageFilename = getPackageFilename(os); |
209 | | - const packageKey = `${os}/fleet-osquery.${os === 'macos' ? 'pkg' : 'msi'}`; |
210 | | - |
211 | | - const getObjectCommand = new GetObjectCommand({ |
212 | | - Bucket: fleetBucketName, |
213 | | - Key: packageKey, |
214 | | - }); |
215 | | - |
216 | | - const s3Response = await s3Client.send(getObjectCommand); |
217 | | - |
218 | | - if (s3Response.Body) { |
219 | | - const s3Stream = s3Response.Body as Readable; |
220 | | - archive.append(s3Stream, { name: packageFilename, store: true }); |
221 | | - } |
222 | | - |
223 | | - // Finalize the archive |
224 | | - archive.finalize(); |
225 | | - |
226 | | - // Convert Node.js stream to Web Stream for NextResponse |
227 | | - const webStream = Readable.toWeb(passThrough) as unknown as ReadableStream; |
228 | | - |
229 | | - // Return streaming response |
230 | | - return new NextResponse(webStream, { |
231 | | - headers: { |
232 | | - 'Content-Type': 'application/zip', |
233 | | - 'Content-Disposition': `attachment; filename="compai-device-agent-${os}.zip"`, |
234 | | - 'Cache-Control': 'no-cache', |
235 | | - }, |
236 | | - }); |
237 | | - } catch (error) { |
238 | | - logger('Error creating agent download', { error }); |
239 | | - return new NextResponse('Failed to create download', { status: 500 }); |
240 | | - } |
241 | | -} |
0 commit comments