Files
scoreodonto.com/backend/dist/modules/api-keys/apikey.routes.js
T

101 lines
3.6 KiB
JavaScript

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildApiKeyRoutes = buildApiKeyRoutes;
const express_1 = require("express");
const zod_1 = require("zod");
const prisma_1 = require("../../infra/database/prisma");
const crypto_1 = __importDefault(require("crypto"));
function buildApiKeyRoutes() {
const router = (0, express_1.Router)();
// GET /api/api-keys
router.get('/', async (req, res) => {
const keys = await prisma_1.prisma.apiKey.findMany({
where: { tenantId: req.tenantId },
orderBy: { createdAt: 'desc' },
select: {
id: true,
name: true,
key: true,
isActive: true,
createdAt: true,
expiresAt: true,
},
});
// Mask key: show only last 8 chars
const masked = keys.map((k) => ({
...k,
keyPreview: `••••••••${k.key.slice(-8)}`,
key: undefined,
}));
res.json(masked);
});
// POST /api/api-keys — cria nova chave
router.post('/', async (req, res) => {
const schema = zod_1.z.object({
name: zod_1.z.string().min(1).max(80),
expiresAt: zod_1.z.string().datetime().optional(),
});
let body;
try {
body = schema.parse(req.body);
}
catch (err) {
res.status(400).json({ error: err.errors ?? err.message });
return;
}
const key = `nw_${crypto_1.default.randomBytes(24).toString('hex')}`;
const created = await prisma_1.prisma.apiKey.create({
data: {
tenantId: req.tenantId,
name: body.name,
key,
expiresAt: body.expiresAt ? new Date(body.expiresAt) : undefined,
},
});
// Retorna a chave completa apenas uma vez
res.status(201).json({
id: created.id,
name: created.name,
key: created.key, // plaintext — única vez
isActive: created.isActive,
createdAt: created.createdAt,
expiresAt: created.expiresAt,
});
});
// PATCH /api/api-keys/:id — ativar/desativar
router.patch('/:id', async (req, res) => {
const id = req.params['id'];
const schema = zod_1.z.object({ isActive: zod_1.z.boolean() });
let body;
try {
body = schema.parse(req.body);
}
catch (err) {
res.status(400).json({ error: err.errors ?? err.message });
return;
}
const existing = await prisma_1.prisma.apiKey.findFirst({ where: { id, tenantId: req.tenantId } });
if (!existing) {
res.status(404).json({ error: 'Chave não encontrada' });
return;
}
const updated = await prisma_1.prisma.apiKey.update({ where: { id }, data: { isActive: body.isActive } });
res.json({ id: updated.id, name: updated.name, isActive: updated.isActive });
});
// DELETE /api/api-keys/:id
router.delete('/:id', async (req, res) => {
const id = req.params['id'];
const existing = await prisma_1.prisma.apiKey.findFirst({ where: { id, tenantId: req.tenantId } });
if (!existing) {
res.status(404).json({ error: 'Chave não encontrada' });
return;
}
await prisma_1.prisma.apiKey.delete({ where: { id } });
res.status(204).send();
});
return router;
}