Fix dias ferias #28

Merged
deyvisonwanderley merged 10 commits from fix-dias-ferias into master 2025-11-18 13:15:02 +00:00
31 changed files with 4410 additions and 3497 deletions
Showing only changes of commit af6353fa40 - Show all commits

View File

@@ -5,6 +5,7 @@
import { goto } from '$app/navigation';
import { resolve } from '$app/paths';
import { onMount } from 'svelte';
import { Key, Eye, EyeOff, CheckCircle2, XCircle, Shield, Lock, AlertCircle, Info } from 'lucide-svelte';
const convex = useConvexClient();
const currentUser = useQuery(api.auth.getCurrentUser, {});
@@ -136,361 +137,288 @@
}
</script>
<main class="container mx-auto max-w-2xl px-4 py-8">
<!-- Header -->
<main class="container mx-auto max-w-4xl px-4 py-8">
<!-- Header Moderno -->
<div class="mb-8">
<div class="mb-2 flex items-center gap-3">
<svg
xmlns="http://www.w3.org/2000/svg"
class="text-primary h-10 w-10"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"
/>
</svg>
<h1 class="text-primary text-4xl font-bold">Alterar Senha</h1>
<div class="bg-linear-to-r from-primary/20 via-primary/10 to-primary/20 rounded-2xl p-6 mb-6 shadow-lg border border-primary/20">
<div class="flex items-center gap-4">
<div class="p-3 bg-primary/20 rounded-2xl">
<Key class="h-8 w-8 text-primary" strokeWidth={2.5} />
</div>
<div class="flex-1">
<h1 class="text-primary text-4xl font-bold mb-2">Alterar Senha</h1>
<p class="text-base-content/70 text-lg">
Atualize sua senha de acesso ao sistema de forma segura
</p>
</div>
<div class="badge badge-primary badge-lg gap-2">
<Shield class="h-4 w-4" strokeWidth={2} />
Seguro
</div>
</div>
</div>
<p class="text-base-content/70 text-lg">Atualize sua senha de acesso ao sistema</p>
</div>
<!-- Breadcrumbs -->
<div class="breadcrumbs mb-6 text-sm">
<ul>
<li><a href={resolve('/')}>Dashboard</a></li>
<li>Alterar Senha</li>
</ul>
<!-- Breadcrumbs -->
<div class="breadcrumbs text-sm mb-6">
<ul>
<li><a href={resolve('/')} class="link link-hover">Dashboard</a></li>
<li>Alterar Senha</li>
</ul>
</div>
</div>
<!-- Alertas -->
{#if notice}
<div class="alert {notice.type === 'success' ? 'alert-success' : 'alert-error'} mb-6 shadow-lg">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6 shrink-0 stroke-current"
fill="none"
viewBox="0 0 24 24"
>
{#if notice.type === 'success'}
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
/>
{:else}
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
/>
{/if}
</svg>
<span>{notice.message}</span>
<div
class="alert {notice.type === 'success'
? 'alert-success'
: 'alert-error'} mb-6 shadow-xl animate-in fade-in slide-in-from-top duration-300"
>
{#if notice.type === 'success'}
<CheckCircle2 class="h-6 w-6 shrink-0 stroke-current" strokeWidth={2} />
{:else}
<XCircle class="h-6 w-6 shrink-0 stroke-current" strokeWidth={2} />
{/if}
<span class="font-semibold">{notice.message}</span>
</div>
{/if}
<!-- Formulário -->
<div class="card bg-base-100 border-base-300 border shadow-xl">
<div class="card-body">
<form onsubmit={handleSubmit} class="space-y-6">
<!-- Senha Atual -->
<div class="form-control">
<label class="label" for="senha-atual">
<span class="label-text font-semibold">Senha Atual</span>
<span class="label-text-alt text-error">*</span>
</label>
<div class="relative">
<input
id="senha-atual"
type={mostrarSenhaAtual ? 'text' : 'password'}
placeholder="Digite sua senha atual"
class="input input-bordered input-primary w-full pr-12"
bind:value={senhaAtual}
required
disabled={carregando}
/>
<button
type="button"
class="btn btn-sm btn-circle absolute top-1/2 right-3 -translate-y-1/2"
onclick={() => (mostrarSenhaAtual = !mostrarSenhaAtual)}
>
{#if mostrarSenhaAtual}
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21"
/>
</svg>
{:else}
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
/>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"
/>
</svg>
{/if}
</button>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<!-- Formulário Principal -->
<div class="lg:col-span-2">
<div
class="card bg-base-100 border-base-300/50 border-2 shadow-xl hover:shadow-2xl transition-all duration-300"
>
<div class="card-body p-8">
<div class="flex items-center gap-3 mb-6">
<div class="p-2 bg-primary/10 rounded-xl">
<Lock class="h-6 w-6 text-primary" strokeWidth={2} />
</div>
<h2 class="text-2xl font-bold text-base-content">Formulário de Alteração</h2>
</div>
</div>
<!-- Nova Senha -->
<div class="form-control">
<label class="label" for="nova-senha">
<span class="label-text font-semibold">Nova Senha</span>
<span class="label-text-alt text-error">*</span>
</label>
<div class="relative">
<input
id="nova-senha"
type={mostrarNovaSenha ? 'text' : 'password'}
placeholder="Digite sua nova senha"
class="input input-bordered input-primary w-full pr-12"
bind:value={novaSenha}
required
disabled={carregando}
/>
<button
type="button"
class="btn btn-sm btn-circle absolute top-1/2 right-3 -translate-y-1/2"
onclick={() => (mostrarNovaSenha = !mostrarNovaSenha)}
>
{#if mostrarNovaSenha}
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21"
/>
</svg>
{:else}
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
/>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"
/>
</svg>
{/if}
</button>
</div>
<div class="label">
<span class="label-text-alt text-base-content/60">
Mínimo 8 caracteres, com letras maiúsculas, minúsculas, números e caracteres especiais
</span>
</div>
</div>
<!-- Confirmar Senha -->
<div class="form-control">
<label class="label" for="confirmar-senha">
<span class="label-text font-semibold">Confirmar Nova Senha</span>
<span class="label-text-alt text-error">*</span>
</label>
<div class="relative">
<input
id="confirmar-senha"
type={mostrarConfirmarSenha ? 'text' : 'password'}
placeholder="Digite novamente sua nova senha"
class="input input-bordered input-primary w-full pr-12"
bind:value={confirmarSenha}
required
disabled={carregando}
/>
<button
type="button"
class="btn btn-sm btn-circle absolute top-1/2 right-3 -translate-y-1/2"
onclick={() => (mostrarConfirmarSenha = !mostrarConfirmarSenha)}
>
{#if mostrarConfirmarSenha}
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21"
/>
</svg>
{:else}
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
/>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"
/>
</svg>
{/if}
</button>
</div>
</div>
<!-- Requisitos de Senha -->
<div class="alert alert-info">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6 shrink-0 stroke-current"
fill="none"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
<div>
<h3 class="font-bold">Requisitos de Senha:</h3>
<ul class="mt-2 list-inside list-disc space-y-1 text-sm">
<li>Mínimo de 8 caracteres</li>
<li>Pelo menos uma letra maiúscula (A-Z)</li>
<li>Pelo menos uma letra minúscula (a-z)</li>
<li>Pelo menos um número (0-9)</li>
<li>Pelo menos um caractere especial (!@#$%^&*...)</li>
</ul>
</div>
</div>
<!-- Botões -->
<div class="mt-8 flex justify-end gap-4">
<button type="button" class="btn" onclick={cancelar} disabled={carregando}>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"
/>
</svg>
Cancelar
</button>
<button type="submit" class="btn btn-primary" disabled={carregando}>
{#if carregando}
<span class="loading loading-spinner loading-sm"></span>
Alterando...
{:else}
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M5 13l4 4L19 7"
<form onsubmit={handleSubmit} class="space-y-6">
<!-- Senha Atual -->
<div class="form-control">
<label class="label" for="senha-atual">
<span class="label-text font-semibold text-base">Senha Atual</span>
<span class="label-text-alt text-error font-bold">*</span>
</label>
<div class="relative">
<input
id="senha-atual"
type={mostrarSenhaAtual ? 'text' : 'password'}
placeholder="Digite sua senha atual"
class="input input-bordered input-primary w-full pr-12 h-12 text-base"
bind:value={senhaAtual}
required
disabled={carregando}
/>
</svg>
Alterar Senha
{/if}
</button>
</div>
</form>
</div>
</div>
<button
type="button"
class="btn btn-sm btn-ghost btn-circle absolute top-1/2 right-2 -translate-y-1/2 hover:bg-primary/10"
onclick={() => (mostrarSenhaAtual = !mostrarSenhaAtual)}
disabled={carregando}
aria-label={mostrarSenhaAtual ? 'Ocultar senha' : 'Mostrar senha'}
>
{#if mostrarSenhaAtual}
<EyeOff class="h-5 w-5 text-base-content/60" strokeWidth={2} />
{:else}
<Eye class="h-5 w-5 text-base-content/60" strokeWidth={2} />
{/if}
</button>
</div>
</div>
<!-- Dicas de Segurança -->
<div class="card bg-base-200 mt-6 shadow-lg">
<div class="card-body">
<h3 class="card-title text-lg">
<svg
xmlns="http://www.w3.org/2000/svg"
class="text-warning h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
/>
</svg>
Dicas de Segurança
</h3>
<ul class="text-base-content/70 space-y-2 text-sm">
<li>✅ Nunca compartilhe sua senha com ninguém</li>
<li>✅ Use uma senha única para cada sistema</li>
<li>✅ Altere sua senha regularmente</li>
<li>✅ Não use informações pessoais óbvias (nome, data de nascimento, etc.)</li>
<li>✅ Considere usar um gerenciador de senhas</li>
</ul>
<!-- Nova Senha -->
<div class="form-control">
<label class="label" for="nova-senha">
<span class="label-text font-semibold text-base">Nova Senha</span>
<span class="label-text-alt text-error font-bold">*</span>
</label>
<div class="relative">
<input
id="nova-senha"
type={mostrarNovaSenha ? 'text' : 'password'}
placeholder="Digite sua nova senha"
class="input input-bordered input-primary w-full pr-12 h-12 text-base"
bind:value={novaSenha}
required
disabled={carregando}
/>
<button
type="button"
class="btn btn-sm btn-ghost btn-circle absolute top-1/2 right-2 -translate-y-1/2 hover:bg-primary/10"
onclick={() => (mostrarNovaSenha = !mostrarNovaSenha)}
disabled={carregando}
aria-label={mostrarNovaSenha ? 'Ocultar senha' : 'Mostrar senha'}
>
{#if mostrarNovaSenha}
<EyeOff class="h-5 w-5 text-base-content/60" strokeWidth={2} />
{:else}
<Eye class="h-5 w-5 text-base-content/60" strokeWidth={2} />
{/if}
</button>
</div>
<div class="label">
<span class="label-text-alt text-base-content/60 text-xs">
Mínimo 8 caracteres com maiúsculas, minúsculas, números e especiais
</span>
</div>
</div>
<!-- Confirmar Senha -->
<div class="form-control">
<label class="label" for="confirmar-senha">
<span class="label-text font-semibold text-base">Confirmar Nova Senha</span>
<span class="label-text-alt text-error font-bold">*</span>
</label>
<div class="relative">
<input
id="confirmar-senha"
type={mostrarConfirmarSenha ? 'text' : 'password'}
placeholder="Digite novamente sua nova senha"
class="input input-bordered input-primary w-full pr-12 h-12 text-base"
bind:value={confirmarSenha}
required
disabled={carregando}
/>
<button
type="button"
class="btn btn-sm btn-ghost btn-circle absolute top-1/2 right-2 -translate-y-1/2 hover:bg-primary/10"
onclick={() => (mostrarConfirmarSenha = !mostrarConfirmarSenha)}
disabled={carregando}
aria-label={mostrarConfirmarSenha ? 'Ocultar senha' : 'Mostrar senha'}
>
{#if mostrarConfirmarSenha}
<EyeOff class="h-5 w-5 text-base-content/60" strokeWidth={2} />
{:else}
<Eye class="h-5 w-5 text-base-content/60" strokeWidth={2} />
{/if}
</button>
</div>
</div>
<!-- Botões -->
<div class="flex flex-col sm:flex-row justify-end gap-4 mt-8 pt-6 border-t border-base-300">
<button
type="button"
class="btn btn-outline btn-lg flex-1 sm:flex-initial"
onclick={cancelar}
disabled={carregando}
>
<XCircle class="h-5 w-5" strokeWidth={2} />
Cancelar
</button>
<button
type="submit"
class="btn btn-primary btn-lg flex-1 sm:flex-initial shadow-lg hover:shadow-xl transition-all duration-200"
disabled={carregando}
>
{#if carregando}
<span class="loading loading-spinner loading-sm"></span>
Alterando...
{:else}
<CheckCircle2 class="h-5 w-5" strokeWidth={2} />
Alterar Senha
{/if}
</button>
</div>
</form>
</div>
</div>
</div>
<!-- Sidebar com Informações -->
<div class="space-y-6">
<!-- Requisitos de Senha -->
<div
class="card bg-linear-to-br from-info/10 to-info/5 border-2 border-info/20 shadow-lg"
>
<div class="card-body p-6">
<div class="flex items-center gap-3 mb-4">
<div class="p-2 bg-info/20 rounded-xl">
<Info class="h-6 w-6 text-info" strokeWidth={2} />
</div>
<h3 class="text-lg font-bold text-base-content">Requisitos de Senha</h3>
</div>
<ul class="space-y-3 text-sm">
<li class="flex items-start gap-2">
<CheckCircle2 class="h-5 w-5 text-success shrink-0 mt-0.5" strokeWidth={2} />
<span class="text-base-content/80">Mínimo de 8 caracteres</span>
</li>
<li class="flex items-start gap-2">
<CheckCircle2 class="h-5 w-5 text-success shrink-0 mt-0.5" strokeWidth={2} />
<span class="text-base-content/80">Pelo menos uma letra maiúscula (A-Z)</span>
</li>
<li class="flex items-start gap-2">
<CheckCircle2 class="h-5 w-5 text-success shrink-0 mt-0.5" strokeWidth={2} />
<span class="text-base-content/80">Pelo menos uma letra minúscula (a-z)</span>
</li>
<li class="flex items-start gap-2">
<CheckCircle2 class="h-5 w-5 text-success shrink-0 mt-0.5" strokeWidth={2} />
<span class="text-base-content/80">Pelo menos um número (0-9)</span>
</li>
<li class="flex items-start gap-2">
<CheckCircle2 class="h-5 w-5 text-success shrink-0 mt-0.5" strokeWidth={2} />
<span class="text-base-content/80">Pelo menos um caractere especial (!@#$%...)</span>
</li>
</ul>
</div>
</div>
<!-- Dicas de Segurança -->
<div
class="card bg-linear-to-br from-warning/10 to-warning/5 border-2 border-warning/20 shadow-lg"
>
<div class="card-body p-6">
<div class="flex items-center gap-3 mb-4">
<div class="p-2 bg-warning/20 rounded-xl">
<Shield class="h-6 w-6 text-warning" strokeWidth={2} />
</div>
<h3 class="text-lg font-bold text-base-content">Dicas de Segurança</h3>
</div>
<ul class="space-y-3 text-sm">
<li class="flex items-start gap-2">
<AlertCircle class="h-5 w-5 text-warning shrink-0 mt-0.5" strokeWidth={2} />
<span class="text-base-content/80">Nunca compartilhe sua senha</span>
</li>
<li class="flex items-start gap-2">
<AlertCircle class="h-5 w-5 text-warning shrink-0 mt-0.5" strokeWidth={2} />
<span class="text-base-content/80">Use uma senha única para cada sistema</span>
</li>
<li class="flex items-start gap-2">
<AlertCircle class="h-5 w-5 text-warning shrink-0 mt-0.5" strokeWidth={2} />
<span class="text-base-content/80">Altere sua senha regularmente</span>
</li>
<li class="flex items-start gap-2">
<AlertCircle class="h-5 w-5 text-warning shrink-0 mt-0.5" strokeWidth={2} />
<span class="text-base-content/80">Evite informações pessoais óbvias</span>
</li>
<li class="flex items-start gap-2">
<AlertCircle class="h-5 w-5 text-warning shrink-0 mt-0.5" strokeWidth={2} />
<span class="text-base-content/80">Considere usar um gerenciador de senhas</span>
</li>
</ul>
</div>
</div>
</div>
</div>
</main>
<style>
@keyframes fade-in {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.animate-in {
animation: fade-in 0.3s ease-out;
}
</style>

View File

@@ -15,6 +15,7 @@ import type * as actions_smtp from "../actions/smtp.js";
import type * as actions_utils_nodeCrypto from "../actions/utils/nodeCrypto.js";
import type * as atestadosLicencas from "../atestadosLicencas.js";
import type * as ausencias from "../ausencias.js";
import type * as autenticacao from "../autenticacao.js";
import type * as auth from "../auth.js";
import type * as auth_utils from "../auth/utils.js";
import type * as chamados from "../chamados.js";
@@ -63,6 +64,7 @@ declare const fullApi: ApiFromModules<{
"actions/utils/nodeCrypto": typeof actions_utils_nodeCrypto;
atestadosLicencas: typeof atestadosLicencas;
ausencias: typeof ausencias;
autenticacao: typeof autenticacao;
auth: typeof auth;
"auth/utils": typeof auth_utils;
chamados: typeof chamados;

View File

@@ -0,0 +1,72 @@
import { mutation } from './_generated/server';
import { v } from 'convex/values';
import { updatePassword } from './auth';
import { authComponent } from './auth';
/**
* Alterar senha do usuário autenticado
*/
export const alterarSenha = mutation({
args: {
token: v.string(), // Token não é usado, mas mantido para compatibilidade
senhaAtual: v.string(),
novaSenha: v.string()
},
returns: v.union(
v.object({ sucesso: v.literal(true) }),
v.object({ sucesso: v.literal(false), erro: v.string() })
),
handler: async (ctx, args) => {
try {
// Verificar se o usuário está autenticado
const authUser = await authComponent.safeGetAuthUser(ctx);
if (!authUser) {
return {
sucesso: false as const,
erro: 'Usuário não autenticado'
};
}
// Validar que a nova senha não está vazia
if (!args.novaSenha || args.novaSenha.trim().length === 0) {
return {
sucesso: false as const,
erro: 'A nova senha não pode estar vazia'
};
}
// Chamar a função de atualização de senha
await updatePassword(ctx, {
currentPassword: args.senhaAtual,
newPassword: args.novaSenha
});
return {
sucesso: true as const
};
} catch (error: any) {
// Capturar erros específicos do Better Auth
let mensagemErro = 'Erro ao alterar senha';
if (error?.message) {
mensagemErro = error.message;
} else if (typeof error === 'string') {
mensagemErro = error;
}
// Mensagens de erro mais amigáveis
if (mensagemErro.toLowerCase().includes('password') ||
mensagemErro.toLowerCase().includes('senha') ||
mensagemErro.toLowerCase().includes('incorrect') ||
mensagemErro.toLowerCase().includes('incorreta')) {
mensagemErro = 'Senha atual incorreta';
}
return {
sucesso: false as const,
erro: mensagemErro
};
}
}
});