Source: Router/orgaSettings.js

// @ts-check
/**
 * @import {ExpressRequestAuthorized, ExpressResponse} from '../types.js'
 */

/**
 * OrgaSettings Router
 *
 * Endpoints for managing per-organisation settings stored in Vault.
 * All routes require admin privileges (checkAdmin middleware).
 *
 * Mounted at: /api/kpe20/orgaSettings  (see http-server.js)
 *
 * @swagger
 * tags:
 *   - name: OrgaSettings
 *     description: |
 *       Per-organisation settings stored in Vault —
 *       domain mappings and SMTP configuration.
 *       Schemas and examples are defined in ./orgaSettings/orgaSettings.swagger.yaml.
 *       Use $ref: './orgaSettings/orgaSettings.swagger.yaml#/components/schemas/{SchemaName}' in route blocks.
 */

import express from 'express';
import { checkAdmin }               from '../utils/authChecks.js';
import { requestUpdateLogger }      from '../utils/requestLogger.js';
import * as orgaSettingsController  from './orgaSettings/controller.js';

/** @type {express.Express} */
const api = express();

// ── Domains ───────────────────────────────────────────────────────────────────

/**
 * @swagger
 * /api/kpe20/orgaSettings/domains:
 *   get:
 *     summary: Load domain settings for the current organisation
 *     description: >
 *       Returns the full domain map (domain → type) stored in Vault
 *       for the authenticated user's organisation.
 *     tags: [OrgaSettings]
 *     security:
 *       - bearerAuth: []
 *     responses:
 *       200:
 *         description: Domain map retrieved successfully
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 result:
 *                   $ref: './orgaSettings/orgaSettings.swagger.yaml#/components/schemas/DomainMap'
 *       400:
 *         description: No organisation in session
 *       500:
 *         description: Failed to load domain settings
 */
// @ts-ignore
api.get('/domains', checkAdmin, orgaSettingsController.getDomainsController);

/**
 * @swagger
 * /api/kpe20/orgaSettings/domains:
 *   put:
 *     summary: Save domain settings for the current organisation
 *     description: >
 *       Validates and persists the domain map for the authenticated user's
 *       organisation in Vault.  Each entry maps a domain name to its type
 *       ("internal" or "external").  Validation checks format rules and
 *       conflicts with other organisations.
 *     tags: [OrgaSettings]
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             $ref: './orgaSettings/orgaSettings.swagger.yaml#/components/schemas/DomainMap'
 *           example:
 *             myclub: internal
 *             myclub.de: external
 *     responses:
 *       200:
 *         description: Domains saved successfully
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *       400:
 *         description: Validation errors or missing organisation
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 errors:
 *                   type: array
 *                   items:
 *                     $ref: './orgaSettings/orgaSettings.swagger.yaml#/components/schemas/DomainValidationError'
 *       500:
 *         description: Failed to save domain settings
 */
// @ts-ignore
api.put('/domains', checkAdmin, requestUpdateLogger, orgaSettingsController.saveDomainsController);

// ── Apps ─────────────────────────────────────────────────────────────────────

/**
 * @swagger
 * /api/kpe20/orgaSettings/apps:
 *   get:
 *     summary: Load app registry for the current organisation
 *     description: >
 *       Returns all configured apps (domain, roles, title, etc.) stored in
 *       Vault for the authenticated user's organisation.
 *     tags: [OrgaSettings]
 *     security:
 *       - bearerAuth: []
 *     responses:
 *       200:
 *         description: App registry retrieved successfully
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 result:
 *                   $ref: './orgaSettings/orgaSettings.swagger.yaml#/components/schemas/AppsMap'
 *       400:
 *         description: No organisation in session
 *       500:
 *         description: Failed to load app settings
 */
// @ts-ignore
api.get('/apps', checkAdmin, orgaSettingsController.getAppsController);

