From fb6933edd042a58b4f8d97a357319957d0095d72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deniz=20Bekta=C5=9F?= Date: Fri, 3 Apr 2026 16:20:51 +0300 Subject: [PATCH] =?UTF-8?q?deniz=20bekta=C5=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude/launch.json | 11 + .claude/settings.local.json | 6 +- app/aktivite/page.tsx | 75 ++ app/altyapi/page.tsx | 81 ++ app/api/rss/all/route.ts | 42 + app/api/rss/blog/route.ts | 38 + app/api/rss/infosec/route.ts | 38 + app/api/rss/podcast/route.ts | 23 + app/blog/[slug]/page.tsx | 47 ++ app/blog/page.tsx | 47 ++ app/email/page.tsx | 5 + app/faydali-linkler/page.tsx | 122 +++ app/fikirlerim/page.tsx | 71 ++ app/gizlilik/page.tsx | 57 ++ app/globals.css | 172 +++- app/hakkimda/page.tsx | 66 ++ app/hobilerim/page.tsx | 74 ++ app/humans.txt/route.ts | 36 + app/iletisim/page.tsx | 69 ++ app/infosec/[slug]/page.tsx | 54 ++ app/infosec/page.tsx | 48 ++ app/kullanim-kosullari/page.tsx | 60 ++ app/layout.tsx | 89 +- app/mastodon/page.tsx | 5 + app/merhaba/page.tsx | 57 ++ app/misyon/page.tsx | 49 ++ app/notebook/[slug]/page.tsx | 44 + app/notebook/page.tsx | 47 ++ app/ozgecmis/page.tsx | 149 ++++ app/page.tsx | 264 ++++-- app/podcast/page.tsx | 80 ++ app/projeler/page.tsx | 123 +++ app/public.pgp/route.ts | 14 + app/roadmap/page.tsx | 231 ++++++ app/robots.txt/route.ts | 18 + app/rss-beslemeleri/page.tsx | 116 +++ app/security.txt/route.ts | 23 + app/seyir-defteri/page.tsx | 152 ++++ app/sitemap.xml/route.ts | 71 ++ app/statboard/page.tsx | 79 ++ app/su-anda/page.tsx | 62 ++ app/takim-cantam/page.tsx | 138 +++ app/tesekkurler/page.tsx | 52 ++ components/Navigation.tsx | 285 +++++++ components/ThemeProvider.tsx | 36 + content/activity.json | 30 + content/blog/neden-siber-guvenlik.md | 26 + content/infosec/nmap-ag-kesfi.md | 82 ++ content/notebook/ilk-not.md | 12 + lib/activity.ts | 30 + lib/posts.ts | 71 ++ package-lock.json | 1155 +++++++++++++++++++++++++- package.json | 8 +- 53 files changed, 4742 insertions(+), 98 deletions(-) create mode 100644 .claude/launch.json create mode 100644 app/aktivite/page.tsx create mode 100644 app/altyapi/page.tsx create mode 100644 app/api/rss/all/route.ts create mode 100644 app/api/rss/blog/route.ts create mode 100644 app/api/rss/infosec/route.ts create mode 100644 app/api/rss/podcast/route.ts create mode 100644 app/blog/[slug]/page.tsx create mode 100644 app/blog/page.tsx create mode 100644 app/email/page.tsx create mode 100644 app/faydali-linkler/page.tsx create mode 100644 app/fikirlerim/page.tsx create mode 100644 app/gizlilik/page.tsx create mode 100644 app/hakkimda/page.tsx create mode 100644 app/hobilerim/page.tsx create mode 100644 app/humans.txt/route.ts create mode 100644 app/iletisim/page.tsx create mode 100644 app/infosec/[slug]/page.tsx create mode 100644 app/infosec/page.tsx create mode 100644 app/kullanim-kosullari/page.tsx create mode 100644 app/mastodon/page.tsx create mode 100644 app/merhaba/page.tsx create mode 100644 app/misyon/page.tsx create mode 100644 app/notebook/[slug]/page.tsx create mode 100644 app/notebook/page.tsx create mode 100644 app/ozgecmis/page.tsx create mode 100644 app/podcast/page.tsx create mode 100644 app/projeler/page.tsx create mode 100644 app/public.pgp/route.ts create mode 100644 app/roadmap/page.tsx create mode 100644 app/robots.txt/route.ts create mode 100644 app/rss-beslemeleri/page.tsx create mode 100644 app/security.txt/route.ts create mode 100644 app/seyir-defteri/page.tsx create mode 100644 app/sitemap.xml/route.ts create mode 100644 app/statboard/page.tsx create mode 100644 app/su-anda/page.tsx create mode 100644 app/takim-cantam/page.tsx create mode 100644 app/tesekkurler/page.tsx create mode 100644 components/Navigation.tsx create mode 100644 components/ThemeProvider.tsx create mode 100644 content/activity.json create mode 100644 content/blog/neden-siber-guvenlik.md create mode 100644 content/infosec/nmap-ag-kesfi.md create mode 100644 content/notebook/ilk-not.md create mode 100644 lib/activity.ts create mode 100644 lib/posts.ts diff --git a/.claude/launch.json b/.claude/launch.json new file mode 100644 index 0000000..3379044 --- /dev/null +++ b/.claude/launch.json @@ -0,0 +1,11 @@ +{ + "version": "0.0.1", + "configurations": [ + { + "name": "Next.js Dev Server", + "runtimeExecutable": "npm", + "runtimeArgs": ["run", "dev"], + "port": 3000 + } + ] +} diff --git a/.claude/settings.local.json b/.claude/settings.local.json index ee15d8e..9ae5178 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -1,7 +1,11 @@ { "permissions": { "allow": [ - "Bash(npx create-next-app@latest . --typescript --tailwind --eslint --app --no-src-dir --import-alias \"@/*\" --yes)" + "Bash(npx create-next-app@latest . --typescript --tailwind --eslint --app --no-src-dir --import-alias \"@/*\" --yes)", + "Bash(npm install:*)", + "Bash(npm run:*)", + "mcp__Claude_Preview__preview_start", + "Bash(curl -s -o /dev/null -w \"%{http_code}\" http://localhost:3000)" ] } } diff --git a/app/aktivite/page.tsx b/app/aktivite/page.tsx new file mode 100644 index 0000000..de81eb0 --- /dev/null +++ b/app/aktivite/page.tsx @@ -0,0 +1,75 @@ +import type { Metadata } from "next"; +import { getActivity } from "@/lib/activity"; +import Link from "next/link"; + +export const metadata: Metadata = { title: "Aktivite" }; + +const typeIcons: Record = { + post: "✍", notebook: "◎", infosec: "⚔", project: "◈", + link: "⊞", update: "▲", system: "⚙", +}; + +const typeLabels: Record = { + post: "Blog", notebook: "Notebook", infosec: "Infosec", + project: "Proje", link: "Link", update: "Güncelleme", system: "Sistem", +}; + +export default function AktivitePage() { + const activities = getActivity(); + + return ( +
+
Aktivite
+

+ Sitede olan her şeyin kaydı — changelog + activity stream +

+ +
+
+ {activities.length === 0 ? ( +
Henüz aktivite yok
+ ) : ( +
    + {activities.map((a) => ( +
  • + + {formatDateTime(a.timestamp)} + + + {typeIcons[a.type] || "▶"} + {typeLabels[a.type] || a.type} + + + {a.link ? ( + {a.message} + ) : ( + {a.message} + )} + +
  • + ))} +
+ )} +
+
+
+ ); +} + +function formatDateTime(iso: string) { + const d = new Date(iso); + return d.toLocaleString("tr-TR", { + year: "numeric", month: "2-digit", day: "2-digit", + hour: "2-digit", minute: "2-digit", + }); +} diff --git a/app/altyapi/page.tsx b/app/altyapi/page.tsx new file mode 100644 index 0000000..61861b2 --- /dev/null +++ b/app/altyapi/page.tsx @@ -0,0 +1,81 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { title: "Altyapı" }; + +export default function AltyapiPage() { + return ( +
+
Altyapı
+

+ Bu sitenin nasıl çalıştığı +

+ +
+

Tech Stack

+
    +
  • Framework: Next.js 15 (App Router)
  • +
  • Dil: TypeScript
  • +
  • Stil: Tailwind CSS + custom CSS variables (tema sistemi)
  • +
  • İçerik: Markdown dosyaları (gray-matter + remark)
  • +
  • Font: JetBrains Mono (monospace her yerde)
  • +
  • Tema: Dark/Light mode (localStorage tabanlı)
  • +
+ +

Hosting & Deployment

+
    +
  • Hosting: Vercel (free tier)
  • +
  • Domain: denizbektas.com.tr
  • +
  • CDN: Vercel Edge Network
  • +
  • CI/CD: GitHub → Vercel otomatik deploy
  • +
  • SSL: Otomatik (Let's Encrypt via Vercel)
  • +
+ +

İçerik Yönetimi

+

+ CMS yok. Markdown dosyaları doğrudan. Yeni bir yazı eklemek için + /content/blog/ klasörüne .md dosyası eklemek yeterli. + Git commit → GitHub → Vercel deploy → 30 saniye. +

+ +

RSS

+

+ RSS beslemeleri /api/rss/* route'larından dinamik olarak üretiliyor. + Blog, infosec ve podcast için ayrı beslemeler mevcut. +

+ +

Gizlilik

+
    +
  • Analytics yok (Google Analytics, Plausible, vb.)
  • +
  • Cookie yok (tema tercihi hariç — localStorage)
  • +
  • Üçüncü taraf script yok (font CDN hariç)
  • +
  • Log tutulmuyor (Vercel'in standart logları hariç)
  • +
+ +

Kaynak Kodu

+

+ Bu sitenin kaynak kodu açık kaynak:{" "} + + github.com/bugresearch/denizbektas.com.tr + +

+ +

Performans Hedefleri

+
    +
  • Lighthouse Score: 95+
  • +
  • First Contentful Paint: <1s
  • +
  • JavaScript: Minimum (sadece tema toggle)
  • +
  • Sayfa boyutu: <100KB (font hariç)
  • +
+ +

Tasarım Felsefesi

+

+ Terminal estetik. Monospace font her yerde. Minimal JavaScript. + İçerik odaklı. Hızlı. Okunabilir. +

+
+ "The best interface is no interface." — Golden Krishna +
+
+
+ ); +} diff --git a/app/api/rss/all/route.ts b/app/api/rss/all/route.ts new file mode 100644 index 0000000..1803936 --- /dev/null +++ b/app/api/rss/all/route.ts @@ -0,0 +1,42 @@ +import { NextResponse } from "next/server"; +import { getAllPosts } from "@/lib/posts"; + +const SITE_URL = "https://denizbektas.com.tr"; + +export async function GET() { + const posts = getAllPosts(); + + const items = posts + .map( + (post) => ` + + <![CDATA[${post.title}]]> + ${SITE_URL}/${post.category}/${post.slug} + ${SITE_URL}/${post.category}/${post.slug} + ${new Date(post.date).toUTCString()} + + ${post.category} + ` + ) + .join("\n"); + + const xml = ` + + + Deniz Bektaş — Tüm İçerikler + ${SITE_URL} + Siber güvenlik, red team ve kişisel yazılar + tr + + ${new Date().toUTCString()} + ${items} + +`; + + return new NextResponse(xml, { + headers: { + "Content-Type": "application/xml; charset=utf-8", + "Cache-Control": "public, max-age=3600", + }, + }); +} diff --git a/app/api/rss/blog/route.ts b/app/api/rss/blog/route.ts new file mode 100644 index 0000000..0b79f42 --- /dev/null +++ b/app/api/rss/blog/route.ts @@ -0,0 +1,38 @@ +import { NextResponse } from "next/server"; +import { getPosts } from "@/lib/posts"; + +const SITE_URL = "https://denizbektas.com.tr"; + +export async function GET() { + const posts = getPosts("blog"); + + const items = posts + .map( + (post) => ` + + <![CDATA[${post.title}]]> + ${SITE_URL}/blog/${post.slug} + ${SITE_URL}/blog/${post.slug} + ${new Date(post.date).toUTCString()} + + ` + ) + .join("\n"); + + const xml = ` + + + Deniz Bektaş — Kişisel Blog + ${SITE_URL}/blog + Kişisel blog yazıları + tr + + ${new Date().toUTCString()} + ${items} + +`; + + return new NextResponse(xml, { + headers: { "Content-Type": "application/xml; charset=utf-8", "Cache-Control": "public, max-age=3600" }, + }); +} diff --git a/app/api/rss/infosec/route.ts b/app/api/rss/infosec/route.ts new file mode 100644 index 0000000..a556e61 --- /dev/null +++ b/app/api/rss/infosec/route.ts @@ -0,0 +1,38 @@ +import { NextResponse } from "next/server"; +import { getPosts } from "@/lib/posts"; + +const SITE_URL = "https://denizbektas.com.tr"; + +export async function GET() { + const posts = getPosts("infosec"); + + const items = posts + .map( + (post) => ` + + <![CDATA[${post.title}]]> + ${SITE_URL}/infosec/${post.slug} + ${SITE_URL}/infosec/${post.slug} + ${new Date(post.date).toUTCString()} + + ` + ) + .join("\n"); + + const xml = ` + + + Deniz Bektaş — Infosec Posts + ${SITE_URL}/infosec + Teknik siber güvenlik yazıları + tr + + ${new Date().toUTCString()} + ${items} + +`; + + return new NextResponse(xml, { + headers: { "Content-Type": "application/xml; charset=utf-8", "Cache-Control": "public, max-age=3600" }, + }); +} diff --git a/app/api/rss/podcast/route.ts b/app/api/rss/podcast/route.ts new file mode 100644 index 0000000..85d5337 --- /dev/null +++ b/app/api/rss/podcast/route.ts @@ -0,0 +1,23 @@ +import { NextResponse } from "next/server"; + +const SITE_URL = "https://denizbektas.com.tr"; + +export async function GET() { + const xml = ` + + + Deniz Bektaş Podcast + ${SITE_URL}/podcast + Türkçe siber güvenlik podcast'i — red team, pentest ve hacker kültürü + tr + denizbektas + + + ${new Date().toUTCString()} + +`; + + return new NextResponse(xml, { + headers: { "Content-Type": "application/xml; charset=utf-8", "Cache-Control": "public, max-age=3600" }, + }); +} diff --git a/app/blog/[slug]/page.tsx b/app/blog/[slug]/page.tsx new file mode 100644 index 0000000..df4941d --- /dev/null +++ b/app/blog/[slug]/page.tsx @@ -0,0 +1,47 @@ +import type { Metadata } from "next"; +import Link from "next/link"; +import { getPost, getPosts } from "@/lib/posts"; +import { notFound } from "next/navigation"; + +export async function generateStaticParams() { + return getPosts("blog").map((p) => ({ slug: p.slug })); +} + +export async function generateMetadata({ params }: { params: Promise<{ slug: string }> }): Promise { + const { slug } = await params; + const post = await getPost("blog", slug); + if (!post) return {}; + return { title: post.title, description: post.excerpt }; +} + +export default async function BlogPostPage({ params }: { params: Promise<{ slug: string }> }) { + const { slug } = await params; + const post = await getPost("blog", slug); + if (!post) notFound(); + + return ( +
+ + ← Blog'a Dön + + +
+
+

+ {post.title} +

+
+ + {new Date(post.date).toLocaleDateString("tr-TR", { year: "numeric", month: "long", day: "numeric" })} + +
+ {post.tags.map((t) => {t})} +
+
+
+ +
+
+
+ ); +} diff --git a/app/blog/page.tsx b/app/blog/page.tsx new file mode 100644 index 0000000..9731f06 --- /dev/null +++ b/app/blog/page.tsx @@ -0,0 +1,47 @@ +import type { Metadata } from "next"; +import Link from "next/link"; +import { getPosts } from "@/lib/posts"; + +export const metadata: Metadata = { title: "Personal Blog" }; + +export default function BlogPage() { + const posts = getPosts("blog"); + + return ( +
+
Personal Blog
+

+ Kişisel yazılar, düşünceler, kariyer notları +

+ + {posts.length === 0 ? ( +
+ Henüz yazı yok. Yakında... +
+ ) : ( +
+ {posts.map((post) => ( +
+ +

+ {post.title} +

+ +

+ {post.excerpt} +

+
+
+ {post.tags.map((t) => {t})} +
+ + {new Date(post.date).toLocaleDateString("tr-TR", { year: "numeric", month: "long", day: "numeric" })} + +
+
+ ))} +
+ )} +
+ ); +} diff --git a/app/email/page.tsx b/app/email/page.tsx new file mode 100644 index 0000000..c187e85 --- /dev/null +++ b/app/email/page.tsx @@ -0,0 +1,5 @@ +import { redirect } from "next/navigation"; + +export default function EmailPage() { + redirect("mailto:info@denizbektas.com.tr"); +} diff --git a/app/faydali-linkler/page.tsx b/app/faydali-linkler/page.tsx new file mode 100644 index 0000000..110288a --- /dev/null +++ b/app/faydali-linkler/page.tsx @@ -0,0 +1,122 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { title: "Faydalı Linkler" }; + +interface LinkItem { + title: string; + url: string; + description: string; +} + +interface Category { + name: string; + icon: string; + links: LinkItem[]; +} + +const categories: Category[] = [ + { + name: "Öğrenme Platformları", + icon: "◈", + links: [ + { title: "HackTheBox", url: "https://hackthebox.com", description: "CTF ve penetrasyon testi platformu" }, + { title: "TryHackMe", url: "https://tryhackme.com", description: "Yeni başlayanlar için siber güvenlik eğitimi" }, + { title: "PentesterLab", url: "https://pentesterlab.com", description: "Web güvenliği odaklı pratik eğitim" }, + { title: "PortSwigger Web Academy", url: "https://portswigger.net/web-security", description: "Burp Suite ekibinin ücretsiz web güvenlik eğitimi" }, + { title: "PicoCTF", url: "https://picoctf.org", description: "Carnegie Mellon üniversitesinin ücretsiz CTF platformu" }, + ], + }, + { + name: "Araçlar", + icon: "⊡", + links: [ + { title: "Nmap", url: "https://nmap.org", description: "Ağ keşif ve güvenlik tarama aracı" }, + { title: "Burp Suite", url: "https://portswigger.net/burp", description: "Web uygulama güvenlik testi aracı" }, + { title: "Metasploit", url: "https://metasploit.com", description: "Penetrasyon testi framework'ü" }, + { title: "Ghidra", url: "https://ghidra-sre.org", description: "NSA'nın açık kaynak reverse engineering aracı" }, + { title: "CyberChef", url: "https://gchq.github.io/CyberChef", description: "Veri dönüştürme ve analiz aracı" }, + { title: "OSINT Framework", url: "https://osintframework.com", description: "OSINT araçları haritası" }, + ], + }, + { + name: "Kaynaklar & Dokümantasyon", + icon: "▤", + links: [ + { title: "OWASP", url: "https://owasp.org", description: "Web güvenlik standartları ve kaynakları" }, + { title: "GTFOBins", url: "https://gtfobins.github.io", description: "Linux privilege escalation teknikleri" }, + { title: "LOLBAS", url: "https://lolbas-project.github.io", description: "Windows living off the land binaries" }, + { title: "PayloadsAllTheThings", url: "https://github.com/swisskyrepo/PayloadsAllTheThings", description: "Güvenlik testleri için payload koleksiyonu" }, + { title: "HackTricks", url: "https://book.hacktricks.xyz", description: "Kapsamlı hacking teknikleri kitabı" }, + { title: "Exploit Database", url: "https://exploit-db.com", description: "Public exploit veritabanı" }, + ], + }, + { + name: "Red Team", + icon: "⚔", + links: [ + { title: "Red Team Notes", url: "https://www.ired.team", description: "Red team teknikleri ve notları" }, + { title: "Cobalt Strike Guide", url: "https://hstechdocs.helpsystems.com/manuals/cobaltstrike", description: "Cobalt Strike resmi dokümantasyonu" }, + { title: "BloodHound", url: "https://github.com/BloodHoundAD/BloodHound", description: "Active Directory saldırı yolları analizi" }, + { title: "Impacket", url: "https://github.com/impacket/impacket", description: "Python ağ protokol kütüphanesi" }, + ], + }, + { + name: "Haberler & Blog", + icon: "◎", + links: [ + { title: "Krebs on Security", url: "https://krebsonsecurity.com", description: "Brian Krebs'in güvenlik blogu" }, + { title: "The Hacker News", url: "https://thehackernews.com", description: "Siber güvenlik haberleri" }, + { title: "Darknet Diaries", url: "https://darknetdiaries.com", description: "Gerçek siber suç hikayeleri podcast'i" }, + { title: "Project Zero Blog", url: "https://googleprojectzero.blogspot.com", description: "Google'ın güvenlik araştırma blogu" }, + ], + }, + { + name: "CTF Writeupları", + icon: "◆", + links: [ + { title: "0xdf hacks stuff", url: "https://0xdf.gitlab.io", description: "HTB ve CTF writeupları" }, + { title: "IppSec YouTube", url: "https://www.youtube.com/@ippsec", description: "HTB makineleri video çözümleri" }, + { title: "CTFtime", url: "https://ctftime.org", description: "CTF yarışmaları takvimi ve arşivi" }, + ], + }, +]; + +export default function FaydalıLinklerPage() { + return ( +
+
Faydalı Linkler
+

+ Kategorilere göre düzenlenmiş faydalı bağlantılar koleksiyonu +

+ +
+ {categories.map((cat) => ( +
+
+ {cat.icon} + {cat.name} +
+
+ {cat.links.map((link) => ( + +
+ {link.title} + +
+

{link.description}

+
+ ))} +
+
+ ))} +
+
+ ); +} diff --git a/app/fikirlerim/page.tsx b/app/fikirlerim/page.tsx new file mode 100644 index 0000000..f69ce5d --- /dev/null +++ b/app/fikirlerim/page.tsx @@ -0,0 +1,71 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { title: "Fikirlerim" }; + +interface Idea { + title: string; + body: string; + tags: string[]; + date: string; +} + +const ideas: Idea[] = [ + { + title: "Güvenlik ve Gizlilik Aynı Şey Değil", + body: "İnsanlar genellikle güvenlik ile gizliliği karıştırıyor. Güvenli bir sistem sizi dış saldırılardan korur ama sizi izleyebilir. Gizlilik odaklı bir sistem ise sizi izlemez ama saldırılara karşı zayıf olabilir. İkisini birlikte sağlamak hem teknik hem felsefi bir meydan okuma.", + tags: ["güvenlik", "gizlilik", "felsefe"], + date: "2026-03-15", + }, + { + title: "İnternet Hafızayı Yok Ediyor mu, Güçlendiriyor mu?", + body: "Her şeyi Google'a sormak beynimizi tembelleştiriyor deniyor. Ama belki de asıl sorunu çözdük: hafıza dışarıda depolanıyor, beyin daha üst düzey düşünmeye odaklanıyor. Problemi, hangi bilginin nerede arandığını bilmek.", + tags: ["bilişsel", "internet", "düşünce"], + date: "2026-02-20", + }, + { + title: "Saldırgan Zihniyeti Savunmayı Güçlendirir", + body: "Red team'in asıl değeri sadece açık bulmak değil, savunma ekibinin göremediği şeyleri görünür kılmak. Bir sistemi kırmayı bilmek, onu korumanın en etkili yolu.", + tags: ["red team", "savunma", "siber güvenlik"], + date: "2026-01-10", + }, + { + title: "Karmaşıklık = Saldırı Yüzeyi", + body: "Bir sistemdeki her özellik bir saldırı vektörüdür. En güvenli sistem en az özelliği olan sistemdir. Yazılım minimalizmi sadece estetik değil, güvenlik gerekliliği.", + tags: ["güvenlik", "tasarım", "minimalizm"], + date: "2025-12-01", + }, + { + title: "Açık Kaynak = Güven mi?", + body: "Açık kaynak kod herkes tarafından incelenebilir ama herkes incelemiyor. Log4Shell açık kaynak bir kütüphanede yıllarca gizliydi. Şeffaflık gerekli ama yeterli değil. Güven, aktif inceleme gerektirir.", + tags: ["açık kaynak", "güven", "güvenlik"], + date: "2025-11-15", + }, +]; + +export default function FikirlerimPage() { + return ( +
+
Fikirlerim
+

+ Düşündüğüm felsefi ve mantıksal şeyler — kısa düşünceler, hipotezler +

+ +
+ {ideas.map((idea) => ( +
+

{idea.title}

+

{idea.body}

+
+
+ {idea.tags.map((t) => {t})} +
+ + {new Date(idea.date).toLocaleDateString("tr-TR", { year: "numeric", month: "long" })} + +
+
+ ))} +
+
+ ); +} diff --git a/app/gizlilik/page.tsx b/app/gizlilik/page.tsx new file mode 100644 index 0000000..8e48ca8 --- /dev/null +++ b/app/gizlilik/page.tsx @@ -0,0 +1,57 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { title: "Gizlilik Politikası" }; + +export default function GizlilikPage() { + return ( +
+
Gizlilik Politikası
+

+ Son güncelleme: 3 Nisan 2026 +

+ +
+

Kısa Versiyon

+

+ Hiçbir şey toplamıyoruz. Analytics yok, cookie yok, izleme yok. +

+ +

Topladığımız Veriler

+

+ denizbektas.com.tr hiçbir kişisel veri toplamamaktadır. Özellikle: +

+
    +
  • Google Analytics veya benzeri analitik araç kullanılmamaktadır
  • +
  • Reklam ağları bulunmamaktadır
  • +
  • Oturum çerezi (session cookie) kullanılmamaktadır
  • +
  • E-posta adresi toplanmamaktadır
  • +
  • IP adresleri loglanmamaktadır (hosting sağlayıcısı olan Vercel'in standart logları hariç)
  • +
+ +

Yerel Depolama

+

+ Yalnızca tema tercihiniz (dark/light) localStorage üzerinde yerel olarak + saklanmaktadır. Bu veri sunucuya gönderilmez. +

+ +

Üçüncü Taraflar

+

+ Site JetBrains Mono fontunu bir CDN üzerinden yüklemektedir. Bu bağlantı sırasında + CDN sağlayıcısı IP adresinizi görebilir. +

+ +

Hosting

+

+ Site Vercel altyapısında barındırılmaktadır. Vercel'in kendi gizlilik politikası + geçerlidir. +

+ +

İletişim

+

+ Gizlilik ile ilgili sorularınız için:{" "} + info@denizbektas.com.tr +

+
+
+ ); +} diff --git a/app/globals.css b/app/globals.css index a2dc41e..645ae0b 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1,26 +1,166 @@ @import "tailwindcss"; :root { - --background: #ffffff; - --foreground: #171717; + --bg: #f5f5f0; + --bg-card: #ffffff; + --bg-hover: #f0f0ea; + --border: #d4d4c8; + --text: #1a1a1a; + --text-muted: #6b6b6b; + --accent: #005f99; + --accent-glow: #0077bb; + --accent-secondary: #6b21a8; + --tag-bg: #e8f4fd; + --tag-text: #005f99; + --sidebar-bg: #fafaf5; + --header-bg: rgba(245, 245, 240, 0.95); + --scrollbar: #c8c8bc; + --code-bg: #1a1a2e; + --code-text: #00d4aa; } -@theme inline { - --color-background: var(--background); - --color-foreground: var(--foreground); - --font-sans: var(--font-geist-sans); - --font-mono: var(--font-geist-mono); +[data-theme="dark"] { + --bg: #0a0e17; + --bg-card: #0f1520; + --bg-hover: #141c2a; + --border: #1e2d3d; + --text: #e2e8f0; + --text-muted: #64748b; + --accent: #00d4aa; + --accent-glow: #00ffcc; + --accent-secondary: #7c6af7; + --tag-bg: #0d2137; + --tag-text: #00d4aa; + --sidebar-bg: #080c14; + --header-bg: rgba(8, 12, 20, 0.95); + --scrollbar: #1e2d3d; + --code-bg: #0d1117; + --code-text: #00d4aa; } -@media (prefers-color-scheme: dark) { - :root { - --background: #0a0a0a; - --foreground: #ededed; - } +* { box-sizing: border-box; margin: 0; padding: 0; } + +html { + font-size: 17px; + font-family: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Consolas', monospace; + background: var(--bg); + color: var(--text); + transition: background 0.2s, color 0.2s; + scroll-behavior: smooth; } -body { - background: var(--background); - color: var(--foreground); - font-family: Arial, Helvetica, sans-serif; +body { min-height: 100vh; background: var(--bg); } + +::-webkit-scrollbar { width: 6px; height: 6px; } +::-webkit-scrollbar-track { background: transparent; } +::-webkit-scrollbar-thumb { background: var(--scrollbar); border-radius: 3px; } + +a { color: var(--accent); text-decoration: none; transition: opacity 0.15s; } +a:hover { opacity: 0.75; } + +.card { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 6px; + padding: 1.25rem; + transition: border-color 0.2s, background 0.2s; } +.card:hover { border-color: var(--accent); } + +.tag { + display: inline-block; + background: var(--tag-bg); + color: var(--tag-text); + font-size: 0.65rem; + padding: 0.15rem 0.5rem; + border-radius: 3px; + font-weight: 700; + letter-spacing: 0.06em; + text-transform: uppercase; +} + +.prose { + line-height: 1.8; + font-size: 0.9rem; +} +.prose h1, .prose h2, .prose h3, .prose h4 { + color: var(--text); + margin-top: 1.75rem; + margin-bottom: 0.75rem; + font-weight: 700; +} +.prose h1 { font-size: 1.5rem; border-bottom: 1px solid var(--border); padding-bottom: 0.5rem; } +.prose h2 { font-size: 1.15rem; color: var(--accent); } +.prose h3 { font-size: 1rem; } +.prose p { margin-bottom: 1rem; } +.prose ul, .prose ol { margin: 0.75rem 0 1rem 1.5rem; } +.prose li { margin-bottom: 0.3rem; } +.prose code { + background: var(--code-bg); + color: var(--code-text); + padding: 0.1rem 0.35rem; + border-radius: 3px; + font-size: 0.85em; + font-family: inherit; +} +.prose pre { + background: var(--code-bg); + color: var(--code-text); + padding: 1rem 1.25rem; + border-radius: 6px; + overflow-x: auto; + margin: 1rem 0; + border: 1px solid var(--border); + font-size: 0.82rem; + line-height: 1.6; +} +.prose pre code { background: none; padding: 0; } +.prose blockquote { + border-left: 3px solid var(--accent); + padding-left: 1rem; + color: var(--text-muted); + margin: 1rem 0; +} +.prose a { color: var(--accent); } +.prose strong { font-weight: 700; } +.prose hr { border: none; border-top: 1px solid var(--border); margin: 2rem 0; } +.prose table { width: 100%; border-collapse: collapse; margin: 1rem 0; font-size: 0.88rem; } +.prose th { background: var(--bg-card); border: 1px solid var(--border); padding: 0.5rem 0.75rem; text-align: left; color: var(--accent); } +.prose td { border: 1px solid var(--border); padding: 0.5rem 0.75rem; } + +.page-title { + font-size: 1.4rem; + font-weight: 700; + color: var(--accent); + display: flex; + align-items: center; + gap: 0.4rem; + margin-bottom: 0.2rem; +} +.page-title::before { content: '//'; opacity: 0.35; font-weight: 400; } + +.section-header { + font-size: 0.72rem; + font-weight: 700; + letter-spacing: 0.1em; + text-transform: uppercase; + color: var(--text-muted); + margin-bottom: 0.5rem; + padding-bottom: 0.35rem; + border-bottom: 1px solid var(--border); +} + +.blink { animation: blink 1s step-end infinite; } +@keyframes blink { 50% { opacity: 0; } } + +.terminal-line { + display: flex; + align-items: flex-start; + gap: 0.5rem; + font-size: 0.85rem; + padding: 0.3rem 0; + border-bottom: 1px solid var(--border); + color: var(--text-muted); +} +.terminal-line:last-child { border-bottom: none; } +.terminal-line .prompt { color: var(--accent); flex-shrink: 0; } diff --git a/app/hakkimda/page.tsx b/app/hakkimda/page.tsx new file mode 100644 index 0000000..30c1ca7 --- /dev/null +++ b/app/hakkimda/page.tsx @@ -0,0 +1,66 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { title: "Hakkımda" }; + +export default function HakkimdaPage() { + return ( +
+
Hakkımda
+

+ Kim olduğum hakkında kısa bilgi +

+ +
+
+
+ 🦈 +
+
+
Deniz Bektaş
+
Siber Güvenlik Araştırmacısı
+
+
+ +
+

+ Merhaba, ben Deniz Bektaş. Siber güvenlik alanında uzmanlaşmış, özellikle offensive security + ve red team operasyonlarına odaklanan bir araştırmacıyım. +

+

+ Sistemlerin güvenlik açıklarını bulmak, istismar etmek ve raporlamak benim işim. + Ama daha önemlisi: bunları anlayarak daha güvenli sistemler inşa etmeye katkı sağlamak. +

+ +

Uzmanlık Alanları

+
    +
  • Red Team Operasyonları
  • +
  • Web Application Penetration Testing
  • +
  • Network Security Assessment
  • +
  • OSINT & Reconnaissance
  • +
  • Malware Analysis (Statik/Dinamik)
  • +
  • CTF (Capture The Flag)
  • +
+ +

Sertifikalar & Eğitim

+
    +
  • OSCP (Hedef — 2026)
  • +
  • eJPT — eLearnSecurity
  • +
  • TryHackMe Top %1
  • +
+ +

Araçlar

+

+ Kali Linux, Burp Suite, Nmap, Metasploit, Cobalt Strike (lab), Ghidra, Wireshark... + Detaylar için{" "} + Takım Çantam sayfasına bakabilirsin. +

+ +

Dışında

+

+ Kod yazmak, kitap okumak, müzik dinlemek (darksynth, industrial), kafein tüketmek. +

+
+
+
+ ); +} diff --git a/app/hobilerim/page.tsx b/app/hobilerim/page.tsx new file mode 100644 index 0000000..66e9e2b --- /dev/null +++ b/app/hobilerim/page.tsx @@ -0,0 +1,74 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { title: "Hobilerim" }; + +const hobbies = [ + { + name: "CTF (Capture The Flag)", + icon: "◆", + desc: "CTF yarışmaları benim için hem öğrenme hem de eğlence. Kriptografi, binary exploitation, web, OSINT kategorilerinde oynuyorum.", + tags: ["pwn", "crypto", "web", "osint"], + }, + { + name: "Müzik Dinleme", + icon: "◉", + desc: "Darksynth, industrial, dark ambient ve black metal. Çalışırken müzik şart.", + tags: ["darksynth", "industrial", "metal"], + }, + { + name: "Kitap Okuma", + icon: "▤", + desc: "Teknik kitaplar, felsefe ve distopik roman. Son okuduğum: Neuromancer.", + tags: ["fiction", "philosophy", "technical"], + }, + { + name: "Araç Geliştirme", + icon: "◈", + desc: "Açık kaynak güvenlik araçları geliştirmek. Python ve Rust ile kendi toollarımı yazıyorum.", + tags: ["python", "rust", "open-source"], + }, + { + name: "Elektronik & Donanım", + icon: "⊡", + desc: "Flipper Zero, Raspberry Pi, Arduino ile oynamak. RF sinyalleri, protokol analizi.", + tags: ["hardware", "RF", "embedded"], + }, + { + name: "Fotoğrafçılık", + icon: "◎", + desc: "Özellikle urban exploration ve siyah-beyaz fotoğrafçılık. Dijital değil, analog film.", + tags: ["film", "analog", "urbex"], + }, + { + name: "Yürüyüş & Doğa", + icon: "◇", + desc: "Ekrandan uzaklaşmak için en iyi şey. Orman yürüyüşleri, mümkün olduğunda kamp.", + tags: ["hiking", "nature", "camping"], + }, +]; + +export default function HobilerimPage() { + return ( +
+
Hobilerim
+

+ İş dışında neler yapıyorum +

+ +
+ {hobbies.map((h) => ( +
+
+ {h.icon} +

{h.name}

+
+

{h.desc}

+
+ {h.tags.map((t) => {t})} +
+
+ ))} +
+
+ ); +} diff --git a/app/humans.txt/route.ts b/app/humans.txt/route.ts new file mode 100644 index 0000000..6a4c19b --- /dev/null +++ b/app/humans.txt/route.ts @@ -0,0 +1,36 @@ +import { NextResponse } from "next/server"; + +export async function GET() { + const content = `/* TEAM */ +Developer / Writer: Deniz Bektaş +Contact: info@denizbektas.com.tr +Mastodon: @denizbektas@mastadon.org +Location: Türkiye + +/* THANKS */ +Next.js team +Vercel +The open source community +Everyone who taught me something + +/* SITE */ +Last update: 2026/04/03 +Language: Turkish / English +Doctype: HTML5 +IDE: Neovim +Standards: CSS3, JavaScript ES2024 +Components: React, Next.js +Software: Cachy OS, Parrot OS, macOS + +/* FOR HUMANS */ +This site was built by a human, for humans. +No AI-generated content. No dark patterns. +Just someone sharing their journey. + +humanstxt.org +`; + + return new NextResponse(content, { + headers: { "Content-Type": "text/plain; charset=utf-8" }, + }); +} diff --git a/app/iletisim/page.tsx b/app/iletisim/page.tsx new file mode 100644 index 0000000..6cf5ab6 --- /dev/null +++ b/app/iletisim/page.tsx @@ -0,0 +1,69 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { title: "İletişim" }; + +const socials = [ + { name: "E-Mail", value: "info@denizbektas.com.tr", href: "mailto:info@denizbektas.com.tr", icon: "✉", desc: "Genel iletişim için" }, + { name: "Mastodon", value: "@denizbektas@infosec.exchange", href: "https://infosec.exchange/@denizbektas", icon: "⊕", desc: "Günlük paylaşımlar" }, + { name: "GitHub", value: "github.com/bugresearch", href: "https://github.com/bugresearch", icon: "◈", desc: "Açık kaynak projeler" }, + { name: "LinkedIn", value: "linkedin.com/in/denizbektas", href: "https://linkedin.com/in/denizbektas", icon: "▤", desc: "Profesyonel ağ" }, + { name: "PGP Key", value: "public.pgp", href: "/public.pgp", icon: "⊘", desc: "Şifreli iletişim için" }, +]; + +export default function IletisimPage() { + return ( +
+
İletişim
+

+ Ulaşabileceğiniz kanallar — iletişim formu yok, doğrudan iletişim var +

+ + + +
+

PGP ile Şifreli İletişim

+

+ Hassas konular için PGP ile şifrelenmiş mesaj gönderebilirsiniz. + Public key'im burada. +

+
+{`gpg --fetch-keys https://denizbektas.com.tr/public.pgp
+gpg --encrypt -r info@denizbektas.com.tr mesaj.txt`}
+        
+ +

Ne Zaman Yanıt Veririm?

+

+ Genellikle 24-48 saat içinde yanıt veriyorum. Reklam, iş birliği teklifi veya + spam içerikli mesajlara yanıt vermiyorum. +

+ +

Responsible Disclosure

+

+ Bir güvenlik açığı bildirmek istiyorsanız lütfen{" "} + /security.txt dosyasını inceleyin. +

+
+
+ ); +} diff --git a/app/infosec/[slug]/page.tsx b/app/infosec/[slug]/page.tsx new file mode 100644 index 0000000..8b6ed7e --- /dev/null +++ b/app/infosec/[slug]/page.tsx @@ -0,0 +1,54 @@ +import type { Metadata } from "next"; +import Link from "next/link"; +import { getPost, getPosts } from "@/lib/posts"; +import { notFound } from "next/navigation"; + +export async function generateStaticParams() { + return getPosts("infosec").map((p) => ({ slug: p.slug })); +} + +export async function generateMetadata({ params }: { params: Promise<{ slug: string }> }): Promise { + const { slug } = await params; + const post = await getPost("infosec", slug); + if (!post) return {}; + return { title: post.title, description: post.excerpt }; +} + +export default async function InfosecPostPage({ params }: { params: Promise<{ slug: string }> }) { + const { slug } = await params; + const post = await getPost("infosec", slug); + if (!post) notFound(); + + return ( +
+ + ← Infosec'e Dön + + +
+
+
+ + infosec +
+

+ {post.title} +

+
+ + {new Date(post.date).toLocaleDateString("tr-TR", { year: "numeric", month: "long", day: "numeric" })} + +
+ {post.tags.map((t) => {t})} +
+
+
+ ⚠ Bu içerik yalnızca eğitim amaçlıdır. Sadece yetkili sistemlerde test yapın. +
+
+ +
+
+
+ ); +} diff --git a/app/infosec/page.tsx b/app/infosec/page.tsx new file mode 100644 index 0000000..512b7c2 --- /dev/null +++ b/app/infosec/page.tsx @@ -0,0 +1,48 @@ +import type { Metadata } from "next"; +import Link from "next/link"; +import { getPosts } from "@/lib/posts"; + +export const metadata: Metadata = { title: "Infosec Posts" }; + +export default function InfosecPage() { + const posts = getPosts("infosec"); + + return ( +
+
Infosec Posts
+

+ Teknik güvenlik yazıları, tool analizleri, CTF writeupları +

+ + {posts.length === 0 ? ( +
Henüz yazı yok.
+ ) : ( +
+ {posts.map((post) => ( +
+
+ + +

+ {post.title} +

+ +
+

+ {post.excerpt} +

+
+
+ {post.tags.map((t) => {t})} +
+ + {new Date(post.date).toLocaleDateString("tr-TR", { year: "numeric", month: "long", day: "numeric" })} + +
+
+ ))} +
+ )} +
+ ); +} diff --git a/app/kullanim-kosullari/page.tsx b/app/kullanim-kosullari/page.tsx new file mode 100644 index 0000000..84ffadf --- /dev/null +++ b/app/kullanim-kosullari/page.tsx @@ -0,0 +1,60 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { title: "Kullanım Koşulları" }; + +export default function KullanimKosullariPage() { + return ( +
+
Kullanım Koşulları
+

+ Son güncelleme: 3 Nisan 2026 +

+ +
+

İçerik Kullanımı

+

+ Bu sitedeki tüm içerikler CC BY-NC-SA 4.0 lisansı altındadır. + Yani: +

+
    +
  • Atıf vererek paylaşabilirsiniz
  • +
  • Ticari amaçla kullanamazsınız
  • +
  • Değiştirdiğinizde aynı lisansla paylaşmalısınız
  • +
+ +

Teknik İçerik

+

+ Sitedeki teknik güvenlik içerikleri yalnızca eğitim amaçlıdır. + Bu bilgileri yetkisiz sistemlerde kullanmak yasadışıdır. Yazar, içeriklerin + kötüye kullanımından sorumlu tutulamaz. +

+ +

Disclaimer

+

+ Bu sitedeki tüm görüşler yalnızca yazara aittir. Herhangi bir kuruluşu + temsil etmemektedir. +

+

+ İçerikler "olduğu gibi" sunulmaktadır. Hata içerebilir. Doğrulamak + okuyucunun sorumluluğundadır. +

+ +

Linkler

+

+ Dış bağlantıların içeriğinden sorumlu değilim. Bir bağlantı bir onay anlamına gelmez. +

+ +

Değişiklikler

+

+ Bu koşullar herhangi bir bildirim yapılmaksızın değiştirilebilir. + Son güncelleme tarihini takip edin. +

+ +

İletişim

+

+ info@denizbektas.com.tr +

+
+
+ ); +} diff --git a/app/layout.tsx b/app/layout.tsx index 976eb90..a85e637 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,33 +1,82 @@ import type { Metadata } from "next"; -import { Geist, Geist_Mono } from "next/font/google"; import "./globals.css"; - -const geistSans = Geist({ - variable: "--font-geist-sans", - subsets: ["latin"], -}); - -const geistMono = Geist_Mono({ - variable: "--font-geist-mono", - subsets: ["latin"], -}); +import { ThemeProvider } from "@/components/ThemeProvider"; +import Navigation from "@/components/Navigation"; export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", + title: { + default: "Deniz Bektaş | Application Security Engineer", + template: "%s | Deniz Bektaş", + }, + description: "Siber güvenlik uzmanı, red teamer ve araştırmacı.", + keywords: ["deniz bektas", "siber güvenlik", "red team", "infosec", "penetration testing", "bugresearch"], + authors: [{ name: "Deniz Bektaş" }], + openGraph: { + type: "website", + locale: "tr_TR", + siteName: "denizbektas.com.tr", + }, }; export default function RootLayout({ children, -}: Readonly<{ +}: { children: React.ReactNode; -}>) { +}) { return ( - - {children} + + + + + + + + +
+ +
+ {children} +
+
+
+ + ); } diff --git a/app/mastodon/page.tsx b/app/mastodon/page.tsx new file mode 100644 index 0000000..a48a3df --- /dev/null +++ b/app/mastodon/page.tsx @@ -0,0 +1,5 @@ +import { redirect } from "next/navigation"; + +export default function MastodonPage() { + redirect("https://infosec.exchange/@denizbektas"); +} diff --git a/app/merhaba/page.tsx b/app/merhaba/page.tsx new file mode 100644 index 0000000..70ed14e --- /dev/null +++ b/app/merhaba/page.tsx @@ -0,0 +1,57 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { title: "Merhaba" }; + +export default function MerhabaPage() { + return ( +
+
Merhaba
+

+ Bu sitenin amacını anlatan sayfa +

+ +
+

Neden bu site?

+

+ İnternette bir köşem olsun istedim. Sosyal medyanın gürültüsünden uzak, kendi sesimle + yazdığım, düşündüğüm ve öğrendiklerimi paylaştığım bir alan. +

+

+ denizbektas.com.tr benim dijital bahçem. Burada blog yazıları, teknik infosec içerikleri, + kısa notlar, projeler ve daha fazlasını bulacaksınız. +

+ +

Kim için?

+

+ Öncelikle kendim için. Bir şeyi yazmak, onu anlamaktır. Ama aynı zamanda: +

+
    +
  • Siber güvenliğe meraklı olanlar için
  • +
  • Red team / pentest yolculuğunda olanlar için
  • +
  • Türkçe teknik içerik arayanlar için
  • +
  • İnternet üzerinde kendi sesini bulmaya çalışanlar için
  • +
+ +

Ne bulacaksınız?

+
    +
  • Personal Blog — Kişisel yazılar, kariyer notları, düşünceler
  • +
  • Infosec Posts — Teknik güvenlik yazıları, tool analizleri, CTF writeupları
  • +
  • Notebook — Anlık notlar, linkler, kısa düşünceler
  • +
  • Seyir Defteri — Hedefler ve ilerleme durumu
  • +
  • Roadmap — Red teamer olmak isteyenler için rehber
  • +
+ +

İletişim

+

+ Benimle konuşmak istersen info@denizbektas.com.tr adresine + yazabilir ya da Mastodon'da bulabilirsin. PGP anahtarım{" "} + burada. +

+ +
+ "The internet is for people who use it, not for people who just consume it." +
+
+
+ ); +} diff --git a/app/misyon/page.tsx b/app/misyon/page.tsx new file mode 100644 index 0000000..3b5f33d --- /dev/null +++ b/app/misyon/page.tsx @@ -0,0 +1,49 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { title: "Misyon" }; + +export default function MisyonPage() { + return ( +
+
Misyon
+

+ Neden yapıyorum, ne yapıyorum +

+ +
+

Neden?

+

+ Siber güvenlik sadece teknik bir alan değil. Sistemleri anlama, onları koruma ve + dijital dünyayı daha güvenli hale getirme misyonu. Bu misyon beni her sabah + bilgisayar başına getiriyor. +

+ +

Ne Yapıyorum?

+

+ Saldırgan bakış açısıyla sistemleri test ediyorum. Red team operasyonları, penetrasyon + testleri, güvenlik değerlendirmeleri... Amacım açıkları bulmak — savunmadan önce. +

+ +

Bu Sitenin Misyonu

+
    +
  • Belgelemek: Öğrendiklerimi kayıt altına almak
  • +
  • Paylaşmak: Türkçe teknik içerik üretmek
  • +
  • İlham vermek: Bu alana girmek isteyenlere yol göstermek
  • +
  • Şeffaf olmak: Yolculuğumu, başarıları ve başarısızlıkları ile açık paylaşmak
  • +
+ +

Değerler

+
    +
  • Etik: Sadece izinli sistemlerde çalışıyorum. Kötü niyetli aktörlere karşıyım.
  • +
  • Açık kaynak: Topluluğa geri vermek önemli
  • +
  • Sürekli öğrenme: Bu alan durmadan değişiyor; ben de duruyorum
  • +
  • Kalite: Az ama öz içerik
  • +
+ +
+ "Hack the planet — but with ethics." +
+
+
+ ); +} diff --git a/app/notebook/[slug]/page.tsx b/app/notebook/[slug]/page.tsx new file mode 100644 index 0000000..bbcb461 --- /dev/null +++ b/app/notebook/[slug]/page.tsx @@ -0,0 +1,44 @@ +import type { Metadata } from "next"; +import Link from "next/link"; +import { getPost, getPosts } from "@/lib/posts"; +import { notFound } from "next/navigation"; + +export async function generateStaticParams() { + return getPosts("notebook").map((p) => ({ slug: p.slug })); +} + +export async function generateMetadata({ params }: { params: Promise<{ slug: string }> }): Promise { + const { slug } = await params; + const post = await getPost("notebook", slug); + if (!post) return {}; + return { title: post.title, description: post.excerpt }; +} + +export default async function NotebookPostPage({ params }: { params: Promise<{ slug: string }> }) { + const { slug } = await params; + const post = await getPost("notebook", slug); + if (!post) notFound(); + + return ( +
+ + ← Notebook'a Dön + + +
+
+

+ {post.title} +

+
+ + {new Date(post.date).toLocaleDateString("tr-TR", { year: "numeric", month: "long", day: "numeric" })} + + {post.tags.map((t) => {t})} +
+
+
+
+
+ ); +} diff --git a/app/notebook/page.tsx b/app/notebook/page.tsx new file mode 100644 index 0000000..e801842 --- /dev/null +++ b/app/notebook/page.tsx @@ -0,0 +1,47 @@ +import type { Metadata } from "next"; +import Link from "next/link"; +import { getPosts } from "@/lib/posts"; + +export const metadata: Metadata = { title: "Notebook" }; + +export default function NotebookPage() { + const posts = getPosts("notebook"); + + return ( +
+
Notebook
+

+ Anlık düşünceler, kısa notlar — twitter'ın sessiz versiyonu +

+ + {posts.length === 0 ? ( +
Henüz not yok.
+ ) : ( +
+ {posts.map((post) => ( +
+
+ +

+ {post.title} +

+ + + {new Date(post.date).toLocaleDateString("tr-TR", { month: "short", day: "numeric" })} + +
+

+ {post.excerpt} +

+ {post.tags.length > 0 && ( +
+ {post.tags.map((t) => {t})} +
+ )} +
+ ))} +
+ )} +
+ ); +} diff --git a/app/ozgecmis/page.tsx b/app/ozgecmis/page.tsx new file mode 100644 index 0000000..5a34fde --- /dev/null +++ b/app/ozgecmis/page.tsx @@ -0,0 +1,149 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { title: "Özgeçmiş" }; + +export default function OzgecmisPage() { + return ( +
+
Özgeçmiş
+

+ CV formatında özgeçmiş +

+ + {/* Header */} +
+
+
+

denizbektas

+
Siber Güvenlik Araştırmacısı & Red Teamer
+
+ ✉ info@denizbektas.com.tr + ⊕ @denizbektas@infosec.exchange + ◈ github.com/bugresearch +
+
+ PGP KEY +
+
+ + {/* Experience */} +
+ + +
+ + {/* Education */} +
+ +
+ + {/* Certifications */} +
+
+ {[ + { name: "eJPT", org: "eLearnSecurity", year: "2022", status: "active" }, + { name: "CompTIA Security+", org: "CompTIA", year: "2021", status: "active" }, + { name: "OSCP", org: "OffSec", year: "2026 (hedef)", status: "pending" }, + ].map((cert) => ( +
+
{cert.name}
+
{cert.org} · {cert.year}
+
+ ))} +
+
+ + {/* Skills */} +
+
+ {[ + { cat: "Pentest & Red Team", skills: ["Web App Testing", "Network Pentest", "AD Attack", "Red Team Ops", "Social Engineering"] }, + { cat: "Araçlar", skills: ["Burp Suite", "Nmap", "Metasploit", "BloodHound", "Cobalt Strike", "Ghidra"] }, + { cat: "Programlama", skills: ["Python", "Bash", "PowerShell", "C/C++", "Rust (öğreniyorum)"] }, + { cat: "OS & Platform", skills: ["Kali Linux", "macOS", "Windows", "Active Directory", "Docker"] }, + ].map((row) => ( +
+
{row.cat}
+
+ {row.skills.map((s) => {s})} +
+
+ ))} +
+
+ + {/* Languages */} +
+
+ {[ + { lang: "Türkçe", level: "Ana dil" }, + { lang: "İngilizce", level: "İleri (C1)" }, + ].map((l) => ( +
+ {l.lang} + {l.level} +
+ ))} +
+
+
+ ); +} + +function Section({ title, icon, children }: { title: string; icon: string; children: React.ReactNode }) { + return ( +
+
+ {icon} + {title} +
+ {children} +
+ ); +} + +function CVItem({ title, org, period, items }: { title: string; org: string; period: string; items: string[] }) { + return ( +
+
+
+
{title}
+
{org}
+
+ {period} +
+
    + {items.map((item) => ( +
  • + + {item} +
  • + ))} +
+
+ ); +} diff --git a/app/page.tsx b/app/page.tsx index 3f36f7c..b969c8c 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,65 +1,215 @@ -import Image from "next/image"; +import Link from "next/link"; +import { getPosts } from "@/lib/posts"; +import { getActivity } from "@/lib/activity"; export default function Home() { + const blogPosts = getPosts("blog").slice(0, 3); + const infosecPosts = getPosts("infosec").slice(0, 3); + const notes = getPosts("notebook").slice(0, 3); + const activities = getActivity().slice(0, 5); + return ( -
-
- Next.js logo -
-

- To get started, edit the page.tsx file. -

-

- Looking for a starting point or more instructions? Head over to{" "} - - Templates - {" "} - or the{" "} - - Learning - {" "} - center. -

+
+ {/* Hero */} +
+
+ root@denizbektas.com.tr:~$ + whoami
-
- - Vercel logomark - Deploy Now - - - Documentation - +

+ denizbektas +

+

+ Siber güvenlik araştırmacısı, red teamer, CTF oyuncusu. Sistemlerin nasıl kırıldığını anlayarak + onları nasıl koruyacağımızı öğreniyoruz. Bu site o yolculuğun kayıtlarıdır. +

+
+ red team + pentest + CTF + OSINT + malware analysis
-
+
+ → Merhaba + Hakkımda + İletişim +
+
+ + {/* Grid */} +
+ + {/* Blog Widget */} + + {blogPosts.length === 0 ? ( + + ) : ( +
    + {blogPosts.map((p) => ( +
  • + + {p.title} + + {formatDate(p.date)} +
  • + ))} +
+ )} +
+ + {/* Infosec Widget */} + + {infosecPosts.length === 0 ? ( + + ) : ( +
    + {infosecPosts.map((p) => ( +
  • + + {p.title} + +
    + {p.tags.slice(0, 2).map((t) => {t})} +
    +
  • + ))} +
+ )} +
+ + {/* Notebook Widget */} + + {notes.length === 0 ? ( + + ) : ( +
    + {notes.map((p) => ( +
  • + + {p.title} + +
    + {p.excerpt.slice(0, 60)}... +
  • + ))} +
+ )} +
+ + {/* Activity Widget */} + +
    + {activities.map((a) => ( +
  • + + {typeIcon(a.type)} + + + {a.link ? {a.message} : a.message} + +
  • + ))} +
+
+ + {/* Now Widget */} + +
+

🔴 Odak: Red team metodolojileri

+

📖 Okuma: The Hacker Playbook 3

+

🎯 Hedef: OSCP sertifikası

+

🎵 Dinleme: Darksynth

+
+
+ + {/* RSS Widget */} + +
+ {[ + { label: "Tüm İçerikler", href: "/api/rss/all" }, + { label: "Blog", href: "/api/rss/blog" }, + { label: "Infosec", href: "/api/rss/infosec" }, + { label: "Podcast", href: "/api/rss/podcast" }, + ].map((r) => ( + + + {r.label} + + ))} +
+
+ + {/* Statboard Widget */} + +
+ {[ + { label: "Blog Yazısı", value: "1" }, + { label: "Infosec Yazı", value: "1" }, + { label: "CTF Çözümü", value: "47" }, + { label: "Çay ☕", value: "∞" }, + ].map((s) => ( +
+
{s.value}
+
{s.label}
+
+ ))} +
+
+ + {/* Projeler Widget */} + +
+ + + +
+
+ +
); } + +function WidgetCard({ title, href, icon, children }: { title: string; href: string; icon: string; children: React.ReactNode }) { + return ( +
+
+
+ {icon} + {title} +
+ tümü → +
+ {children} +
+ ); +} + +function EmptyState({ text }: { text: string }) { + return
{text}
; +} + +function ProjectItem({ name, desc, status }: { name: string; desc: string; status: string }) { + const colors: Record = { active: "#00d4aa", wip: "#f59e0b", archived: "#64748b" }; + return ( +
+ +
+
{name}
+
{desc}
+
+
+ ); +} + +function typeIcon(type: string) { + const icons: Record = { + post: "✍", notebook: "◎", infosec: "⚔", project: "◈", link: "⊞", update: "▲", system: "⚙", + }; + return icons[type] || "▶"; +} + +function formatDate(date: string) { + return new Date(date).toLocaleDateString("tr-TR", { year: "numeric", month: "short", day: "numeric" }); +} diff --git a/app/podcast/page.tsx b/app/podcast/page.tsx new file mode 100644 index 0000000..10cdb74 --- /dev/null +++ b/app/podcast/page.tsx @@ -0,0 +1,80 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { title: "Podcast" }; + +export default function PodcastPage() { + return ( +
+
Podcast
+

+ Türkçe siber güvenlik podcast'i +

+ +
+
+
+ ◉ +
+
+
Deniz Bektaş Podcast
+
Siber güvenlik, red team ve hacker kültürü
+
+
+ +
+

+ 🚧 Yakında başlıyor. Türkçe teknik siber güvenlik podcast'i. + Konular: red team hikayeleri, tool analizleri, kariyer tavsiyeleri, sektör haberleri. +

+
+ +
+ yakında + türkçe + infosec + red team +
+
+ +
+
Takip Kanalları
+
+ {[ + { name: "RSS Beslemesi", href: "/api/rss/podcast", icon: "⊞", desc: "Doğrudan RSS ile takip" }, + { name: "Spotify", href: "#", icon: "◉", desc: "Spotify Podcasts — yakında" }, + { name: "Apple Podcasts", href: "#", icon: "◉", desc: "Apple Podcasts — yakında" }, + { name: "YouTube", href: "#", icon: "▶", desc: "Video formatı — yakında" }, + ].map((c) => ( + + {c.icon} +
+
{c.name}
+
{c.desc}
+
+
+ ))} +
+
+ +
+

Format

+
    +
  • Dil: Türkçe
  • +
  • Süre: 30-60 dakika
  • +
  • Sıklık: İki haftada bir
  • +
  • Format: Tekli bölüm + zaman zaman konuk
  • +
+ +

Konu Planı

+
    +
  • Red team operasyonları — sahadan hikayeler
  • +
  • CTF yarışmaları — nasıl katılırsınız, nasıl öğrenirsiniz
  • +
  • Güvenlik sertifikaları — gerçekten değer mi?
  • +
  • OSCP yolculuğu
  • +
  • Kariyer tavsiyeleri — siber güvenliğe nasıl girilir
  • +
  • Sektör haberleri ve büyük olayların analizi
  • +
+
+
+ ); +} diff --git a/app/projeler/page.tsx b/app/projeler/page.tsx new file mode 100644 index 0000000..9248b7a --- /dev/null +++ b/app/projeler/page.tsx @@ -0,0 +1,123 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { title: "Projeler" }; + +interface Project { + name: string; + description: string; + status: "active" | "wip" | "archived" | "planned"; + tags: string[]; + url?: string; + github?: string; +} + +const projects: Project[] = [ + { + name: "denizbektas.com.tr", + description: "Bu site. Next.js, TypeScript, Markdown tabanlı kişisel alan. Açık kaynak.", + status: "active", + tags: ["nextjs", "typescript", "website"], + github: "https://github.com/bugresearch/denizbektas.com.tr", + }, + { + name: "recon-toolkit", + description: "Python ile geliştirilmiş modüler recon otomasyon aracı. Subdomain enumeration, port scan, tech fingerprinting.", + status: "wip", + tags: ["python", "recon", "osint", "automation"], + github: "https://github.com/bugresearch/recon-toolkit", + }, + { + name: "ctf-writeups", + description: "HackTheBox ve çeşitli CTF yarışmalarından çözüm yazıları koleksiyonu.", + status: "active", + tags: ["ctf", "writeup", "hactkthebox"], + github: "https://github.com/bugresearch/ctf-writeups", + }, + { + name: "nuclei-templates", + description: "Özel Nuclei tarama şablonları. Web uygulamaları için özelleştirilmiş güvenlik testleri.", + status: "active", + tags: ["nuclei", "pentest", "templates"], + github: "https://github.com/bugresearch/nuclei-templates", + }, + { + name: "implant-rs", + description: "Rust ile yazılan minimal C2 implant — eğitim ve araştırma amaçlı.", + status: "wip", + tags: ["rust", "c2", "red-team", "research"], + }, + { + name: "wordlist-tr", + description: "Türkçe hedef sistemler için özelleştirilmiş wordlist koleksiyonu.", + status: "planned", + tags: ["wordlist", "pentest", "turkish"], + }, +]; + +const statusConfig = { + active: { label: "Aktif", color: "#00d4aa", icon: "●" }, + wip: { label: "Yapım Aşamasında", color: "#f59e0b", icon: "◉" }, + archived: { label: "Arşivlendi", color: "#64748b", icon: "◎" }, + planned: { label: "Planlandı", color: "#7c6af7", icon: "◇" }, +}; + +export default function ProjelerPage() { + return ( +
+
Projeler
+

+ Üzerinde çalıştığım ve geliştirdiğim projeler +

+ +
+ {projects.map((p) => { + const cfg = statusConfig[p.status]; + return ( +
+
+

{p.name}

+ + {cfg.icon} + {cfg.label} + +
+ +

+ {p.description} +

+ +
+ {p.tags.map((t) => {t})} +
+ +
+ {p.github && ( + + GitHub + + )} + {p.url && ( + + Demo + + )} +
+
+ ); + })} +
+
+ ); +} diff --git a/app/public.pgp/route.ts b/app/public.pgp/route.ts new file mode 100644 index 0000000..084b70b --- /dev/null +++ b/app/public.pgp/route.ts @@ -0,0 +1,14 @@ +import { NextResponse } from "next/server"; + +export async function GET() { + // Replace with your actual PGP public key + const pgpKey = `-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBGX... (replace with your actual PGP public key) +-----END PGP PUBLIC KEY BLOCK----- +`; + + return new NextResponse(pgpKey, { + headers: { "Content-Type": "text/plain; charset=utf-8" }, + }); +} diff --git a/app/roadmap/page.tsx b/app/roadmap/page.tsx new file mode 100644 index 0000000..631a5ed --- /dev/null +++ b/app/roadmap/page.tsx @@ -0,0 +1,231 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { title: "Red Teamer Roadmap" }; + +interface RoadmapItem { + title: string; + description: string; + resources: { name: string; url?: string }[]; + level: "beginner" | "intermediate" | "advanced"; +} + +interface Phase { + phase: number; + title: string; + subtitle: string; + duration: string; + items: RoadmapItem[]; +} + +const phases: Phase[] = [ + { + phase: 1, + title: "Temel Kavramlar", + subtitle: "Foundation", + duration: "1-3 ay", + items: [ + { + title: "Ağ Temelleri", + description: "TCP/IP, OSI modeli, DNS, HTTP/S, temel protokoller", + resources: [ + { name: "TryHackMe — Pre-Security path" }, + { name: "Professor Messer Network+", url: "https://www.professormesser.com" }, + { name: "Practical Networking", url: "https://www.practicalnetworking.net" }, + ], + level: "beginner", + }, + { + title: "Linux Temelleri", + description: "Komut satırı, dosya sistemi, izinler, scripting", + resources: [ + { name: "OverTheWire: Bandit", url: "https://overthewire.org/wargames/bandit" }, + { name: "TryHackMe — Linux Fundamentals" }, + { name: "The Linux Command Line (kitap)" }, + ], + level: "beginner", + }, + { + title: "Python ile Scripting", + description: "Temel Python, otomasyon, araç geliştirme", + resources: [ + { name: "Automate the Boring Stuff with Python", url: "https://automatetheboringstuff.com" }, + { name: "Violent Python (kitap)" }, + ], + level: "beginner", + }, + ], + }, + { + phase: 2, + title: "Güvenlik Temelleri", + subtitle: "Security Basics", + duration: "2-4 ay", + items: [ + { + title: "Web Uygulama Güvenliği", + description: "OWASP Top 10, SQL injection, XSS, CSRF, authentication bypass", + resources: [ + { name: "PortSwigger Web Academy", url: "https://portswigger.net/web-security" }, + { name: "OWASP WebGoat", url: "https://owasp.org/www-project-webgoat" }, + { name: "The Web Application Hacker's Handbook" }, + ], + level: "intermediate", + }, + { + title: "Pentest Temelleri", + description: "Metodoloji, keşif, tarama, exploitation, raporlama", + resources: [ + { name: "TryHackMe — Jr Penetration Tester path" }, + { name: "eJPT (eLearnSecurity)" }, + { name: "Penetration Testing (Georgia Weidman)" }, + ], + level: "intermediate", + }, + { + title: "Kriptografi Temelleri", + description: "Şifreleme algoritmaları, hash fonksiyonları, PKI", + resources: [ + { name: "CryptoHack", url: "https://cryptohack.org" }, + { name: "Cryptopals Challenges", url: "https://cryptopals.com" }, + ], + level: "intermediate", + }, + ], + }, + { + phase: 3, + title: "Offensive Security", + subtitle: "Going Deeper", + duration: "3-6 ay", + items: [ + { + title: "Active Directory Saldırıları", + description: "Kerberoasting, Pass-the-Hash, DCSync, BloodHound, lateral movement", + resources: [ + { name: "HackTheBox — AD machines" }, + { name: "Red Team Notes — AD", url: "https://www.ired.team" }, + { name: "Impacket tools" }, + ], + level: "advanced", + }, + { + title: "OSCP Hazırlığı", + description: "Buffer overflow, privilege escalation, pivoting, tunneling", + resources: [ + { name: "OffSec PEN-200 course" }, + { name: "HackTheBox — OSCP-like machines" }, + { name: "The Hacker Playbook 3" }, + ], + level: "advanced", + }, + { + title: "Malware Analizi", + description: "Statik ve dinamik analiz, reverse engineering, sandbox", + resources: [ + { name: "Malware Traffic Analysis", url: "https://malware-traffic-analysis.net" }, + { name: "Ghidra kullanımı" }, + { name: "Practical Malware Analysis (kitap)" }, + ], + level: "advanced", + }, + ], + }, + { + phase: 4, + title: "Red Team Operasyonları", + subtitle: "Professional Level", + duration: "Süregelen", + items: [ + { + title: "C2 Framework & İmplant Geliştirme", + description: "Cobalt Strike, Havoc, Sliver — C2 mimarisi ve özel implant yazımı", + resources: [ + { name: "Red Team Development and Operations (kitap)" }, + { name: "Sektor7 courses", url: "https://institute.sektor7.net" }, + { name: "VX Underground malware samples" }, + ], + level: "advanced", + }, + { + title: "Physical & Social Engineering", + description: "Fiziksel saldırılar, phishing kampanyaları, vishing", + resources: [ + { name: "The Art of Intrusion (kitap)" }, + { name: "Hacking: The Art of Exploitation" }, + ], + level: "advanced", + }, + ], + }, +]; + +const levelColors = { beginner: "#22c55e", intermediate: "#f59e0b", advanced: "#ef4444" }; +const phaseColors = ["#00d4aa", "#7c6af7", "#f59e0b", "#ef4444"]; + +export default function RoadmapPage() { + return ( +
+
Red Teamer Roadmap
+

+ Red teamer olmak isteyenler için kişisel rehberim +

+
+ ⚠ Bu yalnızca benim izlediğim yol. Herkes farklı öğrenir. Ayrıca: her zaman etik ve yasal sınırlar içinde kalın. +
+ +
+ {phases.map((phase, pi) => ( +
+ {/* Phase Header */} +
+
+ {phase.phase} +
+
+
{phase.title}
+
{phase.subtitle} · {phase.duration}
+
+
+ +
+ {phase.items.map((item) => ( +
+
+

{item.title}

+ + {item.level} + +
+

{item.description}

+
+
Kaynaklar
+
    + {item.resources.map((r) => ( +
  • + + {r.url ? ( + {r.name} + ) : ( + {r.name} + )} +
  • + ))} +
+
+
+ ))} +
+
+ ))} +
+
+ ); +} diff --git a/app/robots.txt/route.ts b/app/robots.txt/route.ts new file mode 100644 index 0000000..cd52e9c --- /dev/null +++ b/app/robots.txt/route.ts @@ -0,0 +1,18 @@ +import { NextResponse } from "next/server"; + +export async function GET() { + const content = `User-agent: * +Allow: / + +Disallow: /api/ + +Sitemap: https://denizbektas.com.tr/sitemap.xml + +# Hi! If you're a human reading this, check out /humans.txt +# If you're a security researcher, check out /security.txt +`; + + return new NextResponse(content, { + headers: { "Content-Type": "text/plain; charset=utf-8" }, + }); +} diff --git a/app/rss-beslemeleri/page.tsx b/app/rss-beslemeleri/page.tsx new file mode 100644 index 0000000..07527c4 --- /dev/null +++ b/app/rss-beslemeleri/page.tsx @@ -0,0 +1,116 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { title: "RSS Beslemeleri" }; + +const feeds = [ + { + name: "Tüm İçerikler", + url: "/api/rss/all", + desc: "Blog, infosec yazıları ve notebook notlarının tamamı tek beslemede", + icon: "⊞", + }, + { + name: "Personal Blog", + url: "/api/rss/blog", + desc: "Yalnızca kişisel blog yazıları", + icon: "✍", + }, + { + name: "Infosec Posts", + url: "/api/rss/infosec", + desc: "Yalnızca teknik güvenlik yazıları", + icon: "⚔", + }, + { + name: "Podcast", + url: "/api/rss/podcast", + desc: "Podcast bölümleri — yakında", + icon: "◉", + }, +]; + +export default function RssBeslemeleriPage() { + return ( +
+
RSS Beslemeleri
+

+ İçerikleri RSS ile takip edin — algoritmalar olmadan +

+ + {/* Feed List */} +
+ {feeds.map((feed) => ( +
+
+
+ {feed.icon} +
+
+
{feed.name}
+
{feed.desc}
+
+ + Abone Ol → + +
+
+ ))} +
+ + {/* What is RSS */} +
+

RSS Nedir?

+

+ RSS (Really Simple Syndication), web sitelerinin yeni içeriklerini otomatik olarak + takipçilerine bildirmesini sağlayan bir teknolojidir. 2000'li yılların başında + popülerleşen bu teknoloji, günümüzde hâlâ aktif olarak kullanılmaktadır. +

+ +

Neden RSS?

+
    +
  • Algoritma yok: Hangi içeriği göreceğinizi siz seçersiniz
  • +
  • Reklam yok: Doğrudan içerik, gürültüsüz
  • +
  • Gizlilik: Okuma alışkanlıklarınız üçüncü taraflarla paylaşılmaz
  • +
  • Merkezi değil: Tek platform bağımlılığı yok
  • +
  • Hız: Yeni içerikler anında ulaşır
  • +
+ +

Nasıl Kullanılır?

+

+ Bir RSS okuyucusuna ihtiyacınız var. Önerilen okuyucular: +

+
    +
  • Miniflux — Self-hosted, minimalist, açık kaynak
  • +
  • Feedbin — Bulut tabanlı, güzel arayüz
  • +
  • NetNewsWire — macOS/iOS için ücretsiz
  • +
  • Reeder — iOS/macOS için ücretli ama kaliteli
  • +
+ +

+ RSS okuyucunuzu açın, yukarıdaki feed URL'lerinden birini kopyalayın ve + okuyucunuza ekleyin. Artık yeni içerikler otomatik olarak gelecek. +

+ +

OPML Dosyası

+

+ Tüm beslemeleri tek seferde eklemek için OPML dosyasını indirin: +

+
{`
+  
+    
+      
+      
+      
+    
+  
+`}
+
+
+ ); +} diff --git a/app/security.txt/route.ts b/app/security.txt/route.ts new file mode 100644 index 0000000..ebcd577 --- /dev/null +++ b/app/security.txt/route.ts @@ -0,0 +1,23 @@ +import { NextResponse } from "next/server"; + +export async function GET() { + const content = `Contact: mailto:info@denizbektas.com.tr +Contact: https://infosec.exchange/@denizbektas +Encryption: https://denizbektas.com.tr/public.pgp +Preferred-Languages: tr, en +Canonical: https://denizbektas.com.tr/security.txt + +# Responsible Disclosure Policy +# Please report security vulnerabilities to info@denizbektas.com.tr +# Use PGP encryption for sensitive reports +# We will acknowledge receipt within 48 hours +# We do not offer a bug bounty program at this time +# Please do not disclose publicly before we have addressed the issue + +Expires: 2027-04-03T00:00:00.000Z +`; + + return new NextResponse(content, { + headers: { "Content-Type": "text/plain; charset=utf-8" }, + }); +} diff --git a/app/seyir-defteri/page.tsx b/app/seyir-defteri/page.tsx new file mode 100644 index 0000000..6e66834 --- /dev/null +++ b/app/seyir-defteri/page.tsx @@ -0,0 +1,152 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { title: "Kaptanın Seyir Defteri" }; + +interface Goal { + id: string; + title: string; + description: string; + status: "completed" | "in-progress" | "planned" | "paused"; + progress: number; + category: string; + deadline?: string; + notes?: string; +} + +const goals: Goal[] = [ + { + id: "1", + title: "OSCP Sertifikası", + description: "Offensive Security Certified Professional sınavını geçmek", + status: "in-progress", + progress: 35, + category: "Sertifika", + deadline: "2026-12-31", + notes: "Active Directory modüllerine odaklanılıyor", + }, + { + id: "2", + title: "denizbektas.com.tr Yayına Almak", + description: "Kişisel siteyi oluşturmak ve yayına almak", + status: "completed", + progress: 100, + category: "Proje", + }, + { + id: "3", + title: "50 HTB Makinesi", + description: "HackTheBox'ta 50 makine çözmek", + status: "in-progress", + progress: 47, + category: "Pratik", + }, + { + id: "4", + title: "Podcast Başlatmak", + description: "Türkçe siber güvenlik podcast'i yayınlamak", + status: "planned", + progress: 10, + category: "İçerik", + deadline: "2026-09-01", + }, + { + id: "5", + title: "Red Team Araç Geliştirme", + description: "Kendi C2 implant'ımı yazmak (Rust ile)", + status: "paused", + progress: 15, + category: "Geliştirme", + }, + { + id: "6", + title: "10 Infosec Yazısı", + description: "Kaliteli teknik yazılar yayınlamak", + status: "in-progress", + progress: 10, + category: "İçerik", + }, +]; + +const statusConfig = { + completed: { label: "Tamamlandı", color: "#00d4aa", icon: "✓" }, + "in-progress": { label: "Devam Ediyor", color: "#f59e0b", icon: "◉" }, + planned: { label: "Planlandı", color: "#64748b", icon: "◎" }, + paused: { label: "Durduruldu", color: "#ef4444", icon: "⏸" }, +}; + +export default function SeyirDefteriPage() { + const byCategory = goals.reduce((acc, g) => { + if (!acc[g.category]) acc[g.category] = []; + acc[g.category].push(g); + return acc; + }, {} as Record); + + return ( +
+
Kaptanın Seyir Defteri
+

+ Hedeflerim ve ilerleme durumum +

+ + {/* Summary */} +
+ {(["completed", "in-progress", "planned", "paused"] as const).map((s) => { + const count = goals.filter((g) => g.status === s).length; + const cfg = statusConfig[s]; + return ( +
+
{count}
+
{cfg.label}
+
+ ); + })} +
+ + {/* Goals by category */} + {Object.entries(byCategory).map(([cat, catGoals]) => ( +
+
{cat}
+
+ {catGoals.map((goal) => { + const cfg = statusConfig[goal.status]; + return ( +
+
+
+
+ {cfg.icon} +

{goal.title}

+
+

{goal.description}

+
+ + {cfg.label} + +
+ + {/* Progress bar */} +
+
+ İlerleme + {goal.progress}% +
+
+
+
+
+ + {(goal.deadline || goal.notes) && ( +
+ {goal.deadline && 🗓 {new Date(goal.deadline).toLocaleDateString("tr-TR", { year: "numeric", month: "long" })}} + {goal.notes && 📝 {goal.notes}} +
+ )} +
+ ); + })} +
+
+ ))} +
+ ); +} diff --git a/app/sitemap.xml/route.ts b/app/sitemap.xml/route.ts new file mode 100644 index 0000000..99d42a4 --- /dev/null +++ b/app/sitemap.xml/route.ts @@ -0,0 +1,71 @@ +import { NextResponse } from "next/server"; +import { getAllPosts } from "@/lib/posts"; + +const SITE_URL = "https://denizbektas.com.tr"; + +const staticPages = [ + { url: "/", priority: "1.0", changefreq: "weekly" }, + { url: "/merhaba", priority: "0.8", changefreq: "monthly" }, + { url: "/hakkimda", priority: "0.8", changefreq: "monthly" }, + { url: "/su-anda", priority: "0.7", changefreq: "weekly" }, + { url: "/misyon", priority: "0.6", changefreq: "monthly" }, + { url: "/blog", priority: "0.9", changefreq: "weekly" }, + { url: "/infosec", priority: "0.9", changefreq: "weekly" }, + { url: "/notebook", priority: "0.8", changefreq: "weekly" }, + { url: "/seyir-defteri", priority: "0.7", changefreq: "weekly" }, + { url: "/faydali-linkler", priority: "0.7", changefreq: "monthly" }, + { url: "/roadmap", priority: "0.8", changefreq: "monthly" }, + { url: "/takim-cantam", priority: "0.6", changefreq: "monthly" }, + { url: "/hobilerim", priority: "0.5", changefreq: "monthly" }, + { url: "/fikirlerim", priority: "0.7", changefreq: "monthly" }, + { url: "/projeler", priority: "0.8", changefreq: "monthly" }, + { url: "/podcast", priority: "0.7", changefreq: "weekly" }, + { url: "/iletisim", priority: "0.6", changefreq: "monthly" }, + { url: "/ozgecmis", priority: "0.7", changefreq: "monthly" }, + { url: "/aktivite", priority: "0.6", changefreq: "daily" }, + { url: "/rss-beslemeleri", priority: "0.5", changefreq: "monthly" }, + { url: "/statboard", priority: "0.5", changefreq: "monthly" }, + { url: "/altyapi", priority: "0.5", changefreq: "monthly" }, + { url: "/tesekkurler", priority: "0.4", changefreq: "yearly" }, + { url: "/gizlilik", priority: "0.3", changefreq: "yearly" }, + { url: "/kullanim-kosullari", priority: "0.3", changefreq: "yearly" }, +]; + +export async function GET() { + const posts = getAllPosts(); + const now = new Date().toISOString().split("T")[0]; + + const staticUrls = staticPages + .map( + (p) => ` + + ${SITE_URL}${p.url} + ${now} + ${p.changefreq} + ${p.priority} + ` + ) + .join(""); + + const postUrls = posts + .map( + (p) => ` + + ${SITE_URL}/${p.category}/${p.slug} + ${p.date} + monthly + 0.8 + ` + ) + .join(""); + + const xml = ` + + ${staticUrls} + ${postUrls} +`; + + return new NextResponse(xml, { + headers: { "Content-Type": "application/xml; charset=utf-8", "Cache-Control": "public, max-age=86400" }, + }); +} diff --git a/app/statboard/page.tsx b/app/statboard/page.tsx new file mode 100644 index 0000000..1d11977 --- /dev/null +++ b/app/statboard/page.tsx @@ -0,0 +1,79 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { title: "Statboard" }; + +const stats = [ + { label: "Blog Yazısı", value: "1", icon: "✍", unit: "yazı", desc: "Yayınlanmış blog yazıları" }, + { label: "Infosec Yazısı", value: "1", icon: "⚔", unit: "yazı", desc: "Teknik güvenlik yazıları" }, + { label: "Notebook Notu", value: "1", icon: "◎", unit: "not", desc: "Kısa düşünceler" }, + { label: "HTB Makinesi", value: "47", icon: "◆", unit: "makine", desc: "HackTheBox'ta çözülen makineler" }, + { label: "CTF Çözümü", value: "23", icon: "◈", unit: "flag", desc: "Yakalanan CTF bayrakları" }, + { label: "Satır Kod", value: "12.4k", icon: "▦", unit: "satır", desc: "Bu yıl yazılan kod satırı" }, + { label: "Çay", value: "∞", icon: "☕", unit: "bardak", desc: "Tüketilen çay miktarı" }, + { label: "Kahvesiz Gün", value: "0", icon: "◎", unit: "gün", desc: "Çünkü kahve olmadan olmaz" }, + { label: "Terminal Oturumu", value: "847", icon: "▶", unit: "oturum", desc: "Açılan terminal oturumları" }, + { label: "Git Commit", value: "234", icon: "◇", unit: "commit", desc: "Bu yıl yapılan commit'ler" }, + { label: "Gece Çalışması", value: "67", icon: "◑", unit: "gece", desc: "Gece 00:00 sonrası aktif gün" }, + { label: "VPN Bağlantısı", value: "365", icon: "⊘", unit: "gün", desc: "VPN açık gün sayısı" }, +]; + +const milestones = [ + { date: "2026-04-03", event: "denizbektas.com.tr yayına alındı", icon: "🚀" }, + { date: "2026-03-15", event: "HTB'de 40. makine çözüldü", icon: "◆" }, + { date: "2026-02-01", event: "eJPT sertifikası alındı", icon: "🏆" }, + { date: "2025-12-25", event: "İlk CTF birinciliği", icon: "🥇" }, + { date: "2025-06-10", event: "İlk pentest projesi", icon: "⚔" }, +]; + +export default function StatboardPage() { + return ( +
+
Statboard
+

+ Anlamsız ama eğlenceli istatistikler +

+ + {/* Main stats grid */} +
+ {stats.map((stat) => ( +
+
{stat.icon}
+
{stat.value}
+
{stat.unit}
+
{stat.label}
+
{stat.desc}
+
+ ))} +
+ + {/* Milestones */} +
Kilometre Taşları
+
+
    + {milestones.map((m, i) => ( +
  • + {m.icon} + {m.event} + + {new Date(m.date).toLocaleDateString("tr-TR", { year: "numeric", month: "short", day: "numeric" })} + +
  • + ))} +
+
+ +
+ Veriler elle güncellenmektedir. Kesinlik garantisi verilmez. ¯\_(ツ)_/¯ +
+
+ ); +} diff --git a/app/su-anda/page.tsx b/app/su-anda/page.tsx new file mode 100644 index 0000000..dc5a0e2 --- /dev/null +++ b/app/su-anda/page.tsx @@ -0,0 +1,62 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { title: "Şu Anda" }; + +const lastUpdated = "2026-04-03"; + +export default function SuAndaPage() { + return ( +
+
Şu Anda
+

+ Şu anda nelerle ilgileniyorum — bir /now sayfası +

+

+ Son güncelleme: {lastUpdated} +

+ +
+

Odak

+

+ Red team metodolojileri üzerine yoğunlaşıyorum. Özellikle Active Directory saldırı + vektörleri ve lateral movement teknikleri üzerine lab çalışmaları yapıyorum. +

+ +

Okuma

+
    +
  • The Hacker Playbook 3 — Peter Kim
  • +
  • Red Team Development and Operations — Joe Vest
  • +
  • Pentest.ws writeupları — çeşitli yazarlar
  • +
+ +

Öğrenme

+
    +
  • Active Directory güvenliği (BloodHound, Impacket)
  • +
  • C2 framework mimarisi (Havoc, Sliver)
  • +
  • Rust ile araç geliştirme
  • +
+ +

Hedefler

+
    +
  • 🎯 OSCP sınavına girmek
  • +
  • 🎯 Bu siteyi canlıya almak ✅
  • +
  • 🎯 10 HTB makinesi çözmek
  • +
  • 🎯 Podcast başlatmak
  • +
+ +

Dinleme

+

Darksynth, Industrial, Dark Ambient — çalışırken müzik olmazsa olmaz.

+ +

İzleme

+
    +
  • Mr. Robot (yeniden izleme)
  • +
  • Darknet Diaries Podcast
  • +
+
+ +
+ Bu sayfa /now hareketi ilhamıyla oluşturulmuştur. +
+
+ ); +} diff --git a/app/takim-cantam/page.tsx b/app/takim-cantam/page.tsx new file mode 100644 index 0000000..f9e1563 --- /dev/null +++ b/app/takim-cantam/page.tsx @@ -0,0 +1,138 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { title: "Takım Çantam" }; + +const sections = [ + { + title: "Donanım", + icon: "⊡", + items: [ + { name: "MacBook Pro M3", desc: "Ana geliştirme makinesi", badge: "primary" }, + { name: "Thinkpad X1 Carbon", desc: "Kali Linux dedicated lab makinesi", badge: "lab" }, + { name: "Raspberry Pi 4", desc: "Home lab server", badge: "server" }, + { name: "Alfa AWUS036ACM", desc: "WiFi pentesting adaptör", badge: "tool" }, + { name: "HakCat USB Nugget", desc: "BadUSB payload testi", badge: "tool" }, + { name: "Flipper Zero", desc: "RF/NFC/IR/Sub-GHz multi-tool", badge: "tool" }, + ], + }, + { + title: "İşletim Sistemleri", + icon: "◈", + items: [ + { name: "Kali Linux", desc: "Ana pentest OS — rolling release", badge: "primary" }, + { name: "macOS Sequoia", desc: "Günlük sürücü", badge: "primary" }, + { name: "ParrotOS", desc: "Alternatif güvenlik distrosu", badge: "secondary" }, + { name: "Windows 11", desc: "Lab için VM", badge: "vm" }, + ], + }, + { + title: "Güvenlik Araçları", + icon: "⚔", + items: [ + { name: "Burp Suite Pro", desc: "Web uygulama test aracı", badge: "pro" }, + { name: "Nmap", desc: "Ağ keşif ve tarama", badge: "oss" }, + { name: "Metasploit Framework", desc: "Exploit framework", badge: "oss" }, + { name: "Cobalt Strike", desc: "Red team C2 (lab)", badge: "pro" }, + { name: "BloodHound", desc: "AD attack path analizi", badge: "oss" }, + { name: "Impacket", desc: "Python ağ protokol kütüphanesi", badge: "oss" }, + { name: "Ghidra", desc: "Reverse engineering", badge: "oss" }, + { name: "Wireshark", desc: "Ağ protokol analizi", badge: "oss" }, + { name: "Hashcat", desc: "GPU hızlandırmalı şifre kırma", badge: "oss" }, + { name: "John the Ripper", desc: "Şifre kırma aracı", badge: "oss" }, + { name: "SQLMap", desc: "Otomatik SQL injection", badge: "oss" }, + { name: "Nuclei", desc: "Hızlı güvenlik tarayıcı", badge: "oss" }, + ], + }, + { + title: "Geliştirme", + icon: "◎", + items: [ + { name: "Neovim", desc: "Birincil editör (LazyVim)", badge: "primary" }, + { name: "VS Code", desc: "İkincil editör", badge: "secondary" }, + { name: "WezTerm", desc: "Terminal emülatör", badge: "primary" }, + { name: "tmux", desc: "Terminal multiplexer", badge: "tool" }, + { name: "Fish Shell", desc: "Interaktif shell", badge: "tool" }, + { name: "Git", desc: "Versiyon kontrolü", badge: "tool" }, + { name: "Docker", desc: "Container ortamları", badge: "tool" }, + ], + }, + { + title: "Programlama Dilleri", + icon: "▦", + items: [ + { name: "Python", desc: "Script, otomasyon, exploit geliştirme", badge: "primary" }, + { name: "Bash", desc: "Shell scripting", badge: "primary" }, + { name: "Rust", desc: "Öğreniyorum — araç geliştirme için", badge: "learning" }, + { name: "C/C++", desc: "Exploit geliştirme, düşük seviye", badge: "secondary" }, + { name: "PowerShell", desc: "Windows otomasyon", badge: "secondary" }, + { name: "JavaScript/TypeScript", desc: "Bu site!", badge: "secondary" }, + ], + }, + { + title: "Servisler & Abonelikler", + icon: "◆", + items: [ + { name: "HackTheBox VIP", desc: "Lab makineleri ve challenge'lar", badge: "sub" }, + { name: "1Password", desc: "Şifre yöneticisi", badge: "sub" }, + { name: "Mullvad VPN", desc: "Gizlilik odaklı VPN", badge: "sub" }, + { name: "Proton Mail", desc: "Şifreli e-posta", badge: "sub" }, + ], + }, +]; + +const badgeColors: Record = { + primary: "#00d4aa", + secondary: "#64748b", + pro: "#f59e0b", + oss: "#22c55e", + lab: "#7c6af7", + server: "#3b82f6", + vm: "#64748b", + tool: "#ef4444", + sub: "#ec4899", + learning: "#f97316", +}; + +export default function TakimCantamPage() { + return ( +
+
Takım Çantam
+

+ Kullandığım cihazlar, araçlar, yazılımlar ve servisler +

+ +
+ {sections.map((section) => ( +
+
+ {section.icon} + {section.title} +
+
+ {section.items.map((item) => ( +
+
+ {item.name} + + {item.badge} + +
+

{item.desc}

+
+ ))} +
+
+ ))} +
+
+ ); +} diff --git a/app/tesekkurler/page.tsx b/app/tesekkurler/page.tsx new file mode 100644 index 0000000..3491aed --- /dev/null +++ b/app/tesekkurler/page.tsx @@ -0,0 +1,52 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { title: "Teşekkürler" }; + +export default function TesekkurlerPage() { + return ( +
+
Teşekkürler
+

+ Sitede ve kariyerimde emeği geçenlere +

+ +
+

İnsanlar

+

+ Bana siber güvenliği öğreten, mentorluk eden ve bu yolculukta yanımda olan herkese. + İsim vermek yerine biliyorlar. 🤝 +

+ +

İçerik Üreticileri

+
    +
  • IppSec — HTB makinelerini anlatan YouTube videoları, öğrenmenin en iyi yolu
  • +
  • 0xdf — Detaylı ve açıklayıcı writeupları
  • +
  • Darknet Diaries (Jack Rhysider) — Siber suç hikayelerini mükemmel anlatan podcast
  • +
  • LiveOverflow — Binary exploitation ve CTF içerikleri
  • +
  • John Hammond — CTF çözümleri ve güvenlik araştırmaları
  • +
+ +

Topluluklar

+
    +
  • HackTheBox Community — Forumlarda yardımcı olan herkese
  • +
  • Türk infosec topluluğu — Discord, Twitter ve meetup'larda tanıştığım herkes
  • +
  • CTF ekipleri — Beraber oynadığımız turnuvalarda takım arkadaşlarım
  • +
+ +

Açık Kaynak

+

+ Bu site ve kariyer yolculuğumda kullandığım tüm açık kaynak araçların geliştiricilerine. + Özellikle: Next.js, Kali Linux, Metasploit, Burp Suite Community Edition, Ghidra, Nmap... +

+

+ Açık kaynak olmadan bu alan bu kadar demokratik olamazdı. +

+ +

Aileme

+

+ Gece yarıları terminalde oturup garip şeyler yaptığımda soru sormayan aileme. ❤ +

+
+
+ ); +} diff --git a/components/Navigation.tsx b/components/Navigation.tsx new file mode 100644 index 0000000..8d7b5ee --- /dev/null +++ b/components/Navigation.tsx @@ -0,0 +1,285 @@ +'use client'; + +import Link from 'next/link'; +import { usePathname } from 'next/navigation'; +import { useState } from 'react'; +import { useTheme } from './ThemeProvider'; + +const navGroups = [ + { + label: 'Ana', + items: [ + { href: '/', label: 'Anasayfa', icon: '~' }, + { href: '/merhaba', label: 'Merhaba', icon: '>' }, + { href: '/hakkimda', label: 'Hakkımda', icon: '@' }, + { href: '/su-anda', label: 'Şu Anda', icon: '◉' }, + { href: '/misyon', label: 'Misyon', icon: '⚑' }, + ], + }, + { + label: 'İçerik', + items: [ + { href: '/blog', label: 'Personal Blog', icon: '✍' }, + { href: '/notebook', label: 'Notebook', icon: '◎' }, + { href: '/infosec', label: 'Infosec Posts', icon: '⚔' }, + { href: '/seyir-defteri', label: 'Seyir Defteri', icon: '⚓' }, + { href: '/projeler', label: 'Projeler', icon: '◈' }, + { href: '/podcast', label: 'Podcast', icon: '◉' }, + ], + }, + { + label: 'Koleksiyon', + items: [ + { href: '/faydali-linkler', label: 'Faydalı Linkler', icon: '⊞' }, + { href: '/roadmap', label: 'Roadmap', icon: '◆' }, + { href: '/takim-cantam', label: 'Takım Çantam', icon: '⊡' }, + { href: '/hobilerim', label: 'Hobilerim', icon: '♦' }, + { href: '/fikirlerim', label: 'Fikirlerim', icon: '◇' }, + ], + }, + { + label: 'Bilgi', + items: [ + { href: '/iletisim', label: 'İletişim', icon: '✉' }, + { href: '/ozgecmis', label: 'Özgeçmiş', icon: '▤' }, + { href: '/aktivite', label: 'Aktivite', icon: '▶' }, + { href: '/rss-beslemeleri', label: 'RSS Beslemeleri', icon: '◈' }, + { href: '/statboard', label: 'Statboard', icon: '▦' }, + { href: '/altyapi', label: 'Altyapı', icon: '⊟' }, + { href: '/tesekkurler', label: 'Teşekkürler', icon: '♡' }, + ], + }, + { + label: 'Meta', + items: [ + { href: '/gizlilik', label: 'Gizlilik', icon: '⊘' }, + { href: '/kullanim-kosullari', label: 'Kullanım Koşulları', icon: '⊘' }, + { href: '/humans.txt', label: 'humans.txt', icon: '▸', external: true }, + { href: '/security.txt', label: 'security.txt', icon: '▸', external: true }, + { href: '/public.pgp', label: 'public.pgp', icon: '▸', external: true }, + ], + }, + { + label: 'Harici', + items: [ + { href: '/mastodon', label: 'Mastodon', icon: '⊕', external: true }, + { href: 'mailto:info@denizbektas.com.tr', label: 'E-Mail', icon: '✉', external: true }, + ], + }, +]; + +export default function Navigation() { + const pathname = usePathname(); + const { theme, toggle } = useTheme(); + const [mobileOpen, setMobileOpen] = useState(false); + + const isActive = (href: string) => { + if (href === '/') return pathname === '/'; + return pathname.startsWith(href); + }; + + const sidebarContent = ( + + ); + + return ( + <> + {/* Desktop Sidebar */} + + + {/* Mobile Header */} +
+ + denizbektas.dev + +
+ + +
+
+ + {/* Mobile Nav Overlay */} + {mobileOpen && ( +
+ {sidebarContent} +
+ )} + + + + ); +} diff --git a/components/ThemeProvider.tsx b/components/ThemeProvider.tsx new file mode 100644 index 0000000..db86479 --- /dev/null +++ b/components/ThemeProvider.tsx @@ -0,0 +1,36 @@ +'use client'; + +import { createContext, useContext, useEffect, useState } from 'react'; + +type Theme = 'dark' | 'light'; + +const ThemeContext = createContext<{ + theme: Theme; + toggle: () => void; +}>({ theme: 'dark', toggle: () => {} }); + +export function ThemeProvider({ children }: { children: React.ReactNode }) { + const [theme, setTheme] = useState('dark'); + + useEffect(() => { + const stored = localStorage.getItem('theme') as Theme | null; + const initial = stored || 'dark'; + setTheme(initial); + document.documentElement.setAttribute('data-theme', initial); + }, []); + + const toggle = () => { + const next = theme === 'dark' ? 'light' : 'dark'; + setTheme(next); + localStorage.setItem('theme', next); + document.documentElement.setAttribute('data-theme', next); + }; + + return ( + + {children} + + ); +} + +export const useTheme = () => useContext(ThemeContext); diff --git a/content/activity.json b/content/activity.json new file mode 100644 index 0000000..d461113 --- /dev/null +++ b/content/activity.json @@ -0,0 +1,30 @@ +[ + { + "id": "1", + "timestamp": "2026-04-03T10:00:00.000Z", + "type": "system", + "message": "Site yayına alındı. denizbektas.com.tr hayata geçti.", + "link": "/" + }, + { + "id": "2", + "timestamp": "2026-04-03T10:05:00.000Z", + "type": "post", + "message": "İlk blog yazısı yayınlandı: Neden Siber Güvenlik?", + "link": "/blog/neden-siber-guvenlik" + }, + { + "id": "3", + "timestamp": "2026-04-03T10:10:00.000Z", + "type": "infosec", + "message": "İlk infosec yazısı: Nmap ile Ağ Keşfi", + "link": "/infosec/nmap-ag-kesfi" + }, + { + "id": "4", + "timestamp": "2026-04-03T10:15:00.000Z", + "type": "notebook", + "message": "Notebook'a ilk not eklendi.", + "link": "/notebook/ilk-not" + } +] diff --git a/content/blog/neden-siber-guvenlik.md b/content/blog/neden-siber-guvenlik.md new file mode 100644 index 0000000..e173643 --- /dev/null +++ b/content/blog/neden-siber-guvenlik.md @@ -0,0 +1,26 @@ +--- +title: "Neden Siber Güvenlik?" +date: "2026-04-01" +excerpt: "Siber güvenliğe nasıl başladım, neden bu alanı seçtim ve bu yolculukta neler öğrendim." +tags: ["kişisel", "kariyer", "siber güvenlik"] +--- + +# Neden Siber Güvenlik? + +Her şey merakla başladı. Çocukluğumda bilgisayarların *nasıl çalıştığını* anlamak istiyordum — sadece kullanmak değil, içini görmek. + +## İlk Adımlar + +İlk kez bir sisteme "girildiğinde" ne hissedildiğini anlamak için yıllarca kafamı duvara vurdum. CTF yarışmaları, HackTheBox, TryHackMe — hepsini denedim. + +## Bu Yolculuk + +Red team operasyonları, offensive security, pentest... Bu kelimelerin arkasında gerçek bir disiplin var. Ve bu disiplin beni her gün daha fazla çekiyor. + +> "The quieter you become, the more you are able to hear." — Kali Linux motto + +## Sonuç + +Siber güvenlik bir meslek değil, bir yaşam biçimi. Sürekli öğrenme, sürekli adaptasyon, sürekli sorgulama. + +Bu site de o yolculuğun bir parçası. diff --git a/content/infosec/nmap-ag-kesfi.md b/content/infosec/nmap-ag-kesfi.md new file mode 100644 index 0000000..af46379 --- /dev/null +++ b/content/infosec/nmap-ag-kesfi.md @@ -0,0 +1,82 @@ +--- +title: "Nmap ile Ağ Keşfi" +date: "2026-04-02" +excerpt: "Nmap'in temel ve ileri düzey kullanımı, port tarama teknikleri ve pratik örnekler." +tags: ["nmap", "reconnaissance", "network", "tools"] +--- + +# Nmap ile Ağ Keşfi + +Nmap (Network Mapper), ağ keşfi ve güvenlik denetimi için kullanılan açık kaynaklı bir araçtır. Her pentest operasyonunun ilk adımı genellikle Nmap ile başlar. + +## Temel Kullanım + +```bash +# Basit port tarama +nmap 192.168.1.1 + +# Belirli portları tara +nmap -p 22,80,443 192.168.1.1 + +# Tüm portları tara +nmap -p- 192.168.1.1 +``` + +## SYN Scan (Stealth Scan) + +```bash +# Root yetkisi gerektirir +sudo nmap -sS 192.168.1.1 +``` + +SYN scan, tam TCP bağlantısı kurmadan portların açık olup olmadığını tespit eder. Daha az iz bırakır. + +## Servis ve Versiyon Tespiti + +```bash +nmap -sV -sC 192.168.1.1 +``` + +## OS Fingerprinting + +```bash +sudo nmap -O 192.168.1.1 +``` + +## Agresif Tarama + +```bash +sudo nmap -A 192.168.1.1 +``` + +`-A` bayrağı; OS tespiti, versiyon tespiti, script tarama ve traceroute'u birleştirir. + +## NSE Scripts + +```bash +# Tüm scriptleri listele +ls /usr/share/nmap/scripts/ + +# Belirli bir script çalıştır +nmap --script=http-title 192.168.1.1 + +# Vuln kategorisi +nmap --script=vuln 192.168.1.1 +``` + +## Pratik Örnekler + +```bash +# Web sunucu keşfi +nmap -p 80,443,8080,8443 --open 192.168.1.0/24 + +# Hızlı subnet tarama +nmap -T4 -F 192.168.1.0/24 + +# XML çıktısı +nmap -oX scan.xml 192.168.1.1 +``` + +## Sonuç + +Nmap, her güvenlik uzmanının toolbox'ında olması gereken temel bir araçtır. Authorization olmadan kullanmak yasadışıdır — her zaman izinli sistemlerde test edin. diff --git a/content/notebook/ilk-not.md b/content/notebook/ilk-not.md new file mode 100644 index 0000000..fa2456d --- /dev/null +++ b/content/notebook/ilk-not.md @@ -0,0 +1,12 @@ +--- +title: "İlk Not" +date: "2026-04-03" +excerpt: "Bu notebook'un ilk notu. Aklımdan geçen şeyleri buraya yazacağım." +tags: ["düşünce"] +--- + +Bir şeyi öğrenmenin en iyi yolu onu başkasına anlatmaktır. + +Bu notebook tam da bu amaçla var — anlık düşünceler, bağlantısız notlar, kafamdan geçen şeyler. + +Twitter gibi ama daha az gürültü, daha çok sinyal. diff --git a/lib/activity.ts b/lib/activity.ts new file mode 100644 index 0000000..4d97680 --- /dev/null +++ b/lib/activity.ts @@ -0,0 +1,30 @@ +import fs from 'fs'; +import path from 'path'; + +export interface ActivityEntry { + id: string; + timestamp: string; + type: 'post' | 'notebook' | 'infosec' | 'project' | 'link' | 'update' | 'system'; + message: string; + link?: string; +} + +const activityFile = path.join(process.cwd(), 'content', 'activity.json'); + +export function getActivity(): ActivityEntry[] { + if (!fs.existsSync(activityFile)) return []; + const raw = fs.readFileSync(activityFile, 'utf-8'); + return JSON.parse(raw); +} + +export function addActivity(entry: Omit) { + const entries = getActivity(); + const newEntry: ActivityEntry = { + id: Date.now().toString(), + timestamp: new Date().toISOString(), + ...entry, + }; + entries.unshift(newEntry); + fs.writeFileSync(activityFile, JSON.stringify(entries.slice(0, 500), null, 2)); + return newEntry; +} diff --git a/lib/posts.ts b/lib/posts.ts new file mode 100644 index 0000000..b6cb999 --- /dev/null +++ b/lib/posts.ts @@ -0,0 +1,71 @@ +import fs from 'fs'; +import path from 'path'; +import matter from 'gray-matter'; +import { remark } from 'remark'; +import html from 'remark-html'; + +const contentDir = path.join(process.cwd(), 'content'); + +export interface Post { + slug: string; + title: string; + date: string; + excerpt: string; + tags: string[]; + content?: string; + category: 'blog' | 'notebook' | 'infosec'; +} + +export function getPosts(category: 'blog' | 'notebook' | 'infosec'): Post[] { + const dir = path.join(contentDir, category); + if (!fs.existsSync(dir)) return []; + + const files = fs.readdirSync(dir).filter((f) => f.endsWith('.md')); + + return files + .map((filename) => { + const slug = filename.replace('.md', ''); + const raw = fs.readFileSync(path.join(dir, filename), 'utf-8'); + const { data } = matter(raw); + return { + slug, + title: data.title || slug, + date: data.date || '2024-01-01', + excerpt: data.excerpt || '', + tags: data.tags || [], + category, + }; + }) + .sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()); +} + +export async function getPost( + category: 'blog' | 'notebook' | 'infosec', + slug: string +): Promise { + const filePath = path.join(contentDir, category, `${slug}.md`); + if (!fs.existsSync(filePath)) return null; + + const raw = fs.readFileSync(filePath, 'utf-8'); + const { data, content } = matter(raw); + + const processed = await remark().use(html).process(content); + + return { + slug, + title: data.title || slug, + date: data.date || '2024-01-01', + excerpt: data.excerpt || '', + tags: data.tags || [], + content: processed.toString(), + category, + }; +} + +export function getAllPosts(): Post[] { + return [ + ...getPosts('blog'), + ...getPosts('infosec'), + ...getPosts('notebook'), + ].sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()); +} diff --git a/package-lock.json b/package-lock.json index 080f37f..22de825 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,9 +8,15 @@ "name": "personalsite", "version": "0.1.0", "dependencies": { + "date-fns": "^4.1.0", + "gray-matter": "^4.0.3", + "lucide-react": "^1.7.0", "next": "16.2.2", + "next-themes": "^0.4.6", "react": "19.2.4", - "react-dom": "19.2.4" + "react-dom": "19.2.4", + "remark": "^15.0.1", + "remark-html": "^16.0.1" }, "devDependencies": { "@tailwindcss/postcss": "^4", @@ -1525,6 +1531,15 @@ "tslib": "^2.4.0" } }, + "node_modules/@types/debug": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -1532,6 +1547,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -1546,6 +1570,21 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, "node_modules/@types/node": { "version": "20.19.37", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.37.tgz", @@ -1577,6 +1616,12 @@ "@types/react": "^19.2.0" } }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.58.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.58.0.tgz", @@ -1873,6 +1918,12 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC" + }, "node_modules/@unrs/resolver-binding-android-arm-eabi": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", @@ -2429,6 +2480,16 @@ "node": ">= 0.4" } }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2587,6 +2648,16 @@ ], "license": "CC-BY-4.0" }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -2604,6 +2675,36 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", @@ -2630,6 +2731,16 @@ "dev": true, "license": "MIT" }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2727,11 +2838,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/date-fns": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz", + "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -2745,6 +2865,19 @@ } } }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -2788,6 +2921,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", @@ -2798,6 +2940,19 @@ "node": ">=8" } }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -3247,6 +3402,7 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -3416,6 +3572,19 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/esquery": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", @@ -3462,6 +3631,24 @@ "node": ">=0.10.0" } }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -3797,6 +3984,43 @@ "dev": true, "license": "ISC" }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "license": "MIT", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/has-bigints": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", @@ -3891,6 +4115,57 @@ "node": ">= 0.4" } }, + "node_modules/hast-util-sanitize": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-5.0.2.tgz", + "integrity": "sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "unist-util-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hermes-estree": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", @@ -3908,6 +4183,16 @@ "hermes-estree": "0.25.1" } }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -4118,6 +4403,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -4230,6 +4524,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", @@ -4510,6 +4816,15 @@ "json-buffer": "3.0.1" } }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/language-subtag-registry": { "version": "0.3.23", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", @@ -4828,6 +5143,16 @@ "dev": true, "license": "MIT" }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -4851,6 +5176,15 @@ "yallist": "^3.0.2" } }, + "node_modules/lucide-react": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.7.0.tgz", + "integrity": "sha512-yI7BeItCLZJTXikmK4KNUGCKoGzSvbKlfCvw44bU4fXAL6v3gYS4uHD1jzsLkfwODYwI6Drw5Tu9Z5ulDe0TSg==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", @@ -4871,6 +5205,99 @@ "node": ">= 0.4" } }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz", + "integrity": "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -4881,6 +5308,448 @@ "node": ">= 8" } }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -4922,7 +5791,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, "license": "MIT" }, "node_modules/nanoid": { @@ -5019,6 +5887,16 @@ } } }, + "node_modules/next-themes": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz", + "integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" + } + }, "node_modules/next/node_modules/postcss": { "version": "8.4.31", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", @@ -5384,6 +6262,16 @@ "react-is": "^16.13.1" } }, + "node_modules/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -5489,6 +6377,70 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/remark": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/remark/-/remark-15.0.1.tgz", + "integrity": "sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-html": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/remark-html/-/remark-html-16.0.1.tgz", + "integrity": "sha512-B9JqA5i0qZe0Nsf49q3OXyGvyXuZFDzAP2iOFLEumymuYJITVpiH1IgsTEwTpdptDmZlMDMWeDmSawdaJIGCXQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "hast-util-sanitize": "^5.0.0", + "hast-util-to-html": "^9.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/resolve": { "version": "2.0.0-next.6", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.6.tgz", @@ -5629,6 +6581,19 @@ "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "license": "MIT" }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -5854,6 +6819,22 @@ "node": ">=0.10.0" } }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" + }, "node_modules/stable-hash": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", @@ -5988,6 +6969,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -5998,6 +6993,15 @@ "node": ">=4" } }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -6143,6 +7147,26 @@ "node": ">=8.0" } }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/ts-api-utils": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", @@ -6344,6 +7368,93 @@ "dev": true, "license": "MIT" }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/unrs-resolver": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", @@ -6420,6 +7531,34 @@ "punycode": "^2.1.0" } }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -6578,6 +7717,16 @@ "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } } } } diff --git a/package.json b/package.json index e230f8b..bf469b5 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,15 @@ "lint": "eslint" }, "dependencies": { + "date-fns": "^4.1.0", + "gray-matter": "^4.0.3", + "lucide-react": "^1.7.0", "next": "16.2.2", + "next-themes": "^0.4.6", "react": "19.2.4", - "react-dom": "19.2.4" + "react-dom": "19.2.4", + "remark": "^15.0.1", + "remark-html": "^16.0.1" }, "devDependencies": { "@tailwindcss/postcss": "^4",