@nice2dev/ui-security 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,292 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),h=require("react"),He={low:.7,medium:.8,high:.85,critical:.95},Ue={matchThreshold:.85,timeout:3e4,maxRetries:3,livenessDetection:!0,verifyEndpoint:"",authToken:"",showFeedback:!0,hapticFeedback:!0,locale:"en",securityLevel:"high",antiSpoofing:!0};function ie(e){const t={...Ue,...e};return e!=null&&e.matchThreshold||(t.matchThreshold=He[t.securityLevel]),t}async function ae(e){const t=new TextEncoder().encode(e),r=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(r)).map(n=>n.toString(16).padStart(2,"0")).join("")}function le(e=8){const t=new Uint8Array(e);return crypto.getRandomValues(t),Array.from(t).map(r=>r.toString(36).padStart(2,"0")).join("").slice(0,e)}function Oe(e){const t=new Uint32Array(1);return crypto.getRandomValues(t),t[0]%e}function qe(e,t){return Math.sqrt((e.x-t.x)**2+(e.y-t.y)**2)}async function oe(e="user"){return navigator.mediaDevices.getUserMedia({video:{facingMode:e,width:{ideal:1280},height:{ideal:720}},audio:!1})}function te(e,t,r){const n=t??e.videoWidth,i=r??e.videoHeight,a=document.createElement("canvas");a.width=n,a.height=i;const o=a.getContext("2d");o.drawImage(e,0,0,n,i);const c=o.getImageData(0,0,n,i);return{canvas:a,ctx:o,imageData:c}}function re(e){const t=new Uint8Array(e.width*e.height),r=e.data;for(let n=0;n<t.length;n++){const i=n*4;t[n]=Math.round(.299*r[i]+.587*r[i+1]+.114*r[i+2])}return t}function Se(e,t,r){const n=new Uint8Array(t*r),i=[1,2,1,2,4,2,1,2,1],a=16;for(let o=1;o<r-1;o++)for(let c=1;c<t-1;c++){let m=0,x=0;for(let y=-1;y<=1;y++)for(let v=-1;v<=1;v++)m+=e[(o+y)*t+(c+v)]*i[x++];n[o*t+c]=Math.round(m/a)}return n}function Ke(e,t,r){const n=new Uint8Array(t*r);for(let i=1;i<r-1;i++)for(let a=1;a<t-1;a++){const o=-e[(i-1)*t+(a-1)]+e[(i-1)*t+(a+1)]+-2*e[i*t+(a-1)]+2*e[i*t+(a+1)]+-e[(i+1)*t+(a-1)]+e[(i+1)*t+(a+1)],c=-e[(i-1)*t+(a-1)]-2*e[(i-1)*t+a]-e[(i-1)*t+(a+1)]+e[(i+1)*t+(a-1)]+2*e[(i+1)*t+a]+e[(i+1)*t+(a+1)];n[i*t+a]=Math.min(255,Math.round(Math.sqrt(o*o+c*c)))}return n}function Ge(e){const t=new Array(256).fill(0);for(const x of e)t[x]++;const r=e.length;let n=0;for(let x=0;x<256;x++)n+=x*t[x];let i=0,a=0,o=0,c=0;for(let x=0;x<256;x++){if(a+=t[x],a===0)continue;const y=r-a;if(y===0)break;i+=x*t[x];const v=i/a,A=(n-i)/y,g=a*y*(v-A)**2;g>o&&(o=g,c=x)}const m=new Uint8Array(e.length);for(let x=0;x<e.length;x++)m[x]=e[x]>c?255:0;return{threshold:c,binary:m}}function ke(e,t=.3){var p;const r=e.width,n=e.height,i=re(e),a=Se(i,r,n),o=Ke(a,r,n),{binary:c}=Ge(o),m=[],x=[],y=[];for(let k=2;k<n-2;k++)for(let u=2;u<r-2;u++){if(c[k*r+u]===0)continue;const w=[c[(k-1)*r+u],c[(k-1)*r+(u+1)],c[k*r+(u+1)],c[(k+1)*r+(u+1)],c[(k+1)*r+u],c[(k+1)*r+(u-1)],c[k*r+(u-1)],c[(k-1)*r+(u-1)]];let l=0;for(let B=0;B<8;B++){const H=w[B]>0?1:0,G=w[(B+1)%8]>0?1:0;l+=Math.abs(H-G)}l/=2;let f=0,z=0;for(let B=-2;B<=2;B++)for(let H=-2;H<=2;H++)f+=o[(k+B)*r+(u+H)],z++;const O=f/z/255;if(O<t)continue;const J=Math.atan2(i[(k+1)*r+u]-i[(k-1)*r+u],i[k*r+(u+1)]-i[k*r+(u-1)]);l===1?m.push({x:u/r,y:k/n,angle:J,type:"ending",quality:O}):l===3&&m.push({x:u/r,y:k/n,angle:J,type:"bifurcation",quality:O})}m.sort((k,u)=>u.quality-k.quality);const v=m.slice(0,120);if(v.length>5){const k=v.reduce((w,l)=>w+l.x,0)/v.length,u=v.reduce((w,l)=>w+l.y,0)/v.length;x.push({x:k,y:u})}const A=v.length,g=v.filter(k=>k.type==="ending").length,D=v.filter(k=>k.type==="bifurcation").length/(g+1);let b="loop-right";D>1.5?b="whorl":D<.5?b="arch":((p=x[0])==null?void 0:p.x)<.45&&(b="loop-left");const T=v.length>20?v.reduce((k,u)=>k+u.quality,0)/v.length:0;return{minutiae:v,corePoints:x,deltaPoints:y,ridgeCount:A,patternType:b,quality:T}}function Ae(e,t){if(e.minutiae.length<5||t.minutiae.length<5)return 0;let r=0;const n=.05,i=.5,a=new Set;for(const c of e.minutiae){let m=1/0,x=-1;for(let y=0;y<t.minutiae.length;y++){if(a.has(y))continue;const v=t.minutiae[y];if(c.type!==v.type)continue;const A=qe(c,v),g=Math.abs(c.angle-v.angle);A<n&&g<i&&A<m&&(m=A,x=y)}x>=0&&(r++,a.add(x))}const o=Math.min(e.minutiae.length,t.minutiae.length);return o>0?r/o:0}async function je(e,t){const r=JSON.stringify(e),n=await ae(r);return{id:`fp_${Date.now()}_${le()}`,method:"fingerprint",templateData:btoa(r),enrolled:Date.now(),label:t,hash:n}}function Te(e){return JSON.parse(atob(e.templateData))}function Ce(e,t="left"){const r=e.width,n=e.height,i=re(e),a=Se(i,r,n);let o={cx:r/2,cy:n/2,r:Math.min(r,n)*.08,score:1/0};for(let I=Math.round(n*.3);I<Math.round(n*.7);I+=2)for(let D=Math.round(r*.3);D<Math.round(r*.7);D+=2)for(let b=Math.round(Math.min(r,n)*.04);b<Math.round(Math.min(r,n)*.15);b+=2){let T=0,p=0;for(let l=0;l<Math.PI*2;l+=.3){const f=Math.round(D+b*Math.cos(l)),z=Math.round(I+b*Math.sin(l));f>=0&&f<r&&z>=0&&z<n&&(T+=a[z*r+f],p++)}const k=p>0?T/p:255,u=a[I*r+D],w=k*.5+u*.5;w<o.score&&(o={cx:D,cy:I,r:b,score:w})}const c=o.r*3,m={cx:o.cx,cy:o.cy,r:Math.min(c,Math.min(r,n)*.4)},x=256,y=[];for(let I=0;I<x;I++){const D=I/x*Math.PI*2,b=o.r+(m.r-o.r)*.5,T=Math.round(o.cx+b*Math.cos(D)),p=Math.round(o.cy+b*Math.sin(D));if(T>=0&&T<r&&p>=0&&p<n){const k=Math.round(o.cx+b*Math.cos(D+.1)),u=Math.round(o.cy+b*Math.sin(D+.1)),w=a[p*r+T],l=k>=0&&k<r&&u>=0&&u<n?a[u*r+k]:w;y.push(w>l?1:0)}else y.push(0)}const v=y.join(""),A=Math.PI*o.r**2,g=Math.min(1,Math.max(0,A/(r*n)*100));return{irisCode:v,pupil:o,iris:m,quality:g,eye:t}}function Ie(e,t){if(!e.irisCode||!t.irisCode)return 0;const r=Math.min(e.irisCode.length,t.irisCode.length);if(r===0)return 0;let n=0,i=r;for(let o=-8;o<=8;o++){let c=0;for(let m=0;m<r;m++){const x=(m+o+r)%r;e.irisCode[m]!==t.irisCode[x]&&c++}c<i&&(i=c)}n=i;const a=n/r;return Math.max(0,1-a*2.5)}async function Re(e,t){const r=JSON.stringify(e),n=await ae(r);return{id:`iris_${Date.now()}_${le()}`,method:"iris",templateData:btoa(r),enrolled:Date.now(),label:t,hash:n}}function De(e){return JSON.parse(atob(e.templateData))}function ne(e){const t=e.width,r=e.height,n=e.data,i=new Uint8Array(t*r);for(let u=0;u<t*r;u++){const w=u*4,l=n[w],f=n[w+1],z=n[w+2],O=.299*l+.587*f+.114*z,J=128-.169*l-.331*f+.5*z,B=128+.5*l-.419*f-.081*z;J>=77&&J<=127&&B>=133&&B<=173&&O>80&&(i[u]=1)}let a=t,o=r,c=0,m=0,x=0;for(let u=0;u<r;u++)for(let w=0;w<t;w++)i[u*t+w]&&(x++,w<a&&(a=w),w>c&&(c=w),u<o&&(o=u),u>m&&(m=u));const y=c-a,v=m-o;if(y<t*.1||v<r*.1)return null;const A={x:a,y:o,width:y,height:v},g=[],I=re(e),D=Math.max(1,Math.floor(y/8)),b=Math.max(1,Math.floor(v/16));for(let u=0;u<16;u++)for(let w=0;w<8;w++){const l=a+w*D+Math.floor(D/2),f=o+u*b+Math.floor(b/2);l<t&&f<r?g.push(I[f*t+l]/255):g.push(0)}const T=[],p={x:a+y/2,y:o+v/2};for(let u=0;u<68;u++){const w=u/68*Math.PI*2,l=y*.4*Math.cos(w),f=v*.45*Math.sin(w);T.push({x:(p.x+l)/t,y:(p.y+f)/r})}const k=Math.min(1,x/(y*v)*2);return{embedding:g,boundingBox:A,landmarks:T,headPose:{yaw:0,pitch:0,roll:0},quality:k}}function ue(e,t){if(e.embedding.length!==t.embedding.length)return 0;let r=0,n=0,i=0;for(let o=0;o<e.embedding.length;o++)r+=e.embedding[o]*t.embedding[o],n+=e.embedding[o]**2,i+=t.embedding[o]**2;const a=Math.sqrt(n)*Math.sqrt(i);return a>0?(r/a+1)/2:0}function Me(e,t){const r=ne(e),n=ne(t);return!r||!n?{similarity:0,cameraFeatures:r,refFeatures:n}:{similarity:ue(r,n),cameraFeatures:r,refFeatures:n}}async function Pe(e,t){const r=JSON.stringify(e),n=await ae(r);return{id:`face_${Date.now()}_${le()}`,method:"face",templateData:btoa(r),enrolled:Date.now(),label:t,hash:n}}function Ee(e){return JSON.parse(atob(e.templateData))}function Je(){const e=["blink","smile","turn-left","turn-right","nod","raise-eyebrows"],t=e[Oe(e.length)];return{type:t,instruction:{blink:"Please blink your eyes",smile:"Please smile","turn-left":"Please turn your head left","turn-right":"Please turn your head right",nod:"Please nod your head","raise-eyebrows":"Please raise your eyebrows"}[t],completed:!1,confidence:0}}function de(e,t=.02){if(e.length<2)return{isLive:!1,confidence:0,motionScore:0};let r=0;for(let o=1;o<e.length;o++){const c=re(e[o-1]),m=re(e[o]);let x=0;for(let y=0;y<c.length;y++)x+=Math.abs(c[y]-m[y]);r+=x/(c.length*255)}const n=r/(e.length-1),i=n>t,a=Math.min(1,n/(t*3));return{isLive:i,confidence:a,motionScore:n}}function he(){return{userAgent:navigator.userAgent,platform:navigator.platform,language:navigator.language,screenResolution:[screen.width,screen.height],timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,touchSupport:"ontouchstart"in window||navigator.maxTouchPoints>0,hardwareConcurrency:navigator.hardwareConcurrency??0}}async function se(){const e=he(),t=JSON.stringify(e);return ae(t)}function fe(){return typeof window<"u"&&!!window.PublicKeyCredential}async function Fe(){if(!fe())return!1;try{return await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return!1}}async function Ne(e){const t={rp:{name:e.rpName,id:e.rpId},user:{id:new TextEncoder().encode(e.userId),name:e.userName,displayName:e.userDisplayName},challenge:e.challenge,pubKeyCredParams:[{alg:-7,type:"public-key"},{alg:-257,type:"public-key"}],authenticatorSelection:{authenticatorAttachment:"platform",userVerification:"required",residentKey:"preferred"},timeout:e.timeout??6e4,attestation:"none"};return await navigator.credentials.create({publicKey:t})}async function ze(e){const t={rpId:e.rpId,challenge:e.challenge,allowCredentials:e.allowCredentials,userVerification:"required",timeout:e.timeout??6e4};return await navigator.credentials.get({publicKey:t})}async function ce(e,t,r){const n={"Content-Type":"application/json"};r&&(n.Authorization=`Bearer ${r}`);const i=await fetch(e,{method:"POST",headers:n,body:JSON.stringify(t)});return i.ok?i.json():{verified:!1,message:`Server error: ${i.status}`}}const Ye=(e,t)=>t,Le=h.createContext(Ye),Ze=({t:e,children:t})=>s.jsx(Le.Provider,{value:e,children:t});function X(){return{t:h.useContext(Le)}}const Xe={sm:200,md:280,lg:380},Qe=e=>{const{mode:t,enrolledTemplates:r=[],fingerPosition:n="right-index",onEnroll:i,onVerify:a,onStatusChange:o,onError:c,className:m,size:x="md",label:y,showQuality:v=!0,showMinutiae:A=!1,instructionText:g,cameraFacing:I="environment",...D}=e,{t:b}=X(),T=ie(D),p=Xe[x],k=h.useRef(null),u=h.useRef(null),w=h.useRef(null),[l,f]=h.useState("idle"),[z,O]=h.useState(0),[J,B]=h.useState(null),[H,G]=h.useState(0),[W,L]=h.useState(""),$=h.useCallback(P=>{f(P),o==null||o(P)},[o]),E=h.useCallback(async()=>{try{const P=await oe(I);w.current=P,k.current&&(k.current.srcObject=P,await k.current.play()),$("idle"),L(b("security.fingerprint.placeFingerPrompt","Place your finger on the scanner"))}catch(P){c==null||c(P instanceof Error?P:new Error(String(P))),L(b("security.fingerprint.cameraError","Camera access denied")),$("error")}},[I,b,$,c]),q=h.useCallback(()=>{var P;(P=w.current)==null||P.getTracks().forEach(C=>C.stop()),w.current=null},[]);h.useEffect(()=>(E(),q),[E,q]);const _=h.useCallback(async()=>{if(!(!k.current||l==="processing"||l==="success")){$("scanning"),L(b("security.fingerprint.scanning","Scanning…"));try{const{imageData:P}=te(k.current);$("processing"),L(b("security.fingerprint.processing","Processing fingerprint…"));const C=ke(P);if(B(C),O(C.quality),C.quality<.2){L(b("security.fingerprint.lowQuality","Low quality — try again")),$("idle");return}if(t==="enroll"){const F=await je(C,y??n);i==null||i(F,C),L(b("security.fingerprint.enrolled","Fingerprint enrolled successfully")),$("success")}else{let F=0;for(const d of r){const j=Te(d),N=Ae(C,j);N>F&&(F=N)}const R=F>=T.matchThreshold,S={success:R,confidence:F,method:"fingerprint",timestamp:Date.now(),duration:0,payload:btoa(JSON.stringify(C))};if(R&&T.verifyEndpoint){const d=await se(),j=await ce(T.verifyEndpoint,{method:"fingerprint",templateData:S.payload,matchScore:F,deviceFingerprint:d},T.authToken);S.success=j.verified}S.success?(L(b("security.fingerprint.verified","Fingerprint verified")),$("success")):(G(d=>d+1),H+1>=T.maxRetries?(L(b("security.fingerprint.maxAttempts","Maximum attempts reached")),$("failure")):(L(b("security.fingerprint.noMatch","No match — try again")),$("idle"))),a==null||a(S)}}catch(P){c==null||c(P instanceof Error?P:new Error(String(P))),L(b("security.fingerprint.error","Scan error — try again")),$("error")}}},[l,t,r,T,b,$,i,a,c,y,n,H]);h.useEffect(()=>{if(!A||!J||!u.current)return;const P=u.current.getContext("2d");P&&(P.clearRect(0,0,p,p),J.minutiae.forEach(C=>{P.beginPath(),P.arc(C.x*p,C.y*p,2,0,Math.PI*2),P.fillStyle=C.type==="ending"?"#10b981":"#f59e0b",P.fill(),P.beginPath(),P.moveTo(C.x*p,C.y*p),P.lineTo(C.x*p+Math.cos(C.angle)*8,C.y*p+Math.sin(C.angle)*8),P.strokeStyle=P.fillStyle,P.lineWidth=1,P.stroke()}))},[J,A,p]);const Y=l==="success"?"var(--security-success)":l==="failure"||l==="error"?"var(--security-error)":l==="scanning"||l==="processing"?"var(--security-biometric)":"var(--security-border)";return s.jsxs("div",{className:m,style:{display:"inline-flex",flexDirection:"column",alignItems:"center",gap:12},children:[y&&s.jsx("div",{style:{fontSize:14,fontWeight:600,color:"var(--security-text)"},children:y}),s.jsxs("div",{style:{width:p,height:p,position:"relative",borderRadius:"var(--security-radius-lg)",overflow:"hidden",border:`3px solid ${Y}`,boxShadow:l==="scanning"?`0 0 20px ${Y}`:"var(--security-shadow)",transition:"border-color 0.3s, box-shadow 0.3s"},children:[s.jsx("video",{ref:k,style:{width:"100%",height:"100%",objectFit:"cover"},playsInline:!0,muted:!0}),A&&s.jsx("canvas",{ref:u,width:p,height:p,style:{position:"absolute",inset:0,pointerEvents:"none"}}),s.jsxs("svg",{viewBox:"0 0 100 100",style:{position:"absolute",inset:0,width:"100%",height:"100%",pointerEvents:"none",opacity:.3},children:[s.jsx("ellipse",{cx:"50",cy:"50",rx:"28",ry:"38",fill:"none",stroke:"white",strokeWidth:"1",strokeDasharray:"4 3"}),s.jsx("ellipse",{cx:"50",cy:"50",rx:"20",ry:"28",fill:"none",stroke:"white",strokeWidth:"0.5",strokeDasharray:"2 3"})]}),(l==="scanning"||l==="processing")&&s.jsx("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,0.3)"},children:s.jsx("div",{style:{width:60,height:60,borderRadius:"50%",border:"3px solid transparent",borderTopColor:Y,animation:"spin 0.8s linear infinite"}})})]}),v&&z>0&&s.jsx("div",{style:{width:p,height:4,background:"var(--security-bg-panel)",borderRadius:2,overflow:"hidden"},children:s.jsx("div",{style:{width:`${z*100}%`,height:"100%",background:z>.6?"var(--security-success)":z>.3?"var(--security-warning)":"var(--security-error)",transition:"width 0.3s"}})}),s.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",textAlign:"center",minHeight:20},children:g??W}),l!=="success"&&l!=="failure"&&s.jsx("button",{onClick:_,disabled:l==="scanning"||l==="processing",style:{padding:"10px 24px",fontSize:14,fontWeight:600,background:"var(--security-biometric)",color:"#fff",border:"none",borderRadius:"var(--security-radius)",cursor:"pointer",opacity:l==="scanning"||l==="processing"?.6:1},children:t==="enroll"?b("security.fingerprint.captureBtn","🖐️ Capture Fingerprint"):b("security.fingerprint.verifyBtn","🖐️ Verify Fingerprint")}),(l==="failure"||l==="error")&&s.jsx("button",{onClick:()=>{G(0),$("idle"),L("")},style:{padding:"8px 20px",fontSize:13,background:"var(--security-bg-panel)",color:"var(--security-text)",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",cursor:"pointer"},children:b("security.common.retry","Try Again")}),s.jsx("style",{children:"@keyframes spin { to { transform: rotate(360deg); } }"})]})},Ve={sm:220,md:300,lg:400},et=e=>{const{mode:t,enrolledTemplates:r=[],eye:n="right",onEnroll:i,onVerify:a,onStatusChange:o,onError:c,className:m,size:x="md",label:y,showQuality:v=!0,showSegmentation:A=!0,showGuide:g=!0,instructionText:I,...D}=e,{t:b}=X(),T=ie(D),p=Ve[x],k=h.useRef(null),u=h.useRef(null),w=h.useRef(null),l=h.useRef([]),[f,z]=h.useState("idle"),[O,J]=h.useState(0),[B,H]=h.useState(null),[G,W]=h.useState(0),[L,$]=h.useState(""),E=h.useCallback(C=>{z(C),o==null||o(C)},[o]),q=h.useCallback(async()=>{try{const C=await oe("user");w.current=C,k.current&&(k.current.srcObject=C,await k.current.play()),E("idle"),$(b("security.iris.alignEyePrompt","Align your eye with the circle"))}catch(C){c==null||c(C instanceof Error?C:new Error(String(C))),$(b("security.iris.cameraError","Camera access denied")),E("error")}},[b,E,c]),_=h.useCallback(()=>{var C;(C=w.current)==null||C.getTracks().forEach(F=>F.stop()),w.current=null},[]);h.useEffect(()=>(q(),_),[q,_]);const Y=h.useCallback(async()=>{if(!(!k.current||f==="processing"||f==="success")){E("scanning"),$(b("security.iris.scanning","Scanning iris…"));try{const C=[];for(let S=0;S<5;S++){const{imageData:d}=te(k.current);C.push(d),await new Promise(j=>setTimeout(j,200))}if(l.current=C,T.livenessDetection&&!de(C).isLive){$(b("security.iris.notLive","Liveness check failed — please blink or move slightly")),E("idle");return}E("processing"),$(b("security.iris.processing","Processing iris pattern…"));const F=C[C.length-1],R=Ce(F,n==="both"?"left":n);if(!R){$(b("security.iris.noIrisDetected","No iris detected — adjust position")),E("idle");return}if(H(R),J(R.quality),R.quality<.1){$(b("security.iris.lowQuality","Low quality — move closer")),E("idle");return}if(A&&u.current){const S=u.current.getContext("2d");if(S){S.clearRect(0,0,p,p);const d=p/F.width,j=p/F.height;S.beginPath(),S.arc(R.pupil.cx*d,R.pupil.cy*j,R.pupil.r*d,0,Math.PI*2),S.strokeStyle="#ef4444",S.lineWidth=2,S.stroke(),S.beginPath(),S.arc(R.iris.cx*d,R.iris.cy*j,R.iris.r*d,0,Math.PI*2),S.strokeStyle="#3b82f6",S.lineWidth=2,S.stroke()}}if(t==="enroll"){const S=await Re(R,y??`${n} eye`);i==null||i(S,R),$(b("security.iris.enrolled","Iris enrolled successfully")),E("success")}else{let S=0;for(const N of r){const M=De(N),U=Ie(R,M);U>S&&(S=U)}const d=S>=T.matchThreshold,j={success:d,confidence:S,method:"iris",timestamp:Date.now(),duration:0,livenessPassed:T.livenessDetection?!0:void 0,payload:btoa(JSON.stringify(R))};if(d&&T.verifyEndpoint){const N=await se(),M=await ce(T.verifyEndpoint,{method:"iris",templateData:j.payload,matchScore:S,deviceFingerprint:N},T.authToken);j.success=M.verified}j.success?($(b("security.iris.verified","Iris verified")),E("success")):(W(N=>N+1),G+1>=T.maxRetries?($(b("security.iris.maxAttempts","Maximum attempts reached")),E("failure")):($(b("security.iris.noMatch","No match — try again")),E("idle"))),a==null||a(j)}}catch(C){c==null||c(C instanceof Error?C:new Error(String(C))),$(b("security.iris.error","Scan error")),E("error")}}},[f,t,r,T,b,E,i,a,c,y,n,G,A,p]),P=f==="success"?"var(--security-success)":f==="failure"||f==="error"?"var(--security-error)":f==="scanning"||f==="processing"?"var(--security-biometric)":"var(--security-border)";return s.jsxs("div",{className:m,style:{display:"inline-flex",flexDirection:"column",alignItems:"center",gap:12},children:[y&&s.jsx("div",{style:{fontSize:14,fontWeight:600,color:"var(--security-text)"},children:y}),s.jsxs("div",{style:{width:p,height:p,position:"relative",borderRadius:"50%",overflow:"hidden",border:`3px solid ${P}`,boxShadow:f==="scanning"?`0 0 30px ${P}`:"var(--security-shadow)",transition:"border-color 0.3s, box-shadow 0.3s"},children:[s.jsx("video",{ref:k,style:{width:"100%",height:"100%",objectFit:"cover"},playsInline:!0,muted:!0}),A&&s.jsx("canvas",{ref:u,width:p,height:p,style:{position:"absolute",inset:0,pointerEvents:"none"}}),g&&f==="idle"&&s.jsxs("svg",{viewBox:"0 0 100 100",style:{position:"absolute",inset:0,width:"100%",height:"100%",pointerEvents:"none",opacity:.4},children:[s.jsx("circle",{cx:"50",cy:"50",r:"35",fill:"none",stroke:"white",strokeWidth:"1",strokeDasharray:"5 3"}),s.jsx("circle",{cx:"50",cy:"50",r:"15",fill:"none",stroke:"white",strokeWidth:"0.5",strokeDasharray:"3 3"}),s.jsx("line",{x1:"50",y1:"10",x2:"50",y2:"25",stroke:"white",strokeWidth:"0.5",opacity:"0.5"}),s.jsx("line",{x1:"50",y1:"75",x2:"50",y2:"90",stroke:"white",strokeWidth:"0.5",opacity:"0.5"}),s.jsx("line",{x1:"10",y1:"50",x2:"25",y2:"50",stroke:"white",strokeWidth:"0.5",opacity:"0.5"}),s.jsx("line",{x1:"75",y1:"50",x2:"90",y2:"50",stroke:"white",strokeWidth:"0.5",opacity:"0.5"})]}),(f==="scanning"||f==="processing")&&s.jsx("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,0.2)"},children:s.jsx("div",{style:{width:p*.7,height:3,background:P,animation:"irisLineAnim 1.5s ease-in-out infinite",position:"absolute",opacity:.7}})})]}),s.jsx("div",{style:{fontSize:11,color:"var(--security-text-muted)",textTransform:"uppercase",letterSpacing:1},children:n==="both"?b("security.iris.bothEyes","Both eyes"):n==="left"?b("security.iris.leftEye","Left eye"):b("security.iris.rightEye","Right eye")}),v&&O>0&&s.jsx("div",{style:{width:p*.6,height:4,background:"var(--security-bg-panel)",borderRadius:2,overflow:"hidden"},children:s.jsx("div",{style:{width:`${Math.min(100,O*300)}%`,height:"100%",background:O>.3?"var(--security-success)":O>.1?"var(--security-warning)":"var(--security-error)",transition:"width 0.3s"}})}),s.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",textAlign:"center",minHeight:20},children:I??L}),f!=="success"&&f!=="failure"&&s.jsx("button",{onClick:Y,disabled:f==="scanning"||f==="processing",style:{padding:"10px 24px",fontSize:14,fontWeight:600,background:"var(--security-biometric)",color:"#fff",border:"none",borderRadius:"var(--security-radius)",cursor:"pointer",opacity:f==="scanning"||f==="processing"?.6:1},children:t==="enroll"?b("security.iris.captureBtn","👁️ Capture Iris"):b("security.iris.verifyBtn","👁️ Verify Iris")}),(f==="failure"||f==="error")&&s.jsx("button",{onClick:()=>{W(0),E("idle"),$("")},style:{padding:"8px 20px",fontSize:13,background:"var(--security-bg-panel)",color:"var(--security-text)",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",cursor:"pointer"},children:b("security.common.retry","Try Again")}),s.jsx("style",{children:`
2
+ @keyframes irisLineAnim {
3
+ 0%, 100% { transform: translateY(-${p*.3}px); opacity: 0.3; }
4
+ 50% { transform: translateY(${p*.3}px); opacity: 0.8; }
5
+ }
6
+ `})]})},tt={sm:240,md:320,lg:440},rt=e=>{const{mode:t,enrolledTemplates:r=[],referencePhoto:n,onEnroll:i,onVerify:a,onStatusChange:o,onError:c,className:m,size:x="md",label:y,showQuality:v=!0,showBoundingBox:A=!0,livenessSteps:g=1,showReference:I=!0,instructionText:D,...b}=e,{t:T}=X(),p=ie(b),k=tt[x],u=h.useRef(null),w=h.useRef(null),l=h.useRef(null),[f,z]=h.useState("idle"),[O,J]=h.useState(0),[B,H]=h.useState(0),[G,W]=h.useState(""),[L,$]=h.useState(null),[E,q]=h.useState(0),_=h.useCallback(S=>{z(S),o==null||o(S)},[o]),Y=h.useCallback(async()=>{try{const S=await oe("user");l.current=S,u.current&&(u.current.srcObject=S,await u.current.play()),_("idle"),W(T("security.face.lookAtCamera","Look at the camera"))}catch(S){c==null||c(S instanceof Error?S:new Error(String(S))),W(T("security.face.cameraError","Camera access denied")),_("error")}},[T,_,c]),P=h.useCallback(()=>{var S;(S=l.current)==null||S.getTracks().forEach(d=>d.stop()),l.current=null},[]);h.useEffect(()=>(Y(),P),[Y,P]);const C=h.useCallback(S=>{var ge,me,ve;const d=(ge=w.current)==null?void 0:ge.getContext("2d");if(!d)return;const j=w.current.width,N=w.current.height;if(d.clearRect(0,0,j,N),!S||!A)return;const M=S.boundingBox,U=j/(((me=u.current)==null?void 0:me.videoWidth)??j),K=N/(((ve=u.current)==null?void 0:ve.videoHeight)??N);d.strokeStyle=f==="success"?"#10b981":"#3b82f6",d.lineWidth=2,d.setLineDash([6,4]),d.strokeRect(M.x*U,M.y*K,M.width*U,M.height*K),d.setLineDash([]);const Z=[[M.x*U,M.y*K],[(M.x+M.width)*U,M.y*K],[M.x*U,(M.y+M.height)*K],[(M.x+M.width)*U,(M.y+M.height)*K]],Q=12;d.lineWidth=3;for(const[V,ee]of Z)d.beginPath(),d.moveTo(V===M.x*U?V:V-Q,ee),d.lineTo(V,ee),d.lineTo(V,ee===M.y*K?ee+Q:ee-Q),d.stroke()},[A,f]),F=h.useCallback(async()=>{if(!(!u.current||f==="processing"||f==="success")){_("scanning"),W(T("security.face.scanning","Scanning face…"));try{if(p.livenessDetection){const j=[];for(let M=0;M<8;M++)j.push(te(u.current).imageData),await new Promise(U=>setTimeout(U,200));if(!de(j).isLive){W(T("security.face.notLive","Liveness check failed — move naturally")),_("idle");return}}_("processing"),W(T("security.face.processing","Analysing face…"));const{imageData:S}=te(u.current);if(t==="compare"&&n){const j=typeof n=="string"?await st(n):nt(n),{similarity:N,cameraFeatures:M,refFeatures:U}=Me(S,j);q(N),J((M==null?void 0:M.quality)??0),C(M);const Z={success:N>=p.matchThreshold,confidence:N,method:"face",timestamp:Date.now(),duration:0,livenessPassed:p.livenessDetection};Z.success?(W(T("security.face.matchFound",`Match: ${(N*100).toFixed(0)}%`)),_("success")):(H(Q=>Q+1),B+1>=p.maxRetries?(W(T("security.face.maxAttempts","Maximum attempts reached")),_("failure")):(W(T("security.face.noMatch","No match — try again")),_("idle"))),a==null||a(Z);return}const d=ne(S);if(!d){W(T("security.face.noFaceDetected","No face detected")),_("idle");return}if(J(d.quality),C(d),t==="enroll"){const j=await Pe(d,y??"face");i==null||i(j,d),W(T("security.face.enrolled","Face enrolled successfully")),_("success")}else{let j=0;for(const U of r){const K=Ee(U),Z=ue(d,K);Z>j&&(j=Z)}q(j);const N=j>=p.matchThreshold,M={success:N,confidence:j,method:"face",timestamp:Date.now(),duration:0,livenessPassed:p.livenessDetection};if(N&&p.verifyEndpoint){const U=await se(),K=await ce(p.verifyEndpoint,{method:"face",templateData:btoa(JSON.stringify(d)),matchScore:j,deviceFingerprint:U},p.authToken);M.success=K.verified}M.success?(W(T("security.face.verified","Face verified")),_("success")):(H(U=>U+1),B+1>=p.maxRetries?(W(T("security.face.maxAttempts","Maximum attempts reached")),_("failure")):(W(T("security.face.noMatch","No match — try again")),_("idle"))),a==null||a(M)}}catch(S){c==null||c(S instanceof Error?S:new Error(String(S))),W(T("security.face.error","Error — try again")),_("error")}}},[f,t,r,n,p,T,_,i,a,c,y,B,C]),R=f==="success"?"var(--security-success)":f==="failure"||f==="error"?"var(--security-error)":f==="scanning"||f==="processing"?"var(--security-biometric)":"var(--security-border)";return s.jsxs("div",{className:m,style:{display:"inline-flex",flexDirection:"column",alignItems:"center",gap:12},children:[y&&s.jsx("div",{style:{fontSize:14,fontWeight:600,color:"var(--security-text)"},children:y}),s.jsxs("div",{style:{display:"flex",gap:16,alignItems:"center"},children:[s.jsxs("div",{style:{width:k,height:k*.75,position:"relative",borderRadius:"var(--security-radius-lg)",overflow:"hidden",border:`3px solid ${R}`,boxShadow:f==="scanning"?`0 0 20px ${R}`:"var(--security-shadow)",transition:"border-color 0.3s, box-shadow 0.3s"},children:[s.jsx("video",{ref:u,style:{width:"100%",height:"100%",objectFit:"cover",transform:"scaleX(-1)"},playsInline:!0,muted:!0}),s.jsx("canvas",{ref:w,width:k,height:k*.75,style:{position:"absolute",inset:0,pointerEvents:"none",transform:"scaleX(-1)"}}),s.jsx("svg",{viewBox:"0 0 100 75",style:{position:"absolute",inset:0,width:"100%",height:"100%",pointerEvents:"none",opacity:.3},children:s.jsx("ellipse",{cx:"50",cy:"37",rx:"22",ry:"30",fill:"none",stroke:"white",strokeWidth:"0.8",strokeDasharray:"4 3"})}),(f==="scanning"||f==="processing")&&s.jsx("div",{style:{position:"absolute",inset:0,background:"rgba(0,0,0,0.15)",display:"flex",alignItems:"center",justifyContent:"center"},children:s.jsx("div",{style:{width:50,height:50,borderRadius:"50%",border:"3px solid transparent",borderTopColor:R,animation:"spin 0.8s linear infinite"}})})]}),t==="compare"&&I&&n&&s.jsxs("div",{style:{width:k*.4,height:k*.5,borderRadius:"var(--security-radius)",overflow:"hidden",border:"2px solid var(--security-border)"},children:[s.jsx("img",{src:typeof n=="string"?n:void 0,alt:"Reference",style:{width:"100%",height:"100%",objectFit:"cover"}}),s.jsx("div",{style:{textAlign:"center",fontSize:10,padding:4,color:"var(--security-text-muted)",background:"var(--security-bg-panel)"},children:T("security.face.reference","Reference")})]})]}),E>0&&s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,fontSize:13},children:[s.jsxs("span",{style:{color:"var(--security-text-secondary)"},children:[T("security.face.confidence","Confidence"),":"]}),s.jsx("div",{style:{width:100,height:6,background:"var(--security-bg-panel)",borderRadius:3,overflow:"hidden"},children:s.jsx("div",{style:{width:`${E*100}%`,height:"100%",background:E>=p.matchThreshold?"var(--security-success)":"var(--security-warning)"}})}),s.jsxs("span",{style:{fontWeight:600,color:E>=p.matchThreshold?"var(--security-success)":"var(--security-warning)"},children:[(E*100).toFixed(0),"%"]})]}),s.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",textAlign:"center",minHeight:20},children:D??G}),f!=="success"&&f!=="failure"&&s.jsx("button",{onClick:F,disabled:f==="scanning"||f==="processing",style:{padding:"10px 24px",fontSize:14,fontWeight:600,background:"var(--security-biometric)",color:"#fff",border:"none",borderRadius:"var(--security-radius)",cursor:"pointer",opacity:f==="scanning"||f==="processing"?.6:1},children:t==="enroll"?T("security.face.captureBtn","📸 Capture Face"):t==="compare"?T("security.face.compareBtn","📸 Compare"):T("security.face.verifyBtn","📸 Verify Face")}),(f==="failure"||f==="error")&&s.jsx("button",{onClick:()=>{H(0),q(0),_("idle"),W("")},style:{padding:"8px 20px",fontSize:13,background:"var(--security-bg-panel)",color:"var(--security-text)",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",cursor:"pointer"},children:T("security.common.retry","Try Again")}),s.jsx("style",{children:"@keyframes spin { to { transform: rotate(360deg); } }"})]})};async function st(e){return new Promise((t,r)=>{const n=new Image;n.crossOrigin="anonymous",n.onload=()=>{const i=document.createElement("canvas");i.width=n.naturalWidth,i.height=n.naturalHeight;const a=i.getContext("2d");a.drawImage(n,0,0),t(a.getImageData(0,0,i.width,i.height))},n.onerror=()=>r(new Error("Failed to load reference image")),n.src=e})}function nt(e){const t=document.createElement("canvas");t.width=e.naturalWidth||e.width,t.height=e.naturalHeight||e.height;const r=t.getContext("2d");return r.drawImage(e,0,0),r.getImageData(0,0,t.width,t.height)}const it=4,at=5,ot=3e4,ct=e=>{const{length:t=it,scramble:r=!1,showDigits:n=!1,maxAttempts:i=at,lockoutDuration:a=ot,keySize:o=64,haptic:c=!0,keyLabels:m,expectedHash:x,expectedPin:y,mode:v="verify",onComplete:A,onVerify:g,onStatusChange:I,onError:D,showBiometricFallback:b=!1,onBiometricFallback:T,label:p,className:k}=e,{t:u}=X(),[w,l]=h.useState([]),[f,z]=h.useState("idle"),[O,J]=h.useState(0),[B,H]=h.useState(0),[G,W]=h.useState(null),L=h.useRef(),$=h.useMemo(()=>{const F=["1","2","3","4","5","6","7","8","9","","0","back"];if(!r)return F;const R=["0","1","2","3","4","5","6","7","8","9"];for(let S=R.length-1;S>0;S--){const d=new Uint32Array(1);crypto.getRandomValues(d);const j=d[0]%(S+1);[R[S],R[j]]=[R[j],R[S]]}return[R[0],R[1],R[2],R[3],R[4],R[5],R[6],R[7],R[8],"",R[9],"back"]},[r,f]),E=h.useCallback(F=>{z(F),I==null||I(F)},[I]);h.useEffect(()=>{if(!(B<=Date.now()))return L.current=setInterval(()=>{Date.now()>=B&&(clearInterval(L.current),E("idle"),J(0),l([]))},500),()=>clearInterval(L.current)},[B,E]);const q=B>Date.now(),_=h.useCallback(()=>{c&&navigator.vibrate&&navigator.vibrate(20)},[c]),Y=h.useCallback(async F=>{if(q||f==="success")return;if(_(),F==="back"){l(j=>j.slice(0,-1));return}if(F==="")return;const R=[...w,F];if(l(R),R.length<t)return;const S=R.join("");if(E("processing"),v==="set"){if(G===null){W(S),l([]),E("idle");return}if(G!==S){W(null),l([]),E("failure"),setTimeout(()=>E("idle"),1200);return}A==null||A(S),E("success");return}let d=!1;if(x){const j=new TextEncoder,N=await crypto.subtle.digest("SHA-256",j.encode(S));d=Array.from(new Uint8Array(N)).map(U=>U.toString(16).padStart(2,"0")).join("")===x}else if(y)d=S===y;else{A==null||A(S),E("success");return}if(d)E("success"),g==null||g({success:!0,confidence:1,method:"pin",timestamp:Date.now(),duration:0}),A==null||A(S);else{const j=O+1;if(J(j),j>=i){const N=Date.now()+a;H(N),E("failure"),D==null||D(new Error("Too many failed PIN attempts"))}else E("failure"),setTimeout(()=>{E("idle"),l([])},800);g==null||g({success:!1,confidence:0,method:"pin",timestamp:Date.now(),duration:0})}},[w,t,q,f,v,G,x,y,O,i,a,_,E,A,g,D]),P=Math.max(0,Math.ceil((B-Date.now())/1e3)),C=f==="success"?"var(--security-success)":f==="failure"?"var(--security-error)":"var(--security-border)";return s.jsxs("div",{className:k,style:{display:"inline-flex",flexDirection:"column",alignItems:"center",gap:16,fontFamily:"var(--security-font)",color:"var(--security-text)"},children:[p&&s.jsx("div",{style:{fontSize:14,fontWeight:600},children:p}),s.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",minHeight:18,textAlign:"center"},children:q?u("security.pin.locked",`Locked — try again in ${P}s`):v==="set"&&G!==null?u("security.pin.confirm","Confirm your PIN"):v==="set"?u("security.pin.setNew","Enter a new PIN"):u("security.pin.enter","Enter your PIN")}),s.jsx("div",{style:{display:"flex",gap:12},children:Array.from({length:t},(F,R)=>s.jsx("div",{style:{width:16,height:16,borderRadius:"50%",border:`2px solid ${C}`,background:R<w.length?C:"transparent",transition:"background 0.15s, border-color 0.15s"}},R))}),s.jsx("div",{style:{display:"grid",gridTemplateColumns:`repeat(3, ${o}px)`,gap:10,opacity:q?.4:1,pointerEvents:q?"none":"auto"},children:$.map((F,R)=>{if(F==="")return s.jsx("div",{},R);const S=F==="back";return s.jsx("button",{onClick:()=>Y(F),disabled:q||f==="success","aria-label":S?"Backspace":F,style:{width:o,height:o,borderRadius:"var(--security-key-border-radius, 50%)",border:"1px solid var(--security-key-border, var(--security-border))",background:"var(--security-key-bg, var(--security-bg-panel))",color:"var(--security-key-text, var(--security-text))",fontSize:S?20:22,fontWeight:600,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"background 0.1s, transform 0.1s",userSelect:"none"},onMouseDown:d=>{d.currentTarget.style.transform="scale(0.92)"},onMouseUp:d=>{d.currentTarget.style.transform=""},onMouseLeave:d=>{d.currentTarget.style.transform=""},children:S?"⌫":(m==null?void 0:m[F])??F},R)})}),w.length>0&&f!=="success"&&s.jsx("button",{onClick:()=>l([]),style:{fontSize:12,background:"none",border:"none",color:"var(--security-text-secondary)",cursor:"pointer",textDecoration:"underline"},children:u("security.pin.clear","Clear")}),b&&s.jsxs("button",{onClick:T,style:{fontSize:13,padding:"8px 16px",background:"none",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",color:"var(--security-biometric)",cursor:"pointer"},children:["🔐 ",u("security.pin.biometricFallback","Use biometrics instead")]}),O>0&&f!=="success"&&!q&&s.jsx("div",{style:{fontSize:11,color:"var(--security-warning)"},children:u("security.pin.attempts",`${O}/${i} attempts`)})]})},lt=3,ut=4,dt=5,ht=14,ft=e=>{const{gridSize:t=lt,minLength:r=ut,showTrail:n=!0,showError:i=!0,maxAttempts:a=dt,dotSize:o=ht,trailColor:c,mode:m="verify",expectedHash:x,expectedPattern:y,onComplete:v,onVerify:A,onStatusChange:g,onError:I,label:D,className:b,canvasSize:T}=e,{t:p}=X(),k=h.useRef(null),[u,w]=h.useState([]),[l,f]=h.useState(!1),[z,O]=h.useState("idle"),[J,B]=h.useState(0),[H,G]=h.useState(null),[W,L]=h.useState(null),$=T??t*80,E=$/t,q=h.useCallback(d=>{O(d),g==null||g(d)},[g]),_=h.useCallback(()=>{const d=[];for(let j=0;j<t;j++)for(let N=0;N<t;N++)d.push({x:N*E+E/2,y:j*E+E/2});return d},[t,E]),Y=h.useCallback(d=>{const j=k.current.getBoundingClientRect(),N="touches"in d?d.touches[0].clientX:d.clientX,M="touches"in d?d.touches[0].clientY:d.clientY;return{x:N-j.left,y:M-j.top}},[]),P=h.useCallback((d,j)=>{const N=_(),M=E*.38;for(let U=0;U<N.length;U++){const K=N[U].x-d,Z=N[U].y-j;if(K*K+Z*Z<M*M)return U}return-1},[_,E]),C=h.useCallback(()=>{var U;const d=(U=k.current)==null?void 0:U.getContext("2d");if(!d)return;d.clearRect(0,0,$,$);const j=_(),M=z==="failure"&&i?"var(--security-error)":c??"var(--security-biometric)";for(let K=0;K<j.length;K++){const Z=u.includes(K);d.beginPath(),d.arc(j[K].x,j[K].y,Z?o*.75:o*.5,0,Math.PI*2),d.fillStyle=Z?M:"var(--security-border)",d.fill(),Z&&(d.beginPath(),d.arc(j[K].x,j[K].y,o*1.2,0,Math.PI*2),d.strokeStyle=M,d.lineWidth=1.5,d.globalAlpha=.3,d.stroke(),d.globalAlpha=1)}if(n&&u.length>1){d.beginPath(),d.moveTo(j[u[0]].x,j[u[0]].y);for(let K=1;K<u.length;K++)d.lineTo(j[u[K]].x,j[u[K]].y);l&&W&&d.lineTo(W.x,W.y),d.strokeStyle=M,d.lineWidth=3,d.lineCap="round",d.lineJoin="round",d.globalAlpha=.5,d.stroke(),d.globalAlpha=1}else n&&u.length===1&&l&&W&&(d.beginPath(),d.moveTo(j[u[0]].x,j[u[0]].y),d.lineTo(W.x,W.y),d.strokeStyle=c??"var(--security-biometric)",d.lineWidth=3,d.globalAlpha=.4,d.stroke(),d.globalAlpha=1)},[$,_,o,u,l,W,z,n,i,c]);h.useEffect(()=>{C()},[C]);const F=h.useCallback(d=>{if(z==="success"||z==="failure")return;d.preventDefault();const{x:j,y:N}=Y(d),M=P(j,N);M>=0&&(f(!0),w([M]),L({x:j,y:N}))},[z,Y,P]),R=h.useCallback(d=>{if(!l)return;d.preventDefault();const{x:j,y:N}=Y(d);L({x:j,y:N});const M=P(j,N);M>=0&&!u.includes(M)&&w(U=>[...U,M])},[l,Y,P,u]),S=h.useCallback(async()=>{if(!l)return;if(f(!1),L(null),u.length<r){w([]);return}const d=u.join(",");if(m==="set"){if(H===null){G([...u]),w([]);return}if(H.join(",")!==d){G(null),q("failure"),setTimeout(()=>{q("idle"),w([])},800);return}v==null||v([...u]),q("success");return}q("processing");let j=!1;if(x){const N=new TextEncoder,M=await crypto.subtle.digest("SHA-256",N.encode(d));j=Array.from(new Uint8Array(M)).map(K=>K.toString(16).padStart(2,"0")).join("")===x}else if(y)j=d===y;else{v==null||v([...u]),q("success");return}if(j)q("success"),A==null||A({success:!0,confidence:1,method:"pattern",timestamp:Date.now(),duration:0}),v==null||v([...u]);else{const N=J+1;B(N),q("failure"),N>=a&&(I==null||I(new Error("Too many failed pattern attempts"))),setTimeout(()=>{q("idle"),w([])},900),A==null||A({success:!1,confidence:0,method:"pattern",timestamp:Date.now(),duration:0})}},[l,u,r,m,H,x,y,J,a,q,v,A,I]);return s.jsxs("div",{className:b,style:{display:"inline-flex",flexDirection:"column",alignItems:"center",gap:12,fontFamily:"var(--security-font)",color:"var(--security-text)"},children:[D&&s.jsx("div",{style:{fontSize:14,fontWeight:600},children:D}),s.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",minHeight:18,textAlign:"center"},children:z==="success"?p("security.pattern.success","Pattern accepted"):z==="failure"?p("security.pattern.wrong","Wrong pattern"):m==="set"&&H!==null?p("security.pattern.confirm","Draw pattern again to confirm"):m==="set"?p("security.pattern.setNew","Draw a new pattern"):p("security.pattern.draw","Draw your pattern")}),s.jsx("canvas",{ref:k,width:$,height:$,style:{touchAction:"none",borderRadius:"var(--security-radius-lg)",background:"var(--security-bg-panel)",border:`1px solid ${z==="failure"?"var(--security-error)":"var(--security-border)"}`,cursor:"pointer",transition:"border-color 0.3s"},onMouseDown:F,onMouseMove:R,onMouseUp:S,onMouseLeave:S,onTouchStart:F,onTouchMove:R,onTouchEnd:S}),(z==="failure"||z==="success")&&s.jsx("button",{onClick:()=>{w([]),B(0),G(null),q("idle")},style:{fontSize:13,padding:"6px 16px",background:"var(--security-bg-panel)",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",color:"var(--security-text)",cursor:"pointer"},children:p("security.common.retry","Try Again")}),J>0&&z!=="success"&&s.jsx("div",{style:{fontSize:11,color:"var(--security-warning)"},children:p("security.pattern.attempts",`${J}/${a} attempts`)})]})},yt={sm:"8px 16px",md:"12px 24px",lg:"14px 32px"},pt={sm:13,md:14,lg:16},gt=e=>{const{mode:t,credentialIds:r=[],challenge:n,rpName:i=window.location.hostname,rpId:a=window.location.hostname,user:o,attestation:c="none",authenticatorAttachment:m,residentKey:x="preferred",userVerification:y="preferred",onRegister:v,onAuthenticate:A,onVerify:g,onStatusChange:I,onError:D,label:b,className:T,variant:p="primary",size:k="md",fullWidth:u=!1,icon:w}=e,{t:l}=X(),[f,z]=h.useState("idle"),[O,J]=h.useState(!0),[B,H]=h.useState(!1),G=h.useCallback(C=>{z(C),I==null||I(C)},[I]);h.useEffect(()=>{J(fe()),Fe().then(H)},[]);const W=h.useCallback(()=>{if(n){const C=atob(n.replace(/-/g,"+").replace(/_/g,"/")),F=new Uint8Array(C.length);for(let R=0;R<C.length;R++)F[R]=C.charCodeAt(R);return F.buffer}return crypto.getRandomValues(new Uint8Array(32)).buffer},[n]),L=h.useCallback(async()=>{if(!O){D==null||D(new Error("WebAuthn not available"));return}G("processing");try{if(t==="register"){const C=(o==null?void 0:o.id)??crypto.getRandomValues(new Uint8Array(16)),F=(o==null?void 0:o.name)??"user",R=(o==null?void 0:o.displayName)??F,S=W(),d=await Ne({rpName:i,rpId:a,userId:typeof C=="string"?C:Array.from(C).join(""),userName:F,userDisplayName:R,challenge:S});G("success"),d&&(v==null||v(d)),g==null||g({success:!0,confidence:1,method:"webauthn",timestamp:Date.now(),duration:0})}else{const C=await ze({rpId:a,challenge:W(),allowCredentials:r==null?void 0:r.map(F=>({id:new TextEncoder().encode(F),type:"public-key"}))});G("success"),C&&(A==null||A(C)),g==null||g({success:!0,confidence:1,method:"webauthn",timestamp:Date.now(),duration:0})}}catch(C){const F=C instanceof Error?C:new Error(String(C));F.name==="NotAllowedError"?G("idle"):(G("error"),D==null||D(F),g==null||g({success:!1,confidence:0,method:"webauthn",timestamp:Date.now(),duration:0}))}},[O,t,r,o,i,a,c,m,x,y,W,G,v,A,g,D]),$=t==="register"?B?l("security.webauthn.registerPasskey","🔑 Register Passkey"):l("security.webauthn.register","🔐 Register Security Key"):B?l("security.webauthn.signInPasskey","🔑 Sign in with Passkey"):l("security.webauthn.signIn","🔐 Sign in with Security Key"),E=b??$,q={primary:"var(--security-biometric)",outline:"transparent",ghost:"transparent"},_={primary:"none",outline:"2px solid var(--security-biometric)",ghost:"none"},Y={primary:"#fff",outline:"var(--security-biometric)",ghost:"var(--security-biometric)"},P=!O||f==="processing"||f==="success";return s.jsxs("div",{className:T,style:{display:u?"block":"inline-block",textAlign:"center"},children:[s.jsxs("button",{onClick:L,disabled:P,style:{width:u?"100%":"auto",padding:yt[k],fontSize:pt[k],fontWeight:600,fontFamily:"var(--security-font)",background:q[p],color:Y[p],border:_[p],borderRadius:"var(--security-radius)",cursor:P?"not-allowed":"pointer",opacity:P?.6:1,display:"inline-flex",alignItems:"center",justifyContent:"center",gap:8,transition:"opacity 0.2s, transform 0.1s"},children:[f==="processing"&&s.jsx("span",{style:{display:"inline-block",width:16,height:16,borderRadius:"50%",border:"2px solid transparent",borderTopColor:"currentColor",animation:"spin 0.6s linear infinite"}}),f==="success"&&s.jsx("span",{children:"✓"}),w&&f!=="processing"&&f!=="success"&&w,E]}),!O&&s.jsx("div",{style:{fontSize:11,marginTop:6,color:"var(--security-warning)"},children:l("security.webauthn.notAvailable","WebAuthn is not supported in this browser")}),f==="error"&&s.jsx("div",{style:{fontSize:11,marginTop:6,color:"var(--security-error)"},children:l("security.webauthn.error","Authentication failed — try again")}),s.jsx("style",{children:"@keyframes spin { to { transform: rotate(360deg); } }"})]})},mt={success:"✅",failure:"❌",error:"⚠️",idle:"⏸️",scanning:"🔍",processing:"⏳",timeout:"⏰"},vt=e=>e>=80?"var(--security-error)":e>=50?"var(--security-warning)":"var(--security-success)",xt=({entries:e,pageSize:t=20,showExport:r=!0,filterMethods:n,onEntryClick:i,className:a,label:o})=>{const{t:c}=X(),[m,x]=h.useState("all"),[y,v]=h.useState("all"),[A,g]=h.useState(0),I=h.useMemo(()=>{let l=[...e];return m!=="all"&&(l=l.filter(f=>f.method===m)),y!=="all"&&(l=l.filter(f=>f.status===y)),l.sort((f,z)=>z.timestamp-f.timestamp),l},[e,m,y]),D=Math.max(1,Math.ceil(I.length/t)),b=I.slice(A*t,(A+1)*t),T=h.useMemo(()=>n||Array.from(new Set(e.map(l=>l.method))),[e,n]),p=h.useMemo(()=>Array.from(new Set(e.map(l=>l.status))),[e]),k=h.useCallback(()=>{const l=new Blob([JSON.stringify(I,null,2)],{type:"application/json"}),f=URL.createObjectURL(l),z=document.createElement("a");z.href=f,z.download=`security-audit-${new Date().toISOString().slice(0,10)}.json`,z.click(),URL.revokeObjectURL(f)},[I]),u=l=>new Date(l).toLocaleString(),w={padding:"8px 12px",borderBottom:"1px solid var(--security-border)",fontSize:13,whiteSpace:"nowrap"};return s.jsxs("div",{className:a,style:{fontFamily:"var(--security-font)",color:"var(--security-text)",background:"var(--security-bg)",borderRadius:"var(--security-radius-lg)",border:"1px solid var(--security-border)",overflow:"hidden"},children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"12px 16px",background:"var(--security-bg-panel)",borderBottom:"1px solid var(--security-border)"},children:[s.jsx("div",{style:{fontWeight:600,fontSize:15},children:o??c("security.audit.title","🔒 Security Audit Log")}),s.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[s.jsxs("select",{value:m,onChange:l=>{x(l.target.value),g(0)},style:xe,children:[s.jsx("option",{value:"all",children:c("security.audit.allMethods","All methods")}),T.map(l=>s.jsx("option",{value:l,children:l},l))]}),s.jsxs("select",{value:y,onChange:l=>{v(l.target.value),g(0)},style:xe,children:[s.jsx("option",{value:"all",children:c("security.audit.allStatuses","All statuses")}),p.map(l=>s.jsx("option",{value:l,children:l},l))]}),r&&s.jsx("button",{onClick:k,style:bt,title:"Export JSON",children:"📥"})]})]}),s.jsx("div",{style:{overflowX:"auto"},children:s.jsxs("table",{style:{width:"100%",borderCollapse:"collapse"},children:[s.jsx("thead",{children:s.jsxs("tr",{style:{background:"var(--security-bg-panel)",fontSize:12,color:"var(--security-text-secondary)",textTransform:"uppercase",letterSpacing:.5},children:[s.jsx("th",{style:{...w,textAlign:"left"},children:c("security.audit.time","Time")}),s.jsx("th",{style:{...w,textAlign:"left"},children:c("security.audit.action","Action")}),s.jsx("th",{style:{...w,textAlign:"center"},children:c("security.audit.method","Method")}),s.jsx("th",{style:{...w,textAlign:"center"},children:c("security.audit.status","Status")}),s.jsx("th",{style:{...w,textAlign:"center"},children:c("security.audit.risk","Risk")}),s.jsx("th",{style:{...w,textAlign:"left"},children:c("security.audit.device","Device")})]})}),s.jsxs("tbody",{children:[b.length===0&&s.jsx("tr",{children:s.jsx("td",{colSpan:6,style:{...w,textAlign:"center",color:"var(--security-text-muted)",padding:24},children:c("security.audit.noEntries","No entries to show")})}),b.map(l=>s.jsxs("tr",{onClick:()=>i==null?void 0:i(l),style:{cursor:i?"pointer":"default"},onMouseEnter:f=>{f.currentTarget.style.background="var(--security-bg-panel)"},onMouseLeave:f=>{f.currentTarget.style.background=""},children:[s.jsx("td",{style:w,children:u(l.timestamp)}),s.jsx("td",{style:w,children:l.action}),s.jsx("td",{style:{...w,textAlign:"center"},children:s.jsx("span",{style:{padding:"2px 8px",borderRadius:12,fontSize:11,fontWeight:600,background:"var(--security-bg-panel)",border:"1px solid var(--security-border)"},children:l.method})}),s.jsxs("td",{style:{...w,textAlign:"center"},children:[mt[l.status]??"•"," ",l.status]}),s.jsx("td",{style:{...w,textAlign:"center"},children:l.riskScore!=null&&s.jsx("span",{style:{color:vt(l.riskScore),fontWeight:600},children:l.riskScore})}),s.jsx("td",{style:{...w,maxWidth:200,overflow:"hidden",textOverflow:"ellipsis"},children:l.device??"—"})]},l.id))]})]})}),D>1&&s.jsxs("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",gap:12,padding:"10px 16px",fontSize:13,color:"var(--security-text-secondary)",borderTop:"1px solid var(--security-border)"},children:[s.jsxs("button",{disabled:A===0,onClick:()=>g(A-1),style:be,children:["← ",c("security.audit.prev","Prev")]}),s.jsxs("span",{children:[A+1," / ",D]}),s.jsxs("button",{disabled:A>=D-1,onClick:()=>g(A+1),style:be,children:[c("security.audit.next","Next")," →"]})]}),s.jsx("div",{style:{padding:"6px 16px",fontSize:11,color:"var(--security-text-muted)",textAlign:"right"},children:c("security.audit.total",`${I.length} entries`)})]})},xe={fontSize:12,padding:"4px 8px",background:"var(--security-bg)",color:"var(--security-text)",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)"},bt={background:"none",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",padding:"4px 8px",cursor:"pointer",fontSize:16},be={background:"none",border:"none",cursor:"pointer",color:"var(--security-biometric)",fontWeight:600,fontSize:13},wt={fingerprint:"👆",iris:"👁️",face:"🧑",voice:"🎙️",webauthn:"🔑",pattern:"✦",pin:"🔢",passphrase:"🔤"},St=({options:e,requiredCount:t=1,onSelect:r,onComplete:n,className:i,label:a,layout:o="grid"})=>{const{t:c}=X(),m=e.filter(y=>y.verified).length,x=m>=t;return s.jsxs("div",{className:i,style:{fontFamily:"var(--security-font)",color:"var(--security-text)",display:"flex",flexDirection:"column",gap:16},children:[a&&s.jsx("div",{style:{fontSize:15,fontWeight:600},children:a}),t>1&&s.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)"},children:c("security.mfa.progress",`Verified ${m} of ${t} required`)}),s.jsx("div",{style:{display:o==="grid"?"grid":"flex",gridTemplateColumns:o==="grid"?"repeat(auto-fill, minmax(140px, 1fr))":void 0,flexDirection:o==="list"?"column":void 0,gap:12},children:e.map(y=>{const v=y.verified??!1,A=y.disabled||x;return s.jsxs("button",{onClick:()=>!A&&!v&&(r==null?void 0:r(y.method)),disabled:A||v,style:{display:"flex",flexDirection:o==="grid"?"column":"row",alignItems:"center",gap:o==="grid"?8:12,padding:o==="grid"?"20px 16px":"12px 16px",background:v?"rgba(16,185,129,0.08)":"var(--security-bg-panel)",border:`2px solid ${v?"var(--security-success)":"var(--security-border)"}`,borderRadius:"var(--security-radius-lg)",cursor:A||v?"default":"pointer",opacity:A&&!v?.5:1,transition:"border-color 0.2s, background 0.2s",textAlign:o==="grid"?"center":"left"},children:[s.jsx("span",{style:{fontSize:28},children:v?"✅":y.icon??wt[y.method]??"🔐"}),s.jsxs("div",{children:[s.jsx("div",{style:{fontSize:14,fontWeight:600,color:"var(--security-text)"},children:y.label??y.method}),y.description&&s.jsx("div",{style:{fontSize:11,color:"var(--security-text-muted)",marginTop:2},children:y.description})]})]},y.method)})}),x&&s.jsxs("div",{style:{textAlign:"center",fontSize:14,fontWeight:600,color:"var(--security-success)",padding:8},children:["✅ ",c("security.mfa.complete","All factors verified")]})]})},kt=({sessions:e,onRevoke:t,onRevokeAll:r,onTrust:n,className:i,label:a,showRevokeAll:o=!0})=>{const{t:c}=X(),[m,x]=h.useState(new Set),y=h.useMemo(()=>[...e].sort((g,I)=>(I.current?1:0)-(g.current?1:0)||I.lastActive-g.lastActive),[e]),v=g=>{const I=new Date(g),b=Date.now()-g;return b<6e4?c("security.session.justNow","Just now"):b<36e5?`${Math.floor(b/6e4)}m ago`:b<864e5?`${Math.floor(b/36e5)}h ago`:I.toLocaleDateString()},A=g=>{x(I=>new Set(I).add(g)),t==null||t(g)};return s.jsxs("div",{className:i,style:{fontFamily:"var(--security-font)",color:"var(--security-text)",background:"var(--security-bg)",borderRadius:"var(--security-radius-lg)",border:"1px solid var(--security-border)",overflow:"hidden"},children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"12px 16px",background:"var(--security-bg-panel)",borderBottom:"1px solid var(--security-border)"},children:[s.jsx("div",{style:{fontSize:15,fontWeight:600},children:a??c("security.session.title","🖥️ Active Sessions")}),o&&e.length>1&&s.jsx("button",{onClick:r,style:{fontSize:12,padding:"4px 12px",background:"none",border:"1px solid var(--security-error)",borderRadius:"var(--security-radius)",color:"var(--security-error)",cursor:"pointer"},children:c("security.session.revokeAll","Revoke all others")})]}),s.jsxs("div",{children:[y.map(g=>s.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"12px 16px",borderBottom:"1px solid var(--security-border)",opacity:m.has(g.id)?.5:1,background:g.current?"rgba(59,130,246,0.04)":void 0},children:[s.jsxs("div",{style:{display:"flex",gap:12,alignItems:"center"},children:[s.jsx("span",{style:{fontSize:24},children:g.device.toLowerCase().includes("mobile")?"📱":"💻"}),s.jsxs("div",{children:[s.jsxs("div",{style:{fontSize:14,fontWeight:500},children:[g.device,g.current&&s.jsx("span",{style:{marginLeft:8,fontSize:10,padding:"1px 6px",background:"var(--security-biometric)",color:"#fff",borderRadius:8},children:c("security.session.current","Current")}),g.trusted&&s.jsx("span",{style:{marginLeft:6,fontSize:10,padding:"1px 6px",background:"var(--security-success)",color:"#fff",borderRadius:8},children:c("security.session.trusted","Trusted")})]}),s.jsx("div",{style:{fontSize:12,color:"var(--security-text-muted)",marginTop:2},children:[g.browser,g.os,g.location].filter(Boolean).join(" · ")}),s.jsxs("div",{style:{fontSize:11,color:"var(--security-text-muted)",marginTop:1},children:[c("security.session.lastActive","Last active"),":"," ",v(g.lastActive)]})]})]}),s.jsxs("div",{style:{display:"flex",gap:6},children:[n&&!g.current&&s.jsx("button",{onClick:()=>n(g.id,!g.trusted),style:{fontSize:11,padding:"4px 8px",background:"none",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",cursor:"pointer",color:"var(--security-text-secondary)"},children:g.trusted?"🚫":"✅"}),!g.current&&s.jsx("button",{onClick:()=>A(g.id),disabled:m.has(g.id),style:{fontSize:11,padding:"4px 10px",background:"none",border:"1px solid var(--security-error)",borderRadius:"var(--security-radius)",cursor:"pointer",color:"var(--security-error)"},children:c("security.session.revoke","Revoke")})]})]},g.id)),e.length===0&&s.jsx("div",{style:{padding:24,textAlign:"center",color:"var(--security-text-muted)",fontSize:13},children:c("security.session.noSessions","No active sessions")})]})]})},At=({trustScore:e,onScoreComputed:t,trustThreshold:r=60,showFactors:n=!0,showFingerprint:i=!1,className:a,label:o})=>{const{t:c}=X(),[m,x]=h.useState(e??null),[y,v]=h.useState(!e),A=h.useCallback(async()=>{var I;v(!0);try{const D=he(),b=await se(),T=[];let p=50;D.platform&&!D.platform.includes("Linux")&&(T.push({name:"Known platform",score:5,description:"Running on a recognized platform",weight:.05}),p+=5),navigator.cookieEnabled&&(T.push({name:"Cookies enabled",score:5,description:"Browser cookies are enabled",weight:.05}),p+=5),D.screenResolution[0]>=360&&D.screenResolution[1]>=640&&(T.push({name:"Standard resolution",score:5,description:"Screen resolution within normal range",weight:.05}),p+=5),typeof window<"u"&&window.isSecureContext&&(T.push({name:"Secure context",score:10,description:"Running in HTTPS secure context",weight:.1}),p+=10),((I=navigator.languages)==null?void 0:I.length)>0&&(T.push({name:"Language configured",score:5,description:"Browser language is set",weight:.05}),p+=5),D.touchSupport&&(T.push({name:"Touch device",score:5,description:"Touch input is supported",weight:.05}),p+=5);try{const l=document.createElement("canvas").getContext("webgl");l&&l.getExtension("WEBGL_debug_renderer_info")&&(T.push({name:"Hardware GPU",score:10,description:"Hardware GPU detected",weight:.1}),p+=10)}catch{}navigator.credentials&&(T.push({name:"Credential API",score:5,description:"Credential Management API available",weight:.05}),p+=5),p=Math.min(100,Math.max(0,p));const k=Date.now(),u={score:p,factors:T,trusted:p>=r,firstSeen:k,lastSeen:k,fingerprint:b};x(u),t==null||t(u)}finally{v(!1)}},[r,t]);h.useEffect(()=>{e||A()},[e,A]),h.useEffect(()=>{e&&x(e)},[e]);const g=m?m.score>=80?"var(--security-success)":m.score>=50?"var(--security-warning)":"var(--security-error)":"var(--security-text-muted)";return s.jsxs("div",{className:a,style:{fontFamily:"var(--security-font)",color:"var(--security-text)",background:"var(--security-bg-panel)",borderRadius:"var(--security-radius-lg)",border:"1px solid var(--security-border)",padding:20,display:"flex",flexDirection:"column",gap:14,alignItems:"center"},children:[s.jsx("div",{style:{fontSize:15,fontWeight:600},children:o??c("security.trust.title","🛡️ Device Trust")}),y?s.jsx("div",{style:{fontSize:13,color:"var(--security-text-muted)"},children:c("security.trust.computing","Analysing device…")}):m?s.jsxs(s.Fragment,{children:[s.jsxs("div",{style:{position:"relative",width:100,height:100},children:[s.jsxs("svg",{viewBox:"0 0 36 36",style:{width:"100%",height:"100%",transform:"rotate(-90deg)"},children:[s.jsx("circle",{cx:"18",cy:"18",r:"15.9",fill:"none",stroke:"var(--security-border)",strokeWidth:"2.5"}),s.jsx("circle",{cx:"18",cy:"18",r:"15.9",fill:"none",stroke:g,strokeWidth:"2.5",strokeDasharray:`${m.score}, 100`,strokeLinecap:"round"})]}),s.jsxs("div",{style:{position:"absolute",inset:0,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},children:[s.jsx("span",{style:{fontSize:24,fontWeight:700,color:g},children:m.score}),s.jsx("span",{style:{fontSize:10,color:"var(--security-text-muted)"},children:"/100"})]})]}),s.jsx("div",{style:{fontSize:14,fontWeight:600,color:m.trusted?"var(--security-success)":"var(--security-warning)"},children:m.trusted?c("security.trust.trusted","✅ Device Trusted"):c("security.trust.untrusted","⚠️ Low Trust Score")}),n&&m.factors.length>0&&s.jsxs("div",{style:{width:"100%",fontSize:12},children:[s.jsxs("div",{style:{fontWeight:600,marginBottom:6,color:"var(--security-text-secondary)"},children:[c("security.trust.factors","Contributing factors"),":"]}),s.jsx("ul",{style:{margin:0,paddingLeft:18,color:"var(--security-text-muted)"},children:m.factors.map((I,D)=>s.jsx("li",{style:{marginBottom:2},children:I.name},D))})]}),i&&m.fingerprint&&s.jsx("div",{style:{fontSize:10,color:"var(--security-text-muted)",wordBreak:"break-all",textAlign:"center",maxWidth:280,fontFamily:"monospace"},children:m.fingerprint})]}):null]})};function jt(e){if(!e)return 0;let t=0;return e.length>=8&&t++,e.length>=12&&t++,/[a-z]/.test(e)&&/[A-Z]/.test(e)&&t++,/\d/.test(e)&&t++,/[^a-zA-Z0-9]/.test(e)&&t++,/(.)\1{3,}/.test(e)&&t--,Math.max(0,Math.min(4,t))}const Tt=["Very weak","Weak","Fair","Strong","Very strong"],we=["#ef4444","#f97316","#eab308","#22c55e","#10b981"],Ct=({mode:e="verify",expectedHash:t,minStrength:r=2,minLength:n=8,onComplete:i,onVerify:a,onStatusChange:o,onError:c,label:m,placeholder:x,className:y,showStrength:v=!0,maxAttempts:A=5})=>{const{t:g}=X(),[I,D]=h.useState(""),[b,T]=h.useState(""),[p,k]=h.useState(!1),[u,w]=h.useState("idle"),[l,f]=h.useState(0),[z,O]=h.useState(""),J=h.useRef(null),B=jt(I),H=h.useCallback(L=>{w(L),o==null||o(L)},[o]),G=h.useCallback(async()=>{if(O(""),H("processing"),e==="set"){if(I.length<n){O(g("security.passphrase.tooShort",`Minimum ${n} characters`)),H("idle");return}if(B<r){O(g("security.passphrase.tooWeak","Passphrase is too weak")),H("idle");return}if(I!==b){O(g("security.passphrase.noMatch","Passphrases do not match")),H("failure"),setTimeout(()=>H("idle"),1e3);return}i==null||i(I),H("success");return}if(t){const L=new TextEncoder,$=await crypto.subtle.digest("SHA-256",L.encode(I));if(Array.from(new Uint8Array($)).map(_=>_.toString(16).padStart(2,"0")).join("")===t)H("success"),a==null||a({success:!0,confidence:1,method:"passphrase",timestamp:Date.now(),duration:0}),i==null||i(I);else{const _=l+1;f(_),_>=A?(H("failure"),c==null||c(new Error("Too many failed attempts"))):(O(g("security.passphrase.incorrect","Incorrect passphrase")),H("idle")),a==null||a({success:!1,confidence:0,method:"passphrase",timestamp:Date.now(),duration:0})}}else i==null||i(I),H("success")},[I,b,e,t,B,r,n,l,A,g,H,i,a,c]),W={width:"100%",padding:"10px 14px",fontSize:14,background:"var(--security-bg)",color:"var(--security-text)",border:`1px solid ${u==="failure"?"var(--security-error)":"var(--security-border)"}`,borderRadius:"var(--security-radius)",boxSizing:"border-box",fontFamily:"var(--security-font)"};return s.jsxs("div",{className:y,style:{display:"flex",flexDirection:"column",gap:10,maxWidth:340,fontFamily:"var(--security-font)",color:"var(--security-text)"},children:[m&&s.jsx("label",{style:{fontSize:14,fontWeight:600},children:m}),s.jsxs("div",{style:{position:"relative"},children:[s.jsx("input",{ref:J,type:p?"text":"password",value:I,onChange:L=>D(L.target.value),placeholder:x??g("security.passphrase.placeholder","Enter passphrase"),style:W,disabled:u==="success",onKeyDown:L=>L.key==="Enter"&&G()}),s.jsx("button",{type:"button",onClick:()=>k(!p),style:{position:"absolute",right:8,top:"50%",transform:"translateY(-50%)",background:"none",border:"none",cursor:"pointer",fontSize:16,color:"var(--security-text-muted)"},tabIndex:-1,children:p?"🙈":"👁️"})]}),e==="set"&&v&&I.length>0&&s.jsxs("div",{children:[s.jsx("div",{style:{display:"flex",gap:3,height:4},children:[0,1,2,3].map(L=>s.jsx("div",{style:{flex:1,borderRadius:2,background:L<B?we[B]:"var(--security-border)",transition:"background 0.2s"}},L))}),s.jsx("div",{style:{fontSize:11,marginTop:4,color:we[B]},children:g(`security.passphrase.strength${B}`,Tt[B])})]}),e==="set"&&s.jsx("input",{type:p?"text":"password",value:b,onChange:L=>T(L.target.value),placeholder:g("security.passphrase.confirmPlaceholder","Confirm passphrase"),style:W,disabled:u==="success",onKeyDown:L=>L.key==="Enter"&&G(),onPaste:L=>L.preventDefault()}),z&&s.jsx("div",{style:{fontSize:12,color:"var(--security-error)"},children:z}),s.jsx("button",{onClick:G,disabled:!I||u==="processing"||u==="success",style:{padding:"10px 20px",fontSize:14,fontWeight:600,background:u==="success"?"var(--security-success)":"var(--security-biometric)",color:"#fff",border:"none",borderRadius:"var(--security-radius)",cursor:u==="success"?"default":"pointer",opacity:!I||u==="processing"?.6:1},children:u==="success"?"✓ "+g("security.passphrase.accepted","Accepted"):e==="set"?g("security.passphrase.setBtn","Set Passphrase"):g("security.passphrase.verifyBtn","Verify")}),l>0&&u!=="success"&&s.jsx("div",{style:{fontSize:11,color:"var(--security-warning)"},children:g("security.passphrase.attempts",`${l}/${A} attempts`)})]})};function It(e){const t=[],r={defaultSrc:"default-src",scriptSrc:"script-src",styleSrc:"style-src",imgSrc:"img-src",fontSrc:"font-src",connectSrc:"connect-src",frameSrc:"frame-src",objectSrc:"object-src",mediaSrc:"media-src",workerSrc:"worker-src",childSrc:"child-src",formAction:"form-action",frameAncestors:"frame-ancestors",baseUri:"base-uri",reportUri:"report-uri",reportTo:"report-to",upgradeInsecureRequests:"upgrade-insecure-requests",blockAllMixedContent:"block-all-mixed-content"};return Object.entries(e.directives).forEach(([n,i])=>{const a=r[n];if(a){if(typeof i=="boolean")i&&t.push(a);else if(typeof i=="string")t.push(`${a} ${i}`);else if(Array.isArray(i)){let o=i;e.nonce&&(n==="scriptSrc"||n==="styleSrc")&&(o=[...o,`'nonce-${e.nonce}'`]),t.push(`${a} ${o.join(" ")}`)}}}),t.join("; ")}function Rt(e){const t="'self'";return{defaultSrc:[t],scriptSrc:[t],styleSrc:[t,"'unsafe-inline'"],imgSrc:[t,"data:","blob:",e==null?void 0:e.cdnDomain].filter(Boolean),fontSrc:[t,"data:",e==null?void 0:e.cdnDomain].filter(Boolean),connectSrc:[t,e==null?void 0:e.apiDomain,"wss:"].filter(Boolean),frameSrc:["'none'"],objectSrc:["'none'"],baseUri:[t],formAction:[t],frameAncestors:["'none'"],upgradeInsecureRequests:!0,reportUri:e==null?void 0:e.reportUri}}function Dt(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID().replace(/-/g,""):Math.random().toString(36).substring(2)+Date.now().toString(36)}const Mt={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","/":"&#x2F;","`":"&#x60;","=":"&#x3D;"};function $e(e){return e.replace(/[&<>"'`=/]/g,t=>Mt[t]||t)}function Pt(e,t){let r=$e(e);return t!=null&&t.maxLength&&r.length>t.maxLength&&(r=r.substring(0,t.maxLength)),r}function Et(e){if(!e)return null;try{const t=new URL(e);return!["http:","https:","mailto:","tel:"].includes(t.protocol)||e.toLowerCase().includes("javascript:")?null:t.toString()}catch{return null}}function Ft(e){const t=["script","iframe","object","embed","form"];let r=e;t.forEach(a=>{const o=new RegExp(`<${a}[^>]*>.*?</${a}>`,"gi");r=r.replace(o,"");const c=new RegExp(`<${a}[^>]*/>`,"gi");r=r.replace(c,"")});const n=/\s+on\w+\s*=/gi;r=r.replace(n," data-removed=");const i=/javascript:/gi;return r=r.replace(i,""),r}function Nt(e,t){let r=e;if(t!=null&&t.allowedTags){const n=/<\/?([a-z][a-z0-9]*)[^>]*>/gi;r=r.replace(n,(i,a)=>t.allowedTags.includes(a.toLowerCase())?i:"")}return r=r.replace(/\s+on\w+\s*=/gi," data-removed="),r=r.replace(/javascript:/gi,""),{__html:r}}const ye={headerName:"X-CSRF-Token",cookieName:"XSRF-TOKEN",fieldName:"_csrf"};function zt(){if(typeof crypto<"u"){const e=new Uint8Array(32);return crypto.getRandomValues(e),Array.from(e,t=>t.toString(16).padStart(2,"0")).join("")}return Math.random().toString(36).substring(2)+Date.now().toString(36)}function pe(e=ye.cookieName){if(typeof document>"u")return null;const t=document.cookie.match(new RegExp(`(^| )${e}=([^;]+)`));return t?decodeURIComponent(t[2]):null}function Lt(e=ye){return async function(r,n={}){const i=pe(e.cookieName);i||console.warn("CSRF token not found");const a=new Headers(n.headers);return i&&e.headerName&&a.set(e.headerName,i),fetch(r,{...n,headers:a})}}function $t(e=ye){const t=pe(e.cookieName);return{token:t,inputProps:{type:"hidden",name:e.fieldName,value:t||""},headerName:e.headerName}}function Be(e){const t=new Map,r=e.keyGenerator||(a=>a.url);function n(a){const o=r(a),c=Date.now();let m=t.get(o);(!m||c>m.resetAt)&&(m={count:0,resetAt:c+e.windowMs}),m.count++,t.set(o,m);const x=m.count<=e.maxRequests,y=Math.max(0,e.maxRequests-m.count);return{allowed:x,remaining:y,resetAt:m.resetAt}}function i(a){a?t.delete(a):t.clear()}return{checkLimit:n,reset:i}}function Bt(e){const t=Be(e);return{checkAndFetch:async(n,i)=>{const a=t.checkLimit({url:n,method:i==null?void 0:i.method});if(!a.allowed){const o=Math.ceil((a.resetAt-Date.now())/1e3);throw new Error(`Rate limit exceeded. Retry after ${o} seconds.`)}return fetch(n,i)},checkLimit:t.checkLimit,reset:t.reset}}function We(e,t){const r=[];if(t.allowedTypes&&t.allowedTypes.length>0&&(t.allowedTypes.includes(e.type)||r.push(`File type '${e.type}' is not allowed. Allowed types: ${t.allowedTypes.join(", ")}`)),t.maxSize&&e.size>t.maxSize){const a=(t.maxSize/1048576).toFixed(2),o=(e.size/(1024*1024)).toFixed(2);r.push(`File size (${o}MB) exceeds maximum allowed size (${a}MB)`)}const n=[".exe",".bat",".cmd",".sh",".ps1",".vbs",".js",".jar"],i=e.name.toLowerCase();for(const a of n)if(i.includes(a+".")||i.endsWith(a)){r.push(`File extension '${a}' is not allowed`);break}return{valid:r.length===0,errors:r,file:r.length===0?e:void 0}}function Wt(e,t){const r=[],n=[],i=[];t.maxFiles&&e.length>t.maxFiles&&r.push(`Too many files. Maximum allowed: ${t.maxFiles}`);const a=e.reduce((o,c)=>o+c.size,0);if(t.maxTotalSize&&a>t.maxTotalSize){const o=(t.maxTotalSize/1048576).toFixed(2),c=(a/(1024*1024)).toFixed(2);r.push(`Total file size (${c}MB) exceeds maximum (${o}MB)`)}return e.forEach(o=>{const c=We(o,t);c.valid?n.push(o):i.push({file:o,errors:c.errors})}),{valid:r.length===0&&i.length===0,errors:[...r,...i.flatMap(o=>o.errors)],validFiles:n,invalidFiles:i}}async function _t(e,t){const r=new FormData;r.append("file",e);try{const n=await fetch(t,{method:"POST",body:r});if(!n.ok)throw new Error("Virus scan failed");return await n.json()}catch(n){return console.error("Virus scan error:",n),{clean:!1,threat:"Scan failed"}}}function _e(){if(typeof localStorage>"u")return null;const e=localStorage.getItem("nice2dev_consent");if(!e)return null;try{return JSON.parse(e)}catch{return null}}function Ht(e){typeof localStorage>"u"||localStorage.setItem("nice2dev_consent",JSON.stringify({...e,necessary:!0,timestamp:new Date().toISOString()}))}function Ut(e){const t=_e();return t?t[e]===!0:!1}function Ot(e){if(typeof document>"u")return;document.cookie.split(";").forEach(r=>{const[n]=r.trim().split("=");e.includes(n)||(document.cookie=`${n}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`)})}async function qt(e,t,r=fetch){const n={exportDate:new Date().toISOString(),userId:e};return await Promise.all(Object.entries(t).map(async([i,a])=>{try{const o=await r(a);o.ok&&(n[i]=await o.json())}catch(o){console.error(`Failed to fetch ${i} data:`,o),n[i]={error:"Failed to retrieve data"}}})),n}async function Kt(e,t,r=fetch){try{const n=await r(t,{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({userId:e,timestamp:new Date().toISOString()})});return n.ok?{success:!0,confirmationId:(await n.json()).confirmationId}:{success:!1,error:"Deletion request failed"}}catch(n){return{success:!1,error:String(n)}}}function Gt(e,t){var n;const r={...e,id:((n=crypto.randomUUID)==null?void 0:n.call(crypto))||Math.random().toString(36),timestamp:new Date};return t&&fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)}).catch(console.error),process.env.NODE_ENV==="development"&&console.warn("[HIPAA] PHI Access:",r),r}function Jt(e){let t=null,r=null,n=Date.now();const i=e.timeoutMinutes*60*1e3,a=e.warningBeforeMs||6e4;function o(){n=Date.now(),t&&clearTimeout(t),r&&clearTimeout(r),e.onWarning&&(r=setTimeout(()=>{var y;const x=i-(Date.now()-n);(y=e.onWarning)==null||y.call(e,x)},i-a)),t=setTimeout(e.onTimeout,i)}function c(){t&&clearTimeout(t),r&&clearTimeout(r)}function m(){return Math.max(0,i-(Date.now()-n))}return o(),typeof window<"u"&&["mousedown","keypress","touchstart","scroll"].forEach(y=>{window.addEventListener(y,o,{passive:!0})}),{resetTimer:o,destroy:c,getTimeRemaining:m}}function Yt(e,t){const r=o=>{const c=o.replace("#",""),m=parseInt(c.substr(0,2),16)/255,x=parseInt(c.substr(2,2),16)/255,y=parseInt(c.substr(4,2),16)/255,v=A=>A<=.03928?A/12.92:Math.pow((A+.055)/1.055,2.4);return .2126*v(m)+.7152*v(x)+.0722*v(y)},n=r(e),i=r(t),a=(Math.max(n,i)+.05)/(Math.min(n,i)+.05);return{ratio:Math.round(a*100)/100,passesAA:a>=4.5,passesAAA:a>=7,passesAALarge:a>=3,passesAAALarge:a>=4.5}}function Zt(e){var r,n,i;if(e.getAttribute("aria-label"))return!0;const t=e.getAttribute("aria-labelledby");if(t){const a=document.getElementById(t);if((r=a==null?void 0:a.textContent)!=null&&r.trim())return!0}if(e.id){const a=document.querySelector(`label[for="${e.id}"]`);if((n=a==null?void 0:a.textContent)!=null&&n.trim())return!0}return!!((i=e.textContent)!=null&&i.trim()||e.getAttribute("title")||e.placeholder)}function Xt(e){const r=(e||document.body).querySelectorAll("h1, h2, h3, h4, h5, h6"),n=[];let i=0,a=!1;return r.forEach(o=>{const c=parseInt(o.tagName[1]);c===1&&(a&&n.push({level:c,element:o,issue:"Multiple H1 elements found"}),a=!0),c>i+1&&i!==0&&n.push({level:c,element:o,issue:`Skipped heading level: H${i} to H${c}`}),i=c}),!a&&r.length>0&&n.push({level:0,element:r[0],issue:"Missing H1 element"}),{valid:n.length===0,issues:n}}function Qt(e){const t=[];let r=null;const n=e.batchSize||10,i=e.flushInterval||5e3;async function a(){if(t.length===0)return;const x=t.splice(0,n);try{await fetch(e.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({entries:x})})}catch(y){console.error("Failed to send audit logs:",y),t.unshift(...x)}}function o(){r||(r=setTimeout(()=>{r=null,a()},i))}function c(x){var v;const y={...x,id:((v=crypto.randomUUID)==null?void 0:v.call(crypto))||Math.random().toString(36),timestamp:new Date,userAgent:e.includeUserAgent&&typeof navigator<"u"?navigator.userAgent:void 0};t.push(y),t.length>=n?a():o()}function m(){r&&clearTimeout(r),a()}return{log:c,flush:a,destroy:m}}function Vt(){return[{controlId:"CC6.1",name:"Logical and Physical Access Controls",category:"security",status:"in_progress",lastAssessed:new Date},{controlId:"CC6.2",name:"User Registration and Authorization",category:"security",status:"in_progress",lastAssessed:new Date},{controlId:"CC6.3",name:"Access Control Removal",category:"security",status:"in_progress",lastAssessed:new Date},{controlId:"A1.1",name:"System Capacity",category:"availability",status:"in_progress",lastAssessed:new Date},{controlId:"A1.2",name:"Backup and Recovery",category:"availability",status:"in_progress",lastAssessed:new Date},{controlId:"C1.1",name:"Confidential Information Classification",category:"confidentiality",status:"in_progress",lastAssessed:new Date},{controlId:"C1.2",name:"Confidential Information Disposal",category:"confidentiality",status:"in_progress",lastAssessed:new Date},{controlId:"P1.1",name:"Privacy Notice",category:"privacy",status:"in_progress",lastAssessed:new Date},{controlId:"P2.1",name:"Consent",category:"privacy",status:"in_progress",lastAssessed:new Date},{controlId:"P3.1",name:"Collection",category:"privacy",status:"in_progress",lastAssessed:new Date}]}const er={hardcodedSecrets:[{pattern:/password\s*[:=]\s*["'][^"']+["']/gi,name:"Hardcoded password"},{pattern:/api[_-]?key\s*[:=]\s*["'][^"']+["']/gi,name:"Hardcoded API key"},{pattern:/secret\s*[:=]\s*["'][^"']+["']/gi,name:"Hardcoded secret"},{pattern:/token\s*[:=]\s*["'][^"']+["']/gi,name:"Hardcoded token"}],sqlInjection:[{pattern:/execute\s*\(\s*["'`].*\$\{/gi,name:"Potential SQL injection (template literal)"},{pattern:/query\s*\(\s*["'`].*\+/gi,name:"Potential SQL injection (string concatenation)"}],xss:[{pattern:/dangerouslySetInnerHTML/g,name:"dangerouslySetInnerHTML usage"},{pattern:/innerHTML\s*=/g,name:"innerHTML assignment"},{pattern:/document\.write\s*\(/g,name:"document.write usage"},{pattern:/eval\s*\(/g,name:"eval usage"}],insecureFunctions:[{pattern:/Math\.random\s*\(\)/g,name:"Insecure random (use crypto)"},{pattern:/new Function\s*\(/g,name:"Function constructor (code injection risk)"},{pattern:/setTimeout\s*\(\s*["']/g,name:"setTimeout with string (code injection)"},{pattern:/setInterval\s*\(\s*["']/g,name:"setInterval with string (code injection)"}],infoExposure:[{pattern:/console\.(log|info|warn|error)\s*\(/g,name:"Console logging (remove in production)"},{pattern:/debugger/g,name:"Debugger statement"},{pattern:/TODO.*password/gi,name:"TODO mentioning password"}]};function tr(){return`# .github/workflows/sast.yml
7
+ name: Security Scan (SAST)
8
+
9
+ on:
10
+ push:
11
+ branches: [main, develop]
12
+ pull_request:
13
+ branches: [main]
14
+
15
+ jobs:
16
+ sast:
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - name: Run Semgrep
22
+ uses: returntocorp/semgrep-action@v2
23
+ with:
24
+ config: >-
25
+ p/security-audit
26
+ p/secrets
27
+ p/javascript
28
+ p/typescript
29
+
30
+ - name: Run ESLint Security
31
+ run: |
32
+ npm ci
33
+ npx eslint --config eslint.security.config.js --format json --output-file eslint-security.json ./src
34
+
35
+ - name: Upload SARIF
36
+ uses: github/codeql-action/upload-sarif@v3
37
+ with:
38
+ sarif_file: semgrep.sarif
39
+
40
+ codeql:
41
+ runs-on: ubuntu-latest
42
+ permissions:
43
+ security-events: write
44
+ steps:
45
+ - uses: actions/checkout@v4
46
+
47
+ - name: Initialize CodeQL
48
+ uses: github/codeql-action/init@v3
49
+ with:
50
+ languages: javascript-typescript
51
+
52
+ - name: Perform Analysis
53
+ uses: github/codeql-action/analyze@v3
54
+ `}function rr(){return`# .github/workflows/sca.yml
55
+ name: Dependency Security (SCA)
56
+
57
+ on:
58
+ push:
59
+ branches: [main]
60
+ pull_request:
61
+ branches: [main]
62
+ schedule:
63
+ - cron: '0 0 * * *' # Daily at midnight
64
+
65
+ jobs:
66
+ npm-audit:
67
+ runs-on: ubuntu-latest
68
+ steps:
69
+ - uses: actions/checkout@v4
70
+
71
+ - name: Setup Node
72
+ uses: actions/setup-node@v4
73
+ with:
74
+ node-version: '20'
75
+
76
+ - name: Install dependencies
77
+ run: npm ci
78
+
79
+ - name: Run npm audit
80
+ run: npm audit --audit-level=high --json > npm-audit.json || true
81
+
82
+ - name: Check critical vulnerabilities
83
+ run: |
84
+ CRITICAL=$(cat npm-audit.json | jq '.metadata.vulnerabilities.critical')
85
+ HIGH=$(cat npm-audit.json | jq '.metadata.vulnerabilities.high')
86
+ if [ "$CRITICAL" -gt 0 ] || [ "$HIGH" -gt 0 ]; then
87
+ echo "Critical: $CRITICAL, High: $HIGH vulnerabilities found"
88
+ exit 1
89
+ fi
90
+
91
+ - name: Upload audit results
92
+ uses: actions/upload-artifact@v4
93
+ with:
94
+ name: npm-audit
95
+ path: npm-audit.json
96
+
97
+ license-check:
98
+ runs-on: ubuntu-latest
99
+ steps:
100
+ - uses: actions/checkout@v4
101
+
102
+ - name: Check licenses
103
+ run: |
104
+ npx license-checker --production --onlyAllow "MIT;Apache-2.0;BSD-2-Clause;BSD-3-Clause;ISC;CC0-1.0"
105
+
106
+ snyk:
107
+ runs-on: ubuntu-latest
108
+ steps:
109
+ - uses: actions/checkout@v4
110
+
111
+ - name: Run Snyk
112
+ uses: snyk/actions/node@master
113
+ env:
114
+ SNYK_TOKEN: \${{ secrets.SNYK_TOKEN }}
115
+ with:
116
+ args: --severity-threshold=high
117
+ `}const sr=[{name:"AWS Access Key ID",pattern:/AKIA[0-9A-Z]{16}/g,severity:"critical"},{name:"AWS Secret Access Key",pattern:/[A-Za-z0-9/+=]{40}/g,severity:"critical"},{name:"Google API Key",pattern:/AIza[0-9A-Za-z-_]{35}/g,severity:"high"},{name:"GitHub Token",pattern:/gh[ps]_[A-Za-z0-9_]{36}/g,severity:"critical"},{name:"GitLab Token",pattern:/glpat-[A-Za-z0-9-_]{20}/g,severity:"critical"},{name:"Slack Token",pattern:/xox[baprs]-[0-9]{10,13}-[0-9]{10,13}[a-zA-Z0-9-]*/g,severity:"high"},{name:"Stripe Key",pattern:/sk_live_[0-9a-zA-Z]{24}/g,severity:"critical"},{name:"SendGrid Key",pattern:/SG\.[a-zA-Z0-9_-]{22}\.[a-zA-Z0-9_-]{43}/g,severity:"high"},{name:"RSA Private Key",pattern:/-----BEGIN RSA PRIVATE KEY-----/g,severity:"critical"},{name:"SSH Private Key",pattern:/-----BEGIN OPENSSH PRIVATE KEY-----/g,severity:"critical"},{name:"PGP Private Key",pattern:/-----BEGIN PGP PRIVATE KEY BLOCK-----/g,severity:"critical"},{name:"Basic Auth",pattern:/basic [a-zA-Z0-9_\-:.=]+/gi,severity:"high"},{name:"Bearer Token",pattern:/bearer [a-zA-Z0-9_\-.=]+/gi,severity:"high"},{name:"Connection String",pattern:/[a-z]+:\/\/[^:]+:[^@]+@[^/]+/gi,severity:"critical"}];function nr(){return`#!/bin/sh
118
+ # .git/hooks/pre-commit
119
+
120
+ echo "Scanning for secrets..."
121
+
122
+ # Define patterns to check
123
+ PATTERNS=(
124
+ 'AKIA[0-9A-Z]{16}'
125
+ 'gh[ps]_[A-Za-z0-9_]{36}'
126
+ 'sk_live_[0-9a-zA-Z]{24}'
127
+ '-----BEGIN.*PRIVATE KEY-----'
128
+ 'password.*=.*["'][^'"]+["']'
129
+ )
130
+
131
+ FILES=$(git diff --cached --name-only --diff-filter=ACM)
132
+
133
+ for FILE in $FILES; do
134
+ for PATTERN in "\${PATTERNS[@]}"; do
135
+ if grep -qE "$PATTERN" "$FILE" 2>/dev/null; then
136
+ echo "ERROR: Potential secret found in $FILE"
137
+ echo "Pattern: $PATTERN"
138
+ exit 1
139
+ fi
140
+ done
141
+ done
142
+
143
+ echo "No secrets detected."
144
+ exit 0
145
+ `}function ir(){return`# .github/workflows/secret-scanning.yml
146
+ name: Secret Scanning
147
+
148
+ on:
149
+ push:
150
+ branches: [main, develop]
151
+ pull_request:
152
+ branches: [main]
153
+
154
+ jobs:
155
+ gitleaks:
156
+ runs-on: ubuntu-latest
157
+ steps:
158
+ - uses: actions/checkout@v4
159
+ with:
160
+ fetch-depth: 0
161
+
162
+ - name: Run Gitleaks
163
+ uses: gitleaks/gitleaks-action@v2
164
+ env:
165
+ GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}
166
+
167
+ trufflehog:
168
+ runs-on: ubuntu-latest
169
+ steps:
170
+ - uses: actions/checkout@v4
171
+ with:
172
+ fetch-depth: 0
173
+
174
+ - name: Run TruffleHog
175
+ uses: trufflesecurity/trufflehog@main
176
+ with:
177
+ path: ./
178
+ base: \${{ github.event.repository.default_branch }}
179
+ head: HEAD
180
+ `}function ar(e){return`# Security Advisory
181
+
182
+ ## ${e.cves.join(", ")} - ${e.description}
183
+
184
+ **Severity:** ${e.severity.toUpperCase()}
185
+ **Date:** ${e.date}
186
+
187
+ ### Affected Versions
188
+
189
+ ${e.affectedVersions}
190
+
191
+ ### Fixed In
192
+
193
+ ${e.fixedIn}
194
+
195
+ ### Description
196
+
197
+ ${e.description}
198
+
199
+ ### Remediation
200
+
201
+ Update to version ${e.version} or later:
202
+
203
+ \`\`\`bash
204
+ npm install @nice2dev/ui@${e.version}
205
+ \`\`\`
206
+
207
+ ${e.acknowledgments?`### Acknowledgments
208
+
209
+ Thank you to the following researchers for responsibly disclosing this issue:
210
+
211
+ ${e.acknowledgments.map(t=>`- ${t}`).join(`
212
+ `)}
213
+ `:""}
214
+
215
+ ### Timeline
216
+
217
+ - **Date reported:** ${e.date}
218
+ - **Date fixed:** ${e.date}
219
+ - **Date disclosed:** ${e.date}
220
+
221
+ ### References
222
+
223
+ ${e.cves.map(t=>`- [${t}](https://www.cve.org/CVERecord?id=${t})`).join(`
224
+ `)}
225
+ `}function or(){return`# Security Policy
226
+
227
+ ## Supported Versions
228
+
229
+ | Version | Supported |
230
+ | ------- | ------------------ |
231
+ | 1.0.x | :white_check_mark: |
232
+ | < 1.0 | :x: |
233
+
234
+ ## Reporting a Vulnerability
235
+
236
+ We take security seriously. If you discover a security vulnerability, please follow these steps:
237
+
238
+ ### 1. Do Not Create a Public Issue
239
+
240
+ **Please do not report security vulnerabilities through public GitHub issues.**
241
+
242
+ ### 2. Report Privately
243
+
244
+ Send an email to **security@nice2dev.com** with:
245
+
246
+ - Description of the vulnerability
247
+ - Steps to reproduce
248
+ - Potential impact
249
+ - Any suggested fixes (optional)
250
+
251
+ ### 3. Encryption
252
+
253
+ For sensitive reports, use our PGP key:
254
+
255
+ \`\`\`
256
+ -----BEGIN PGP PUBLIC KEY BLOCK-----
257
+ [PGP KEY HERE]
258
+ -----END PGP PUBLIC KEY BLOCK-----
259
+ \`\`\`
260
+
261
+ ## Response Timeline
262
+
263
+ - **Initial Response:** Within 24 hours
264
+ - **Severity Assessment:** Within 48 hours
265
+ - **Fix Development:** Depends on severity
266
+ - Critical: Within 24 hours
267
+ - High: Within 72 hours
268
+ - Medium: Within 1 week
269
+ - Low: Within 2 weeks
270
+ - **Disclosure:** After fix is released
271
+
272
+ ## Bug Bounty
273
+
274
+ We offer bug bounties for qualifying vulnerabilities:
275
+
276
+ | Severity | Bounty Range |
277
+ | -------- | ------------ |
278
+ | Critical | $1,000 - $5,000 |
279
+ | High | $500 - $1,000 |
280
+ | Medium | $100 - $500 |
281
+ | Low | Acknowledgment |
282
+
283
+ ## Safe Harbor
284
+
285
+ We will not pursue legal action against researchers who:
286
+
287
+ - Make good faith efforts to comply with this policy
288
+ - Report vulnerabilities in a timely manner
289
+ - Do not access, modify, or delete user data
290
+ - Do not disrupt our services
291
+ - Do not disclose vulnerabilities before they are fixed
292
+ `}exports.NiceDeviceTrust=At;exports.NiceFaceRecognition=rt;exports.NiceFingerprintScanner=Qe;exports.NiceI18nProvider=Ze;exports.NiceIrisScanner=et;exports.NiceMfaSelector=St;exports.NicePassphraseInput=Ct;exports.NicePatternLock=ft;exports.NicePinKeypad=ct;exports.NiceSecurityAuditLog=xt;exports.NiceSessionManager=kt;exports.NiceWebAuthnButton=gt;exports.SECRET_PATTERNS=sr;exports.SECURITY_PATTERNS=er;exports.authenticateWebAuthn=ze;exports.captureFrame=te;exports.checkColorContrast=Yt;exports.checkHeadingHierarchy=Xt;exports.checkLiveness=de;exports.clearNonEssentialCookies=Ot;exports.collectDeviceInfo=he;exports.compareFaceToPhoto=Me;exports.createAuditLogger=Qt;exports.createCSRFFetch=Lt;exports.createHIPAASession=Jt;exports.createRateLimiter=Be;exports.createSafeHtml=Nt;exports.detectIris=Ce;exports.escapeHtml=$e;exports.extractFaceFeatures=ne;exports.extractMinutiae=ke;exports.faceToTemplate=Pe;exports.fingerprintToTemplate=je;exports.generateCSPHeader=It;exports.generateCSRFToken=zt;exports.generateDataExport=qt;exports.generateDeviceFingerprint=se;exports.generateLivenessChallenge=Je;exports.generateNonce=Dt;exports.generatePreCommitHook=nr;exports.generateSASTConfig=tr;exports.generateSCAConfig=rr;exports.generateSecretScanningConfig=ir;exports.generateSecurityAdvisory=ar;exports.generateSecurityMd=or;exports.getCSRFTokenFromCookie=pe;exports.getCameraStream=oe;exports.getConsentPreferences=_e;exports.getRecommendedCSP=Rt;exports.getSOC2Checklist=Vt;exports.hasAccessibleName=Zt;exports.hasConsent=Ut;exports.irisToTemplate=Re;exports.isPasskeyAvailable=Fe;exports.isWebAuthnAvailable=fe;exports.logPHIAccess=Gt;exports.matchFaces=ue;exports.matchFingerprints=Ae;exports.matchIris=Ie;exports.registerWebAuthn=Ne;exports.requestDataDeletion=Kt;exports.resolveConfig=ie;exports.sanitizeInput=Pt;exports.sanitizeSvg=Ft;exports.sanitizeUrl=Et;exports.saveConsentPreferences=Ht;exports.scanFileForViruses=_t;exports.templateToFace=Ee;exports.templateToFingerprint=Te;exports.templateToIris=De;exports.useCSRFToken=$t;exports.useNiceTranslation=X;exports.useRateLimiter=Bt;exports.validateFile=We;exports.validateFiles=Wt;exports.verifyWithBackend=ce;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @nice2dev/ui-security — barrel export
3
+ */
4
+ export { NiceFingerprintScanner } from './components/NiceFingerprintScanner';
5
+ export type { NiceFingerprintScannerProps } from './components/NiceFingerprintScanner';
6
+ export { NiceIrisScanner } from './components/NiceIrisScanner';
7
+ export type { NiceIrisScannerProps } from './components/NiceIrisScanner';
8
+ export { NiceFaceRecognition } from './components/NiceFaceRecognition';
9
+ export type { NiceFaceRecognitionProps } from './components/NiceFaceRecognition';
10
+ export { NicePinKeypad } from './components/NicePinKeypad';
11
+ export type { NicePinKeypadProps } from './components/NicePinKeypad';
12
+ export { NicePatternLock } from './components/NicePatternLock';
13
+ export type { NicePatternLockProps } from './components/NicePatternLock';
14
+ export { NiceWebAuthnButton } from './components/NiceWebAuthnButton';
15
+ export type { NiceWebAuthnButtonProps } from './components/NiceWebAuthnButton';
16
+ export { NiceSecurityAuditLog } from './components/NiceSecurityAuditLog';
17
+ export type { NiceSecurityAuditLogProps } from './components/NiceSecurityAuditLog';
18
+ export { NiceMfaSelector } from './components/NiceMfaSelector';
19
+ export type { NiceMfaSelectorProps, MfaOption } from './components/NiceMfaSelector';
20
+ export { NiceSessionManager } from './components/NiceSessionManager';
21
+ export type { NiceSessionManagerProps, SessionInfo } from './components/NiceSessionManager';
22
+ export { NiceDeviceTrust } from './components/NiceDeviceTrust';
23
+ export type { NiceDeviceTrustProps } from './components/NiceDeviceTrust';
24
+ export { NicePassphraseInput } from './components/NicePassphraseInput';
25
+ export type { NicePassphraseInputProps } from './components/NicePassphraseInput';
26
+ export type { SecurityVerificationStatus, BiometricMethod, BiometricTemplate, BiometricConfig, VerificationResult, FingerPosition, MinutiaePoint, FingerprintFeatures, IrisFeatures, FaceFeatures, FaceLivenessChallenge, KeypadConfig, PatternLockConfig, WebAuthnConfig, SecurityAuditEntry, DeviceTrustScore, } from './core/types';
27
+ export { resolveConfig, getCameraStream, captureFrame, extractMinutiae, matchFingerprints, fingerprintToTemplate, templateToFingerprint, detectIris, matchIris, irisToTemplate, templateToIris, extractFaceFeatures, matchFaces, compareFaceToPhoto, faceToTemplate, templateToFace, generateLivenessChallenge, checkLiveness, collectDeviceInfo, generateDeviceFingerprint, isWebAuthnAvailable, isPasskeyAvailable, registerWebAuthn, authenticateWebAuthn, verifyWithBackend, } from './core/biometricEngine';
28
+ export { NiceI18nProvider, useNiceTranslation } from './core/i18n';
29
+ export type { NiceTranslateFn } from './core/i18n';
30
+ export * from './content-safety';
31
+ export { generateCSPHeader, getRecommendedCSP, generateNonce, type CSPConfig, type CSPDirectives, escapeHtml, sanitizeInput, sanitizeUrl, sanitizeSvg, createSafeHtml, generateCSRFToken, getCSRFTokenFromCookie, createCSRFFetch, useCSRFToken, type CSRFConfig, createRateLimiter, useRateLimiter, type RateLimitConfig, validateFile, validateFiles, scanFileForViruses, type FileUploadConfig, type FileValidationResult, } from './security-utilities';
32
+ export { getConsentPreferences, saveConsentPreferences, hasConsent, clearNonEssentialCookies, generateDataExport, requestDataDeletion, type GDPRConfig, type CookieCategory, type CookieInfo, type ConsentPreferences, logPHIAccess, createHIPAASession, type HIPAAConfig, type PHIAccessLog, checkColorContrast, hasAccessibleName, checkHeadingHierarchy, type WCAGIssue, createAuditLogger, type AuditLogConfig, type AuditLogEntry, getSOC2Checklist, type SOC2ControlStatus, } from './compliance-utilities';
33
+ export { SECURITY_PATTERNS, generateSASTConfig, type SASTConfig, type SASTFinding, generateSCAConfig, type SCAConfig, type SCAVulnerability, SECRET_PATTERNS, generatePreCommitHook, generateSecretScanningConfig, type SecretPattern, generateSecurityAdvisory, generateSecurityMd, type SecurityRelease, } from './security-automation';