Source: RouterProject/credential.js

// @ts-check
/**
 * Credential router - mounted by the project aggregator at /api/project/credential.
 *
 * Credentials are stored ENTIRELY in Vault (no ObjectBase row). Each credential
 * is one ed25519 key pair per (org|user, name); the private key lives in Vault,
 * the API only ever returns the public key and host metadata.
 *
 * The route parameter `:ref` is the URL-encoded credentialsRef `{UID}/{name}`
 * (orgId or userUID + credential name).
 *
 * Routes:
 * - PUT    /            create a credential (generates the key pair)
 * - GET    /            list credentials
 * - GET    /:ref        get a single credential
 * - DELETE /:ref        delete a credential (removes the Vault secret)
 *
 * @import {ExpressRequestAuthorized, ExpressResponse} from '../types.js'
 */

import express from 'express';
import { requestUpdateLogger, readLogger } from '../utils/requestLogger.js';
import * as controller from './credential/controller.js';

const api = express.Router({ caseSensitive: true });

/** Validate that `:ref` looks like "{UID}/{name}" (the service re-validates). */
const validateRef = (req, res, next) => {
    const ref = req.params.ref;
    if (typeof ref !== 'string' || !ref.includes('/') || ref.startsWith('/') || ref.endsWith('/') || ref.length > 200) {
        return res.status(400).json({
            success: false,
            message: 'Invalid credentialsRef format, expected "{UID}/{name}"',
            error: 'INVALID_CREDENTIAL_REF',
        });
    }
    next();
};

// @ts-ignore
api.get('/', readLogger, controller.listCredentials);
// @ts-ignore
api.get('/hostkey', readLogger, controller.scanHostKey);
// @ts-ignore
api.put('/', requestUpdateLogger, controller.putCredential);
// @ts-ignore
api.get('/:ref', validateRef, readLogger, controller.getCredential);
// @ts-ignore
api.delete('/:ref', validateRef, requestUpdateLogger, controller.deleteCredential);

export default api;