daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

[...slug].astro (5044B)


      1 ---
      2 import FuzzField from '../../components/FuzzField.astro';
      3 import { render } from 'astro:content';
      4 import Base from '../../layouts/Base.astro';
      5 import Icon from '../../components/Icon.astro';
      6 import SheetCredit from '../../components/SheetCredit.astro';
      7 import SheetReferences from '../../components/SheetReferences.astro';
      8 import { categoryOf } from '../../lib/taxonomy';
      9 import { sheetsByCategory, prevNext, sheetHref, tagSlug, type Sheet } from '../../lib/sheets';
     10 import { url } from '../../lib/url';
     11 
     12 export async function getStaticPaths() {
     13   const groups = await sheetsByCategory();
     14   const paths: any[] = [];
     15   for (const g of groups) {
     16     // Cross-listed sheets still generate one canonical page and pagination.
     17     const primaryItems = g.items.filter((entry) => entry.data.category === g.slug);
     18     for (const entry of primaryItems) {
     19       const { prev, next } = prevNext(primaryItems, entry);
     20       paths.push({ params: { slug: entry.id }, props: { entry, prev, next } });
     21     }
     22   }
     23   return paths;
     24 }
     25 
     26 interface Props { entry: Sheet; prev?: Sheet; next?: Sheet }
     27 const { entry, prev, next } = Astro.props;
     28 const d = entry.data;
     29 const cat = categoryOf(d.category);
     30 const { Content, headings } = await render(entry);
     31 const toc = headings.filter((h) => h.depth === 2 || h.depth === 3);
     32 const pdfHref = d.pdf ? url(`pdfs/${d.pdf}`) : null;
     33 ---
     34 <Base title={`${d.title} — DÆMON//SEC`} description={d.description}>
     35   <div class="wrap">
     36     <nav class="breadcrumb" style="margin-top:1.5rem;">
     37       <a href={url('')}>~</a><span class="sep">/</span>
     38       <a href={url(cat.slug)} style={`color: var(--${cat.accent})`}>{cat.tag.toLowerCase()}</a>
     39       <span class="sep">/</span>
     40       <span class="muted">{entry.id.split('/').pop()}</span>
     41     </nav>
     42 
     43     <header class="sheet-head plate signal-hero" data-pagefind-meta={`category:${cat.title}`}>
     44       <FuzzField />
     45       <span class="grain grain--local" aria-hidden="true"></span>
     46       <span class="scanlines" aria-hidden="true"></span>
     47       <p class="eyebrow" style={`--acc: var(--${cat.accent});`}>
     48         <span class="eyebrow__n">{cat.tag}</span>
     49         <span class="eyebrow__mark">^:</span>
     50         <span>{cat.title}</span>
     51         <span class="eyebrow__rule" aria-hidden="true"></span>
     52       </p>
     53       <h1 class="sheet-title" data-pagefind-meta="title">{d.title}</h1>
     54       {d.description && <p class="sheet-desc">{d.description}</p>}
     55       <div class="sheet-meta">
     56         <span class="badge badge--{d.difficulty}">{d.difficulty}</span>
     57         {d.updated && <span class="badge">updated {d.updated}</span>}
     58         {d.tools.length > 0 && <span class="badge"><Icon name="wrench" style="width:12px;height:12px;" />{d.tools.slice(0,4).join(' · ')}</span>}
     59       </div>
     60       {d.tags.length > 0 && (
     61         <div class="tags-row" style="margin-top:0.8rem;">
     62           {d.tags.map((t) => <a class="tag-pill" href={url(`tags/${tagSlug(t)}`)}>#{t}</a>)}
     63         </div>
     64       )}
     65     </header>
     66 
     67     <SheetCredit
     68       name={d.upstreamName}
     69       upstreamUrl={d.upstreamUrl}
     70       author={d.upstreamAuthor}
     71       license={d.upstreamLicense}
     72       relation={d.upstreamRelation}
     73       copyright={d.upstreamCopyright}
     74     />
     75 
     76     <div class="sheet-layout">
     77       <article class="prose" data-pagefind-body>
     78         {pdfHref && (
     79           <figure class="code-pane plate corners" style="margin-bottom:1.6rem;">
     80             <figcaption class="code-pane__bar">
     81               <span class="code-pane__lang">{d.pdf}</span>
     82               <a class="code-copy" href={pdfHref} download>Download</a>
     83             </figcaption>
     84             <iframe class="pdf-frame" src={pdfHref} title={`${d.title} (PDF)`} loading="lazy"></iframe>
     85           </figure>
     86         )}
     87         <Content />
     88         <SheetReferences references={d.references} />
     89       </article>
     90 
     91       {/* One TOC serves both layouts. Below 1040px the grid puts it above the
     92           article and <summary> collapses it, so a 2000-line sheet is still
     93           navigable on a phone; from 1040px up it is the sticky rail and the
     94           summary renders as its heading. Keeping a single node means the
     95           scroll-spy in app.ts has one set of links to highlight. */}
     96       {toc.length > 1 && (
     97         <details class="toc plate-dawn corners" open>
     98           <summary>On this page</summary>
     99           <nav aria-label="On this page">
    100             {toc.map((h) => (
    101               <a href={`#${h.slug}`} class={h.depth === 3 ? 'lvl-3' : ''}>{h.text}</a>
    102             ))}
    103           </nav>
    104         </details>
    105       )}
    106     </div>
    107 
    108     <nav class="prevnext" aria-label="Pagination">
    109       {prev ? (
    110         <a href={url(sheetHref(prev))} style={`--acc: var(--${cat.accent})`}>
    111           <span class="dir">← Prev</span><strong>{prev.data.title}</strong>
    112         </a>
    113       ) : <span></span>}
    114       {next ? (
    115         <a class="nx" href={url(sheetHref(next))} style={`--acc: var(--${cat.accent})`}>
    116           <span class="dir">Next →</span><strong>{next.data.title}</strong>
    117         </a>
    118       ) : <span></span>}
    119     </nav>
    120   </div>
    121 </Base>