Ground-Zerro / Phobos Public
Code Issues Pull requests Actions Releases View on GitHub ↗
2.0 KB typescript
import { z } from 'zod';
import {
  hasActiveTlsCert,
  isExternalTlsManaged,
} from '~~/server/utils/TlsInfo';

const TlsUpdateSchema = z.discriminatedUnion('mode', [
  z.object({ mode: z.literal('self-signed') }),
  z.object({
    mode: z.literal('import'),
    cert: z.string().min(1),
    key: z.string().min(1),
  }),
  z.object({
    mode: z.literal('import-path'),
    certPath: z.string().min(1),
    keyPath: z.string().min(1),
  }),
  z.object({ mode: z.literal('skip') }),
]);

export default definePermissionEventHandler('admin', 'any', async ({ event }) => {
  const body = await readValidatedBody(event, validateZod(TlsUpdateSchema, event));

  if (isExternalTlsManaged()) {
    if (!hasActiveTlsCert() && body.mode !== 'skip') {
      throw createError({
        statusCode: 400,
        statusMessage:
          'TLS is managed by the external reverse proxy. Issue or activate the certificate on the host first.',
      });
    }

    await Database.general.setAllowInsecureHttpLogin(false);
    return { success: true, httpsUrl: null };
  }

  if (body.mode === 'skip') {
    await Database.general.setAllowInsecureHttpLogin(true);
    scheduleNodeRestart();
    return { success: true, httpsUrl: null };
  }

  await Database.general.setAllowInsecureHttpLogin(false);

  const userConfig = await Database.userConfigs.get();
  const host = userConfig.host;
  const port = process.env.PORT ?? '51831';

  try {
    if (body.mode === 'self-signed') {
      generateSelfSigned(host);
    } else if (body.mode === 'import') {
      importCert(body.cert, body.key);
    } else if (body.mode === 'import-path') {
      importCertFromPath(body.certPath, body.keyPath);
    }
  } catch (e) {
    const raw = e instanceof Error ? e.message : String(e);
    const firstLine = raw.split('\n').find((l) => l.trim().length > 0) ?? raw;
    throw createError({ statusCode: 400, statusMessage: firstLine });
  }

  scheduleNodeRestart();

  return {
    success: true,
    httpsUrl: `https://${host}:${port}/login`,
  };
});