Files
step-web/src/routes/certificates/create/+page.server.ts
2026-03-24 21:33:48 +08:00

55 lines
2.1 KiB
TypeScript

import { fail, redirect } from '@sveltejs/kit';
import { getDb } from '$lib/server/db';
import { createCertificate, createP12 } from '$lib/server/step';
import { logAudit } from '$lib/server/audit';
import crypto from 'crypto';
export const actions = {
default: async (event: import('@sveltejs/kit').RequestEvent) => {
const data = await event.request.formData();
const deviceName = data.get('device_name')?.toString() || '';
const subject = data.get('subject')?.toString() || '';
const hours = parseInt(data.get('hours')?.toString() || '8760', 10);
const exportP12 = data.get('export_p12') === 'on';
const p12Password = data.get('p12_password')?.toString() || '';
if (!deviceName || !subject || isNaN(hours)) {
return fail(400, { error: 'Missing required fields' });
}
if (exportP12 && !p12Password) {
return fail(400, { error: 'p12 password required if exporting p12' });
}
try {
// generate serial number roughly matching the cert if step output differs, or just a unique ID.
// step ca doesn't easily output the exact serial in simple exec without inspect command,
// so we will just create a unique internal reference for our DB tracking if necessary,
// or parse it from `step certificate inspect`
// For this basic MVP, we generate a UUID for the db relation to file.
const serialNumber = crypto.randomUUID();
const { crtFile } = await createCertificate(deviceName, subject, hours);
if (exportP12) {
await createP12(deviceName, p12Password);
}
const db = getDb();
const expiresAt = new Date();
expiresAt.setHours(expiresAt.getHours() + hours);
const stmt = db.prepare(`
INSERT INTO certificates (device_name, subject, serial_number, status, expires_at, file_path, created_by)
VALUES (?, ?, ?, 'active', ?, ?, 'admin')
`);
stmt.run(deviceName, subject, serialNumber, expiresAt.toISOString(), crtFile);
logAudit('create_cert', `Created device cert ${deviceName}`, 'admin', event.getClientAddress());
} catch (err: any) {
return fail(500, { error: err.message || 'Failed to create certificate' });
}
throw redirect(303, '/certificates');
}
};