1import{b as w,bC as v,r as n,j as e,L as k,a6 as g,a5 as C,a7 as S,bT as x,cp as b,W as u,co as L,b1 as A,B as _,e as I,f as E,K as T,n as f,ab as B,a as j}from"./index-C7BCAWyf.js";import{s as M}from"./seo-S8_BoAwA.js";import{S as R,a as H}from"./securityFindings-DD2cx6O5.js";const N={critical:0,high:1,medium:2,low:3},Q={critical:"bg-destructive/15 text-destructive border-destructive/40",high:"bg-yellow-500/15 text-yellow-500 border-yellow-500/40",medium:"bg-muted text-muted-foreground border-border",low:"bg-muted text-muted-foreground border-border"},q={critical:"Critical",high:"High",medium:"Medium",low:"Low"},U=()=>{const{user:d,loading:c}=w(),{isAdmin:l,loading:t}=v(),[m,p]=n.useState(null);n.useEffect(()=>{M({title:"Security issues â HackerLabs.ai",description:"High and critical security findings with table, policy, and copy-pastable SQL fixes. Admin-only.",url:"https://hackerlabs.ai/admin/security/issues"})},[]);const a=n.useMemo(()=>[...R].filter(r=>r.impact==="critical"||r.impact==="high").sort((r,s)=>N[r.impact]-N[s.impact]),[]),i=n.useMemo(()=>{let r=0,s=0;for(const o of a)o.impact==="critical"?r++:o.impact==="high"&&s++;return{critical:r,high:s,total:a.length}},[a]),y=async(r,s)=>{try{await navigator.clipboard.writeText(s),p(r),j.success("SQL copied â paste into the migration editor"),window.setTimeout(()=>p(o=>o===r?null:o),1800)}catch{j.error("Could not copy to clipboard")}};return c||t?e.jsx("div",{className:"min-h-screen bg-background flex items-center justify-center",children:e.jsx(k,{className:"w-6 h-6 animate-spin text-muted-foreground"})}):d?l?e.jsxs("div",{className:"min-h-screen bg-background flex flex-col",children:[e.jsx(C,{}),e.jsx(S,{items:[{label:"Admin",to:"/admin/site"},{label:"Security",to:"/admin/security"},{label:"Issues"}]}),e.jsxs("main",{className:"container mx-auto px-4 py-8 max-w-4xl flex-1 space-y-6",children:[e.jsxs("header",{className:"space-y-2",children:[e.jsx("p",{className:"text-[10px] font-mono uppercase tracking-wider text-primary",children:'$ grep -E "critical|high" /admin/security/findings.md'}),e.jsxs("h1",{className:"text-2xl font-mono font-extrabold text-foreground flex items-center gap-2",children:[e.jsx(x,{className:"w-6 h-6 text-destructive"}),"Security issues"]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"High and critical findings only, with the affected table, policy name, and a one-click SQL fix you can paste into a migration."})]}),e.jsxs("section",{className:"grid grid-cols-3 gap-3",children:[e.jsx(h,{label:"Total",value:i.total,icon:e.jsx(b,{className:"w-4 h-4"})}),e.jsx(h,{label:"Critical",value:i.critical,tone:i.critical>0?"danger":"ok",icon:e.jsx(x,{className:"w-4 h-4"})}),e.jsx(h,{label:"High",value:i.high,tone:i.high>0?"warn":"ok",icon:e.jsx(x,{className:"w-4 h-4"})})]}),a.length===0?e.jsxs("div",{className:"rounded-lg border border-border bg-card p-8 text-center text-sm text-muted-foreground",children:[e.jsx(b,{className:"w-8 h-8 text-primary mx-auto mb-2"}),"No high or critical issues. Nice work."]}):e.jsx("ul",{className:"space-y-3",children:a.map(r=>{const s=m===r.internal_id;return e.jsxs("li",{className:"rounded-lg border border-border bg-card p-4 space-y-3",children:[e.jsxs("div",{className:"flex items-start gap-2 flex-wrap",children:[e.jsx(u,{variant:"outline",className:Q[r.impact],children:q[r.impact]}),e.jsx(u,{variant:"outline",className:"border-border text-muted-foreground",children:H[r.severity]}),e.jsx(u,{variant:"outline",className:"border-border text-muted-foreground",children:r.scanner}),e.jsxs("span",{className:"ml-auto text-[10px] font-mono text-muted-foreground",children:["+",r.estimated_improvement," pts when resolved"]})]}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-semibold text-card-foreground",children:r.name}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1 leading-relaxed",children:r.description})]}),(r.table||r.policy)&&e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-2 text-xs font-mono",children:[r.table&&e.jsxs("div",{className:"flex items-center gap-2 px-2 py-1.5 rounded border border-border bg-secondary/50",children:[e.jsx(L,{className:"w-3.5 h-3.5 text-muted-foreground shrink-0"}),e.jsx("span",{className:"text-muted-foreground shrink-0",children:"table:"}),e.jsx("span",{className:"text-card-foreground truncate",children:r.table})]}),r.policy&&e.jsxs("div",{className:"flex items-center gap-2 px-2 py-1.5 rounded border border-border bg-secondary/50",children:[e.jsx(A,{className:"w-3.5 h-3.5 text-muted-foreground shrink-0"}),e.jsx("span",{className:"text-muted-foreground shrink-0",children:"policy:"}),e.jsx("span",{className:"text-card-foreground truncate",children:r.policy})]})]}),r.fix_sql?e.jsxs("div",{className:"rounded-md border border-border bg-secondary/40 overflow-hidden",children:[e.jsxs("div",{className:"flex items-center justify-between px-3 py-1.5 border-b border-border bg-secondary/60",children:[e.jsx("span",{className:"text-[10px] font-mono uppercase tracking-wider text-muted-foreground",children:"Fix â paste into a
1new migration"}),e.jsx(_,{size:"sm",variant:"ghost",onClick:()=>y(r.internal_id,r.fix_sql),className:"h-6 px-2 text-xs",children:s?e.jsxs(e.Fragment,{children:[e.jsx(I,{className:"w-3 h-3 mr-1"}),"Copied"]}):e.jsxs(e.Fragment,{children:[e.jsx(E,{className:"w-3 h-3 mr-1"}),"Copy SQL"]})})]}),e.jsx("pre",{className:"text-[11px] font-mono text-card-foreground p-3 overflow-x-auto whitespace-pre",children:r.fix_sql})]}):e.jsx("div",{className:"rounded-md border border-dashed border-border bg-secondary/30 px-3 py-2 text-[11px] font-mono text-muted-foreground",children:"No SQL fix â see the linked docs for remediation steps."}),e.jsxs("div",{className:"flex items-center gap-3 flex-wrap pt-1",children:[e.jsxs("a",{href:r.link,target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-1 text-xs font-mono text-muted-foreground hover:text-foreground",children:["Docs ",e.jsx(T,{className:"w-3 h-3"})]}),e.jsxs(f,{to:"/admin/security",className:"inline-flex items-center gap-1 text-xs font-mono text-primary hover:underline ml-auto",children:["Track status ",e.jsx(B,{className:"w-3 h-3"})]})]})]},r.internal_id)})}),e.jsxs("p",{className:"text-[11px] font-mono text-muted-foreground pt-2",children:["Need to mark something fixed or reopen a finding? Use the"," ",e.jsx(f,{to:"/admin/security",className:"text-primary hover:underline",children:"full security settings page"}),"."]})]})]}):e.jsx(g,{to:"/",replace:!0}):e.jsx(g,{to:"/auth",replace:!0})},h=({label:d,value:c,icon:l,tone:t="neutral"})=>{const m=t==="danger"?"text-destructive":t==="warn"?"text-yellow-500":t==="ok"?"text-primary":"text-foreground";return e.jsxs("div",{className:"rounded-lg border border-border bg-card p-3",children:[e.jsxs("div",{className:"flex items-center gap-1.5 text-[10px] font-mono uppercase tracking-wider text-muted-foreground",children:[l,d]}),e.jsx("div",{className:"text-2xl font-mono font-bold mt-1 "+m,children:c})]})};export{U as default}; 2//# sourceMappingURL=AdminSecurityIssues-BSHIzrXh.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.