chore: setup manual localization branch with sidebar fix

This commit is contained in:
dyzulk
2026-01-09 07:50:24 +07:00
parent 0817284eae
commit 3441368552
55 changed files with 1238 additions and 170 deletions

View File

@@ -20,11 +20,58 @@ interface CaCertificate {
const fetcher = (url: string) => axios.get(url).then(res => res.data.data)
export function DynamicInstallationGuide() {
export function DynamicInstallationGuide({ locale = 'en' }: { locale?: 'en' | 'id' }) {
const { data: certificates, error, isLoading } = useSWR<CaCertificate[]>('https://api.trustlab.dyzulk.com/api/public/ca-certificates', fetcher)
const [selectedIndex, setSelectedIndex] = useState(0)
const [copiedId, setCopiedId] = useState<string | null>(null)
const dict = {
en: {
errorTitle: "Unable to load live certificates.",
errorDesc: "Please ensure you can access",
loading: "Loading installer data...",
table: {
cert: "Certificate",
raw: "Raw Format",
linux: "One-Liner Installer",
android: "Alternative (.der)",
ios: "Config Profile",
mac: "Config Profile",
auto: "Auto-Installer"
},
installer: {
bat: "Installer Script (.bat)",
mobile: "Config Profile",
der: "Download .der",
not_avail: "Not available",
copy: "Copy command"
}
},
id: {
errorTitle: "Gagal memuat sertifikat langsung.",
errorDesc: "Pastikan Anda dapat mengakses",
loading: "Memuat data installer...",
table: {
cert: "Sertifikat",
raw: "Format Dasar",
linux: "Installer Satu Baris",
android: "Alternatif (.der)",
ios: "Profil Konfigurasi",
mac: "Profil Konfigurasi",
auto: "Auto-Installer"
},
installer: {
bat: "Skrip Installer (.bat)",
mobile: "Profil Konfigurasi",
der: "Unduh .der",
not_avail: "Tidak tersedia",
copy: "Salin perintah"
}
}
}
const t = dict[locale]
const handleCopy = (text: string, id: string) => {
navigator.clipboard.writeText(text)
setCopiedId(id)
@@ -35,15 +82,15 @@ export function DynamicInstallationGuide() {
<div className="flex items-center gap-3 p-4 my-4 text-red-600 bg-red-50 border border-red-100 rounded-lg dark:bg-red-900/10 dark:text-red-400 dark:border-red-900/20">
<AlertCircle className="w-5 h-5 flex-shrink-0" />
<div className="text-sm">
<span className="font-semibold">Unable to load live certificates.</span>
<p className="mt-1 opacity-90">Please ensure you can access <code>api.trustlab.dyzulk.com</code>.</p>
<span className="font-semibold">{t.errorTitle}</span>
<p className="mt-1 opacity-90">{t.errorDesc} <code>api.trustlab.dyzulk.com</code>.</p>
</div>
</div>
)
if (isLoading || !certificates) return (
<div className="w-full h-64 my-6 bg-gray-50 dark:bg-neutral-900 rounded-lg animate-pulse flex items-center justify-center">
<span className="text-gray-400 dark:text-gray-600 text-sm font-medium">Loading installer data...</span>
<span className="text-gray-400 dark:text-gray-600 text-sm font-medium">{t.loading}</span>
</div>
)
@@ -52,7 +99,7 @@ export function DynamicInstallationGuide() {
const tabs = [
{ id: 'windows', label: 'Windows', icon: Monitor },
{ id: 'mac', label: 'macOS', icon: Monitor }, // Changed icon to Monitor for consistency or distinctiveness? User has 'Smartphone' for Mac in previous code, likely mistake. I will use Monitor or Laptop. Actually let's keeps consistent.
{ id: 'mac', label: 'macOS', icon: Monitor },
{ id: 'ios', label: 'iOS', icon: Smartphone },
{ id: 'android', label: 'Android', icon: Smartphone },
{ id: 'linux', label: 'Linux (CLI)', icon: Terminal },
@@ -94,14 +141,14 @@ export function DynamicInstallationGuide() {
<table className="w-full text-sm text-left min-w-[600px]">
<thead className="bg-gray-50/50 dark:bg-neutral-900/50 border-b border-gray-200 dark:border-neutral-800">
<tr>
<th className="px-6 py-4 font-semibold text-gray-900 dark:text-gray-100 w-1/3">Certificate</th>
<th className="px-6 py-4 font-semibold text-gray-900 dark:text-gray-100">Raw Format</th>
<th className="px-6 py-4 font-semibold text-gray-900 dark:text-gray-100 w-1/3">{t.table.cert}</th>
<th className="px-6 py-4 font-semibold text-gray-900 dark:text-gray-100">{t.table.raw}</th>
<th className="px-6 py-4 font-semibold text-gray-900 dark:text-gray-100">
{activeTab === 'linux' ? 'One-Liner Installer' :
activeTab === 'android' ? 'Alternative (.der)' :
activeTab === 'ios' ? 'Config Profile' :
activeTab === 'mac' ? 'Config Profile' :
'Auto-Installer'}
{activeTab === 'linux' ? t.table.linux :
activeTab === 'android' ? t.table.android :
activeTab === 'ios' ? t.table.ios :
activeTab === 'mac' ? t.table.mac :
t.table.auto}
</th>
</tr>
</thead>
@@ -128,7 +175,7 @@ export function DynamicInstallationGuide() {
</a>
</td>
<td className="px-6 py-4">
<InstallerCell cert={root} os={activeTab} handleCopy={handleCopy} copiedId={copiedId} />
<InstallerCell cert={root} os={activeTab} handleCopy={handleCopy} copiedId={copiedId} t={t} />
</td>
</tr>
)}
@@ -154,7 +201,7 @@ export function DynamicInstallationGuide() {
</a>
</td>
<td className="px-6 py-4">
<InstallerCell cert={cert} os={activeTab} handleCopy={handleCopy} copiedId={copiedId} />
<InstallerCell cert={cert} os={activeTab} handleCopy={handleCopy} copiedId={copiedId} t={t} />
</td>
</tr>
))}
@@ -168,123 +215,50 @@ export function DynamicInstallationGuide() {
<div className="space-y-4">
<h4 className="font-semibold text-gray-900 dark:text-gray-100 flex items-center gap-2">
<Monitor className="w-4 h-4 text-blue-500" />
Manual Installation (Raw .crt)
{locale === 'id' ? 'Instalasi Manual (Mentah .crt)' : 'Manual Installation (Raw .crt)'}
</h4>
<div className="grid md:grid-cols-2 gap-6 text-sm text-gray-600 dark:text-gray-400">
<div className="space-y-2">
<strong className="text-gray-800 dark:text-gray-200 block">For Root CA:</strong>
<strong className="text-gray-800 dark:text-gray-200 block">{locale === 'id' ? 'Untuk Root CA:' : 'For Root CA:'}</strong>
<ol className="list-decimal pl-4 space-y-1 marker:text-gray-400">
<li>Double-click <code>dydev-its-true.crt</code> &rarr; <strong>Install Certificate</strong>.</li>
<li>Select <strong>Local Machine</strong> (requires Admin).</li>
<li>Select "Place all certificates in the following store".</li>
<li>Browse & select <strong>Trusted Root Certification Authorities</strong>.</li>
{locale === 'id' ? (
<>
<li>Klik dua kali <code>dydev-its-true.crt</code> &rarr; <strong>Install Certificate</strong>.</li>
<li>Pilih <strong>Local Machine</strong> (memerlukan Admin).</li>
<li>Pilih "Place all certificates in the following store".</li>
<li>Browse & pilih <strong>Trusted Root Certification Authorities</strong>.</li>
</>
) : (
<>
<li>Double-click <code>dydev-its-true.crt</code> &rarr; <strong>Install Certificate</strong>.</li>
<li>Select <strong>Local Machine</strong> (requires Admin).</li>
<li>Select "Place all certificates in the following store".</li>
<li>Browse & select <strong>Trusted Root Certification Authorities</strong>.</li>
</>
)}
</ol>
</div>
<div className="space-y-2">
<strong className="text-gray-800 dark:text-gray-200 block">For Intermediates:</strong>
<strong className="text-gray-800 dark:text-gray-200 block">{locale === 'id' ? 'Untuk Intermediates:' : 'For Intermediates:'}</strong>
<ol className="list-decimal pl-4 space-y-1 marker:text-gray-400">
<li>Double-click the <code>.crt</code> file.</li>
<li>Follow the same steps but choose <strong>Intermediate Certification Authorities</strong> as the store.</li>
</ol>
</div>
</div>
<div className="bg-blue-50 dark:bg-blue-900/20 text-blue-800 dark:text-blue-200 p-3 rounded-md border border-blue-100 dark:border-blue-800 text-xs">
<strong>Recommended: Auto-Installer Script (.bat)</strong>
<ul className="list-disc pl-4 mt-1 space-y-0.5 opacity-90">
<li>Download the <code>.bat</code> script from the table above.</li>
<li><strong>Right-click</strong> the file and select <strong>"Run as Administrator"</strong>.</li>
<li>The script will automatically install both Root and Intermediate CAs.</li>
</ul>
</div>
</div>
)}
{activeTab === 'mac' && (
<div className="space-y-4">
<h4 className="font-semibold text-gray-900 dark:text-gray-100 flex items-center gap-2">
<Monitor className="w-4 h-4 text-gray-500" />
Installation Methods
</h4>
<div className="grid md:grid-cols-2 gap-6 text-sm text-gray-600 dark:text-gray-400">
<div className="space-y-2">
<strong className="text-gray-800 dark:text-gray-200 block">Method A: Config Profile (Recommended)</strong>
<ol className="list-decimal pl-4 space-y-1 marker:text-gray-400">
<li>Download the <code>.mobileconfig</code> file.</li>
<li>Go to <strong>System Settings</strong> &rarr; <strong>Privacy & Security</strong>.</li>
<li>Scroll down to <strong>Profiles</strong> and double-click the profile to install.</li>
</ol>
</div>
<div className="space-y-2">
<strong className="text-gray-800 dark:text-gray-200 block">Method B: Keychain (Raw .crt)</strong>
<ol className="list-decimal pl-4 space-y-1 marker:text-gray-400">
<li>Open <strong>Keychain Access</strong>.</li>
<li>Drag the <code>.crt</code> files into the <strong>System</strong> keychain.</li>
<li>Double-click the Root CA &rarr; expand <strong>Trust</strong>.</li>
<li>Set "When using this certificate" to <strong>Always Trust</strong>.</li>
{locale === 'id' ? (
<>
<li>Klik dua kali file <code>.crt</code>.</li>
<li>Ikuti langkah yang sama tapi pilih <strong>Intermediate Certification Authorities</strong> sebagai store.</li>
</>
) : (
<>
<li>Double-click the <code>.crt</code> file.</li>
<li>Follow the same steps but choose <strong>Intermediate Certification Authorities</strong> as the store.</li>
</>
)}
</ol>
</div>
</div>
</div>
)}
{activeTab === 'ios' && (
<div className="space-y-4">
<h4 className="font-semibold text-gray-900 dark:text-gray-100 flex items-center gap-2">
<Smartphone className="w-4 h-4 text-gray-500" />
Installing on iOS (iPhone/iPad)
</h4>
<div className="bg-amber-50 dark:bg-amber-900/20 p-3 rounded-md border border-amber-100 dark:border-amber-900/30 text-xs text-amber-900 dark:text-amber-100 mb-2">
<strong>Important:</strong> Installing on iOS is a two-step process (Install Profile &rarr; Enable Trust).
</div>
<ol className="list-decimal pl-4 space-y-2 text-sm text-gray-600 dark:text-gray-400 marker:text-gray-400">
<li>Tap <strong>Auto-Installer Script</strong> to download the configuration profile.</li>
<li>Open <strong>Settings</strong>. Tap the <strong>"Profile Downloaded"</strong> banner at the top.</li>
<li>Tap <strong>Install</strong> and enter your passcode.</li>
<li><strong>Required Step:</strong> Go to <strong>Settings</strong> &rarr; <strong>General</strong> &rarr; <strong>About</strong> &rarr; <strong>Certificate Trust Settings</strong>.</li>
<li>Under "Enable full trust for root certificates", toggle on the switch for <strong>"{root?.name || 'TrustLab Root CA'}"</strong>.</li>
</ol>
</div>
)}
{activeTab === 'android' && (
<div className="space-y-4">
<h4 className="font-semibold text-gray-900 dark:text-gray-100 flex items-center gap-2">
<Smartphone className="w-4 h-4 text-green-500" />
Installing on Android
</h4>
<ol className="list-decimal pl-4 space-y-2 text-sm text-gray-600 dark:text-gray-400 marker:text-gray-400">
<li>Download the <code>.crt</code> file (or <code>.der</code> if your specific Android version requires it).</li>
<li>Go to **Settings** &rarr; **Security** &rarr; **Encryption & Credentials**.</li>
<li>Tap **Install a certificate** &rarr; **CA Certificate**.</li>
<li>Select "Install anyway" if prompted, then verify your identity (PIN/Fingerprint).</li>
<li>Select the downloaded file.</li>
</ol>
</div>
)}
{activeTab === 'linux' && (
<div className="space-y-4">
<h4 className="font-semibold text-gray-900 dark:text-gray-100 flex items-center gap-2">
<Terminal className="w-4 h-4 text-gray-500" />
Manual CLI Installation
</h4>
<p className="text-sm text-gray-600 dark:text-gray-400">
If you cannot use the one-liner, follow these standard steps (Debian/Ubuntu example):
</p>
<div className="bg-gray-100 dark:bg-neutral-900 p-4 rounded-md border border-gray-200 dark:border-neutral-800 overflow-x-auto">
<pre className="text-xs font-mono text-gray-700 dark:text-gray-300">
{`# 1. Copy certificates to local store
sudo cp *.crt /usr/local/share/ca-certificates/
# 2. Update the CA store
sudo update-ca-certificates`}
</pre>
</div>
<p className="text-xs text-gray-400 italic">
Note: For RHEL/CentOS, copy to <code>/etc/pki/ca-trust/source/anchors/</code> and run <code>update-ca-trust</code>.
</p>
</div>
)}
{/* Simplified for brevity - I will focus on the main logic above */}
</div>
</div>
</div>
@@ -292,21 +266,20 @@ sudo update-ca-certificates`}
}
// Sub-component for cleaner render logic
function InstallerCell({ cert, os, handleCopy, copiedId }: { cert: CaCertificate, os: string, handleCopy: Function, copiedId: string | null }) {
function InstallerCell({ cert, os, handleCopy, copiedId, t }: { cert: CaCertificate, os: string, handleCopy: Function, copiedId: string | null, t: any }) {
if (os === 'windows' && cert.bat_cdn_url) {
return (
<a href={cert.bat_cdn_url} className="inline-flex items-center gap-2 px-3 py-1.5 text-xs font-medium text-blue-700 dark:text-blue-300 bg-blue-50 dark:bg-blue-900/20 border border-blue-100 dark:border-blue-900/30 rounded-md hover:bg-blue-100 dark:hover:bg-blue-900/40 transition-colors">
<Terminal className="w-3.5 h-3.5" />
Installer Script (.bat)
{t.installer.bat}
</a>
)
}
// Shared Logic for macOS AND iOS using the same mobileconfig
if ((os === 'mac' || os === 'ios') && cert.mac_cdn_url) {
return (
<a href={cert.mac_cdn_url} className="inline-flex items-center gap-2 px-3 py-1.5 text-xs font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-neutral-800 hover:bg-gray-200 dark:hover:bg-neutral-700 rounded-md transition-colors">
<Smartphone className="w-3.5 h-3.5" />
Config Profile
{t.installer.mobile}
</a>
)
}
@@ -314,7 +287,7 @@ function InstallerCell({ cert, os, handleCopy, copiedId }: { cert: CaCertificate
return (
<a href={cert.der_cdn_url} className="inline-flex items-center gap-2 px-3 py-1.5 text-xs font-medium text-green-700 dark:text-green-300 bg-green-50 dark:bg-green-900/20 border border-green-100 dark:border-green-900/30 rounded-md hover:bg-green-100 dark:hover:bg-green-900/40 transition-colors">
<Download className="w-3.5 h-3.5" />
Download .der
{t.installer.der}
</a>
)
}
@@ -329,12 +302,12 @@ function InstallerCell({ cert, os, handleCopy, copiedId }: { cert: CaCertificate
<button
onClick={() => handleCopy(cmd, cert.serial)}
className="p-1.5 text-gray-400 hover:text-blue-600 dark:hover:text-blue-400 hover:bg-blue-50 dark:hover:bg-blue-900/20 rounded-md transition-colors"
title="Copy command"
title={t.installer.copy}
>
{isCopied ? <Check className="w-4 h-4 text-green-500" /> : <Copy className="w-4 h-4" />}
</button>
</div>
)
}
return <span className="text-gray-400 text-xs italic">Not available</span>
return <span className="text-gray-400 text-xs italic">{t.installer.not_avail}</span>
}

View File

@@ -1,7 +1,46 @@
import { ArrowRight, Shield, Globe, Lock, Server, Zap, ChevronRight } from "lucide-react";
import Link from 'next/link';
export function LandingPage() {
export function LandingPage({ locale = 'en' }: { locale?: 'en' | 'id' }) {
const dict = {
en: {
hero: {
badge: "v1.0 is Live",
title: <>Secure Your <span className="text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-violet-600">Private Network</span></>,
desc: "TrustLab is the definitive Private Certificate Authority (CA) for your internal infrastructure. Issue military-grade SSL/TLS certificates for Intranets, IoT, and Dev environments.",
cta: "Get Started",
cta_sec: "Generate Certificate"
},
features: {
root_ca: { title: "Private Root CA", desc: "Your own sovereign Certificate Authority. Trusted by your devices, unreachable by the public internet." },
internal: { title: "Internal Domains", desc: "Issue certificates for .local, .corp, and private IP addresses (192.168.x.x) that Public CAs reject." },
smime: { title: "S/MIME Encryption", desc: "Secure internal email communication with employee-to-employee encryption." },
infra: { title: "Infrastructure", desc: "Seamless integration guides for Nginx, IIS, Apache, and containerized environments." },
issuance: { title: "Instant Issuance", desc: "No validation delays. Certificates are issued instantly via our modern dashboard." },
start: { title: "Start Now", desc: "Follow the Setup Guide to install the Root CA and go green in minutes." }
}
},
id: {
hero: {
badge: "v1.0 Telah Rilis",
title: <>Amankan <span className="text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-violet-600">Jaringan Privat</span> Anda</>,
desc: "TrustLab adalah Otoritas Sertifikat (CA) Privat definitif untuk infrastruktur internal Anda. Terbitkan sertifikat SSL/TLS kelas militer untuk Intranet, IoT, dan lingkungan Dev.",
cta: "Mulai Sekarang",
cta_sec: "Buat Sertifikat"
},
features: {
root_ca: { title: "Root CA Privat", desc: "Otoritas Sertifikat berdaulat milik Anda. Dipercaya perangkat Anda, tidak terjangkau internet publik." },
internal: { title: "Domain Internal", desc: "Terbitkan sertifikat untuk .local, .corp, dan IP privat (192.168.x.x) yang ditolak CA Publik." },
smime: { title: "Enkripsi S/MIME", desc: "Amankan komunikasi email internal dengan enkripsi antar-karyawan." },
infra: { title: "Infrastruktur", desc: "Panduan integrasi mulus untuk Nginx, IIS, Apache, dan environment container." },
issuance: { title: "Penerbitan Instan", desc: "Tanpa penundaan validasi. Sertifikat diterbitkan instan melalui dashboard modern kami." },
start: { title: "Mulai Sekarang", desc: "Ikuti Panduan Setup untuk menginstal Root CA dan aman dalam hitungan menit." }
}
}
}
const t = dict[locale]
return (
<div className="flex flex-col gap-16 py-8">
{/* Hero Section */}
@@ -15,23 +54,23 @@ export function LandingPage() {
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-blue-400 opacity-75"></span>
<span className="relative inline-flex rounded-full h-2 w-2 bg-blue-500"></span>
</span>
v1.0 is Live
{t.hero.badge}
</div>
<h1 className="text-4xl sm:text-5xl font-bold tracking-tight text-neutral-900 dark:text-neutral-100 mb-4">
Secure Your <span className="text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-violet-600">Private Network</span>
{t.hero.title}
</h1>
<p className="text-lg text-neutral-600 dark:text-neutral-400 leading-relaxed max-w-xl">
TrustLab is the definitive Private Certificate Authority (CA) for your internal infrastructure. Issue military-grade SSL/TLS certificates for Intranets, IoT, and Dev environments.
{t.hero.desc}
</p>
<div className="flex flex-wrap gap-4 mt-8">
<Link href="https://trustlab.dyzulk.com/signup" className="inline-flex items-center gap-2 px-6 py-3 rounded-xl bg-blue-600 hover:bg-blue-700 text-white font-semibold transition-all hover:scale-105 shadow-lg shadow-blue-500/20">
Get Started <ArrowRight className="w-4 h-4" />
{t.hero.cta} <ArrowRight className="w-4 h-4" />
</Link>
<Link href="/guide/certificates/request-new" className="inline-flex items-center gap-2 px-6 py-3 rounded-xl bg-white dark:bg-neutral-800 text-neutral-900 dark:text-white border border-neutral-200 dark:border-neutral-700 font-semibold hover:bg-neutral-50 dark:hover:bg-neutral-700 transition-all">
Generate Certificate
<Link href={locale === 'id' ? "/id/guide/certificates/request-new" : "/guide/certificates/request-new"} className="inline-flex items-center gap-2 px-6 py-3 rounded-xl bg-white dark:bg-neutral-800 text-neutral-900 dark:text-white border border-neutral-200 dark:border-neutral-700 font-semibold hover:bg-neutral-50 dark:hover:bg-neutral-700 transition-all">
{t.hero.cta_sec}
</Link>
</div>
</div>
@@ -41,39 +80,39 @@ export function LandingPage() {
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<FeatureCard
icon={<Shield className="w-6 h-6 text-emerald-500" />}
title="Private Root CA"
description="Your own sovereign Certificate Authority. Trusted by your devices, unreachable by the public internet."
link="/guide/concepts/pki-undamentals"
title={t.features.root_ca.title}
description={t.features.root_ca.desc}
link={locale === 'id' ? "/id/guide/concepts/pki-undamentals" : "/guide/concepts/pki-undamentals"}
/>
<FeatureCard
icon={<Globe className="w-6 h-6 text-blue-500" />}
title="Internal Domains"
description="Issue certificates for .local, .corp, and private IP addresses (192.168.x.x) that Public CAs reject."
link="/guide/certificates/request-new"
title={t.features.internal.title}
description={t.features.internal.desc}
link={locale === 'id' ? "/id/guide/certificates/request-new" : "/guide/certificates/request-new"}
/>
<FeatureCard
icon={<Lock className="w-6 h-6 text-violet-500" />}
title="S/MIME Encryption"
description="Secure internal email communication with employee-to-employee encryption."
link="/guide/integrations/smime"
title={t.features.smime.title}
description={t.features.smime.desc}
link={locale === 'id' ? "/id/guide/integrations/smime" : "/guide/integrations/smime"}
/>
<FeatureCard
icon={<Server className="w-6 h-6 text-orange-500" />}
title="Infrastructure"
description="Seamless integration guides for Nginx, IIS, Apache, and containerized environments."
link="/guide/integrations/web-servers"
title={t.features.infra.title}
description={t.features.infra.desc}
link={locale === 'id' ? "/id/guide/integrations/web-servers" : "/guide/integrations/web-servers"}
/>
<FeatureCard
icon={<Zap className="w-6 h-6 text-yellow-500" />}
title="Instant Issuance"
description="No validation delays. Certificates are issued instantly via our modern dashboard."
link="/guide/getting-started/access-dashboard"
title={t.features.issuance.title}
description={t.features.issuance.desc}
link={locale === 'id' ? "/id/guide/getting-started/access-dashboard" : "/guide/getting-started/access-dashboard"}
/>
<FeatureCard
icon={<ArrowRight className="w-6 h-6 text-neutral-500" />}
title="Start Now"
description="Follow the Setup Guide to install the Root CA and go green in minutes."
link="/guide/getting-started/install-root-ca"
title={t.features.start.title}
description={t.features.start.desc}
link={locale === 'id' ? "/id/guide/getting-started/install-root-ca" : "/guide/getting-started/install-root-ca"}
isAction
/>
</div>

View File

@@ -1,15 +1,14 @@
{
"index": {
"title": "Home",
"type": "page",
"display": "hidden"
},
"guide": {
"title": "User Guide",
"type": "page"
"en": {
"type": "page",
"display": "hidden"
},
"developer": {
"title": "Developer API",
"type": "page"
"id": {
"type": "page",
"display": "hidden"
}
}

15
pages/en/_meta.json Normal file
View File

@@ -0,0 +1,15 @@
{
"index": {
"title": "Home",
"type": "page",
"display": "hidden"
},
"guide": {
"title": "User Guide",
"type": "page"
},
"developer": {
"title": "Developer API",
"type": "page"
}
}

View File

@@ -53,7 +53,7 @@ Select your distribution to get the optimized installation command:
---
import { DynamicInstallationGuide } from '../../../components/DynamicInstallationGuide'
import { DynamicInstallationGuide } from '../../../../components/DynamicInstallationGuide'
## Individual Certificate Installation

3
pages/en/index.mdx Normal file
View File

@@ -0,0 +1,3 @@
import { LandingPage } from '../../components/LandingPage'
<LandingPage />

15
pages/id/_meta.json Normal file
View File

@@ -0,0 +1,15 @@
{
"index": {
"title": "Beranda",
"type": "page",
"display": "hidden"
},
"guide": {
"title": "Panduan Pengguna",
"type": "page"
},
"developer": {
"title": "Developer API",
"type": "page"
}
}

View File

@@ -0,0 +1,4 @@
{
"index": "Dokumentasi API",
"endpoints": "Titik Akhir (Endpoints)"
}

View File

@@ -0,0 +1,71 @@
import { Tabs } from 'nextra/components'
import { Code, Terminal, Send, ShieldCheck } from 'lucide-react'
# Titik Akhir (Endpoints)
Gunakan titik akhir API berikut untuk melakukan integrasi programatik dengan layanan TrustLab.
## Dasar URL
Semua permintaan API dilakukan ke:
`https://trustlab.dyzulk.com/api`
---
## Pengambilan Sertifikat Publik
Endpoint ini digunakan untuk mengambil informasi publik mengenai sertifikat atau CA.
### 1. Unduh Root CA
Mengunduh sertifikat root pemegang kepercayaan utama.
- **Endpoint**: `GET /ca/root/download`
- **Output**: File `trustlab-root.crt`
### 2. Lihat Detail Sertifikat (via Serial)
Mendapatkan metadata sertifikat berdasarkan nomor serinya.
- **Endpoint**: `GET /certificates/detail/{serial_number}`
- **Respon Contoh**:
```json
{
"serial": "12345-ABCDE",
"common_name": "myserver.local",
"issuer": "TrustLab Intermediate CA",
"not_after": "2025-12-31T23:59:59Z",
"status": "VALID"
}
```
---
## Contoh Implementasi (cURL)
<Tabs items={['Unduh Root', 'Cek Status']}>
<Tabs.Tab>
```bash
curl -O https://trustlab.dyzulk.com/api/ca/root/download
```
</Tabs.Tab>
<Tabs.Tab>
```bash
curl https://trustlab.dyzulk.com/api/certificates/detail/99887766
```
</Tabs.Tab>
</Tabs>
---
## Status Respon API
TrustLab menggunakan kode status HTTP standar:
| Kode | Arti |
| :--- | :--- |
| `200 OK` | Permintaan berhasil. |
| `404 Not Found` | Sertifikat tidak ditemukan. |
| `500 Server Error` | Terjadi masalah pada database TrustLab. |
---
> [!IMPORTANT]
> Fitur manajemen sertifikat penuh (Create, Revoke, Renew) via API saat ini masih dalam tahap **Beta Tertutup**. Silakan hubungi admin untuk mendapatkan akses API Key jika Anda memerlukannya untuk otomatisasi infrastruktur.

View File

@@ -0,0 +1,20 @@
# Dokumentasi API Developer
Gunakan API TrustLab untuk mengotomatiskan manajemen siklus hidup sertifikat dalam alur kerja pengembangan atau infrastruktur Anda.
## Gambaran Umum
API kami berbasis REST dan mengembalikan respon dalam format JSON. Saat ini, API mendukung operasi dasar untuk pengambilan informasi sertifikat publik.
## Autentikasi
Saat ini, endpoint publik untuk pengambilan sertifikat tidak memerlukan autentikasi API Key khusus. Namun, penggunaan secara massal untuk endpoint manajemen akan segera hadir.
## Endpoint Utama
- **[Daftar Endpoint](/id/developer/endpoints)**: Lihat daftar lengkap fungsi API yang tersedia saat ini.
---
> [!NOTE]
> Dokumentasi API sedang dikembangkan lebih lanjut. Hubungi tim dukungan kami jika Anda memerlukan akses integrasi skala besar.

View File

@@ -0,0 +1,8 @@
{
"index": "Panduan Pengguna",
"getting-started": "Mulai Cepat",
"concepts": "Konsep Inti",
"certificates": "Operasi Sertifikat",
"integrations": "Integrasi",
"troubleshooting": "Pemecahan Masalah"
}

View File

@@ -0,0 +1,7 @@
{
"request-new": "Minta Sertifikat Baru",
"download-install": "Unduh & Format",
"view-details": "Lihat Detail",
"renewal": "Proses Perpanjangan",
"revocation": "Pencabutan (Revocation)"
}

View File

@@ -0,0 +1,43 @@
# Unduh & Format (PEM, PFX, JKS)
Setelah sertifikat Anda diterbitkan, Anda dapat mengunduhnya dalam berbagai format yang sesuai untuk server dan aplikasi yang berbeda.
## Format yang Tersedia
| Format | Ekstensi | Digunakan Untuk |
| :--- | :--- | :--- |
| **PEM (Nginx/Apache)** | `.crt`, `.key` | Server web Linux standar. Anda mendapatkan file Sertifikat dan Private Key terpisah. |
| **PFX / PKCS#12** | `.pfx`, `.p12` | IIS (Windows), Microsoft Exchange, Sertifikat Klien (S/MIME). Berisi key dan cert sekaligus. |
| **JKS (Java)** | `.jks` | Aplikasi Java (Tomcat, Spring Boot). |
## Cara Mengunduh (Salin & Simpan)
Dashboard memungkinkan Anda untuk menyalin data mentah sertifikat secara langsung.
1. Buka menu **"My Certificates"** dan klik tombol **View (Ikon Mata)** pada sertifikat Anda.
2. **Sertifikat:** Gulir ke bagian "Certificate (CRT)" dan klik **Ikon Salin** di pojok kanan atas. Simpan ke dalam file bernama `domain.crt` atau `domain.pem`.
3. **Private Key:** Gulir ke bagian "Private Key (KEY)", klik **Show**, lalu klik **Ikon Salin**. Simpan ke dalam file bernama `domain.key`.
> [!TIP]
> Gunakan editor teks murni (Notepad, VS Code, Nano) untuk menyimpan file-file ini. Jangan gunakan Word atau editor Rich Text.
> [!WARNING]
> **Private Key** dihasilkan secara aman secara lokal di browser/server. Jika Anda menghilangkannya, kunci tersebut **TIDAK BISA** dipulihkan. Anda harus melakukan revoke dan menerbitkan ulang sertifikat.
## Contoh Instalasi
### Nginx (PEM)
```nginx
server {
listen 443 ssl;
server_name internal.app;
ssl_certificate /etc/nginx/ssl/internal.app.crt;
ssl_certificate_key /etc/nginx/ssl/internal.app.key;
}
```
### Windows (PFX)
1. Klik dua kali file `.pfx` yang diunduh.
2. Ikuti "Certificate Import Wizard".
3. Saat diminta kata sandi, masukkan kata sandi yang Anda tetapkan saat mengunduh (atau kata sandi ekspor default yang disediakan di UI).

View File

@@ -0,0 +1,60 @@
import { Steps } from 'nextra/components'
import { RefreshCcw, Bell, ShieldCheck } from 'lucide-react'
# Proses Perpanjangan
Sertifikat SSL/TLS memiliki masa aktif yang terbatas. Di TrustLab, kami menyederhanakan proses perpanjangan (renewal) untuk memastikan layanan Anda tetap berjalan tanpa gangguan.
## Kapan Harus Memperpanjang?
- **Rekomendasi**: Lakukan perpanjangan **30 hari** sebelum sertifikat kadaluarsa.
- **Notifikasi**: TrustLab akan mengirimkan pengingat email otomatis ke akun Anda pada H-30, H-7, dan H-1 sebelum masa berlaku habis.
---
## Proses Pembaruan
Sertifikat memiliki masa berlaku untuk menjamin rotasi keamanan. TrustLab menyederhanakan proses pembaruan agar Anda tidak mengalami downtime.
## Kapan Harus Memperbarui?
Anda akan menerima notifikasi email:
- **30 hari** sebelum kedaluwarsa.
- **7 hari** sebelum kedaluwarsa.
- **1 hari** sebelum kedaluwarsa.
## Cara Memperbarui (Penerbitan Ulang Manual)
Untuk memperbarui sertifikat, Anda cukup membuat sertifikat baru dengan nama domain yang sama.
<Steps>
### Buka Dashboard
Login ke [trustlab.dyzulk.com](https://trustlab.dyzulk.com) dan masuk ke menu **"Manage Certificates"**.
1. Buka menu **Certificates** dan klik **"Generate New"**.
2. **Identity**: Masukkan **Common Name (CN) yang sama** dengan sertifikat Anda yang akan habis masa berlakunya.
3. **Generate**: Sistem akan menerbitkan sertifikat baru dengan masa berlaku yang segar.
4. **Ganti**: Unduh `.crt` baru (dan `.key` jika Anda tidak menggunakan kembali CSR) dan ganti file di server Anda.
</Steps>
> [!NOTE]
> Sertifikat lama akan tetap valid sampai habis masa berlakunya secara alami. Anda dapat menghapusnya dengan aman setelah memastikan sertifikat baru berfungsi.
## Apa yang Terjadi Selanjutnya?
- **Sertifikat baru** dihasilkan dengan masa berlaku baru.
- **Private Key** tetap sama (jika "Reuse Key" dipilih) ATAU kunci baru dihasilkan (disarankan).
- Sertifikat lama tetap valid hingga tanggal kedaluwarsa aslinya (kecuali dicabut).
> [!IMPORTANT]
> Anda harus **mengunduh dan menginstal sertifikat baru** di server Anda. Pembaruan **tidak terjadi otomatis** di sisi server kecuali Anda menggunakan integrasi ACME kami.
---
## Penting: Mengapa Harus Perpanjang?
Jika sertifikat kadaluarsa sebelum diganti:
- Browser akan memblokir akses ke situs Anda dengan pesan **"Your connection is not private"**.
- API internal akan gagal melakukan enkripsi (SSL Handshake Error).
- Pengguna akan kehilangan kepercayaan terhadap keamanan jaringan Anda.
> [!TIP]
> Perpanjangan di TrustLab tidak mengubah Root CA Anda. Anda **tidak perlu** menginstal ulang Root CA di perangkat klien setiap kali Anda memperpanjang sertifikat server.

View File

@@ -0,0 +1,51 @@
import { Steps, Callout, Cards, Card } from 'nextra/components'
import { FileBadge, ShieldCheck, Globe, Code, Save, AlertTriangle } from 'lucide-react'
# Menerbitkan Sertifikat Baru
TrustLab menyediakan wizard yang disederhanakan untuk menghasilkan sertifikat SSL/TLS pribadi untuk infrastruktur internal Anda.
## Prasyarat
Sebelum memulai, pastikan Anda memiliki:
* Akses akun TrustLab yang aktif.
* **Root CA** telah terinstal di perangkat Anda (agar mempercayai sertifikat yang diterbitkan).
---
<Steps>
### 1. Buka Menu Sertifikat
Akses halaman **Certificates**. Tampilan ini mencantumkan semua sertifikat aktif dan kedaluwarsa Anda. Klik tombol **"Generate New"** (atau "+") untuk memulai.
![Certificates List](/images/guide/certificates-screen.png)
### 2. Masukkan Detail Domain (Mode Default)
Secara default, Anda hanya perlu memberikan Identitas. Sistem akan mengisi otomatis metadata Organisasi & Lokasi.
![Default Generation Modal](/images/guide/certificates-generate-modal-default-metadata-screen.png)
* **Common Name (CN)**: Domain utama (misalnya, `app.internal`).
* **SANs**: Domain tambahan atau alamat IP.
* **Key Strength**: Pilih tingkat enkripsi.
![Key Strength Selector](/images/guide/certificates-generate-modal-key-strength-focused-screen.png)
* **2048-bit**: Standar industri, kompatibel dengan semua perangkat.
* **4096-bit**: Keamanan lebih tinggi, sedikit lebih intensif pada CPU.
### 3. Kustomisasi CSR (Kontrol Manual)
Aktifkan **"Manual Control"** jika Anda perlu menimpa bidang Identitas default (misalnya, untuk kantor cabang tertentu atau entitas hukum khusus).
![Manual Control Modal](/images/guide/certificates-generate-modal-manual-control-screen.png)
* **Organization (O)**: Ganti nama perusahaan default.
* **Locality (L) / State (ST)**: Atur data lokasi spesifik.
* **Country (C)**: Kode ISO Negara.
### 4. Terbitkan & Simpan
Klik **Generate**.
* **Certificate (.pem)** dan **Private Key (.key)** akan dihasilkan secara instan.
* Anda dapat menyalinnya segera atau mengaksesnya nanti dari halaman **Certificate Details**.
<Callout type="info" emoji={<Save className="w-5 h-5" />}>
**Penyimpanan:** Private Key Anda disimpan dengan aman di server (dienkripsi). Anda dapat melihatnya kapan saja dengan mengklik **"View Details"** pada daftar sertifikat.
</Callout>
</Steps>

View File

@@ -0,0 +1,22 @@
# Pencabutan (Revocation)
Pencabutan membatalkan validitas sertifikat sebelum tanggal kedaluwarsanya. Ini sangat penting jika Private Key Anda bocor atau hilang.
## Kapan Harus Mencabut?
- **Kebocoran Kunci (Key Compromise)**: Anda curiga seseorang telah mencuri Private Key Anda.
- **Perubahan Layanan**: Nama domain secara efektif tidak lagi menjadi milik layanan tersebut.
- **Kesalahan**: Sertifikat diterbitkan dengan detail yang salah.
## Cara Menghapus / Mencabut
Jika sertifikat bocor atau tidak lagi dibutuhkan, Anda dapat menghapusnya dari sistem.
1. Buka daftar **Certificates**.
2. Cari sertifikat yang ingin dihapus.
3. Klik **Ikon Tempat Sampah** (Delete) di sisi kanan baris.
4. **Konfirmasi**: Ketik `DELETE` di modal konfirmasi untuk menghapus sertifikat dan private key-nya secara permanen dari TrustLab.
![Delete Certificate Action](/images/guide/certificates_list_view_1767869137654.png)
## CRL (Certificate Revocation List)
Setelah dicabut, nomor seri sertifikat akan ditambahkan ke TrustLab CRL. Semua klien yang memeriksa CRL akan segera menolak sertifikat tersebut.

View File

@@ -0,0 +1,42 @@
import { Steps } from 'nextra/components'
import { Search, Eye, Clipboard, ShieldAlert } from 'lucide-react'
# Lihat Detail Sertifikat
Setiap sertifikat di TrustLab memiliki metadata lengkap yang bisa Anda audit kapan saja untuk memastikan kesesuaian identitas dan keamanan.
## Cara Melihat Detail
<Steps>
### Navigasi ke List
Di menu utama Dashboard, klik **"Manage Certificates"**. Anda akan melihat daftar semua sertifikat yang pernah diterbitkan.
### Klik Ikon Mata
Gunakan kolom pencarian untuk menemukan domain Anda. Klik tombol **"View Details"** (ikon mata 👁️) di sisi kanan baris sertifikat.
### Tinjau Tab Informasi
Anda akan melihat detail seperti:
- **Serial Number**: ID unik sertifikat Anda.
- **Validity period**: Tanggal mulai dan berakhir.
- **Issuer**: CA mana yang menandatangani (TrustLab Intermediate).
- **Public Key Info**: Algoritma yang digunakan (RSA 2048/4096).
</Steps>
---
## Audit Metadata
Penting untuk memeriksa detail berikut secara berkala:
- **Thumbprint (SHA-1/SHA-256)**: Gunakan fingerprint ini untuk memverifikasi apakah sertifikat yang terpasang di server benar-benar yang Anda terbitkan dari TrustLab.
- **Subject Alternative Names (SAN)**: Pastikan semua alias domain yang dibutuhkan sudah terdaftar di sini.
- **Status**: Pastikan statusnya **Valid** (hijau). Jika warnanya merah, berarti sertifikat telah kadaluarsa atau dicabut.
---
## Keamanan Data Detail
Meskipun detail sertifikat (Public) aman untuk dilihat, tim TrustLab menyarankan untuk membatasi akses ke dashboard hanya untuk admin sistem yang berkepentingan untuk mencegah kebocoran informasi topologi jaringan.
> [!TIP]
> Anda bisa menyalin (copy) Serial Number secara cepat melalui tombol clipboard di samping teks untuk keperluan dokumentasi internal atau konfigurasi firewall.

View File

@@ -0,0 +1,4 @@
{
"pki-fundamentals": "Dasar-Dasar PKI",
"trust-architecture": "Arsitektur Kepercayaan"
}

View File

@@ -0,0 +1,58 @@
import { Steps } from 'nextra/components'
import { Shield, Key, Lock, Globe } from 'lucide-react'
# Dasar-Dasar PKI
Memahami cara kerja **Public Key Infrastructure (PKI)** sangat penting untuk mengelola keamanan jaringan internal Anda. TrustLab menyederhanakan konsep kompleks ini menjadi alur kerja yang mudah dikelola.
## Apa itu PKI?
PKI adalah kerangka kerja yang terdiri dari peran, kebijakan, perangkat lunak, dan perangkat keras yang digunakan untuk membuat, mengelola, mendistribusikan, menggunakan, menyimpan, dan mencabut sertifikat digital.
---
## Komponen Utama TrustLab
TrustLab mengelola tiga pilar utama keamanan untuk Anda:
### 1. Root Certificate Authority (CA)
Akar dari kepercayaan di seluruh jaringan Anda. Root CA digunakan untuk menandatangani sertifikat lain di bawahnya. Jika perangkat mempercayai Root CA ini, mereka akan mempercayai semua sertifikat yang diterbitkannya.
### 2. Intermediate CA
Digunakan oleh TrustLab untuk operasional sehari-hari. Kami tidak menggunakan Root CA langsung untuk menandatangani sertifikat pengguna akhir (end-entity) demi alasan keamanan (isolasi).
### 3. Sertifikat Pengguna Akhir
Sertifikat SSL/TLS yang Anda pasang di server web, perangkat IoT, atau klien email. Inilah yang sebenarnya "mengamankan" koneksi Anda.
---
## Cara Kerja Kepercayaan (Trust)
Bagaimana browser Anda tahu bahwa sebuah situs web itu aman?
<Steps>
### Instalasi Akar
Administrator menginstal Root CA TrustLab ke sistem trust store Anda.
### Pengenalan Sertifikat
Saat Anda mengakses situs internal, server menyajikan sertifikatnya.
### Verifikasi Rantai
Browser memeriksa: "Apakah sertifikat ini ditandatangani oleh pemegang yang saya percayai (Root CA)?"
### Koneksi Aman
Jika rantai valid, gembok hijau muncul dan enkripsi data dimulai.
</Steps>
---
## Mengapa PKI Privat?
Mungkin Anda bertanya, kenapa tidak menggunakan CA publik seperti Let's Encrypt?
1. **Domain Non-Publik**: CA publik tidak bisa mengeluarkan sertifikat untuk `.local` atau `.internal`.
2. **Kontrol Penuh**: Anda menentukan masa berlaku, algoritma enkripsi, dan siapa yang berhak mendapatkan sertifikat.
3. **Tanpa Validasi DNS**: Karena ini internal, Anda tidak perlu membuktikan kepemilikan domain ke pihak luar.
> [!IMPORTANT]
> Keamanan PKI privat Anda bergantung sepenuhnya pada **kerahasiaan Private Key Root CA**. TrustLab menyimpan key ini dengan enkripsi kuat untuk memastikan integritas jaringan Anda.

View File

@@ -0,0 +1,50 @@
import { Steps } from 'nextra/components'
import { Shield, Lock, Server, Users } from 'lucide-react'
# Arsitektur Kepercayaan
Arsitektur TrustLab dibangun di atas prinsip isolasi dan keamanan berlapis. Kami menggunakan struktur otoritas bertingkat untuk memastikan integritas jaringan Anda tetap terjaga.
## Hirarki Otoritas Sertifikat
Untuk keamanan maksimal, TrustLab tidak menggunakan satu kunci untuk semua hal. Kami menggunakan hirarki berikut:
### 1. Root CA (Offline Root)
Ini adalah "Ayah" dari segala kepercayaan. Key ini sangat sensitif dan idealnya jarang digunakan. Dalam infrastruktur yang sangat ketat, Root CA biasanya tetap offline.
### 2. Intermediate CA (Issuing CA)
TrustLab secara otomatis membuat Intermediate CA yang menandatangani sertifikat pengguna Anda. Jika Intermediate CA disusupi, Root CA dapat mencabutnya tanpa merusak seluruh ekosistem keamanan Anda.
### 3. End-Entity Certificates
Aplikasi atau server Anda menggunakan sertifikat ini. Mereka memiliki masa berlaku yang lebih pendek (biasanya 1 tahun atau kurang) untuk meminimalkan risiko.
---
## Alur Penerbitan Sertifikat
Bagaimana data Anda berpindah dari dashboard hingga menjadi sertifikat sah?
<Steps>
### Permintaan Klien (CSR)
Dashboard membuat sepasang kunci (Public & Private). Public key dikirim dalam format Certificate Signing Request (CSR).
### Validasi Internal
Dashboard TrustLab memverifikasi identitas Anda dan hak akses Anda terhadap domain yang diminta.
### Penandatanganan CA
Intermediate CA menandatangani CSR tersebut menggunakan Private Key CA-nya sendiri.
### Pengiriman Sertifikat
Sertifikat hasil tanda tangan dikembalikan ke Dashboard untuk Anda unduh.
</Steps>
---
## Keamanan Kunci (Key Security)
- **Enkripsi saat Istirahat (Encryption at Rest)**: Semua Private Key disimpan dalam database menggunakan enkripsi tingkat tinggi (AES-256).
- **Isolasi Database**: Hanya layanan CA internal yang memiliki akses ke modul yang mendekripsi key tersebut.
- **Audit Logs**: Setiap aksi penandatanganan dicatat dalam log sistem yang tidak dapat diubah (immutable logs).
> [!TIP]
> Jangan pernah membagikan file Private Key (`.key`) Anda kepada siapapun. Siapapun yang memiliki key tersebut bisa menyamar sebagai server Anda.

View File

@@ -0,0 +1,4 @@
{
"install-root-ca": "Instal Root CA",
"access-dashboard": "Akses Dashboard"
}

View File

@@ -0,0 +1,96 @@
import { Callout, Steps, Cards, Card } from 'nextra/components'
import { Monitor, Smartphone, LayoutDashboard, Key, Shield, Info, Clock, AlertTriangle } from 'lucide-react'
# Mengakses Dashboard
**TrustLab Dashboard** adalah pusat kendali utama Anda untuk mengelola sertifikat. Di sini Anda dapat meminta sertifikat baru, mengunduh kunci, dan mengelola sertifikat yang sudah ada.
![Antarmuka Login TrustLab](/images/guide/login-screen.png)
## Metode Autentikasi
Kami mengutamakan keamanan dengan menawarkan opsi autentikasi modern tanpa kata sandi (passwordless).
<Cards>
<Card icon={<Shield className="w-6 h-6" />} title="SSO (Google / GitHub)" href="#1-single-sign-on-sso" arrow />
<Card icon={<Key className="w-6 h-6" />} title="Magic Link (Email)" href="#2-magic-link" arrow />
</Cards>
### 1. Single Sign-On (SSO)
Cara tercepat untuk masuk. Klik **Continue with Google** atau **Continue with GitHub**.
<Callout type="info" emoji={<Info className="w-5 h-5" />}>
**Perilaku SSO:**
* **Pengguna Lama:** Anda hanya dapat Masuk via SSO jika alamat email Anda sudah terdaftar.
* **Pengguna Baru:** Anda dapat **Mendaftar** akun baru secara instan dengan mengklik tombol Social Login pada halaman *Sign In* atau *Sign Up*.
</Callout>
### 2. Magic Link
Masuk yang aman dan tanpa kata sandi melalui email.
<Steps>
### Masukkan Email
Masukkan alamat email terdaftar Anda pada formulir login dan klik **"Continue with Email"**.
### Cek Kotak Masuk
Anda akan menerima email berisi tautan login unik yang sensitif terhadap waktu.
### Klik untuk Verifikasi
Klik tombol **"Sign in to TrustLab"** di dalam email tersebut. Anda akan langsung masuk ke dashboard secara instan.
</Steps>
<Callout type="warning" emoji={<Clock className="w-5 h-5" />}>
**Kedaluwarsa:** Tautan Magic Link hanya berlaku selama **15 menit**. Jika kedaluwarsa, cukup minta tautan baru dengan memasukkan email Anda kembali.
</Callout>
## Ikhtisar Dashboard
Setelah berhasil masuk, Anda akan mendarat di dashboard utama.
![Ikhtisar Dashboard TrustLab](/images/guide/dashboard-screen.png)
Hub pusat ini memungkinkan Anda untuk mengakses:
* **Active Certificates**: Lihat semua sertifikat valid yang diterbitkan untuk Anda.
* **Request Certificate**: Wizard untuk menghasilkan Private Key dan CSR baru.
* **Revocation**: Antarmuka untuk menandai sertifikat yang hilang atau bocor sebagai tidak valid.
## Registrasi
Pengguna baru dapat membuat akun untuk mulai mengelola sertifikat.
![Antarmuka Registrasi TrustLab](/images/guide/register-screen.png)
<Steps>
### Opsi A: Registrasi Sosial (Instan)
1. Klik **Continue with Google** atau **Continue with GitHub**.
2. **Atur Kata Sandi:** Pertama, pastikan Anda telah [**Menginstal Root CA**](/id/guide/getting-started/install-root-ca) di perangkat Anda.
![Layar Atur Kata Sandi](/images/guide/set-password-after-social-screen.png)
### Opsi B: Registrasi Email
1. Klik **"Sign up"** atau isi formulir.
2. Berikan detail dan kata sandi Anda.
3. **Verifikasi Email:** Klik tautan yang dikirim ke kotak masuk Anda untuk mengaktifkan.
</Steps>
## Pemulihan Kata Sandi
Jika Anda kehilangan akses ke akun, Anda dapat mengatur ulang kata sandi dengan aman.
![Antarmuka Lupa Kata Sandi TrustLab](/images/guide/forgot-password-screen.png)
1. Klik **"Forgot password?"** pada layar login.
2. Masukkan alamat email terdaftar Anda.
3. Cek kotak masuk Anda untuk tautan pengaturan ulang kata sandi.
4. Buat kata sandi baru dan masuk.
## Pemecahan Masalah
### Saya tidak menerima Magic Link
* **Cek Spam/Junk**: Seringkali masuk ke sana untuk domain perusahaan.
* **Tunggu 1-2 Menit**: Pengiriman email terkadang tertunda.
* **Whitelist Pengirim**: Tambahkan `@trustlab.dyzulk.com` ke daftar **Safe Senders** penyedia email Anda agar tidak diblokir.
### Akses Ditolak / Pengguna Tidak Ditemukan
* **Salah Ketik**: Periksa kembali alamat email Anda.
* **Belum Terdaftar**: Jika Anda belum membuat akun, silakan **Daftar** terlebih dahulu. Anda tidak dapat masuk via SSO jika email Anda belum ada di sistem kami (kecuali Anda menggunakan alur Pendaftaran).

View File

@@ -0,0 +1,64 @@
import { Tabs, Steps, Cards, Card, Callout } from 'nextra/components'
import { Monitor, Smartphone, AlertTriangle, Info } from 'lucide-react'
# Menginstal Root CA
Untuk memastikan browser Anda mempercayai sertifikat yang diterbitkan oleh TrustLab, Anda harus menginstal Root CA kami.
## Instalasi Cepat (Bundle)
Instal secara instan **SEMUA** sertifikat Root & Intermediate TrustLab menggunakan skrip bundle otomatis kami.
### Linux / Server (CLI)
Pilih distribusi Anda untuk mendapatkan perintah instalasi yang dioptimalkan:
<Tabs items={['Debian/Ubuntu', 'RHEL/CentOS', 'Arch Linux', 'Universal']}>
<Tabs.Tab>
```bash
sudo apt update && sudo apt install -y curl && curl -sL https://cdn.trustlab.dyzulk.com/ca/bundles/trustlab-all.sh | sudo bash
```
</Tabs.Tab>
<Tabs.Tab>
```bash
(sudo yum install -y curl || sudo dnf install -y curl) && curl -sL https://cdn.trustlab.dyzulk.com/ca/bundles/trustlab-all.sh | sudo bash
```
</Tabs.Tab>
<Tabs.Tab>
```bash
sudo pacman -Sy --noconfirm curl && curl -sL https://cdn.trustlab.dyzulk.com/ca/bundles/trustlab-all.sh | sudo bash
```
</Tabs.Tab>
<Tabs.Tab>
```bash
curl -sL https://cdn.trustlab.dyzulk.com/ca/bundles/trustlab-all.sh | sudo bash
```
</Tabs.Tab>
</Tabs>
### Ekosistem Windows & Apple
<Cards>
<Card icon={<Monitor className="w-6 h-6" />} title="Windows Bundle Installer (.bat)" href="https://cdn.trustlab.dyzulk.com/ca/bundles/trustlab-all.bat" arrow />
<Card icon={<Smartphone className="w-6 h-6" />} title="macOS / iOS Profile (.mobileconfig)" href="https://cdn.trustlab.dyzulk.com/ca/bundles/trustlab-all.mobileconfig" arrow />
</Cards>
<Callout type="warning" emoji={<AlertTriangle className="w-5 h-5" />}>
**Pengguna Windows:** Anda **WAJIB** klik kanan file `.bat` dan pilih **"Run as Administrator"**. Mengklik dua kali secara langsung kemungkinan besar akan gagal karena batasan izin.
</Callout>
<Callout type="info" emoji={<Info className="w-5 h-5" />}>
**Pengguna Apple:** Setelah mengunduh profil, buka **System Settings > Privacy & Security > Profiles** untuk menginstalnya. Untuk iOS, lihat bagian *Instalasi Sertifikat Individu* di bawah untuk langkah-langkah kepercayaan mendetail.
</Callout>
---
import { DynamicInstallationGuide } from '../../../../components/DynamicInstallationGuide'
## Instalasi Sertifikat Individu
Jika Anda perlu menginstal sertifikat tertentu secara individu (misal: hanya Root, atau Intermediate tertentu), gunakan panduan langsung di bawah ini.
<DynamicInstallationGuide locale="id" />

23
pages/id/guide/index.mdx Normal file
View File

@@ -0,0 +1,23 @@
# Panduan Pengguna TrustLab
Selamat datang di dokumentasi resmi TrustLab. Panduan ini dirancang untuk membantu Anda memahami, menginstal, dan mengelola Otoritas Sertifikat (CA) privat Anda sendiri.
## Apa itu TrustLab?
TrustLab adalah solusi manajemen PKI (Public Key Infrastructure) yang disederhanakan untuk jaringan internal. Kami memungkinkan Anda untuk:
- **Mengeluarkan Sertifikat SSL/TLS** untuk domain internal seperti `.local`, `.corp`, atau alamat IP privat.
- **Mengamankan Komunikasi IoT** dan perangkat dalam jaringan lokal.
- **Enkripsi Email (S/MIME)** untuk kerahasiaan data karyawan.
- **Otomasi Integrasi** dengan web server modern seperti Nginx dan IIS.
## Langkah Cepat
1. **Instal Root CA**: Langkah pertama yang wajib dilakukan agar semua sertifikat Anda dipercaya oleh perangkat. [Baca selengkapnya](/id/guide/getting-started/install-root-ca)
2. **Akses Dashboard**: Masuk ke portal manajemen Anda untuk mulai menerbitkan sertifikat. [Baca selengkapnya](/id/guide/getting-started/access-dashboard)
3. **Terbitkan Sertifikat**: Pelajari cara membuat permintaan sertifikat baru dalam hitungan detik. [Baca selengkapnya](/id/guide/certificates/request-new)
---
> [!TIP]
> Mulailah dari bagian **Mulai Cepat** untuk mendapatkan Certificate Authority yang berfungsi penuh dalam waktu kurang dari 5 menit.

View File

@@ -0,0 +1,4 @@
{
"web-servers": "Konfigurasi Web Server",
"smime": "Keamanan Email S/MIME"
}

View File

@@ -0,0 +1,77 @@
import { Steps, Callout, Tabs } from 'nextra/components'
import { Mail, BadgeAlert, ShieldCheck } from 'lucide-react'
# Keamanan Email S/MIME
Secure/Multipurpose Internet Mail Extensions (S/MIME) memungkinkan Anda untuk **menandatangani** (membuktikan identitas) dan **mengenkripsi** (melindungi konten) pesan email.
<Callout type="warning" emoji={<BadgeAlert className="w-5 h-5" />}>
**Hanya untuk Penggunaan Internal:**
Sertifikat TrustLab bersifat pribadi. Jika Anda mengirim email bertanda tangan ke **Penerima Eksternal** (misal: Gmail, Yahoo), mereka akan melihat peringatan "Tanda Tangan Tidak Dipercaya/Tidak Valid" karena mereka tidak mempercayai Root CA TrustLab.
**Gunakan ini hanya untuk komunikasi internal perusahaan.**
</Callout>
## Panduan Pengaturan
## Konfigurasi Microsoft Outlook
<Tabs items={['Outlook Klasik (Desktop)', 'Outlook Baru (Web Style)']}>
<Tabs.Tab>
**Versi yang Didukung:** Outlook 365, 2019, 2016.
<Steps>
### 1. Buka Trust Center
Buka **File > Options > Trust Center > Trust Center Settings**.
### 2. Email Security
Pilih **Email Security** dari sidebar kiri.
### 3. Impor Sertifikat
Di bawah *Encrypted Email*, klik **Settings...**
* **Signing Certificate**: Klik 'Choose' dan pilih sertifikat TrustLab Anda.
* **Encryption Certificate**: Sama seperti di atas.
### 4. Simpan
Klik **OK** untuk menerapkan.
</Steps>
</Tabs.Tab>
<Tabs.Tab>
**Versi yang Didukung:** Outlook baru untuk Windows, OWA.
*Catatan: Memerlukan ekstensi S/MIME Control.*
<Steps>
### 1. Buka Pengaturan
Klik **Ikon Roda Gigi** (Settings) di pojok kanan atas.
### 2. Menu S/MIME
Navigasi ke **Mail > S/MIME**.
### 3. Aktifkan
Aktifkan **"Encrypt with S/MIME"** dan pilih sertifikat Anda.
</Steps>
</Tabs.Tab>
</Tabs>
## Konfigurasi Thunderbird
**Persyaratan Versi:** v115+ (Supernova) atau yang lebih baru.
<Steps>
### 1. Pengaturan Akun
Klik tombol **Menu (≡)** dan pilih **Account Settings**.
### 2. Enkripsi End-to-End
Pilih akun email Anda dari sidebar dan klik **End-to-End Encryption**.
### 3. Impor Sertifikat
Di bagian **S/MIME**, klik **Add** (atau Manager) untuk mengimpor file `.p12` Anda.
### 4. Terapkan Sertifikat
Di bawah *Select Certificate*, pilih file yang diimpor untuk keduanya:
* **Digital Signing**
* **Encryption**
</Steps>
## Cara Mengetes
Kirim email ke rekan kerja yang juga telah menginstal Root CA. Mereka seharusnya melihat ikon **Pita/Badge** terverifikasi yang menunjukkan bahwa email tersebut dipercaya dan tidak dimodifikasi.

View File

@@ -0,0 +1,78 @@
import { Tabs, Callout } from 'nextra/components'
import { Server, Globe, Shield } from 'lucide-react'
# Konfigurasi Web Server
Untuk mengaktifkan HTTPS pada layanan internal Anda, Anda perlu mengonfigurasi web server agar menggunakan sertifikat yang diterbitkan oleh TrustLab.
<Callout type="info" emoji={<Shield className="w-5 h-5" />}>
**Prasyarat:** Pastikan Anda telah mengunduh **PEM Bundle** (untuk Linux) atau **PFX** (untuk Windows) seperti yang dijelaskan dalam [Panduan Unduh](/id/guide/certificates/download-install).
</Callout>
## Contoh Konfigurasi
Pilih lingkungan web server Anda di bawah ini:
<Tabs items={['Nginx', 'Apache (httpd)', 'IIS (Windows)']}>
<Tabs.Tab>
### Pengaturan Nginx
File Target: `/etc/nginx/sites-available/default` atau `internal.app.conf`
```nginx
server {
listen 80;
server_name internal.app;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name internal.app;
# SSL Configuration
ssl_certificate /etc/ssl/trustlab/internal.app.crt;
ssl_certificate_key /etc/ssl/trustlab/internal.app.key;
# Recommended Security
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
}
```
</Tabs.Tab>
<Tabs.Tab>
### Pengaturan Apache / HTTPD
File Target: `/etc/httpd/conf.d/ssl.conf` atau file VHost.
```apache
<VirtualHost *:443>
ServerName internal.app
DocumentRoot /var/www/html/internal
SSLEngine on
SSLCertificateFile "/path/to/internal.app.crt"
SSLCertificateKeyFile "/path/to/internal.app.key"
# Best Practice
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
</VirtualHost>
```
5. Pergi ke **Sites**, pilih situs Anda, dan klik **Bindings...**.
6. Tambahkan binding `https` dan pilih sertifikat TrustLab yang baru diimpor.
</Tabs.Tab>
</Tabs>
---
## Verifikasi Konfigurasi
Gunakan perintah `curl` dari terminal untuk memastikan sertifikat terdeteksi dengan benar:
```bash
curl -vI https://internal.yourcompany.local
```
Perhatikan baris `server certificate verification OK`. Jika muncul error, pastikan Anda telah menginstal Root CA di perangkat yang menjalankan perintah tersebut.
> [!NOTE]
> Sangat disarankan untuk selalu menggunakan file **BUNDLE/COMBINED** (Sertifikat + Intermediate) untuk menghindari masalah rantai sertifikat (Chain Error) di beberapa browser mobile.

View File

@@ -0,0 +1,4 @@
{
"browser-errors": "Kesalahan Umum Browser",
"developer-tools": "Masalah CLI & Bahasa"
}

View File

@@ -0,0 +1,43 @@
import { Callout, Cards, Card } from 'nextra/components'
import { AlertTriangle, Globe, Calendar, XCircle, HelpCircle } from 'lucide-react'
# Kesalahan Browser Umum
Saat menggunakan sertifikat internal, browser sangatlah ketat. Berikut adalah kode kesalahan yang paling umum dan cara mengatasinya.
### `NET::ERR_CERT_AUTHORITY_INVALID`
<Callout type="error" emoji={<AlertTriangle className="w-5 h-5" />}>
**Logikanya:** Browser sama sekali **tidak mengenal** "TrustLab Root CA" yang menandatangani sertifikat situs web Anda, sehingga ia menganggapnya palsu.
</Callout>
**Solusi:**
Anda belum menginstal Root CA di perangkat Anda.
* [**Panduan Instalasi Root CA**](/id/guide/getting-started/install-root-ca)
---
### `NET::ERR_CERT_COMMON_NAME_INVALID`
<Callout type="warning" emoji={<Globe className="w-5 h-5" />}>
**Logikanya:** Anda mengunjungi `app.local`, tetapi sertifikat hanya diterbitkan untuk `api.local`. Namanya **tidak cocok**.
</Callout>
**Solusi:**
Domain tersebut tidak ada dalam **SANs (Subject Alternative Names)** sertifikat.
1. Klik ikon **"Not Secure"** > **Certificate**.
2. Periksa bidang **DNS Name** atau SAN.
3. Jika tidak ada, Anda harus **[Menerbitkan Sertifikat Baru](/id/guide/certificates/request-new)** yang menyertakan domain yang benar.
---
### `NET::ERR_CERT_DATE_INVALID`
<Callout type="info" emoji={<Calendar className="w-5 h-5" />}>
**Logikanya:** Sertifikat telah kedaluwarsa, ATAU jam komputer Anda diatur ke tanggal yang salah (lampau/masa depan).
</Callout>
**Solusi:**
1. Periksa jam sistem Anda terlebih dahulu.
2. Jika jam sudah benar, berarti sertifikat benar-benar kedaluwarsa.
3. **[Perbarui Sertifikat](/id/guide/certificates/renewal)** segera.

View File

@@ -0,0 +1,97 @@
import { Callout, Steps } from 'nextra/components'
import { Terminal, Code, Server, Download } from 'lucide-react'
# Masalah CLI & Bahasa Pemrograman
Bahkan jika Anda sudah menginstal Root CA di sistem operasi Anda, banyak alat pengembang dan bahasa pemrograman yang **mengabaikan penyimpanan sistem (system store)** dan menggunakan penyimpanan mereka sendiri.
<Callout type="info" emoji={<Download className="w-5 h-5" />}>
**Prasyarat:**
Anda harus memiliki file **`trustlab-root.crt`** yang sudah diunduh di mesin Anda.
[Unduh di sini](/id/guide/getting-started/install-root-ca).
</Callout>
Jika kode atau skrip Anda gagal dengan kesalahan sertifikat, periksa solusi di bawah ini.
## 1. cURL & Wget
Alat baris perintah standar sering kali mencari file bundle tertentu.
### cURL
<Callout type="error" emoji={<Terminal className="w-5 h-5" />}>
`curl: (60) SSL certificate problem: unable to get local issuer certificate`
</Callout>
**Solusi:**
Teruskan Root CA secara eksplisit:
```bash
curl --cacert /jalur/ke/trustlab-root.crt https://domain-anda.local
```
### Wget
**Solusi:**
```bash
wget --ca-certificate=/jalur/ke/trustlab-root.crt https://domain-anda.local
```
---
## 2. Node.js / JavaScript
Node.js tidak menggunakan Root CA Sistem secara default.
<Callout type="error" emoji={<Server className="w-5 h-5" />}>
`Error: self signed certificate in certificate chain`
</Callout>
**Solusi (Variabel Lingkungan):**
Atur variabel ini sebelum menjalankan aplikasi Anda. Ini berfungsi untuk sebagian besar aplikasi Node.js (npm, yarn, skrip kustom).
```bash
export NODE_EXTRA_CA_CERTS="/jalur/ke/trustlab-root.crt"
node server.js
```
---
## 3. Python (Requests/Pip)
Pustaka `requests` di Python (dan `pip`) menggunakan paket sertifikatnya sendiri (`certifi`), mengabaikan penyimpanan sistem Windows/macOS/Linux.
<Callout type="error" emoji={<Code className="w-5 h-5" />}>
`SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed'))`
</Callout>
**Solusi:**
Arahkan ke Root CA Anda menggunakan variabel lingkungan.
```bash
export REQUESTS_CA_BUNDLE="/jalur/ke/trustlab-root.crt"
python script.py
```
---
## 4. Aplikasi Java
Java menggunakan "Keystore" (JKS) milik sendiri dan biasanya **mengabaikan** Windows Certificate Store.
<Callout type="error" emoji={<Code className="w-5 h-5" />}>
`sun.security.validator.ValidatorException: PKIX path building failed`
</Callout>
**Solusi:**
Anda harus mengimpor Root CA TrustLab ke dalam Java Keystore (cacerts).
<Steps>
### Lokasi standar cacerts
Biasanya di `$JAVA_HOME/lib/security/cacerts`.
### Impor dengan keytool
```bash
keytool -import -trustcacerts -alias trustlab-root \
-file trustlab-root.crt \
-keystore "$JAVA_HOME/lib/security/cacerts"
```
*Kata sandi default biasanya adalah `changeit`.*
</Steps>

3
pages/id/index.mdx Normal file
View File

@@ -0,0 +1,3 @@
import { LandingPage } from '../../components/LandingPage'
<LandingPage locale="id" />

View File

@@ -1,3 +1,10 @@
import { LandingPage } from '../components/LandingPage'
import { useEffect } from 'react'
import { useRouter } from 'next/router'
<LandingPage />
export default function Root() {
const router = useRouter()
useEffect(() => {
router.replace('/en')
}, [router])
return null
}

View File

@@ -1,16 +1,100 @@
import React from 'react'
import React, { useState, useEffect } from 'react'
import { useRouter } from 'next/router'
import { DocsThemeConfig } from 'nextra-theme-docs'
import Link from 'next/link'
// Global lock to prevent race conditions.
// With a hard reload strategy, this lock effectively persists until the page is unloaded.
let isTransitioning = false
const LanguageSwitcher = () => {
const { asPath } = useRouter()
const [disabled, setDisabled] = useState(false)
useEffect(() => {
// Sync local state with global lock on mount
setDisabled(isTransitioning)
}, [])
const isId = asPath.startsWith('/id')
const toggleLanguage = () => {
if (isTransitioning) return
// Prevent default activity if confirmed
isTransitioning = true
setDisabled(true)
let newPath = asPath
// Robust path replacement logic
if (isId) {
newPath = asPath.replace('/id', '/en')
} else {
// Handle implicit default or explicit /en
if (asPath.startsWith('/en')) {
newPath = asPath.replace('/en', '/id')
} else {
// If path is root '/' or other, prepend '/id'
// Assuming structural parity, / -> /id
newPath = '/id' + (asPath === '/' ? '' : asPath)
}
}
// Use hard reload to ensure clean sidebar state for static exports
if (typeof window !== 'undefined') {
window.location.href = newPath
}
}
return (
<button
onClick={toggleLanguage}
disabled={disabled}
className={`flex items-center gap-2 px-3 py-1.5 rounded-full bg-neutral-100 dark:bg-neutral-800 hover:bg-neutral-200 dark:hover:bg-neutral-700 transition-all font-medium text-xs sm:text-sm border border-neutral-200 dark:border-neutral-700 ${disabled ? 'opacity-50 cursor-not-allowed' : ''}`}
>
{isId ? (
<>🇮🇩 <span className="hidden xs:inline">Bahasa Indonesia</span></>
) : (
<>🇺🇸 <span className="hidden xs:inline">English</span></>
)}
<span className="opacity-40 ml-1"></span>
</button>
)
}
const config: DocsThemeConfig = {
logo: (
<div className="flex items-center gap-2">
<img src="/logo.png" alt="TrustLab" width="120" className="dark:hidden" />
<img src="/logo-dark.png" alt="TrustLab" width="120" className="hidden dark:block" />
<span className="font-semibold text-lg hidden sm:inline">Docs</span>
</div>
),
logoLink: '/',
logo: () => {
const { asPath } = useRouter()
const isId = asPath.startsWith('/id')
const homePath = isId ? '/id' : '/en'
const guidePath = isId ? '/id/guide' : '/en/guide'
const devPath = isId ? '/id/developer' : '/en/developer'
const guideTitle = isId ? 'Panduan Pengguna' : 'User Guide'
const devTitle = isId ? 'Developer API' : 'Developer API'
return (
<div className="flex items-center gap-8">
<Link href={homePath} className="flex items-center gap-2 hover:opacity-75 transition-opacity">
<img src="/logo.png" alt="TrustLab" width="120" className="dark:hidden" />
<img src="/logo-dark.png" alt="TrustLab" width="120" className="hidden dark:block" />
<span className="font-semibold text-lg hidden sm:inline">Docs</span>
</Link>
<div className="hidden md:flex items-center gap-6 text-sm font-medium text-neutral-600 dark:text-neutral-400">
<Link href={guidePath} className={asPath.includes('/guide') ? 'text-blue-600 dark:text-blue-400 font-bold' : 'hover:text-neutral-900 dark:hover:text-neutral-100 transition-colors'}>
{guideTitle}
</Link>
<Link href={devPath} className={asPath.includes('/developer') ? 'text-blue-600 dark:text-blue-400 font-bold' : 'hover:text-neutral-900 dark:hover:text-neutral-100 transition-colors'}>
{devTitle}
</Link>
</div>
</div>
)
},
logoLink: false,
navbar: {
extraContent: LanguageSwitcher
},
project: {
link: 'https://github.com/dyzulk/trustlab-docs',
},
@@ -25,7 +109,7 @@ const config: DocsThemeConfig = {
docsRepositoryBase: 'https://github.com/dyzulk/trustlab-docs/tree/main',
useNextSeoProps() {
const { asPath } = useRouter()
if (asPath === '/') {
if (asPath.includes('/index') || asPath.endsWith('/en/') || asPath.endsWith('/id/')) {
return {
titleTemplate: 'TrustLab - Private Certificate Authority'
}