Files
MIKROTIK-RMM/frontend/src/components/SecurityBanners.tsx
T
2GT-RichandClaude Opus 4.8 8e564fc813 fix(system): report real version so update banner clears; move update notice to Operations (v0.16.11-beta)
Update-availability fixes:
- The backend read its version from npm_package_version, which is unset
  when the container runs `node dist/index.js` directly, so current was
  always "0.0.0" and every release looked newer — the "update available"
  banner never cleared. Read the bundled package.json instead
  (routes/system.ts), falling back to npm_package_version.
- Move the update notification out of the top-of-app banner into the
  Operations dashboard (a dedicated notice under the network-status hero),
  shown only when genuinely behind and cleared once up to date.

Security banner:
- Replace the now-dead jwt_secret_default / encryption_key_default checks
  with the current secrets_not_persisted warning (auto-generated secrets
  that couldn't be persisted), matching the self-healing secrets model.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 17:18:25 -07:00

64 lines
2.6 KiB
TypeScript

import { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import { AlertTriangle, ShieldAlert } from 'lucide-react';
import { authApi } from '../services/api';
interface SecurityStatus {
warnings: string[];
}
export default function SecurityBanners() {
const [status, setStatus] = useState<SecurityStatus | null>(null);
useEffect(() => {
authApi.securityStatus()
.then((r) => setStatus(r.data))
.catch(() => {});
}, []);
const noWarnings = !status || status.warnings.length === 0;
if (noWarnings) return null;
const hasSecretsNotPersisted = !!status && status.warnings.includes('secrets_not_persisted');
const hasAdminWarning = !!status && status.warnings.includes('admin_password_default');
return (
<div>
{hasSecretsNotPersisted && (
<div className="flex items-center gap-2 bg-yellow-50 dark:bg-yellow-900/20 border-b border-yellow-200 dark:border-yellow-800 px-4 py-2 text-sm text-yellow-800 dark:text-yellow-200">
<AlertTriangle className="w-4 h-4 shrink-0" />
<span>
<span className="font-semibold">Security warning:</span>{' '}
Auto-generated secrets could not be saved, so they will change on
every restart — logging users out and potentially orphaning stored
device credentials. Mount a writable volume at{' '}
<code className="font-mono text-xs">SECRETS_DIR</code> (default{' '}
<code className="font-mono text-xs">/app/data</code>) or set{' '}
<code className="font-mono text-xs">JWT_SECRET</code> and{' '}
<code className="font-mono text-xs">ENCRYPTION_KEY</code> in your{' '}
<code className="font-mono text-xs">.env</code>.
</span>
</div>
)}
{hasAdminWarning && (
<div className="flex items-center justify-between gap-4 bg-red-50 dark:bg-red-900/20 border-b border-red-200 dark:border-red-800 px-4 py-2 text-sm text-red-800 dark:text-red-200">
<div className="flex items-center gap-2">
<ShieldAlert className="w-4 h-4 shrink-0" />
<span>
<span className="font-semibold">Critical:</span> The{' '}
<code className="font-mono text-xs">admin</code> account is
using the default password. Change it immediately.
</span>
</div>
<Link
to="/settings"
className="shrink-0 bg-red-600 hover:bg-red-700 text-white text-xs px-3 py-1 rounded font-medium"
>
Change password
</Link>
</div>
)}
</div>
);
}