/**
 * @swagger
 * /api/kpe20/orgaSettings/apps:
 *   put:
 *     summary: Save app registry for the current organisation
 *     description: >
 *       Persists the full app registry for the authenticated user's organisation
 *       in Vault.  The entire object is replaced; pass the full updated map.
 *     tags: [OrgaSettings]
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             $ref: './orgaSettings/orgaSettings.swagger.yaml#/components/schemas/AppsMap'
 *     responses:
 *       200:
 *         description: App registry saved
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *       400:
 *         description: Invalid request body or missing organisation
 *       500:
 *         description: Failed to save app settings
 */
// @ts-ignore
api.post('/apps', checkAdmin, requestUpdateLogger, orgaSettingsController.saveAppsController);

/**
 * @swagger
 * /api/kpe20/orgaSettings/apps/{appId}/icon:
 *   post:
 *     summary: Upload an icon for an app
 *     description: >
 *       Uploads an image file (PNG, JPG, SVG, GIF or WebP) to the
 *       `commtool-public` MinIO bucket under `{orgId}/icons/{appId}.{ext}`
 *       and persists the resulting public URL in Vault under
 *       `apps[appId].icon` for the current organisation.
 *     tags: [OrgaSettings]
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: appId
 *         required: true
 *         schema:
 *           type: string
 *         description: The app identifier key (e.g. member.app)
 *     requestBody:
 *       required: true
 *       content:
 *         multipart/form-data:
 *           schema:
 *             type: object
 *             properties:
 *               files:
 *                 type: string
 *                 format: binary
 *                 description: Image file (PNG / JPG / SVG / GIF / WebP, max recommended 512 KB)
 *     responses:
 *       200:
 *         description: Icon uploaded and URL stored in Vault
 *         content:
 *           application/json:
 *             schema:
 *               $ref: './orgaSettings/orgaSettings.swagger.yaml#/components/schemas/IconUploadResponse'
 *       400:
 *         description: Unsupported file type, missing app or missing organisation
 *       500:
 *         description: Upload or Vault write failed
 */
// @ts-ignore
api.post('/apps/:appId/icon', checkAdmin, requestUpdateLogger, orgaSettingsController.uploadAppIconController);

// ── Mail / SMTP ───────────────────────────────────────────────────────────────

/**
 * @swagger
 * /api/kpe20/orgaSettings/mail:
 *   get:
 *     summary: Load SMTP settings for the current organisation
 *     description: >
 *       Returns the SMTP configuration stored in Vault for the authenticated
 *       user's organisation.  The `password` field is masked before being
 *       returned.
 *     tags: [OrgaSettings]
 *     security:
 *       - bearerAuth: []
 *     responses:
 *       200:
 *         description: SMTP settings retrieved (password masked)
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 result:
 *                   $ref: './orgaSettings/orgaSettings.swagger.yaml#/components/schemas/MailSettings'
 *       400:
 *         description: No organisation in session
 *       500:
 *         description: Failed to load mail settings
 */
// @ts-ignore
api.get('/mail', checkAdmin, orgaSettingsController.getMailController);

/**
 * @swagger
 * /api/kpe20/orgaSettings/mail:
 *   post:
 *     summary: Save SMTP settings for the current organisation
 *     description: >
 *       Validates and persists SMTP configuration for the authenticated
 *       user's organisation in Vault.  If `password` is the mask sentinel
 *       (••••••••) the existing password is preserved unchanged.
 *     tags: [OrgaSettings]
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             $ref: './orgaSettings/orgaSettings.swagger.yaml#/components/schemas/MailSettings'
 *     responses:
 *       200:
 *         description: SMTP settings saved
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *       400:
 *         description: Validation error (missing host/user or invalid port)
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: 'Field "host" is required.'
 *       500:
 *         description: Failed to save mail settings
 */
// @ts-ignore
api.post('/mail', checkAdmin, requestUpdateLogger, orgaSettingsController.saveMailController);

export default api;