@nice2dev/auth 1.0.27 → 1.1.5

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/CHANGELOG.md CHANGED
@@ -1,5 +1,48 @@
1
1
  # @nice2dev/auth — Changelog
2
2
 
3
+ ## 1.1.5
4
+
5
+ No changes in this release.
6
+
7
+ ## 1.0.29
8
+
9
+ ### Patch Changes
10
+
11
+ - Dependency review: align every declared range and adopt React 19 in the dev/test toolchain.
12
+
13
+ - Version drift across the monorepo went from 24 packages to 0; every external package is now
14
+ declared with a single range.
15
+ - `@testing-library/jest-dom` 6 → 7. jest-dom 6 augments `declare module 'vitest'`, which
16
+ vitest 4 no longer uses, so matcher types were broken in every package already on vitest 4.
17
+ - React 19 in devDependencies: `useRef` now requires an initial value, `useRef<T>(null)` yields
18
+ `RefObject<T | null>`, and element props default to `unknown`. Public peer ranges are
19
+ unchanged (`react >=17.0.0`), so consumers are unaffected.
20
+ - Build configs now externalise `react-dom` subpaths (`/^react-dom(\/.*)?$/`). An exact-string
21
+ external does not match `react-dom/server`, which under React 19 resolves to the Node build
22
+ and pulled `async_hooks` into the `ui-graphics` bundle.
23
+ - Buffer-boundary casts for TypeScript 5.7+ generic TypedArrays in audio, graphics and crypto code.
24
+ - `@nice2dev/ui-ai` now externalises `@nice2dev/*`, matching the peer dependencies it already
25
+ declared. It was inlining the whole `@nice2dev/ui` barrel, which put it 8x over its bundle
26
+ budget; it now measures 72.8 kB against 95 kB.
27
+ - `packages/ui/scripts/postbuild-style.mjs` no longer nests a CSS comment inside the generated
28
+ `dist/style.css` banner. CSS comments do not nest, so the inner `*/` closed the block early and
29
+ strict minifiers (lightningcss, used by Vite 8) rejected the file outright.
30
+ - Every remaining minor and patch update applied (44 packages), plus 14 tooling majors
31
+ (`@changesets/cli`, `glob`, `ora`, `lint-staged`, `concurrently`, `chromatic`, `phaser`,
32
+ `fast-check`, `@stripe/stripe-js`, `@nuxt/*`, `@skpm/builder`, `conventional-changelog-angular`,
33
+ `@typescript-eslint/typescript-estree`) and `framer-motion` 12 → 13.
34
+ - `chroma-js` and `@types/chroma-js` moved to 3.x **together**; `transforms.ts` now types the
35
+ lazily-imported binding as the module's default export rather than its namespace, which
36
+ @types/chroma-js 3 distinguishes.
37
+ - `fast-check` 4 removed the `hexaString` arbitrary; `@nice2dev/testing` now builds hex colours
38
+ with `string({ unit })`.
39
+ - `@nice2dev/game-engine` declares `@webgpu/types` instead of relying on an undeclared, hoisted
40
+ copy, and its hand-rolled WebGPU `declare global` block is gone.
41
+ - 25 bare `JSX.*` type references became `React.JSX.*` — React 19 removed the global JSX namespace.
42
+ - 13 packages that run tests in the jsdom environment now declare `jsdom`, and 14 that invoke
43
+ `vitest` now declare `vitest`. They were free-riding on hoisted copies that disappeared the
44
+ moment every manifest agreed on one range.
45
+
3
46
  ## [0.2.0] — 2026-03-25
4
47
 
5
48
  ### Added (FAZA 7.6)
@@ -26,6 +69,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
26
69
  ## [0.1.0] — 2026-01-XX
27
70
 
28
71
  ### Added
72
+
29
73
  - `NiceLoginForm` — login form with validation and i18n
30
74
  - `NiceRegistrationForm` — registration form with password strength
31
75
  - `NiceTwoFaSetup` — TOTP 2FA configuration with QR code
