fix: version 2.7.1 -- Contraseñas pide PIN de nuevo al volver, auto-salida a los 3 min
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,12 @@
|
|||||||
# Changelog - project.linkedcorp.net
|
# Changelog - project.linkedcorp.net
|
||||||
|
|
||||||
|
## [2.7.1] - 2026-10-01
|
||||||
|
### Changed
|
||||||
|
- "Contraseñas" vuelve a pedir el PIN cada vez que se sale del menú (a otro, o cerrando la
|
||||||
|
pestaña) y se vuelve a entrar — antes quedaba desbloqueado el resto de la sesión del sistema.
|
||||||
|
- Si el menú queda abierto sin atención, sale solo al Panel a los 3 minutos de haberse
|
||||||
|
desbloqueado.
|
||||||
|
|
||||||
## [2.7.0] - 2026-10-01
|
## [2.7.0] - 2026-10-01
|
||||||
### Added
|
### Added
|
||||||
- Nuevo menú "Contraseñas": repositorio personal de credenciales (nombre, enlace, usuario,
|
- Nuevo menú "Contraseñas": repositorio personal de credenciales (nombre, enlace, usuario,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "project-linkedcorp-backend",
|
"name": "project-linkedcorp-backend",
|
||||||
"version": "2.7.0",
|
"version": "2.7.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/server.js",
|
"main": "src/server.js",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "project-linkedcorp-frontend",
|
"name": "project-linkedcorp-frontend",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "2.7.0",
|
"version": "2.7.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@@ -212,6 +212,7 @@ export const messages = {
|
|||||||
vault_copy: 'Copiar',
|
vault_copy: 'Copiar',
|
||||||
vault_copied: 'Copiado al portapapeles',
|
vault_copied: 'Copiado al portapapeles',
|
||||||
vault_generate: 'Generar',
|
vault_generate: 'Generar',
|
||||||
|
vault_auto_lock_notice: 'Saliste de Contraseñas por seguridad — ingresa tu PIN de nuevo para volver a entrar.',
|
||||||
notes_title: 'Notas',
|
notes_title: 'Notas',
|
||||||
notes_placeholder: 'Escribe un apunte rápido...',
|
notes_placeholder: 'Escribe un apunte rápido...',
|
||||||
notes_add: 'Agregar',
|
notes_add: 'Agregar',
|
||||||
@@ -538,6 +539,7 @@ export const messages = {
|
|||||||
vault_copy: 'Copy',
|
vault_copy: 'Copy',
|
||||||
vault_copied: 'Copied to clipboard',
|
vault_copied: 'Copied to clipboard',
|
||||||
vault_generate: 'Generate',
|
vault_generate: 'Generate',
|
||||||
|
vault_auto_lock_notice: 'You left Passwords for security — enter your PIN again to come back in.',
|
||||||
notes_title: 'Notes',
|
notes_title: 'Notes',
|
||||||
notes_placeholder: 'Write a quick note...',
|
notes_placeholder: 'Write a quick note...',
|
||||||
notes_add: 'Add',
|
notes_add: 'Add',
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { Plus, Trash2, Eye, EyeOff, Copy, Pencil, Save, X, RefreshCw, ShieldAlert } from 'lucide-react';
|
import { Plus, Trash2, Eye, EyeOff, Copy, Pencil, Save, X, RefreshCw, ShieldAlert } from 'lucide-react';
|
||||||
import { useUi } from '../../context/ui-context.jsx';
|
import { useUi } from '../../context/ui-context.jsx';
|
||||||
import { useAction } from '../../hooks/useAsync.js';
|
import { useAction } from '../../hooks/useAsync.js';
|
||||||
import {
|
import {
|
||||||
getVaultStatus, createVaultPin, unlockVault, changeVaultPin, forgotVaultPin,
|
getVaultStatus, createVaultPin, unlockVault, changeVaultPin, forgotVaultPin, setVaultToken,
|
||||||
listVaultEntries, getVaultEntry, createVaultEntry, updateVaultEntry, deleteVaultEntry,
|
listVaultEntries, getVaultEntry, createVaultEntry, updateVaultEntry, deleteVaultEntry,
|
||||||
} from '../../services/vault.js';
|
} from '../../services/vault.js';
|
||||||
import { ListView } from '../../components/ListView.jsx';
|
import { ListView } from '../../components/ListView.jsx';
|
||||||
@@ -13,6 +14,7 @@ import { PasswordInput } from '../../components/PasswordInput.jsx';
|
|||||||
import { DetailPopup } from '../../components/DetailPopup.jsx';
|
import { DetailPopup } from '../../components/DetailPopup.jsx';
|
||||||
|
|
||||||
const EMPTY_FORM = { title: '', url: '', username: '', password: '', notes: '' };
|
const EMPTY_FORM = { title: '', url: '', username: '', password: '', notes: '' };
|
||||||
|
const AUTO_LOCK_MS = 3 * 60 * 1000; // 3 minutos: salir solo del menu si queda abierto sin atencion
|
||||||
|
|
||||||
function randomPassword(length = 20) {
|
function randomPassword(length = 20) {
|
||||||
const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789!@#$%^&*';
|
const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789!@#$%^&*';
|
||||||
@@ -23,6 +25,7 @@ function randomPassword(length = 20) {
|
|||||||
export default function ContrasenasPage() {
|
export default function ContrasenasPage() {
|
||||||
const { t, pushToast, openDialog } = useUi();
|
const { t, pushToast, openDialog } = useUi();
|
||||||
const runAction = useAction();
|
const runAction = useAction();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const [locked, setLocked] = useState(true);
|
const [locked, setLocked] = useState(true);
|
||||||
const [checking, setChecking] = useState(true);
|
const [checking, setChecking] = useState(true);
|
||||||
@@ -68,6 +71,21 @@ export default function ContrasenasPage() {
|
|||||||
|
|
||||||
useEffect(() => { checkAccess(); }, []);
|
useEffect(() => { checkAccess(); }, []);
|
||||||
|
|
||||||
|
// Por seguridad: salir de este menu (a otro, o cerrando la pestaña) siempre bloquea de nuevo --
|
||||||
|
// el token de desbloqueo se borra al desmontar, asi que la proxima vez que se entra aca pide el
|
||||||
|
// PIN de nuevo, sin importar cuanto haya durado la sesion del sistema.
|
||||||
|
useEffect(() => () => setVaultToken(null), []);
|
||||||
|
|
||||||
|
// Si queda abierto sin atencion, sale solo al Panel a los 3 minutos de haberse desbloqueado.
|
||||||
|
useEffect(() => {
|
||||||
|
if (locked) return;
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
pushToast({ tone: 'warning', message: t('vault_auto_lock_notice') });
|
||||||
|
navigate('/');
|
||||||
|
}, AUTO_LOCK_MS);
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
}, [locked]);
|
||||||
|
|
||||||
async function submitPin() {
|
async function submitPin() {
|
||||||
setPinError('');
|
setPinError('');
|
||||||
if (!/^\d{4}$/.test(pin)) { setPinError(t('vault_pin_invalid')); return; }
|
if (!/^\d{4}$/.test(pin)) { setPinError(t('vault_pin_invalid')); return; }
|
||||||
|
|||||||
Reference in New Issue
Block a user