PageSourceSearch

https://shyftsync-pro.lovable.app/assets/SecurityDashboard-7ktmxHdg.js

js shyftsync-pro.lovable.app collected 2026-10-03 03:44:53 UTC 9,317 bytes, 1 lines download raw bytes

1import{r as d,j as e}from"./react-vendor-DTqDINLx.js";import{s as i,d as w,G as z,K as B,M as Q,N as K,R as G,L as H,I as V,O as W,a as C,u as M,C as S,e as F,g as T,h as Y,j as P,B as k,l as $,n as x}from"./index-CDEEPAFL.js";import{P as J}from"./progress-C3mTwkAQ.js";import{u as X,a as Z}from"./query-VC2inT0K.js";import{u as ee}from"./useAuthReady-DooKsU0j.js";import{i as R,L as I,A as te,aS as E,F as q,aT as L,H as ae,aU as se,a0 as re,aV as ie}from"./icons-Dgyx7aoh.js";import{f as ne}from"./date-fns-Ca3Aqc6k.js";import"./papaparse-CBdttS9C.js";import"./pdf-BJftjdFv.js";import"./router-CMJOq0Ni.js";import"./supabase-BX9gqKp5.js";function ce({open:c,onOpenChange:t,onEnrolled:n}){const[l,o]=d.useState(!1),[r,p]=d.useState(!1),[h,g]=d.useState(null),[y,u]=d.useState(null),[j,b]=d.useState(null),[m,v]=d.useState("");d.useEffect(()=>{if(!c){g(null),u(null),b(null),v("");return}let a=!1;return(async()=>{o(!0);try{const{data:s}=await i.auth.getUser();if(!s?.user){w.error("Your session expired. Please sign out and sign back in, then try again."),t(!1);return}const{data:f}=await i.auth.mfa.listFactors(),U=[...f?.totp??[],...f?.all??[]].filter(D=>D.status!=="verified");for(const D of U)try{await i.auth.mfa.unenroll({factorId:D.id})}catch{}const{data:_,error:O}=await i.auth.mfa.enroll({factorType:"totp",friendlyName:`Authenticator ${new Date().toISOString().slice(0,10)}`});if(O)throw O;if(a)return;g(_.id),u(_.totp.qr_code),b(_.totp.secret)}catch(s){w.error(s.message||"Failed to start enrollment"),t(!1)}finally{o(!1)}})(),()=>{a=!0}},[c,t]);const A=async()=>{if(!(!h||m.length<6)){p(!0);try{const{data:a,error:s}=await i.auth.mfa.challenge({factorId:h});if(s)throw s;const{error:f}=await i.auth.mfa.verify({factorId:h,challengeId:a.id,code:m});if(f)throw f;w.success("Two-factor authentication enabled"),n?.(),t(!1)}catch(a){w.error(a.message||"Invalid code, try again")}finally{p(!1)}}};return e.jsx(z,{open:c,onOpenChange:t,children:e.jsxs(B,{className:"max-w-md",children:[e.jsxs(Q,{children:[e.jsxs(K,{className:"flex items-center gap-2",children:[e.jsx(R,{className:"h-5 w-5"})," Enable two-factor authentication"]}),e.jsx(G,{children:"Scan the QR code with Google Authenticator, 1Password, Authy, or any TOTP app, then enter the 6-digit code below."})]}),l||!y?e.jsx("div",{className:"flex items-center justify-center py-10",children:e.jsx(I,{className:"h-6 w-6 animate-spin text-muted-foreground"})}):e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"flex justify-center bg-white p-4 rounded-md border",children:e.jsx("img",{src:y,alt:"MFA QR code",className:"h-48 w-48"})}),j&&e.jsxs("div",{className:"text-xs text-muted-foreground text-center",children:["Can't scan? Enter this key: ",e.jsx("code",{className:"font-mono break-all",children:j})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(H,{htmlFor:"mfa-code",children:"Verification code"}),e.jsx(V,{id:"mfa-code",inputMode:"numeric",autoComplete:"one-time-code",maxLength:6,placeholder:"123456",value:m,onChange:a=>v(a.target.value.replace(/\D/g,"").slice(0,6))})]})]}),e.jsxs(W,{children:[e.jsx(C,{variant:"outline",onClick:()=>t(!1),disabled:r,children:"Cancel"}),e.jsx(C,{onClick:A,disabled:l||r||m.length!==6,children:r?e.jsx(I,{className:"h-4 w-4 animate-spin"}):"Verify & enable"})]})]})})}const oe=[{icon:ae,title:"Data Encryption",status:"Active",description:"AES-256 at rest, TLS 1.3 in transit."},{icon:se,title:"Australian Data Residency",status:"Active",description:"Hosted in AWS ap-southeast-2 (Sydney)."},{icon:re,title:"Australian Privacy Principles",status:"Compliant",description:"Aligned with the 13 APPs of the Privacy Act 1988."},{icon:R,title:"Access Control & RLS",status:"Active",description:"Row-Level Security on every table, scoped by workspace."},{icon:ie,title:"Audit Logging",status:"Active",description:"Append-only audit log for clients, notes, incidents, vault, agreements, ABN, rates."},{icon:L,title:"Admin MFA",status:"Mandatory",description:"TOTP enforced for admins after 14-day grace."},{icon:E,title:"Notifiable Data Breaches",status:"Ready",description:"Breach log + OAIC notification workflow (Part IIIC)."}
1,{icon:q,title:"DSAR (APP 12)",status:"Ready",description:"One-click subject data export bundles, audited."}];function le(){const{isAdmin:c,isSuperAdmin:t,organizationId:n}=M(),{ready:l}=ee();return Z({queryKey:["compliance_dashboard_metrics",n,t],enabled:c&&l,queryFn:async()=>{if($()){const[u,j,b,m,v,A]=await Promise.all([x("audit_log",{limit:1,select:"id"}).then(a=>a.data?.length??0).catch(()=>0),t?x("data_breach_log",{limit:2e3,select:"id,status"}).then(a=>(a.data??[]).filter(s=>s.status!=="closed").length).catch(()=>0):Promise.resolve(0),x("dsar_requests",{limit:2e3,select:"id,status"}).then(a=>(a.data??[]).filter(s=>s.status!=="completed").length).catch(()=>0),x("audit_log",{limit:1,order_by:"created_at",select:"created_at,action"}).then(a=>(a.data??[]).find(s=>s.action==="dsar_export")?.created_at??null).catch(()=>null),x("organization_members",{limit:1e3,select:"user_id,role"}).then(a=>(a.data??[]).filter(s=>s.role==="admin").length).catch(()=>0),i.auth.mfa.listFactors()]);return{auditCount:u,breachOpen:j,dsarOpen:b,lastDsar:m,adminCount:v,currentUserMfa:!!A.data?.all?.some(a=>a.status==="verified")}}const[o,r,p,h,g,y]=await Promise.all([i.from("audit_log").select("id",{count:"exact",head:!0}).eq("organization_id",n),t?i.from("data_breach_log").select("id",{count:"exact",head:!0}).eq("organization_id",n).neq("status","closed"):Promise.resolve({count:0}),i.from("dsar_requests").select("id",{count:"exact",head:!0}).eq("organization_id",n).neq("status","completed"),i.from("audit_log").select("created_at").eq("organization_id",n).eq("action","dsar_export").order("created_at",{ascending:!1}).limit(1).maybeSingle(),i.from("organization_members").select("user_id",{count:"exact",head:!0}).eq("organization_id",n).eq("role","admin"),i.auth.mfa.listFactors()]);return{auditCount:o.count??0,breachOpen:r.count??0,dsarOpen:p.count??0,lastDsar:h.data?.created_at,adminCount:g.count??0,currentUserMfa:!!y.data?.all?.some(u=>u.status==="verified")}}})}const ve=()=>{const{isAdmin:c}=M(),{data:t}=le(),n=X(),[l,o]=d.useState(!1);return e.jsxs("div",{className:"space-y-6 px-1.5",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl md:text-3xl font-heading font-bold",children:"Security & Compliance"}),e.jsx("p",{className:"text-muted-foreground mt-1",children:"Data protection status aligned with Australian Privacy Principles."})]}),c&&e.jsxs("div",{className:"grid gap-4 md:grid-cols-4",children:[e.jsx(N,{label:"Audit entries",value:t?.auditCount??"—",icon:te,hint:"All time, append-only"}),e.jsx(N,{label:"Open breaches",value:t?.breachOpen??"—",icon:E,hint:t?.breachOpen?"Action required":"None recorded",tone:t?.breachOpen?"warn":"ok"}),e.jsx(N,{label:"Open DSARs",value:t?.dsarOpen??"—",icon:q,hint:"Due within 30 days"}),e.jsx(N,{label:"Last DSAR export",value:t?.lastDsar?ne(new Date(t.lastDsar),{addSuffix:!0}):"—",icon:q,hint:"From audit log"})]}),c&&e.jsxs(S,{className:"glass-card",children:[e.jsxs(F,{className:"pb-3",children:[e.jsxs(T,{className:"text-base font-heading flex items-center gap-2",children:[e.jsx(L,{className:"h-4 w-4"})," Your MFA status"]}),e.jsx(Y,{children:"Admins are required to enroll TOTP. Use any authenticator app (Google Authenticator, 1Password, Authy)."})]}),e.jsxs(P,{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between text-sm",children:[e.jsx("span",{children:t?.currentUserMfa?"Two-factor authentication enabled":"Two-factor authentication not enabled"}),e.jsx(k,{variant:t?.currentUserMfa?"secondary":"destructive",children:t?.currentUserMfa?"OK":"Action required"})]}),e.jsx(J,{value:t?.currentUserMfa?100:0}),!t?.currentUserMfa&&e.jsx(C,{size:"sm",onClick:()=>o(!0),children:"Enable two-factor authentication"})]})]}),e.jsx(ce,{open:l,onOpenChange:o,onEnrolled:()=>n.invalidateQueries({queryKey:["compliance_dashboard_metrics"]})}),e.jsx("div",{className:"grid gap-4 md:grid-cols-2",children:oe.map(r=>e.jsxs(S,{className:"glass-card",children:[e.jsxs(F,{className:"flex flex-row items-center gap-3 pb-2",children:[e.jsx("div",{className:"h-10 w-10 rounded-lg bg-primary/10 flex items-center justify-center shrink-0",children:e.jsx(r.icon,{className:"h-5 w-5 text-primary"})}),e.jsx("div",{className:"flex-1 min-w-0",children:e.jsx(T,{className:"text-base font-heading",children:r.title})}),e.jsx(k,{variant:"secondary",className:"bg-success/15 text-success border-success/30 shrink-0",children:r.status})]}),e.jsx(P,{children:e.jsx("p",{className:"text-sm text-muted-foreground",children:r.description})})]},r.title))})]})};function N({label:c,value:t,icon:n,hint:l,tone:o="neutral"}){const r=o==="warn"?"text-amber-600":o==="ok"?"text-success":"text-foreground";return e.jsx(S,{className:"glass-card",children:e.jsxs(P,{className:"p-4 space-y-1",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:c}),e.jsx(n,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsx("div",{className:`text-2xl font-heading font-bold ${r}`,children:t}),l&&e.jsx("div",{className:"text-xs text-muted-foreground",children:l})]})})}export{ve as default};

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.