package/dist/index.cjs CHANGED
@@ -1,3 +1,3 @@
1
1
  "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react"),e=require("react/jsx-runtime");function ae(c={}){const{onLogin:s,onRefresh:n,onLogout:a,storageKey:i="nice_auth",persistAuth:l=!1}=c,[o,p]=t.useState(()=>{if(l&&typeof window<"u")try{const u=localStorage.getItem(i);if(u)return{...JSON.parse(u),loading:!1,error:null}}catch{}return{isAuthenticated:!1,user:null,tokens:null,loading:!1,error:null}}),d=t.useCallback(u=>{p(m=>{const f={...m,...u};return l&&typeof window<"u"&&(f.isAuthenticated?localStorage.setItem(i,JSON.stringify({isAuthenticated:!0,user:f.user})):localStorage.removeItem(i)),f})},[l,i]),y=t.useCallback(async(u,m)=>{d({loading:!0,error:null});try{if(s){const f=await s(u,m);return d({isAuthenticated:!0,user:f.user,tokens:f.tokens,loading:!1}),!0}return d({loading:!1,error:"No login handler configured"}),!1}catch(f){return d({loading:!1,error:(f==null?void 0:f.message)??"Login failed"}),!1}},[s,d]),r=t.useCallback(()=>{a==null||a(),d({isAuthenticated:!1,user:null,tokens:null,loading:!1,error:null})},[a,d]),v=t.useCallback(async()=>{var u;if(!((u=o.tokens)!=null&&u.refreshToken)||!n)return!1;try{const m=await n(o.tokens.refreshToken);return d({tokens:m}),!0}catch{return r(),!1}},[o.tokens,n,d,r]),g=t.useCallback((u,m)=>{d({isAuthenticated:!0,user:u,tokens:m,loading:!1,error:null})},[d]),k=t.useCallback((...u)=>o.user?u.every(m=>o.user.roles.includes(m)):!1,[o.user]),x=t.useCallback((...u)=>o.user?u.every(m=>o.user.permissions.includes(m)):!1,[o.user]),R=t.useCallback(()=>{d({error:null})},[d]);return{...o,login:y,logout:r,refreshToken:v,setAuth:g,hasRoles:k,hasPermissions:x,clearError:R}}const Q=t.forwardRef(({onSubmit:c,loading:s=!1,error:n,showRememberMe:a=!0,showForgotPassword:i=!0,onForgotPassword:l,showRegisterLink:o=!0,onRegisterClick:p,title:d="Sign In",submitLabel:y="Sign In",logo:r,footer:v,className:g,style:k,emailLabel:x="Email",passwordLabel:R="Password",tracelessPolicy:u,privacyMessage:m},f)=>{const[S,b]=t.useState(""),[F,w]=t.useState(""),[M,N]=t.useState(!1),T=t.useMemo(()=>!(!a||u&&!u.cookiesAllowed),[a,u]),I=t.useCallback(C=>{C.preventDefault();const A=(u==null?void 0:u.cookiesAllowed)===!1?!1:M;c==null||c({email:S,password:F,rememberMe:A})},[S,F,M,c,u]);return e.jsxs("form",{ref:f,className:`nice-login-form${g?` ${g}`:""}`,style:k,onSubmit:I,noValidate:!0,children:[r&&e.jsx("div",{className:"nice-login-form__logo",children:r}),e.jsx("h2",{className:"nice-login-form__title",children:d}),n&&e.jsx("div",{className:"nice-login-form__error",role:"alert",children:n}),e.jsxs("div",{className:"nice-login-form__field",children:[e.jsx("label",{htmlFor:"nice-login-email",children:x}),e.jsx("input",{id:"nice-login-email",className:"nice-input",type:"email",value:S,onChange:C=>b(C.target.value),autoComplete:"email",required:!0,disabled:s})]}),e.jsxs("div",{className:"nice-login-form__field",children:[e.jsx("label",{htmlFor:"nice-login-password",children:R}),e.jsx("input",{id:"nice-login-password",className:"nice-input",type:"password",value:F,onChange:C=>w(C.target.value),autoComplete:"current-password",required:!0,disabled:s})]}),e.jsxs("div",{className:"nice-login-form__options",children:[T&&e.jsxs("label",{className:"nice-login-form__remember",children:[e.jsx("input",{type:"checkbox",checked:M,onChange:C=>N(C.target.checked),disabled:s}),e.jsx("span",{children:"Remember me"})]}),!T&&a&&m&&e.jsx("span",{className:"nice-login-form__privacy-notice",children:m}),i&&e.jsx("button",{type:"button",className:"nice-login-form__forgot",onClick:l,disabled:s,children:"Forgot password?"})]}),e.jsx("button",{type:"submit",className:"nice-btn nice-btn--primary nice-login-form__submit",disabled:s||!S||!F,children:s?"…":y}),o&&e.jsxs("div",{className:"nice-login-form__register",children:[e.jsx("span",{children:"Don't have an account? "}),e.jsx("button",{type:"button",onClick:p,disabled:s,children:"Register"})]}),v&&e.jsx("div",{className:"nice-login-form__footer",children:v})]})});Q.displayName="NiceLoginForm";const ne={0:"Very weak",1:"Weak",2:"Fair",3:"Strong",4:"Very strong"},ce={0:"#d9534f",1:"#f0ad4e",2:"#5bc0de",3:"#5cb85c",4:"#2e7d32"};function B(c){if(!c)return 0;let s=0;return c.length>=8&&s++,c.length>=12&&s++,/[a-z]/.test(c)&&/[A-Z]/.test(c)&&s++,/\d/.test(c)&&s++,/[^a-zA-Z0-9]/.test(c)&&s++,Math.min(4,s)}const K=t.forwardRef(({password:c,strength:s,showLabel:n=!0,labels:a=ne,className:i},l)=>{const o=s??B(c),p=ce[o],d=(o+1)/5*100;return e.jsxs("div",{ref:l,className:`nice-password-strength${i?` ${i}`:""}`,children:[e.jsx("div",{className:"nice-password-strength__bar",children:e.jsx("div",{className:"nice-password-strength__fill",style:{width:`${d}%`,backgroundColor:p}})}),n&&e.jsx("span",{className:"nice-password-strength__label",style:{color:p},children:a[o]})]})});K.displayName="NicePasswordStrength";const U=t.forwardRef(({onSubmit:c,loading:s=!1,error:n,onLoginClick:a,showPasswordStrength:i=!0,minPasswordStrength:l=2,termsUrl:o,privacyUrl:p,title:d="Create Account",logo:y,footer:r,className:v,style:g},k)=>{const[x,R]=t.useState(""),[u,m]=t.useState(""),[f,S]=t.useState(""),[b,F]=t.useState(""),[w,M]=t.useState(""),[N,T]=t.useState(!1),I=B(b),C=b===w,A=x&&f&&b&&C&&N&&I>=l&&!s,h=t.useCallback(_=>{_.preventDefault(),A&&(c==null||c({firstName:x,lastName:u,email:f,password:b,acceptTerms:N}))},[A,x,u,f,b,N,c]);return e.jsxs("form",{ref:k,className:`nice-register-form${v?` ${v}`:""}`,style:g,onSubmit:h,noValidate:!0,children:[y&&e.jsx("div",{className:"nice-register-form__logo",children:y}),e.jsx("h2",{className:"nice-register-form__title",children:d}),n&&e.jsx("div",{className:"nice-register-form__error",role:"alert",children:n}),e.jsxs("div",{className:"nice-register-form__row",children:[e.jsxs("div",{className:"nice-register-form__field",children:[e.jsx("label",{htmlFor:"nice-reg-first",children:"First name *"}),e.jsx("input",{id:"nice-reg-first",className:"nice-input",type:"text",value:x,onChange:_=>R(_.target.value),required:!0,disabled:s,autoComplete:"given-name"})]}),e.jsxs("div",{className:"nice-register-form__field",children:[e.jsx("label",{htmlFor:"nice-reg-last",children:"Last name"}),e.jsx("input",{id:"nice-reg-last",className:"nice-input",type:"text",value:u,onChange:_=>m(_.target.value),disabled:s,autoComplete:"family-name"})]})]}),e.jsxs("div",{className:"nice-register-form__field",children:[e.jsx("label",{htmlFor:"nice-reg-email",children:"Email *"}),e.jsx("input",{id:"nice-reg-email",className:"nice-input",type:"email",value:f,onChange:_=>S(_.target.value),required:!0,disabled:s,autoComplete:"email"})]}),e.jsxs("div",{className:"nice-register-form__field",children:[e.jsx("label",{htmlFor:"nice-reg-pass",children:"Password *"}),e.jsx("input",{id:"nice-reg-pass",className:"nice-input",type:"password",value:b,onChange:_=>F(_.target.value),required:!0,disabled:s,autoComplete:"new-password"}),i&&b.length>0&&e.jsx(K,{password:b})]}),e.jsxs("div",{className:"nice-register-form__field",children:[e.jsx("label",{htmlFor:"nice-reg-confirm",children:"Confirm password *"}),e.jsx("input",{id:"nice-reg-confirm",className:"nice-input",type:"password",value:w,onChange:_=>M(_.target.value),required:!0,disabled:s,autoComplete:"new-password"}),w&&!C&&e.jsx("span",{className:"nice-error-text",children:"Passwords do not match"})]}),e.jsxs("label",{className:"nice-register-form__terms",children:[e.jsx("input",{type:"checkbox",checked:N,onChange:_=>T(_.target.checked),disabled:s}),e.jsxs("span",{children:["I accept the"," ",o?e.jsx("a",{href:o,target:"_blank",rel:"noopener noreferrer",children:"Terms"}):"Terms",p&&e.jsxs(e.Fragment,{children:[" ","and"," ",e.jsx("a",{href:p,target:"_blank",rel:"noopener noreferrer",children:"Privacy Policy"})]})," *"]})]}),e.jsx("button",{type:"submit",className:"nice-btn nice-btn--primary nice-register-form__submit",disabled:!A,children:s?"…":"Register"}),a&&e.jsxs("div",{className:"nice-register-form__login",children:[e.jsx("span",{children:"Already have an account? "}),e.jsx("button",{type:"button",onClick:a,children:"Sign in"})]}),r&&e.jsx("div",{className:"nice-register-form__footer",children:r})]})});U.displayName="NiceRegistrationForm";const W=t.forwardRef(({requireCurrentPassword:c=!0,onSubmit:s,loading:n=!1,error:a,success:i,minPasswordStrength:l=2,title:o="Change Password",className:p,style:d},y)=>{const[r,v]=t.useState(""),[g,k]=t.useState(""),[x,R]=t.useState(""),u=B(g),m=g===x,f=(!c||r.length>0)&&g.length>0&&m&&u>=l&&!n,S=t.useCallback(b=>{b.preventDefault(),f&&(s==null||s({currentPassword:c?r:void 0,newPassword:g}))},[f,r,g,c,s]);return e.jsxs("form",{ref:y,className:`nice-change-password${p?` ${p}`:""}`,style:d,onSubmit:S,noValidate:!0,children:[e.jsx("h3",{className:"nice-change-password__title",children:o}),a&&e.jsx("div",{className:"nice-change-password__error",role:"alert",children:a}),i&&e.jsx("div",{className:"nice-change-password__success",role:"status",children:i}),c&&e.jsxs("div",{className:"nice-change-password__field",children:[e.jsx("label",{htmlFor:"nice-cp-current",children:"Current password"}),e.jsx("input",{id:"nice-cp-current",className:"nice-input",type:"password",value:r,onChange:b=>v(b.target.value),autoComplete:"current-password",disabled:n,required:!0})]}),e.jsxs("div",{className:"nice-change-password__field",children:[e.jsx("label",{htmlFor:"nice-cp-new",children:"New password"}),e.jsx("input",{id:"nice-cp-new",className:"nice-input",type:"password",value:g,onChange:b=>k(b.target.value),autoComplete:"new-password",disabled:n,required:!0}),g.length>0&&e.jsx(K,{password:g})]}),e.jsxs("div",{className:"nice-change-password__field",children:[e.jsx("label",{htmlFor:"nice-cp-confirm",children:"Confirm new password"}),e.jsx("input",{id:"nice-cp-confirm",className:"nice-input",type:"password",value:x,onChange:b=>R(b.target.value),autoComplete:"new-password",disabled:n,required:!0}),x&&!m&&e.jsx("span",{className:"nice-error-text",children:"Passwords do not match"})]}),e.jsx("button",{type:"submit",className:"nice-btn nice-btn--primary",disabled:!f,children:n?"…":"Change Password"})]})});W.displayName="NiceChangePassword";const J=t.forwardRef(({secret:c,qrCodeUrl:s,issuer:n,accountName:a,onVerify:i,loading:l=!1,error:o,onCancel:p,recoveryCodes:d,step:y="setup",onStepChange:r,className:v,style:g},k)=>{const[x,R]=t.useState(""),[u,m]=t.useState(!1),[f,S]=t.useState(!1),b=t.useCallback(w=>{w.preventDefault(),x.length>=6&&(i==null||i(x))},[x,i]),F=`otpauth://totp/${n?`${n}:`:""}${a??"user"}?secret=${c}${n?`&issuer=${n}`:""}&digits=6&period=30`;return e.jsxs("div",{ref:k,className:`nice-2fa-setup${v?` ${v}`:""}`,style:g,children:[e.jsx("h3",{className:"nice-2fa-setup__title",children:"Two-Factor Authentication"}),y==="setup"&&e.jsxs("div",{className:"nice-2fa-setup__step",children:[e.jsx("p",{className:"nice-2fa-setup__instruction",children:"Scan this QR code with your authenticator app (Google Authenticator, Authy, etc.):"}),s?e.jsx("img",{src:s,alt:"2FA QR Code",className:"nice-2fa-setup__qr"}):e.jsxs("div",{className:"nice-2fa-setup__qr-placeholder",children:[e.jsx("span",{children:"QR Code"}),e.jsx("code",{className:"nice-2fa-setup__uri",children:F})]}),e.jsxs("div",{className:"nice-2fa-setup__secret",children:[e.jsx("span",{children:"Or enter manually: "}),u?e.jsx("code",{className:"nice-2fa-setup__secret-key",children:c}):e.jsx("button",{type:"button",onClick:()=>m(!0),children:"Show secret key"})]}),e.jsx("button",{type:"button",className:"nice-btn nice-btn--primary",onClick:()=>r==null?void 0:r("verify"),children:"Next — Verify"})]}),y==="verify"&&e.jsxs("form",{className:"nice-2fa-setup__step",onSubmit:b,children:[e.jsx("p",{className:"nice-2fa-setup__instruction",children:"Enter the 6-digit code from your authenticator app:"}),o&&e.jsx("div",{className:"nice-2fa-setup__error",role:"alert",children:o}),e.jsx("input",{className:"nice-input nice-2fa-setup__code-input",type:"text",inputMode:"numeric",maxLength:6,value:x,onChange:w=>R(w.target.value.replace(/\D/g,"").slice(0,6)),placeholder:"000000",autoFocus:!0,disabled:l,autoComplete:"one-time-code"}),e.jsxs("div",{className:"nice-2fa-setup__actions",children:[e.jsx("button",{type:"button",className:"nice-btn",onClick:()=>r==null?void 0:r("setup"),children:"Back"}),e.jsx("button",{type:"submit",className:"nice-btn nice-btn--primary",disabled:l||x.length<6,children:l?"…":"Verify"})]})]}),y==="recovery"&&d&&e.jsxs("div",{className:"nice-2fa-setup__step",children:[e.jsx("p",{className:"nice-2fa-setup__instruction",children:"Save these recovery codes in a safe place. Each code can only be used once:"}),e.jsx("div",{className:"nice-2fa-setup__recovery-codes",children:d.map((w,M)=>e.jsx("code",{className:"nice-2fa-setup__recovery-code",children:w},M))}),e.jsx("button",{type:"button",className:"nice-btn",onClick:()=>{var w;(w=navigator.clipboard)==null||w.writeText(d.join(`
2
- `)),S(!0)},children:f?"Copied!":"Copy all codes"}),p&&e.jsx("button",{type:"button",className:"nice-btn nice-btn--primary",onClick:p,children:"Done"})]}),p&&y!=="recovery"&&e.jsx("button",{type:"button",className:"nice-2fa-setup__cancel",onClick:p,children:"Cancel"})]})});J.displayName="NiceTwoFaSetup";const ie=500;function P(c,s){return Math.floor(Math.random()*(s-c+1))+c}function re(){return`${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`}function le(c,s){switch(c){case"math":{const n=s==="easy"?5:s==="hard"?20:10,a=P(1,n),i=P(1,n),l=s!=="easy"&&a>=i&&Math.random()<.5,o=l?a-i:a+i;return{kind:"math",prompt:`${a} ${l?"−":"+"} ${i}`,answer:o}}case"text":{const n=s==="easy"?4:s==="hard"?7:5,a="ABCDEFGHJKMNPQRSTUVWXYZ23456789";let i="";for(let l=0;l<n;l++)i+=a[P(0,a.length-1)];return{kind:"text",text:i}}case"slider":return{kind:"slider",target:P(70,92),tolerance:s==="easy"?8:s==="hard"?2:4};case"checkbox":default:return{kind:"checkbox"}}}function oe(c,s,n){if(!c)return;const a=c.getContext("2d");if(!a)return;const i=c.width,l=c.height;a.clearRect(0,0,i,l),a.fillStyle=n?"#1a1a1a":"#f3f4f6",a.fillRect(0,0,i,l),a.strokeStyle=n?"rgba(255,255,255,0.18)":"rgba(0,0,0,0.18)",a.lineWidth=1;for(let p=0;p<6;p++)a.beginPath(),a.moveTo(P(0,i),P(0,l)),a.lineTo(P(0,i),P(0,l)),a.stroke();a.fillStyle=n?"#e5e7eb":"#111827",a.textBaseline="middle";const o=i/(s.length+1);for(let p=0;p<s.length;p++){const d=P(22,30);a.save(),a.translate(o*(p+1),l/2+P(-4,4)),a.rotate(P(-22,22)*Math.PI/180),a.font=`bold ${d}px monospace`,a.fillText(s[p],-d/3,0),a.restore()}}const Z=t.forwardRef((c,s)=>{const{variant:n,difficulty:a="medium",refreshable:i=!0,verifyToken:l,expiresMs:o,label:p="I'm not a robot",provider:d="custom",siteKey:y,onVerify:r,onExpire:v,onError:g,onRefresh:k,theme:x="light",size:R="normal",customRender:u,className:m,style:f}=c,S=t.useRef(null),b=t.useRef(null),F=t.useRef(),[w,M]=t.useState(0),[N,T]=t.useState("idle"),[I,C]=t.useState(""),[A,h]=t.useState(""),[_,V]=t.useState(0),$=t.useMemo(()=>le(n??"checkbox",a),[n,a,w]),O=t.useCallback(()=>{T("idle"),C(""),h(""),V(0),M(j=>j+1)},[]),z=t.useCallback(()=>{O(),k==null||k()},[O,k]);t.useImperativeHandle(s,()=>({reset:O,refresh:z,container:S.current}),[O,z]),t.useEffect(()=>{n==="text"&&$.kind==="text"&&oe(b.current,$.text,x==="dark")},[n,$,x]),t.useEffect(()=>{if(N!=="verified"||!o)return;const j=setTimeout(()=>{v==null||v(),O()},o);return()=>clearTimeout(j)},[N,o,v,O]);const L=t.useCallback(()=>{const j=`ntd-cap:${n}:${re()}`;l?(T("verifying"),C(""),Promise.resolve().then(()=>l(j)).then(H=>{H?(T("verified"),r==null||r(j)):(T("error"),C("Verification failed. Please try again."),M(se=>se+1),h(""))}).catch(H=>{T("error"),C("Verification error. Please try again."),g==null||g(H)})):(T("verified"),r==null||r(j))},[n,l,r,g]),G=t.useCallback(()=>{T("error"),C("Incorrect, please try again."),M(j=>j+1),h("")},[]),Y=t.useCallback(()=>{N==="verifying"||N==="verified"||(T("verifying"),C(""),F.current=setTimeout(L,ie))},[N,L]);t.useEffect(()=>()=>clearTimeout(F.current),[]);const q=t.useCallback(()=>{$.kind==="math"?A.trim()!==""&&Number(A)===$.answer?L():G():$.kind==="text"&&(A.trim().toUpperCase()===$.text?L():G())},[$,A,L,G]),ee=t.useCallback(j=>{V(j),!($.kind!=="slider"||N==="verified"||N==="verifying")&&Math.abs(j-$.target)<=$.tolerance&&L()},[$,N,L]);if(!n)return d==="custom"&&u?e.jsx("div",{ref:S,className:`nice-captcha nice-captcha--custom${m?` ${m}`:""}`,style:f,children:u}):e.jsx("div",{ref:S,className:`nice-captcha nice-captcha--${d} nice-captcha--${x}${R==="compact"?" nice-captcha--compact":""}${m?` ${m}`:""}`,style:f,"data-sitekey":y,"data-theme":x,"data-size":R,children:e.jsxs("div",{className:"nice-captcha__placeholder",children:[e.jsxs("span",{children:["🔒 Captcha (",d,")"]}),e.jsxs("p",{children:["Load the ",d," SDK to activate verification."]})]})});const D=N==="verifying",E=N==="verified",te=`nice-captcha nice-captcha--${n} nice-captcha--${x} nice-captcha--${N}${R==="compact"?" nice-captcha--compact":""}${m?` ${m}`:""}`;return e.jsxs("div",{ref:S,className:te,style:f,role:"group","aria-label":"Captcha challenge","data-variant":n,"data-status":N,"data-theme":x,children:[n==="checkbox"&&e.jsxs("button",{type:"button",className:"nice-captcha__checkbox",role:"checkbox","aria-checked":E,"aria-busy":D,disabled:D||E,onClick:Y,children:[e.jsx("span",{className:"nice-captcha__box","aria-hidden":"true",children:D?"…":E?"✓":""}),e.jsx("span",{className:"nice-captcha__label",children:p})]}),n==="math"&&$.kind==="math"&&e.jsxs("div",{className:"nice-captcha__challenge",children:[e.jsxs("span",{className:"nice-captcha__prompt","aria-hidden":"true",children:[$.prompt," ="]}),e.jsx("input",{className:"nice-input nice-captcha__answer",type:"number",inputMode:"numeric",value:A,"aria-label":`What is ${$.prompt}?`,disabled:D||E,onChange:j=>h(j.target.value),onKeyDown:j=>{j.key==="Enter"&&(j.preventDefault(),q())}}),e.jsx("button",{type:"button",className:"nice-btn nice-btn--primary nice-captcha__verify",disabled:D||E||A.trim()==="",onClick:q,children:D?"…":"Verify"})]}),n==="text"&&$.kind==="text"&&e.jsxs("div",{className:"nice-captcha__challenge",children:[e.jsx("canvas",{ref:b,className:"nice-captcha__canvas",width:160,height:56,"aria-hidden":"true"}),e.jsx("input",{className:"nice-input nice-captcha__answer",type:"text",autoCapitalize:"characters",autoComplete:"off",value:A,"aria-label":"Type the characters shown in the image",disabled:D||E,onChange:j=>h(j.target.value),onKeyDown:j=>{j.key==="Enter"&&(j.preventDefault(),q())}}),e.jsx("button",{type:"button",className:"nice-btn nice-btn--primary nice-captcha__verify",disabled:D||E||A.trim()==="",onClick:q,children:D?"…":"Verify"})]}),n==="slider"&&$.kind==="slider"&&e.jsxs("div",{className:"nice-captcha__challenge nice-captcha__challenge--slider",children:[e.jsx("span",{className:"nice-captcha__slider-hint","aria-hidden":"true",children:E?"Verified ✓":"Slide to the marker"}),e.jsxs("div",{className:"nice-captcha__track",children:[e.jsx("span",{className:"nice-captcha__target","aria-hidden":"true",style:{left:`${$.target}%`}}),e.jsx("input",{className:"nice-captcha__slider",type:"range",min:0,max:100,value:_,"aria-label":"Slide the handle to the marker to verify","aria-valuetext":`${_}%`,disabled:E||D,onChange:j=>ee(Number(j.target.value))})]})]}),e.jsxs("div",{className:"nice-captcha__footer",children:[e.jsx("div",{className:"nice-captcha__message",role:"status","aria-live":"polite",children:I}),i&&e.jsx("button",{type:"button",className:"nice-captcha__refresh","aria-label":"Refresh challenge",title:"Refresh challenge",onClick:z,children:"↻"})]})]})});Z.displayName="NiceCaptcha";const de=[{id:"google",label:"Google",icon:"🔵",color:"#4285f4",textColor:"#fff"},{id:"microsoft",label:"Microsoft",icon:"🟦",color:"#00a4ef",textColor:"#fff"},{id:"discord",label:"Discord",icon:"💬",color:"#5865f2",textColor:"#fff"},{id:"spotify",label:"Spotify",icon:"🎵",color:"#1db954",textColor:"#fff"},{id:"github",label:"GitHub",icon:"🐙",color:"#24292e",textColor:"#fff"}],X=t.forwardRef(({providers:c=de,onProviderClick:s,disabled:n=!1,loadingProvider:a,direction:i="vertical",separatorText:l="or continue with",showSeparator:o=!0,className:p,style:d},y)=>e.jsxs("div",{ref:y,className:`nice-oauth nice-oauth--${i}${p?` ${p}`:""}`,style:d,children:[o&&e.jsxs("div",{className:"nice-oauth__separator",children:[e.jsx("hr",{}),e.jsx("span",{children:l}),e.jsx("hr",{})]}),e.jsx("div",{className:"nice-oauth__buttons",children:c.map(r=>e.jsxs("button",{type:"button",className:`nice-oauth__btn${a===r.id?" nice-oauth__btn--loading":""}`,style:{backgroundColor:r.color,color:r.textColor},onClick:()=>s==null?void 0:s(r.id),disabled:n||!!a,children:[r.icon&&e.jsx("span",{className:"nice-oauth__btn-icon",children:r.icon}),e.jsx("span",{className:"nice-oauth__btn-label",children:a===r.id?"…":r.label})]},r.id))})]}));X.displayName="NiceOAuthButtons";const ue=t.forwardRef(function(s,n){const{tokens:a,onCreate:i,onRevoke:l,availableScopes:o=[],maxTokens:p=10,title:d="API Tokens",className:y,style:r}=s,[v,g]=t.useState(!1),[k,x]=t.useState(""),[R,u]=t.useState([]),[m,f]=t.useState("90"),[S,b]=t.useState(null),[F,w]=t.useState(!1),[M,N]=t.useState(null),T=t.useCallback(async()=>{if(!(!i||!k.trim())){w(!0);try{const h=m?parseInt(m,10):void 0,_=await i(k.trim(),R,h);b(_),x(""),u([]),g(!1)}finally{w(!1)}}},[i,k,R,m]),I=t.useCallback(async h=>{if(l){N(h);try{await l(h)}finally{N(null)}}},[l]),C=h=>{u(_=>_.includes(h)?_.filter(V=>V!==h):[..._,h])},A=a.length<p;return e.jsxs("div",{ref:n,className:`nice-token-management ${y??""}`,style:r,children:[e.jsxs("div",{className:"nice-token-management__header",children:[e.jsx("h3",{children:d}),A&&e.jsx("button",{className:"nice-token-management__new-btn",onClick:()=>g(!0),disabled:v,children:"+ New Token"})]}),S&&e.jsxs("div",{className:"nice-token-management__reveal",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"New token created!"})," Copy it now — it won't be shown again."]}),e.jsx("code",{className:"nice-token-management__token-value",children:S}),e.jsx("button",{onClick:()=>b(null),children:"Dismiss"})]}),v&&e.jsxs("div",{className:"nice-token-management__create-form",children:[e.jsxs("label",{children:["Name",e.jsx("input",{type:"text",value:k,onChange:h=>x(h.target.value),placeholder:"My API token",maxLength:64})]}),o.length>0&&e.jsxs("fieldset",{children:[e.jsx("legend",{children:"Scopes"}),o.map(h=>e.jsxs("label",{className:"nice-token-management__scope",children:[e.jsx("input",{type:"checkbox",checked:R.includes(h),onChange:()=>C(h)}),h]},h))]}),e.jsxs("label",{children:["Expires in (days)",e.jsx("input",{type:"number",value:m,onChange:h=>f(h.target.value),min:1,max:365})]}),e.jsxs("div",{className:"nice-token-management__create-actions",children:[e.jsx("button",{onClick:T,disabled:F||!k.trim(),children:F?"Creating…":"Create Token"}),e.jsx("button",{onClick:()=>g(!1),children:"Cancel"})]})]}),a.length===0?e.jsx("p",{className:"nice-token-management__empty",children:"No API tokens yet."}):e.jsxs("table",{className:"nice-token-management__table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Name"}),e.jsx("th",{children:"Prefix"}),e.jsx("th",{children:"Created"}),e.jsx("th",{children:"Expires"}),e.jsx("th",{children:"Last Used"}),e.jsx("th",{children:"Scopes"}),e.jsx("th",{})]})}),e.jsx("tbody",{children:a.map(h=>{var _;return e.jsxs("tr",{children:[e.jsx("td",{children:h.name}),e.jsx("td",{children:e.jsxs("code",{children:[h.prefix,"…"]})}),e.jsx("td",{children:h.createdAt}),e.jsx("td",{children:h.expiresAt??"—"}),e.jsx("td",{children:h.lastUsedAt??"Never"}),e.jsx("td",{children:((_=h.scopes)==null?void 0:_.join(", "))||"—"}),e.jsx("td",{children:e.jsx("button",{className:"nice-token-management__revoke-btn",onClick:()=>I(h.id),disabled:M===h.id,children:M===h.id?"Revoking…":"Revoke"})})]},h.id)})})]})]})});exports.NiceCaptcha=Z;exports.NiceChangePassword=W;exports.NiceLoginForm=Q;exports.NiceOAuthButtons=X;exports.NicePasswordStrength=K;exports.NiceRegistrationForm=U;exports.NiceTokenManagement=ue;exports.NiceTwoFaSetup=J;exports.calcPasswordStrength=B;exports.useAuth=ae;
2
+ `)),S(!0)},children:f?"Copied!":"Copy all codes"}),p&&e.jsx("button",{type:"button",className:"nice-btn nice-btn--primary",onClick:p,children:"Done"})]}),p&&y!=="recovery"&&e.jsx("button",{type:"button",className:"nice-2fa-setup__cancel",onClick:p,children:"Cancel"})]})});J.displayName="NiceTwoFaSetup";const ie=500;function P(c,s){return Math.floor(Math.random()*(s-c+1))+c}function re(){return`${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`}function le(c,s){switch(c){case"math":{const n=s==="easy"?5:s==="hard"?20:10,a=P(1,n),i=P(1,n),l=s!=="easy"&&a>=i&&Math.random()<.5,o=l?a-i:a+i;return{kind:"math",prompt:`${a} ${l?"−":"+"} ${i}`,answer:o}}case"text":{const n=s==="easy"?4:s==="hard"?7:5,a="ABCDEFGHJKMNPQRSTUVWXYZ23456789";let i="";for(let l=0;l<n;l++)i+=a[P(0,a.length-1)];return{kind:"text",text:i}}case"slider":return{kind:"slider",target:P(70,92),tolerance:s==="easy"?8:s==="hard"?2:4};case"checkbox":default:return{kind:"checkbox"}}}function oe(c,s,n){if(!c)return;const a=c.getContext("2d");if(!a)return;const i=c.width,l=c.height;a.clearRect(0,0,i,l),a.fillStyle=n?"#1a1a1a":"#f3f4f6",a.fillRect(0,0,i,l),a.strokeStyle=n?"rgba(255,255,255,0.18)":"rgba(0,0,0,0.18)",a.lineWidth=1;for(let p=0;p<6;p++)a.beginPath(),a.moveTo(P(0,i),P(0,l)),a.lineTo(P(0,i),P(0,l)),a.stroke();a.fillStyle=n?"#e5e7eb":"#111827",a.textBaseline="middle";const o=i/(s.length+1);for(let p=0;p<s.length;p++){const d=P(22,30);a.save(),a.translate(o*(p+1),l/2+P(-4,4)),a.rotate(P(-22,22)*Math.PI/180),a.font=`bold ${d}px monospace`,a.fillText(s[p],-d/3,0),a.restore()}}const Z=t.forwardRef((c,s)=>{const{variant:n,difficulty:a="medium",refreshable:i=!0,verifyToken:l,expiresMs:o,label:p="I'm not a robot",provider:d="custom",siteKey:y,onVerify:r,onExpire:v,onError:g,onRefresh:k,theme:x="light",size:R="normal",customRender:u,className:m,style:f}=c,S=t.useRef(null),b=t.useRef(null),F=t.useRef(void 0),[w,M]=t.useState(0),[N,T]=t.useState("idle"),[I,C]=t.useState(""),[A,h]=t.useState(""),[_,V]=t.useState(0),$=t.useMemo(()=>le(n??"checkbox",a),[n,a,w]),O=t.useCallback(()=>{T("idle"),C(""),h(""),V(0),M(j=>j+1)},[]),z=t.useCallback(()=>{O(),k==null||k()},[O,k]);t.useImperativeHandle(s,()=>({reset:O,refresh:z,container:S.current}),[O,z]),t.useEffect(()=>{n==="text"&&$.kind==="text"&&oe(b.current,$.text,x==="dark")},[n,$,x]),t.useEffect(()=>{if(N!=="verified"||!o)return;const j=setTimeout(()=>{v==null||v(),O()},o);return()=>clearTimeout(j)},[N,o,v,O]);const L=t.useCallback(()=>{const j=`ntd-cap:${n}:${re()}`;l?(T("verifying"),C(""),Promise.resolve().then(()=>l(j)).then(H=>{H?(T("verified"),r==null||r(j)):(T("error"),C("Verification failed. Please try again."),M(se=>se+1),h(""))}).catch(H=>{T("error"),C("Verification error. Please try again."),g==null||g(H)})):(T("verified"),r==null||r(j))},[n,l,r,g]),G=t.useCallback(()=>{T("error"),C("Incorrect, please try again."),M(j=>j+1),h("")},[]),Y=t.useCallback(()=>{N==="verifying"||N==="verified"||(T("verifying"),C(""),F.current=setTimeout(L,ie))},[N,L]);t.useEffect(()=>()=>clearTimeout(F.current),[]);const q=t.useCallback(()=>{$.kind==="math"?A.trim()!==""&&Number(A)===$.answer?L():G():$.kind==="text"&&(A.trim().toUpperCase()===$.text?L():G())},[$,A,L,G]),ee=t.useCallback(j=>{V(j),!($.kind!=="slider"||N==="verified"||N==="verifying")&&Math.abs(j-$.target)<=$.tolerance&&L()},[$,N,L]);if(!n)return d==="custom"&&u?e.jsx("div",{ref:S,className:`nice-captcha nice-captcha--custom${m?` ${m}`:""}`,style:f,children:u}):e.jsx("div",{ref:S,className:`nice-captcha nice-captcha--${d} nice-captcha--${x}${R==="compact"?" nice-captcha--compact":""}${m?` ${m}`:""}`,style:f,"data-sitekey":y,"data-theme":x,"data-size":R,children:e.jsxs("div",{className:"nice-captcha__placeholder",children:[e.jsxs("span",{children:["🔒 Captcha (",d,")"]}),e.jsxs("p",{children:["Load the ",d," SDK to activate verification."]})]})});const D=N==="verifying",E=N==="verified",te=`nice-captcha nice-captcha--${n} nice-captcha--${x} nice-captcha--${N}${R==="compact"?" nice-captcha--compact":""}${m?` ${m}`:""}`;return e.jsxs("div",{ref:S,className:te,style:f,role:"group","aria-label":"Captcha challenge","data-variant":n,"data-status":N,"data-theme":x,children:[n==="checkbox"&&e.jsxs("button",{type:"button",className:"nice-captcha__checkbox",role:"checkbox","aria-checked":E,"aria-busy":D,disabled:D||E,onClick:Y,children:[e.jsx("span",{className:"nice-captcha__box","aria-hidden":"true",children:D?"…":E?"✓":""}),e.jsx("span",{className:"nice-captcha__label",children:p})]}),n==="math"&&$.kind==="math"&&e.jsxs("div",{className:"nice-captcha__challenge",children:[e.jsxs("span",{className:"nice-captcha__prompt","aria-hidden":"true",children:[$.prompt," ="]}),e.jsx("input",{className:"nice-input nice-captcha__answer",type:"number",inputMode:"numeric",value:A,"aria-label":`What is ${$.prompt}?`,disabled:D||E,onChange:j=>h(j.target.value),onKeyDown:j=>{j.key==="Enter"&&(j.preventDefault(),q())}}),e.jsx("button",{type:"button",className:"nice-btn nice-btn--primary nice-captcha__verify",disabled:D||E||A.trim()==="",onClick:q,children:D?"…":"Verify"})]}),n==="text"&&$.kind==="text"&&e.jsxs("div",{className:"nice-captcha__challenge",children:[e.jsx("canvas",{ref:b,className:"nice-captcha__canvas",width:160,height:56,"aria-hidden":"true"}),e.jsx("input",{className:"nice-input nice-captcha__answer",type:"text",autoCapitalize:"characters",autoComplete:"off",value:A,"aria-label":"Type the characters shown in the image",disabled:D||E,onChange:j=>h(j.target.value),onKeyDown:j=>{j.key==="Enter"&&(j.preventDefault(),q())}}),e.jsx("button",{type:"button",className:"nice-btn nice-btn--primary nice-captcha__verify",disabled:D||E||A.trim()==="",onClick:q,children:D?"…":"Verify"})]}),n==="slider"&&$.kind==="slider"&&e.jsxs("div",{className:"nice-captcha__challenge nice-captcha__challenge--slider",children:[e.jsx("span",{className:"nice-captcha__slider-hint","aria-hidden":"true",children:E?"Verified ✓":"Slide to the marker"}),e.jsxs("div",{className:"nice-captcha__track",children:[e.jsx("span",{className:"nice-captcha__target","aria-hidden":"true",style:{left:`${$.target}%`}}),e.jsx("input",{className:"nice-captcha__slider",type:"range",min:0,max:100,value:_,"aria-label":"Slide the handle to the marker to verify","aria-valuetext":`${_}%`,disabled:E||D,onChange:j=>ee(Number(j.target.value))})]})]}),e.jsxs("div",{className:"nice-captcha__footer",children:[e.jsx("div",{className:"nice-captcha__message",role:"status","aria-live":"polite",children:I}),i&&e.jsx("button",{type:"button",className:"nice-captcha__refresh","aria-label":"Refresh challenge",title:"Refresh challenge",onClick:z,children:"↻"})]})]})});Z.displayName="NiceCaptcha";const de=[{id:"google",label:"Google",icon:"🔵",color:"#4285f4",textColor:"#fff"},{id:"microsoft",label:"Microsoft",icon:"🟦",color:"#00a4ef",textColor:"#fff"},{id:"discord",label:"Discord",icon:"💬",color:"#5865f2",textColor:"#fff"},{id:"spotify",label:"Spotify",icon:"🎵",color:"#1db954",textColor:"#fff"},{id:"github",label:"GitHub",icon:"🐙",color:"#24292e",textColor:"#fff"}],X=t.forwardRef(({providers:c=de,onProviderClick:s,disabled:n=!1,loadingProvider:a,direction:i="vertical",separatorText:l="or continue with",showSeparator:o=!0,className:p,style:d},y)=>e.jsxs("div",{ref:y,className:`nice-oauth nice-oauth--${i}${p?` ${p}`:""}`,style:d,children:[o&&e.jsxs("div",{className:"nice-oauth__separator",children:[e.jsx("hr",{}),e.jsx("span",{children:l}),e.jsx("hr",{})]}),e.jsx("div",{className:"nice-oauth__buttons",children:c.map(r=>e.jsxs("button",{type:"button",className:`nice-oauth__btn${a===r.id?" nice-oauth__btn--loading":""}`,style:{backgroundColor:r.color,color:r.textColor},onClick:()=>s==null?void 0:s(r.id),disabled:n||!!a,children:[r.icon&&e.jsx("span",{className:"nice-oauth__btn-icon",children:r.icon}),e.jsx("span",{className:"nice-oauth__btn-label",children:a===r.id?"…":r.label})]},r.id))})]}));X.displayName="NiceOAuthButtons";const ue=t.forwardRef(function(s,n){const{tokens:a,onCreate:i,onRevoke:l,availableScopes:o=[],maxTokens:p=10,title:d="API Tokens",className:y,style:r}=s,[v,g]=t.useState(!1),[k,x]=t.useState(""),[R,u]=t.useState([]),[m,f]=t.useState("90"),[S,b]=t.useState(null),[F,w]=t.useState(!1),[M,N]=t.useState(null),T=t.useCallback(async()=>{if(!(!i||!k.trim())){w(!0);try{const h=m?parseInt(m,10):void 0,_=await i(k.trim(),R,h);b(_),x(""),u([]),g(!1)}finally{w(!1)}}},[i,k,R,m]),I=t.useCallback(async h=>{if(l){N(h);try{await l(h)}finally{N(null)}}},[l]),C=h=>{u(_=>_.includes(h)?_.filter(V=>V!==h):[..._,h])},A=a.length<p;return e.jsxs("div",{ref:n,className:`nice-token-management ${y??""}`,style:r,children:[e.jsxs("div",{className:"nice-token-management__header",children:[e.jsx("h3",{children:d}),A&&e.jsx("button",{className:"nice-token-management__new-btn",onClick:()=>g(!0),disabled:v,children:"+ New Token"})]}),S&&e.jsxs("div",{className:"nice-token-management__reveal",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"New token created!"})," Copy it now — it won't be shown again."]}),e.jsx("code",{className:"nice-token-management__token-value",children:S}),e.jsx("button",{onClick:()=>b(null),children:"Dismiss"})]}),v&&e.jsxs("div",{className:"nice-token-management__create-form",children:[e.jsxs("label",{children:["Name",e.jsx("input",{type:"text",value:k,onChange:h=>x(h.target.value),placeholder:"My API token",maxLength:64})]}),o.length>0&&e.jsxs("fieldset",{children:[e.jsx("legend",{children:"Scopes"}),o.map(h=>e.jsxs("label",{className:"nice-token-management__scope",children:[e.jsx("input",{type:"checkbox",checked:R.includes(h),onChange:()=>C(h)}),h]},h))]}),e.jsxs("label",{children:["Expires in (days)",e.jsx("input",{type:"number",value:m,onChange:h=>f(h.target.value),min:1,max:365})]}),e.jsxs("div",{className:"nice-token-management__create-actions",children:[e.jsx("button",{onClick:T,disabled:F||!k.trim(),children:F?"Creating…":"Create Token"}),e.jsx("button",{onClick:()=>g(!1),children:"Cancel"})]})]}),a.length===0?e.jsx("p",{className:"nice-token-management__empty",children:"No API tokens yet."}):e.jsxs("table",{className:"nice-token-management__table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Name"}),e.jsx("th",{children:"Prefix"}),e.jsx("th",{children:"Created"}),e.jsx("th",{children:"Expires"}),e.jsx("th",{children:"Last Used"}),e.jsx("th",{children:"Scopes"}),e.jsx("th",{})]})}),e.jsx("tbody",{children:a.map(h=>{var _;return e.jsxs("tr",{children:[e.jsx("td",{children:h.name}),e.jsx("td",{children:e.jsxs("code",{children:[h.prefix,"…"]})}),e.jsx("td",{children:h.createdAt}),e.jsx("td",{children:h.expiresAt??"—"}),e.jsx("td",{children:h.lastUsedAt??"Never"}),e.jsx("td",{children:((_=h.scopes)==null?void 0:_.join(", "))||"—"}),e.jsx("td",{children:e.jsx("button",{className:"nice-token-management__revoke-btn",onClick:()=>I(h.id),disabled:M===h.id,children:M===h.id?"Revoking…":"Revoke"})})]},h.id)})})]})]})});exports.NiceCaptcha=Z;exports.NiceChangePassword=W;exports.NiceLoginForm=Q;exports.NiceOAuthButtons=X;exports.NicePasswordStrength=K;exports.NiceRegistrationForm=U;exports.NiceTokenManagement=ue;exports.NiceTwoFaSetup=J;exports.calcPasswordStrength=B;exports.useAuth=ae;
3
3
  //# sourceMappingURL=index.cjs.map