256 lines
11 KiB
TypeScript
256 lines
11 KiB
TypeScript
"use client";
|
||
|
||
import { useEffect, useState } from "react";
|
||
|
||
export default function SovereignSetup() {
|
||
const [os, setOs] = useState<string>("unknown");
|
||
const [certStatus, setCertStatus] = useState<"idle" | "testing" | "ok" | "fail">("idle");
|
||
const [tenantName, setTenantName] = useState("SOVEREIGN TENANT");
|
||
|
||
useEffect(() => {
|
||
const ua = navigator.userAgent.toLowerCase();
|
||
if (ua.includes("android")) setOs("android");
|
||
else if (ua.includes("iphone") || ua.includes("ipad")) setOs("ios");
|
||
else if (ua.includes("mac")) setOs("macos");
|
||
else if (ua.includes("windows")) setOs("windows");
|
||
else if (ua.includes("linux")) setOs("linux");
|
||
else setOs("unknown");
|
||
|
||
// Fetch tenant info
|
||
fetch("/api/auth/me").then(r => r.json()).then(d => {
|
||
if (d.tenantName) setTenantName(d.tenantName);
|
||
}).catch(() => {});
|
||
}, []);
|
||
|
||
const testConnection = async () => {
|
||
setCertStatus("testing");
|
||
try {
|
||
const resp = await fetch("/api/superadmin/xcu-tls-switch");
|
||
if (resp.ok) {
|
||
const data = await resp.json();
|
||
const onlineNodes = data.nodes?.filter((n: any) => n.online) || [];
|
||
setCertStatus(onlineNodes.length > 0 ? "ok" : "fail");
|
||
} else {
|
||
setCertStatus("fail");
|
||
}
|
||
} catch {
|
||
setCertStatus("fail");
|
||
}
|
||
};
|
||
|
||
const instructions: Record<string, { title: string; icon: string; steps: string[] }> = {
|
||
android: {
|
||
title: "Android",
|
||
icon: "📱",
|
||
steps: [
|
||
"Tap tombol \"Download CA Certificate\" di bawah",
|
||
"Buka Settings → Security → Encryption & Credentials",
|
||
"Tap \"Install a certificate\" → \"CA certificate\"",
|
||
"Pilih file xcu-sovereign-ca.crt yang baru di-download",
|
||
"Konfirmasi dengan PIN/Fingerprint",
|
||
"Selesai! Certificate berlaku 30 tahun"
|
||
]
|
||
},
|
||
ios: {
|
||
title: "iPhone / iPad",
|
||
icon: "🍎",
|
||
steps: [
|
||
"Tap tombol \"Download CA Certificate\" di bawah",
|
||
"iOS akan menampilkan \"Profile Downloaded\"",
|
||
"Buka Settings → General → VPN & Device Management",
|
||
"Tap profile \"XCU Sovereign CA\" → Install",
|
||
"Buka Settings → General → About → Certificate Trust Settings",
|
||
"Enable trust untuk \"XCU Sovereign CA\"",
|
||
"Selesai! Certificate berlaku 30 tahun"
|
||
]
|
||
},
|
||
windows: {
|
||
title: "Windows",
|
||
icon: "🖥️",
|
||
steps: [
|
||
"Klik tombol \"Download CA Certificate\" di bawah",
|
||
"Double-click file xcu-sovereign-ca.crt",
|
||
"Klik \"Install Certificate...\"",
|
||
"Pilih \"Local Machine\" → Next",
|
||
"Pilih \"Place all certificates in the following store\"",
|
||
"Klik Browse → pilih \"Trusted Root Certification Authorities\"",
|
||
"Klik Finish → Yes",
|
||
"Restart browser. Selesai!"
|
||
]
|
||
},
|
||
macos: {
|
||
title: "macOS",
|
||
icon: "💻",
|
||
steps: [
|
||
"Klik tombol \"Download CA Certificate\" di bawah",
|
||
"Double-click file xcu-sovereign-ca.crt → Keychain Access terbuka",
|
||
"Certificate muncul di login keychain",
|
||
"Double-click certificate → Trust → \"Always Trust\"",
|
||
"Tutup dialog, masukkan password Mac",
|
||
"Restart browser. Selesai!"
|
||
]
|
||
},
|
||
linux: {
|
||
title: "Linux",
|
||
icon: "🐧",
|
||
steps: [
|
||
"Download CA Certificate",
|
||
"sudo cp xcu-sovereign-ca.crt /usr/local/share/ca-certificates/",
|
||
"sudo update-ca-certificates",
|
||
"Restart browser. Selesai!"
|
||
]
|
||
},
|
||
unknown: {
|
||
title: "Device",
|
||
icon: "🔧",
|
||
steps: ["Download CA Certificate dan install sesuai OS Anda"]
|
||
}
|
||
};
|
||
|
||
const currentOs = instructions[os] || instructions.unknown;
|
||
|
||
return (
|
||
<div className="min-h-screen bg-gradient-to-br from-slate-950 via-slate-900 to-slate-950 text-white">
|
||
{/* Header */}
|
||
<header className="border-b border-slate-800 px-6 py-4">
|
||
<div className="max-w-4xl mx-auto flex items-center justify-between">
|
||
<div className="flex items-center gap-3">
|
||
<div className="w-10 h-10 rounded-xl bg-gradient-to-br from-amber-500 to-orange-600 flex items-center justify-center shadow-lg">
|
||
<svg className="w-5 h-5 text-white" fill="currentColor" viewBox="0 0 24 24"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
|
||
</div>
|
||
<div>
|
||
<h1 className="text-lg font-bold tracking-tight">Sovereign Security Setup</h1>
|
||
<p className="text-xs text-slate-400">{tenantName} • Private CA Installation</p>
|
||
</div>
|
||
</div>
|
||
<a href="/supreme-admin" className="text-xs text-slate-400 hover:text-white transition-colors">← Back to Dashboard</a>
|
||
</div>
|
||
</header>
|
||
|
||
<main className="max-w-4xl mx-auto px-6 py-10 space-y-8">
|
||
{/* Hero Card */}
|
||
<div className="bg-gradient-to-r from-amber-500/10 via-orange-500/5 to-transparent border border-amber-500/20 rounded-2xl p-8">
|
||
<div className="flex items-start gap-4">
|
||
<div className="text-4xl">🛡️</div>
|
||
<div>
|
||
<h2 className="text-2xl font-bold mb-2">Mode Sovereign Aktif</h2>
|
||
<p className="text-slate-300 text-sm leading-relaxed">
|
||
Tenant ini beroperasi dalam <strong className="text-amber-400">Security Tier SOVEREIGN</strong>.
|
||
Semua koneksi QUIC/WebTransport menggunakan Private CA yang tidak bergantung pada internet global.
|
||
Setiap device perlu install sertifikat CA <strong>1× saja</strong>, berlaku <strong>30 tahun</strong>.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Download Section */}
|
||
<div className="bg-slate-800/50 border border-slate-700 rounded-2xl p-8">
|
||
<h3 className="text-lg font-bold mb-4 flex items-center gap-2">
|
||
<span className="w-8 h-8 rounded-lg bg-emerald-500/20 flex items-center justify-center text-emerald-400 text-sm font-bold">1</span>
|
||
Download Certificate
|
||
</h3>
|
||
<div className="flex flex-wrap gap-4">
|
||
<a
|
||
href="/api/superadmin/sovereign-ca/download"
|
||
download="xcu-sovereign-ca.crt"
|
||
className="inline-flex items-center gap-3 px-6 py-3 bg-gradient-to-r from-emerald-600 to-emerald-500 hover:from-emerald-500 hover:to-emerald-400 text-white font-bold rounded-xl transition-all duration-300 shadow-lg shadow-emerald-500/20 hover:shadow-emerald-500/40 hover:scale-105"
|
||
>
|
||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /></svg>
|
||
Download CA Certificate
|
||
</a>
|
||
<div className="flex items-center gap-2 text-xs text-slate-500">
|
||
<span>Format: X.509 PEM</span>
|
||
<span>•</span>
|
||
<span>Validitas: 30 tahun</span>
|
||
<span>•</span>
|
||
<span>Algorithm: RSA-4096 + SHA-256</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* OS-Specific Instructions */}
|
||
<div className="bg-slate-800/50 border border-slate-700 rounded-2xl p-8">
|
||
<h3 className="text-lg font-bold mb-1 flex items-center gap-2">
|
||
<span className="w-8 h-8 rounded-lg bg-blue-500/20 flex items-center justify-center text-blue-400 text-sm font-bold">2</span>
|
||
Install Certificate
|
||
</h3>
|
||
<p className="text-xs text-slate-400 mb-6">
|
||
Terdeteksi: <strong className="text-cyan-400">{currentOs.icon} {currentOs.title}</strong>
|
||
</p>
|
||
|
||
{/* OS Tabs */}
|
||
<div className="flex flex-wrap gap-2 mb-6">
|
||
{Object.entries(instructions).filter(([k]) => k !== 'unknown').map(([key, val]) => (
|
||
<button
|
||
key={key}
|
||
onClick={() => setOs(key)}
|
||
className={`px-4 py-2 rounded-lg text-xs font-bold uppercase tracking-wider transition-all ${
|
||
os === key
|
||
? 'bg-cyan-500 text-white shadow-lg shadow-cyan-500/30'
|
||
: 'bg-slate-700 text-slate-400 hover:bg-slate-600 hover:text-white'
|
||
}`}
|
||
>
|
||
{val.icon} {val.title}
|
||
</button>
|
||
))}
|
||
</div>
|
||
|
||
{/* Steps */}
|
||
<div className="space-y-3">
|
||
{currentOs.steps.map((step, idx) => (
|
||
<div key={idx} className="flex gap-3 items-start">
|
||
<div className="w-6 h-6 rounded-full bg-slate-700 flex items-center justify-center text-[10px] font-bold text-cyan-400 flex-shrink-0 mt-0.5">
|
||
{idx + 1}
|
||
</div>
|
||
<p className="text-sm text-slate-300">{step}</p>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Connection Test */}
|
||
<div className="bg-slate-800/50 border border-slate-700 rounded-2xl p-8">
|
||
<h3 className="text-lg font-bold mb-4 flex items-center gap-2">
|
||
<span className="w-8 h-8 rounded-lg bg-purple-500/20 flex items-center justify-center text-purple-400 text-sm font-bold">3</span>
|
||
Verify Connection
|
||
</h3>
|
||
<div className="flex items-center gap-4">
|
||
<button
|
||
onClick={testConnection}
|
||
disabled={certStatus === "testing"}
|
||
className="inline-flex items-center gap-2 px-6 py-3 bg-gradient-to-r from-purple-600 to-purple-500 hover:from-purple-500 hover:to-purple-400 text-white font-bold rounded-xl transition-all duration-300 shadow-lg shadow-purple-500/20 disabled:opacity-50"
|
||
>
|
||
{certStatus === "testing" ? (
|
||
<div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin"></div>
|
||
) : (
|
||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
|
||
)}
|
||
Test Connection
|
||
</button>
|
||
{certStatus === "ok" && (
|
||
<div className="flex items-center gap-2 px-4 py-2 bg-emerald-500/10 border border-emerald-500/20 rounded-xl">
|
||
<span className="relative flex h-3 w-3">
|
||
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"></span>
|
||
<span className="relative inline-flex rounded-full h-3 w-3 bg-emerald-400"></span>
|
||
</span>
|
||
<span className="text-sm font-bold text-emerald-400">Koneksi Aman — XCU Engine Online</span>
|
||
</div>
|
||
)}
|
||
{certStatus === "fail" && (
|
||
<div className="flex items-center gap-2 px-4 py-2 bg-red-500/10 border border-red-500/20 rounded-xl">
|
||
<span className="w-3 h-3 rounded-full bg-red-500"></span>
|
||
<span className="text-sm font-bold text-red-400">Koneksi Gagal — Pastikan certificate sudah terinstall</span>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Info */}
|
||
<div className="text-center text-xs text-slate-600 py-4">
|
||
XCom ULTRA • Sovereign Security Infrastructure • Private CA • Zero Internet Dependency
|
||
</div>
|
||
</main>
|
||
</div>
|
||
);
|
||
}
|