@cybermem/dashboard 0.5.14 → 0.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Dockerfile +2 -1
- package/app/api/audit-logs/route.ts +79 -56
- package/app/api/auth/token/route.ts +59 -0
- package/app/api/health/route.ts +49 -22
- package/app/api/metrics/route.ts +272 -86
- package/app/api/reset/route.ts +1 -1
- package/app/api/restore/route.ts +1 -1
- package/app/api/settings/route.ts +37 -26
- package/app/api/system/restart/route.ts +1 -1
- package/app/layout.tsx +25 -17
- package/app/page.tsx +135 -110
- package/components/dashboard/audit-log-table.tsx +3 -3
- package/components/dashboard/mcp-config-modal.tsx +356 -247
- package/components/dashboard/metric-card.tsx +4 -7
- package/components/dashboard/settings-modal.tsx +53 -58
- package/e2e/crud-happy-path.spec.ts +243 -173
- package/lib/auth.ts +50 -0
- package/lib/data/dashboard-context.tsx +117 -70
- package/lib/data/production-strategy.ts +124 -85
- package/middleware.ts +53 -31
- package/next.config.mjs +12 -20
- package/package.json +4 -1
- package/playwright.config.ts +50 -15
- package/public/clients.json +7 -23
|
@@ -18,8 +18,7 @@ export default function MetricCard({
|
|
|
18
18
|
loading = false,
|
|
19
19
|
hasData = true,
|
|
20
20
|
}: MetricCardProps) {
|
|
21
|
-
const
|
|
22
|
-
!hasData || value === "N/A" || value === "0" || value === "0.0%";
|
|
21
|
+
const isValueNA = value === "N/A";
|
|
23
22
|
|
|
24
23
|
// Skeleton state
|
|
25
24
|
if (loading) {
|
|
@@ -33,15 +32,13 @@ export default function MetricCard({
|
|
|
33
32
|
);
|
|
34
33
|
}
|
|
35
34
|
|
|
36
|
-
//
|
|
37
|
-
if (
|
|
35
|
+
// N/A state
|
|
36
|
+
if (isValueNA) {
|
|
38
37
|
return (
|
|
39
38
|
<Card className="bg-white/5 border-white/10 backdrop-blur-md text-white shadow-lg overflow-hidden relative opacity-60">
|
|
40
39
|
<CardContent className="p-6 relative z-10">
|
|
41
40
|
<div className="text-sm font-medium text-slate-500 mb-2">{label}</div>
|
|
42
|
-
<div className="text-4xl font-bold text-slate-500">
|
|
43
|
-
{value === "N/A" ? "N/A" : "—"}
|
|
44
|
-
</div>
|
|
41
|
+
<div className="text-4xl font-bold text-slate-500">N/A</div>
|
|
45
42
|
</CardContent>
|
|
46
43
|
</Card>
|
|
47
44
|
);
|
|
@@ -30,6 +30,7 @@ export default function SettingsModal({ onClose }: { onClose: () => void }) {
|
|
|
30
30
|
const [adminPassword, setAdminPassword] = useState(
|
|
31
31
|
localStorage.getItem("adminPassword") || "admin",
|
|
32
32
|
);
|
|
33
|
+
const [settings, setSettings] = useState<any>(null);
|
|
33
34
|
const [isLoading, setIsLoading] = useState(true);
|
|
34
35
|
|
|
35
36
|
const { isDemo, toggleDemo } = useDashboard();
|
|
@@ -66,6 +67,7 @@ export default function SettingsModal({ onClose }: { onClose: () => void }) {
|
|
|
66
67
|
.then((data) => {
|
|
67
68
|
// Enforce Local Mode if server says so
|
|
68
69
|
setIsManaged(data.isManaged || false);
|
|
70
|
+
setSettings(data);
|
|
69
71
|
|
|
70
72
|
if (localKey && !data.isManaged) {
|
|
71
73
|
setApiKey(localKey);
|
|
@@ -284,7 +286,7 @@ export default function SettingsModal({ onClose }: { onClose: () => void }) {
|
|
|
284
286
|
Local Mode
|
|
285
287
|
</p>
|
|
286
288
|
<p className="text-xs text-neutral-500">
|
|
287
|
-
|
|
289
|
+
Auto-authenticated local connection
|
|
288
290
|
</p>
|
|
289
291
|
</div>
|
|
290
292
|
</>
|
|
@@ -293,13 +295,10 @@ export default function SettingsModal({ onClose }: { onClose: () => void }) {
|
|
|
293
295
|
<div className="w-2 h-2 bg-yellow-400 rounded-full" />
|
|
294
296
|
<div className="flex-1">
|
|
295
297
|
<p className="text-sm text-yellow-300 font-medium">
|
|
296
|
-
|
|
298
|
+
Security Token
|
|
297
299
|
</p>
|
|
298
300
|
<p className="text-xs text-neutral-500">
|
|
299
|
-
Using
|
|
300
|
-
<span className="text-yellow-500 ml-1">
|
|
301
|
-
(deprecated)
|
|
302
|
-
</span>
|
|
301
|
+
Using static token authentication
|
|
303
302
|
</p>
|
|
304
303
|
</div>
|
|
305
304
|
<a
|
|
@@ -338,20 +337,20 @@ export default function SettingsModal({ onClose }: { onClose: () => void }) {
|
|
|
338
337
|
</section>
|
|
339
338
|
|
|
340
339
|
{/* API Configuration */}
|
|
341
|
-
{!isManaged
|
|
340
|
+
{!isManaged && (
|
|
342
341
|
<section>
|
|
343
342
|
<h3 className="text-lg font-semibold text-white mb-4 flex items-center gap-2">
|
|
344
343
|
<Key className="w-5 h-5" />
|
|
345
|
-
|
|
344
|
+
Token Configuration
|
|
346
345
|
</h3>
|
|
347
346
|
<div className="bg-white/5 border border-white/10 rounded-lg p-5 space-y-4 shadow-[inset_0_0_20px_rgba(255,255,255,0.02)] backdrop-blur-sm">
|
|
348
347
|
<div className="space-y-2">
|
|
349
|
-
<Label htmlFor="api-key">
|
|
348
|
+
<Label htmlFor="api-key">Security Token</Label>
|
|
350
349
|
<div className="flex gap-2">
|
|
351
350
|
<div className="relative flex-1">
|
|
352
351
|
<Input
|
|
353
352
|
id="api-key"
|
|
354
|
-
value={apiKey || "
|
|
353
|
+
value={apiKey || "not-generated-yet"}
|
|
355
354
|
readOnly
|
|
356
355
|
className="bg-black/40 border-white/10 text-white font-mono"
|
|
357
356
|
type={showApiKey ? "text" : "password"}
|
|
@@ -379,6 +378,7 @@ export default function SettingsModal({ onClose }: { onClose: () => void }) {
|
|
|
379
378
|
)}
|
|
380
379
|
</Button>
|
|
381
380
|
</div>
|
|
381
|
+
|
|
382
382
|
<div className="flex justify-end pt-2">
|
|
383
383
|
{showRegenConfirm ? (
|
|
384
384
|
<div className="flex items-center gap-2">
|
|
@@ -426,37 +426,6 @@ export default function SettingsModal({ onClose }: { onClose: () => void }) {
|
|
|
426
426
|
</div>
|
|
427
427
|
</div>
|
|
428
428
|
</section>
|
|
429
|
-
) : (
|
|
430
|
-
<section>
|
|
431
|
-
<h3 className="text-lg font-semibold text-white mb-4 flex items-center gap-2">
|
|
432
|
-
<Shield className="w-5 h-5 text-emerald-400" />
|
|
433
|
-
API Security
|
|
434
|
-
</h3>
|
|
435
|
-
<div className="bg-emerald-500/5 border border-emerald-500/20 rounded-lg p-5 space-y-2 backdrop-blur-sm">
|
|
436
|
-
<p className="text-sm font-medium text-emerald-300">
|
|
437
|
-
Local Mode Active
|
|
438
|
-
</p>
|
|
439
|
-
<p className="text-xs text-emerald-200/60">
|
|
440
|
-
No API key required for connection from your laptop. Key
|
|
441
|
-
management is hidden.
|
|
442
|
-
</p>
|
|
443
|
-
|
|
444
|
-
<div className="mt-4 pt-4 border-t border-white/10">
|
|
445
|
-
<Label
|
|
446
|
-
htmlFor="endpoint"
|
|
447
|
-
className="text-xs text-neutral-500 mb-2 block"
|
|
448
|
-
>
|
|
449
|
-
System Endpoint
|
|
450
|
-
</Label>
|
|
451
|
-
<Input
|
|
452
|
-
id="endpoint"
|
|
453
|
-
value={endpoint}
|
|
454
|
-
readOnly
|
|
455
|
-
className="h-9 bg-black/40 border-white/10 text-neutral-400 text-sm"
|
|
456
|
-
/>
|
|
457
|
-
</div>
|
|
458
|
-
</div>
|
|
459
|
-
</section>
|
|
460
429
|
)}
|
|
461
430
|
|
|
462
431
|
{/* Data Management */}
|
|
@@ -469,7 +438,7 @@ export default function SettingsModal({ onClose }: { onClose: () => void }) {
|
|
|
469
438
|
<div className="flex items-center gap-3">
|
|
470
439
|
<Button
|
|
471
440
|
variant="outline"
|
|
472
|
-
className="flex-1 justify-center bg-white/5 border-white/10 hover:bg-white/10 hover:border-white/20 text-white h-11 px-6 transition-all"
|
|
441
|
+
className="flex-1 justify-center bg-white/5 border-white/10 hover:bg-white/10 hover:border-white/20 text-white hover:text-white h-11 px-6 transition-all"
|
|
473
442
|
onClick={handleBackup}
|
|
474
443
|
disabled={isBackingUp}
|
|
475
444
|
>
|
|
@@ -492,7 +461,7 @@ export default function SettingsModal({ onClose }: { onClose: () => void }) {
|
|
|
492
461
|
/>
|
|
493
462
|
<Button
|
|
494
463
|
variant="outline"
|
|
495
|
-
className="w-full justify-center bg-white/5 border-white/10 hover:bg-white/10 hover:border-white/20 text-white h-11 px-6 transition-all"
|
|
464
|
+
className="w-full justify-center bg-white/5 border-white/10 hover:bg-white/10 hover:border-white/20 text-white hover:text-white h-11 px-6 transition-all"
|
|
496
465
|
onClick={() =>
|
|
497
466
|
document.getElementById("restore-file")?.click()
|
|
498
467
|
}
|
|
@@ -509,7 +478,7 @@ export default function SettingsModal({ onClose }: { onClose: () => void }) {
|
|
|
509
478
|
|
|
510
479
|
<Button
|
|
511
480
|
variant="outline"
|
|
512
|
-
className="flex-1 justify-center bg-
|
|
481
|
+
className="flex-1 justify-center bg-red-500/5 border-red-500/10 hover:bg-red-500/10 hover:border-red-500/30 text-red-400 hover:text-red-300 h-11 px-6 transition-all"
|
|
513
482
|
onClick={() => setShowResetConfirm(true)}
|
|
514
483
|
disabled={isResetting}
|
|
515
484
|
>
|
|
@@ -588,29 +557,51 @@ export default function SettingsModal({ onClose }: { onClose: () => void }) {
|
|
|
588
557
|
System
|
|
589
558
|
</h3>
|
|
590
559
|
<div className="bg-white/5 border border-white/10 rounded-xl p-6 shadow-[inset_0_0_30px_rgba(255,255,255,0.01)] backdrop-blur-md space-y-6">
|
|
591
|
-
<div className="grid grid-cols-2 gap-
|
|
592
|
-
<div>
|
|
593
|
-
<span className="text-[10px] uppercase text-neutral-500 font-bold tracking-[0.2em]">
|
|
594
|
-
|
|
560
|
+
<div className="grid grid-cols-2 gap-12">
|
|
561
|
+
<div className="space-y-4">
|
|
562
|
+
<span className="text-[10px] uppercase text-neutral-500 font-bold tracking-[0.2em] block mb-2">
|
|
563
|
+
Versions
|
|
595
564
|
</span>
|
|
596
|
-
<
|
|
597
|
-
|
|
598
|
-
|
|
565
|
+
<div className="space-y-3">
|
|
566
|
+
<div className="flex justify-between items-center group/version">
|
|
567
|
+
<span className="text-xs text-neutral-400 group-hover/version:text-neutral-300 transition-colors">
|
|
568
|
+
Dashboard
|
|
569
|
+
</span>
|
|
570
|
+
<code className="text-[13px] font-mono text-neutral-200 bg-white/5 px-2 py-0.5 rounded border border-white/10 group-hover/version:border-emerald-500/30 group-hover/version:text-emerald-400 transition-all">
|
|
571
|
+
{settings?.dashboardVersion || "v0.7.5"}
|
|
572
|
+
</code>
|
|
573
|
+
</div>
|
|
574
|
+
<div className="flex justify-between items-center group/version">
|
|
575
|
+
<span className="text-xs text-neutral-400 group-hover/version:text-neutral-300 transition-colors">
|
|
576
|
+
MCP Server
|
|
577
|
+
</span>
|
|
578
|
+
<code className="text-[13px] font-mono text-neutral-200 bg-white/5 px-2 py-0.5 rounded border border-white/10 group-hover/version:border-emerald-500/30 group-hover/version:text-emerald-400 transition-all">
|
|
579
|
+
{settings?.mcpVersion || "v0.7.5"}
|
|
580
|
+
</code>
|
|
581
|
+
</div>
|
|
582
|
+
</div>
|
|
599
583
|
</div>
|
|
600
|
-
<div>
|
|
601
|
-
<span className="text-[10px] uppercase text-neutral-500 font-bold tracking-[0.2em]">
|
|
584
|
+
<div className="border-l border-white/5 pl-8">
|
|
585
|
+
<span className="text-[10px] uppercase text-neutral-500 font-bold tracking-[0.2em] block mb-2">
|
|
602
586
|
Environment
|
|
603
587
|
</span>
|
|
604
|
-
<
|
|
605
|
-
|
|
606
|
-
|
|
588
|
+
<div className="mt-4 flex flex-col justify-center">
|
|
589
|
+
<p className="text-emerald-400 font-bold text-2xl tracking-tight drop-shadow-[0_0_15px_rgba(52,211,153,0.3)]">
|
|
590
|
+
Production
|
|
591
|
+
</p>
|
|
592
|
+
<p className="text-[10px] text-neutral-500 mt-1 uppercase tracking-[0.2em] font-medium">
|
|
593
|
+
{settings?.isManaged
|
|
594
|
+
? "Managed Instance"
|
|
595
|
+
: "Local Instance"}
|
|
596
|
+
</p>
|
|
597
|
+
</div>
|
|
607
598
|
</div>
|
|
608
599
|
</div>
|
|
609
600
|
|
|
610
601
|
<div className="pt-2 border-t border-white/5">
|
|
611
602
|
<Button
|
|
612
603
|
variant="outline"
|
|
613
|
-
className="w-full bg-sky-500/5 border-sky-500/10 hover:bg-sky-500/10 hover:border-sky-500/30 text-sky-400 h-10 transition-all font-medium flex items-center justify-center gap-2 group"
|
|
604
|
+
className="w-full bg-sky-500/5 border-sky-500/10 hover:bg-sky-500/10 hover:border-sky-500/30 text-sky-400 hover:text-sky-300 h-10 transition-all font-medium flex items-center justify-center gap-2 group"
|
|
614
605
|
onClick={handleRestart}
|
|
615
606
|
disabled={isRestarting}
|
|
616
607
|
>
|
|
@@ -628,7 +619,11 @@ export default function SettingsModal({ onClose }: { onClose: () => void }) {
|
|
|
628
619
|
|
|
629
620
|
{/* Footer */}
|
|
630
621
|
<div className="sticky bottom-0 bg-[#0B1116]/80 backdrop-blur-md border-t border-emerald-500/20 px-6 py-4 flex justify-end gap-3 z-10">
|
|
631
|
-
<Button
|
|
622
|
+
<Button
|
|
623
|
+
onClick={onClose}
|
|
624
|
+
variant="ghost"
|
|
625
|
+
className="text-neutral-400 hover:text-white hover:bg-white/5"
|
|
626
|
+
>
|
|
632
627
|
Cancel
|
|
633
628
|
</Button>
|
|
634
629
|
<Button
|