This commit is contained in:
valenti 2026-04-09 05:45:40 -04:00
parent bb5be80a71
commit 514cc9c05c
10 changed files with 84 additions and 14 deletions

View File

@ -1,7 +1,7 @@
{ {
"name": "duxiter-fast-check", "name": "duxiter-fast-check",
"private": true, "private": true,
"version": "1.5.58", "version": "1.6.00",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View File

@ -1,6 +1,6 @@
{ {
"name": "duxiter-server", "name": "duxiter-server",
"version": "1.6.10", "version": "1.6.20",
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {

View File

@ -3,10 +3,13 @@ import dotenv from 'dotenv';
dotenv.config(); dotenv.config();
const MONGODB_URI = process.env.MONGODB_URI || null; const MONGODB_URI = process.env.MONGODB_URI;
export const connectDB = async () => { export const connectDB = async () => {
try { try {
if (!MONGODB_URI) {
throw new Error('MONGODB_URI is not set');
}
await mongoose.connect(MONGODB_URI); await mongoose.connect(MONGODB_URI);
console.log('MongoDB connected successfully'); console.log('MongoDB connected successfully');
@ -23,4 +26,4 @@ export const connectDB = async () => {
} }
}; };
export default mongoose; export default mongoose;

View File

@ -3,14 +3,17 @@ import dotenv from 'dotenv';
dotenv.config(); dotenv.config();
const MONGODB_URI = process.env.MONGODB_URI || null; const MONGODB_URI = process.env.MONGODB_URI;
export const connectDB = async (): Promise<void> => { export const connectDB = async (): Promise<void> => {
try { try {
if (!MONGODB_URI) {
throw new Error('MONGODB_URI is not set');
}
console.log(`[connectDB] Connecting to MongoDB at ${MONGODB_URI}`); console.log(`[connectDB] Connecting to MongoDB at ${MONGODB_URI}`);
await mongoose.connect(MONGODB_URI); await mongoose.connect(MONGODB_URI);
} catch (error) { } catch (error) {
console.error('MongoDB connection error:', error); console.error('MongoDB connection error:', error);
throw error; throw error;
} }
}; };

View File

@ -757,7 +757,7 @@ export class RutController {
//AV sheriffV2 //AV sheriffV2
if (newSheriff && (newSheriff as any).compliance) { if (newSheriff && (newSheriff as any).compliance) {
console.warn(586, "-------------------- newSheriff", newSheriff?.compliance?.data); console.warn(586, "-------------------- newSheriff", (newSheriff as any)?.compliance?.data);
(filteredDetails as any).complianceSelectedRowsPepChile = (newSheriff as any)?.compliance?.data?.pepChile?.coincidencias || []; (filteredDetails as any).complianceSelectedRowsPepChile = (newSheriff as any)?.compliance?.data?.pepChile?.coincidencias || [];
(filteredDetails as any).complianceSelectedRowsPublicOfficial = (newSheriff as any)?.compliance?.data?.funcionariosPublicos?.coincidencias || []; (filteredDetails as any).complianceSelectedRowsPublicOfficial = (newSheriff as any)?.compliance?.data?.funcionariosPublicos?.coincidencias || [];
(filteredDetails as any).complianceSelectedRowsPepChileFamily = (newSheriff as any)?.compliance?.data?.familiaresPep?.coincidencias || []; (filteredDetails as any).complianceSelectedRowsPepChileFamily = (newSheriff as any)?.compliance?.data?.familiaresPep?.coincidencias || [];

View File

@ -204,4 +204,28 @@ export const getSystemStatus = async (req: Request, res: Response): Promise<void
message: error instanceof Error ? error.message : 'Unknown error' message: error instanceof Error ? error.message : 'Unknown error'
}); });
} }
}; };
const getVmIpv4Addresses = (): string[] => {
const interfaces = os.networkInterfaces();
const results: string[] = [];
for (const infos of Object.values(interfaces)) {
if (!infos) continue;
for (const info of infos) {
if (info.family !== 'IPv4') continue;
if (info.internal) continue;
results.push(info.address);
}
}
return results;
};
export const getVmIp = async (req: Request, res: Response): Promise<void> => {
const override = (process.env.VM_IP || process.env.HOST_IP || '').trim();
const ips = override ? [override] : getVmIpv4Addresses();
const ip = ips[0] || null;
res.json({ ip, ips });
};

View File

@ -1,5 +1,5 @@
import { Router } from 'express'; import { Router } from 'express';
import { getSystemStatus } from '../controllers/system.controller'; import { getSystemStatus, getVmIp } from '../controllers/system.controller';
import { authenticate } from '../middleware/auth.middleware'; import { authenticate } from '../middleware/auth.middleware';
import { requirePermission, Permission } from '../middleware/permissions.middleware'; import { requirePermission, Permission } from '../middleware/permissions.middleware';
@ -87,5 +87,6 @@ const router = Router();
* description: Internal server error * description: Internal server error
*/ */
router.get('/status', authenticate, requirePermission(Permission.ADMIN_DASHBOARD), getSystemStatus); router.get('/status', authenticate, requirePermission(Permission.ADMIN_DASHBOARD), getSystemStatus);
router.get('/vm-ip', authenticate, getVmIp);
export default router; export default router;

View File

@ -7,7 +7,10 @@ dotenv.config();
async function migrateTenantCredits() { async function migrateTenantCredits() {
try { try {
const MONGODB_URI = process.env.MONGODB_URI || null; const MONGODB_URI = process.env.MONGODB_URI;
if (!MONGODB_URI) {
throw new Error('MONGODB_URI is not set');
}
await mongoose.connect(MONGODB_URI); await mongoose.connect(MONGODB_URI);
console.log('Connected to MongoDB'); console.log('Connected to MongoDB');
@ -62,4 +65,4 @@ async function migrateTenantCredits() {
} }
} }
migrateTenantCredits(); migrateTenantCredits();

View File

@ -7,7 +7,10 @@ dotenv.config();
async function migrateTenants() { async function migrateTenants() {
try { try {
const MONGODB_URI = process.env.MONGODB_URI || null; const MONGODB_URI = process.env.MONGODB_URI;
if (!MONGODB_URI) {
throw new Error('MONGODB_URI is not set');
}
await mongoose.connect(MONGODB_URI); await mongoose.connect(MONGODB_URI);
console.log('Connected to MongoDB'); console.log('Connected to MongoDB');
@ -34,4 +37,4 @@ async function migrateTenants() {
} }
} }
migrateTenants(); migrateTenants();

View File

@ -33,11 +33,21 @@ import packageJson from '../../../package.json';
import logger from '../../utils/logger'; import logger from '../../utils/logger';
import LanguageSwitcher from '../common/LanguageSwitcher'; import LanguageSwitcher from '../common/LanguageSwitcher';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { apiClient } from '../../services/api';
interface DashboardLayoutProps { interface DashboardLayoutProps {
children: ReactNode; children: ReactNode;
} }
const getLastTwoIpv4Blocks = (ip: string): string | null => {
const match = ip.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);
if (!match) return null;
const third = Number(match[3]);
const fourth = Number(match[4]);
if (Number.isNaN(third) || Number.isNaN(fourth)) return null;
return `${third}.${fourth}`;
};
const DashboardLayout: React.FC<DashboardLayoutProps> = ({ children }) => { const DashboardLayout: React.FC<DashboardLayoutProps> = ({ children }) => {
const { user, logout } = useAuth(); const { user, logout } = useAuth();
const { tenant } = useTenant(); const { tenant } = useTenant();
@ -45,6 +55,7 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ children }) => {
const [sidebarOpen, setSidebarOpen] = useState(false); const [sidebarOpen, setSidebarOpen] = useState(false);
const location = useLocation(); const location = useLocation();
const navigate = useNavigate(); const navigate = useNavigate();
const [vmIpSuffix, setVmIpSuffix] = useState<string | null>(null);
// Force language from localStorage on mount to ensure immediate consistency // Force language from localStorage on mount to ensure immediate consistency
useEffect(() => { useEffect(() => {
@ -62,6 +73,26 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ children }) => {
} catch { } } catch { }
}, [i18n.resolvedLanguage]); }, [i18n.resolvedLanguage]);
useEffect(() => {
let isMounted = true;
const loadVmIp = async () => {
try {
const response = await apiClient.get<{ ip: string | null; ips?: string[] }>('/system/vm-ip');
const ip = response.data?.ip;
const suffix = ip ? getLastTwoIpv4Blocks(ip) : null;
if (isMounted) setVmIpSuffix(suffix);
} catch {
if (isMounted) setVmIpSuffix(null);
}
};
loadVmIp();
return () => {
isMounted = false;
};
}, []);
const handleLogout = async () => { const handleLogout = async () => {
try { try {
await logout(); await logout();
@ -196,6 +227,7 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ children }) => {
<div className="flex items-center justify-between text-xs text-gray-500 dark:text-gray-400"> <div className="flex items-center justify-between text-xs text-gray-500 dark:text-gray-400">
<span>v{packageJson.version}</span> <span>v{packageJson.version}</span>
{vmIpSuffix && <span>IP {vmIpSuffix}</span>}
</div> </div>
</div> </div>
</div> </div>
@ -266,6 +298,7 @@ const DashboardLayout: React.FC<DashboardLayoutProps> = ({ children }) => {
<div className="flex items-center justify-between text-xs text-gray-500 dark:text-gray-400"> <div className="flex items-center justify-between text-xs text-gray-500 dark:text-gray-400">
<span>v{packageJson.version}</span> <span>v{packageJson.version}</span>
{vmIpSuffix && <span>IP {vmIpSuffix}</span>}
</div> </div>
</div> </div>
</div> </div>