Mejora de seguridad

This commit is contained in:
2026-03-03 09:29:53 -07:00
parent b187aa1b46
commit 49dfb3ef24
19 changed files with 428 additions and 657 deletions

View File

@@ -11,8 +11,8 @@
let mounted = false;
onMount(() => {
auth.init();
onMount(async () => {
await auth.init();
mounted = true;
});
@@ -27,6 +27,12 @@
</script>
<div class="min-h-screen bg-gray-50 font-sans">
{#if !mounted}
<!-- Esperando inicialización de sesión -->
<div class="flex items-center justify-center min-h-screen bg-gray-50">
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
</div>
{:else}
{#if showHeader}
<Header />
{/if}
@@ -39,6 +45,7 @@
<footer class="py-4 text-center border-t border-gray-200 bg-white">
<p class="text-xs text-gray-400">ServiceManagerWeb v1.9.0 · © 2026 Aduanasoft</p>
</footer>
{/if}
<!-- Toast notifications -->
{#each $toast.toasts as toastMessage (toastMessage.id)}

View File

@@ -38,11 +38,14 @@
async function loadProfile() {
isLoading = true;
try {
const headers: Record<string, string> = {
'X-App': 'client',
'X-Tenant-ID': $auth.user?.tenant_id ?? ''
};
if ($auth.token) headers['Authorization'] = `Bearer ${$auth.token}`;
const response = await fetch('/api/v1/client-profile/', {
headers: {
Authorization: `Bearer ${$auth.token}`,
'X-Tenant-ID': $auth.user?.tenant_id ?? ''
}
credentials: 'include',
headers
});
if (!response.ok) throw new Error((await response.json()).detail);
profile = await response.json();
@@ -62,13 +65,16 @@
async function saveProfile() {
isSaving = true;
try {
const headers: Record<string, string> = {
'Content-Type': 'application/json',
'X-App': 'client',
'X-Tenant-ID': $auth.user?.tenant_id ?? ''
};
if ($auth.token) headers['Authorization'] = `Bearer ${$auth.token}`;
const response = await fetch('/api/v1/client-profile/', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${$auth.token}`,
'X-Tenant-ID': $auth.user?.tenant_id ?? ''
},
credentials: 'include',
headers,
body: JSON.stringify(form)
});
if (!response.ok) throw new Error((await response.json()).detail);

View File

@@ -34,7 +34,11 @@
try {
const response = await fetch('/api/v1/auth/2fa/setup', {
method: 'POST',
headers: { Authorization: `Bearer ${$auth.token}` }
credentials: 'include',
headers: {
'X-App': 'client',
...($auth.token ? { Authorization: `Bearer ${$auth.token}` } : {})
}
});
if (!response.ok) throw new Error((await response.json()).detail);
const data = await response.json();
@@ -57,7 +61,12 @@
try {
const response = await fetch('/api/v1/auth/2fa/enable', {
method: 'POST',
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${$auth.token}` },
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'X-App': 'client',
...($auth.token ? { Authorization: `Bearer ${$auth.token}` } : {})
},
body: JSON.stringify({ totp_code: totpSetupCode })
});
if (!response.ok) throw new Error((await response.json()).detail);
@@ -84,7 +93,12 @@
try {
const response = await fetch('/api/v1/auth/2fa/disable', {
method: 'POST',
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${$auth.token}` },
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'X-App': 'client',
...($auth.token ? { Authorization: `Bearer ${$auth.token}` } : {})
},
body: JSON.stringify({ totp_code: disableTotpCode })
});
if (!response.ok) throw new Error((await response.json()).detail);
@@ -157,16 +171,20 @@
async function loadBusinessProfile() {
try {
if (!$auth.token || !$auth.user) {
if (!$auth.user) {
console.warn('Usuario no autenticado');
return;
}
const _lpHeaders: Record<string, string> = {
'X-App': 'client',
'X-Tenant-ID': $auth.user.tenant_id
};
if ($auth.token) _lpHeaders['Authorization'] = `Bearer ${$auth.token}`;
const response = await fetch('/api/v1/client-profile/', {
headers: {
Authorization: `Bearer ${$auth.token}`,
'X-Tenant-ID': $auth.user.tenant_id
}
credentials: 'include',
headers: _lpHeaders
});
if (response.ok) {
@@ -267,9 +285,11 @@
try {
const response = await fetch('/api/v1/auth/profile', {
method: 'PATCH',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${$auth.token}`
'X-App': 'client',
...($auth.token ? { Authorization: `Bearer ${$auth.token}` } : {})
},
body: JSON.stringify({
first_name: firstName.trim(),
@@ -300,9 +320,11 @@
try {
const response = await fetch('/api/v1/auth/change-password', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${$auth.token}`
'X-App': 'client',
...($auth.token ? { Authorization: `Bearer ${$auth.token}` } : {})
},
body: JSON.stringify({
current_password: currentPassword,
@@ -349,13 +371,16 @@
profileData.credit_limit = parseFloat(profileData.credit_limit);
}
const _bpHeaders: Record<string, string> = {
'Content-Type': 'application/json',
'X-App': 'client',
'X-Tenant-ID': $auth.user?.tenant_id ?? ''
};
if ($auth.token) _bpHeaders['Authorization'] = `Bearer ${$auth.token}`;
const response = await fetch('/api/v1/client-profile/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${$auth.token}`,
'X-Tenant-ID': $auth.user.tenant_id
},
credentials: 'include',
headers: _bpHeaders,
body: JSON.stringify(profileData)
});