- Updated the `AprovarFerias.svelte` component to use specific types for `solicitacao` and `gestorId`, enhancing type safety. - Improved error handling by refining catch blocks to handle errors more accurately. - Made minor adjustments to ensure consistent code formatting and readability across the component.
175 lines
4.6 KiB
TypeScript
175 lines
4.6 KiB
TypeScript
import { v } from "convex/values";
|
|
import { mutation, query, action } from "./_generated/server";
|
|
import { hashPassword } from "./auth/utils";
|
|
import { registrarAtividade } from "./logsAtividades";
|
|
|
|
/**
|
|
* Obter configuração de email ativa (senha mascarada)
|
|
*/
|
|
export const obterConfigEmail = query({
|
|
args: {},
|
|
handler: async (ctx) => {
|
|
const config = await ctx.db
|
|
.query("configuracaoEmail")
|
|
.withIndex("by_ativo", (q) => q.eq("ativo", true))
|
|
.first();
|
|
|
|
if (!config) {
|
|
return null;
|
|
}
|
|
|
|
// Retornar config com senha mascarada
|
|
return {
|
|
_id: config._id,
|
|
servidor: config.servidor,
|
|
porta: config.porta,
|
|
usuario: config.usuario,
|
|
senhaHash: "********", // Mascarar senha
|
|
emailRemetente: config.emailRemetente,
|
|
nomeRemetente: config.nomeRemetente,
|
|
usarSSL: config.usarSSL,
|
|
usarTLS: config.usarTLS,
|
|
ativo: config.ativo,
|
|
testadoEm: config.testadoEm,
|
|
atualizadoEm: config.atualizadoEm,
|
|
};
|
|
},
|
|
});
|
|
|
|
/**
|
|
* Salvar configuração de email (apenas TI_MASTER)
|
|
*/
|
|
export const salvarConfigEmail = mutation({
|
|
args: {
|
|
servidor: v.string(),
|
|
porta: v.number(),
|
|
usuario: v.string(),
|
|
senha: v.string(),
|
|
emailRemetente: v.string(),
|
|
nomeRemetente: v.string(),
|
|
usarSSL: v.boolean(),
|
|
usarTLS: v.boolean(),
|
|
configuradoPorId: v.id("usuarios"),
|
|
},
|
|
returns: v.union(
|
|
v.object({ sucesso: v.literal(true), configId: v.id("configuracaoEmail") }),
|
|
v.object({ sucesso: v.literal(false), erro: v.string() })
|
|
),
|
|
handler: async (ctx, args) => {
|
|
// Validar email
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
if (!emailRegex.test(args.emailRemetente)) {
|
|
return { sucesso: false as const, erro: "Email remetente inválido" };
|
|
}
|
|
|
|
// Criptografar senha
|
|
const senhaHash = await hashPassword(args.senha);
|
|
|
|
// Desativar config anterior
|
|
const configsAntigas = await ctx.db
|
|
.query("configuracaoEmail")
|
|
.withIndex("by_ativo", (q) => q.eq("ativo", true))
|
|
.collect();
|
|
|
|
for (const config of configsAntigas) {
|
|
await ctx.db.patch(config._id, { ativo: false });
|
|
}
|
|
|
|
// Criar nova config
|
|
const configId = await ctx.db.insert("configuracaoEmail", {
|
|
servidor: args.servidor,
|
|
porta: args.porta,
|
|
usuario: args.usuario,
|
|
senhaHash,
|
|
emailRemetente: args.emailRemetente,
|
|
nomeRemetente: args.nomeRemetente,
|
|
usarSSL: args.usarSSL,
|
|
usarTLS: args.usarTLS,
|
|
ativo: true,
|
|
configuradoPor: args.configuradoPorId,
|
|
atualizadoEm: Date.now(),
|
|
});
|
|
|
|
// Log de atividade
|
|
await registrarAtividade(
|
|
ctx,
|
|
args.configuradoPorId,
|
|
"configurar",
|
|
"email",
|
|
JSON.stringify({ servidor: args.servidor, porta: args.porta }),
|
|
configId
|
|
);
|
|
|
|
return { sucesso: true as const, configId };
|
|
},
|
|
});
|
|
|
|
/**
|
|
* Testar conexão SMTP (action - precisa de Node.js)
|
|
*
|
|
* NOTA: Esta action será implementada quando instalarmos nodemailer.
|
|
* Por enquanto, retorna sucesso simulado para não bloquear o desenvolvimento.
|
|
*/
|
|
export const testarConexaoSMTP = action({
|
|
args: {
|
|
servidor: v.string(),
|
|
porta: v.number(),
|
|
usuario: v.string(),
|
|
senha: v.string(),
|
|
usarSSL: v.boolean(),
|
|
usarTLS: v.boolean(),
|
|
},
|
|
returns: v.union(
|
|
v.object({ sucesso: v.literal(true) }),
|
|
v.object({ sucesso: v.literal(false), erro: v.string() })
|
|
),
|
|
handler: async (ctx, args) => {
|
|
// TODO: Implementar teste real com nodemailer
|
|
// Por enquanto, simula sucesso
|
|
|
|
try {
|
|
// Validações básicas
|
|
if (!args.servidor || args.servidor.trim() === "") {
|
|
return {
|
|
sucesso: false as const,
|
|
erro: "Servidor SMTP não pode estar vazio",
|
|
};
|
|
}
|
|
|
|
if (args.porta < 1 || args.porta > 65535) {
|
|
return { sucesso: false as const, erro: "Porta inválida" };
|
|
}
|
|
|
|
// Simular delay de teste
|
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
|
|
// Retornar sucesso simulado
|
|
console.log(
|
|
"⚠️ AVISO: Teste de conexão SMTP simulado (nodemailer não instalado ainda)"
|
|
);
|
|
return { sucesso: true as const };
|
|
} catch (error) {
|
|
const errorMessage =
|
|
error instanceof Error ? error.message : String(error);
|
|
return {
|
|
sucesso: false as const,
|
|
erro: errorMessage || "Erro ao testar conexão",
|
|
};
|
|
}
|
|
},
|
|
});
|
|
|
|
/**
|
|
* Marcar que a configuração foi testada com sucesso
|
|
*/
|
|
export const marcarConfigTestada = mutation({
|
|
args: {
|
|
configId: v.id("configuracaoEmail"),
|
|
},
|
|
handler: async (ctx, args) => {
|
|
await ctx.db.patch(args.configId, {
|
|
testadoEm: Date.now(),
|
|
});
|
|
},
|
|
});
|