@nice2dev/auth 1.1.5 → 1.1.7

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,57 @@
1
1
  # @nice2dev/auth — Changelog
2
2
 
3
+ ## 1.1.7
4
+
5
+ ### Patch Changes
6
+
7
+ - Close the three items left open in the 1.1.6 response to OmniVerk.
8
+
9
+ **Every value control works without state in the parent.** The `audit-controllable-state` gate
10
+ counted 87 value props that were required with no `default*`, so the control could not render from a
11
+ manifest without data. It now reports 0 and gates CI at `--max=0`. 48 controls gained `default*` props
12
+ through `useControllableState` (existing `value` + handler call sites behave as before); 33 read-only
13
+ data lists are optional with a stable empty default; 4 props paired with a handler only by name are
14
+ optional; `NiceWhiteboard` and `NiceMetricsDashboard` render an empty state until a session or
15
+ dashboard arrives. Additive API only — nothing renamed or removed.
16
+
17
+ - `NicePivotGrid.fields`, `NiceScheduler.events` and `NiceGitHooks.hooks` are controlled only together
18
+ with their change handler, as `NiceScheduler` already documented for `currentDate`/`view`. A bare
19
+ prop stays an initial value; prop plus handler now always wins (later prop updates used to be
20
+ ignored). `NiceGitHooks.onHookChange` is now called; `onHooksChange` and
21
+ `NiceLocaleManager.onTranslationsChange` are new.
22
+ - `NiceCodeEditor` / `NiceCodeDiffEditor` no longer report a value written from the prop back through
23
+ `onChange`, and call the latest handler rather than the one captured at mount.
24
+ - `NiceHtmlEditor` no longer rewrites its content on every render (React 19 compares the
25
+ `dangerouslySetInnerHTML` object, not its string), which moved the caret; the HTML source and
26
+ Markdown views can be closed again.
27
+ - Selections seeded once from the first item (access manager, automation/scene editors, git diff
28
+ viewer, ribbon, setup wizard) follow data that arrives after mount.
29
+ - `useControllableState`: new `fallbackValue` seed that never triggers the value/default clash warning;
30
+ two functional updates in one tick no longer lose the first; `onChange` is called with one argument
31
+ when there is no meta. `UseControllableStateOptions` is now a union type alias.
32
+
33
+ **`--nice-*` is the source of truth for design tokens.** Controls read only `--nice-*` (9,225 reads in
34
+ 339 files). The unprefixed names (`--color-primary`, `--bg-primary`, `--text-muted`, …) stay declared
35
+ as aliases pointing at the Nice tokens, so reading them works, but setting them no longer repaints Nice
36
+ controls. Apps that relied on that can import `@nice2dev/ui/css/legacy-bg-text-aliases.css` after
37
+ `style.css` (removed in 1.2), or set `--nice-color-primary` and friends directly. 13 tokens that were
38
+ read and never declared (`--color-danger`, `--text-on-primary`, `--color-white`, …) are defined; the
39
+ dark blocks define the canonical names, so `.nice-dark` on `<body>` no longer leaves them on light
40
+ values; `--nice-primary-bg` and `--nice-selected-bg` are a primary tint instead of falling through to
41
+ grey. New gate `audit-token-names`.
42
+
43
+ **Node ESM and `require()`.** `@nice2dev/spatial-core` imports from plain Node ESM (51 relative
44
+ specifiers gained extensions, enforced by `nodenext`), and so does `@nice2dev/ui-buildings`, which
45
+ failed through it. `require()` works for `ui-3d`, `ui-graphics` and `game-engine`. The package-exports
46
+ gate now loads every entry in both module systems.
47
+
48
+ **Hygiene.** Sources are prettier-formatted and CI gates on it; 640 stale `.d.ts` files were removed
49
+ from source trees (never published).
50
+
51
+ ## 1.1.6
52
+
53
+ No changes in this release.
54
+
3
55
  ## 1.1.5
4
56
 
5
57
  No changes in this release.
@@ -71,4 +71,3 @@ export interface NiceCaptchaProps {
71
71
  * only. Enforce real verification on the server (see `verifyToken`).
72
72
  */
73
73
  export declare const NiceCaptcha: React.ForwardRefExoticComponent<NiceCaptchaProps & React.RefAttributes<NiceCaptchaHandle>>;
74
- //# sourceMappingURL=NiceCaptcha.d.ts.map
@@ -25,4 +25,3 @@ export interface NiceChangePasswordProps {
25
25
  * {@link NiceChangePassword} — Change/reset password form with strength meter.
26
26
  */
27
27
  export declare const NiceChangePassword: React.ForwardRefExoticComponent<NiceChangePasswordProps & React.RefAttributes<HTMLFormElement>>;
28
- //# sourceMappingURL=NiceChangePassword.d.ts.map
@@ -55,4 +55,3 @@ export interface NiceLoginFormProps {
55
55
  */
56
56
  export declare const NiceLoginForm: React.ForwardRefExoticComponent<NiceLoginFormProps & React.RefAttributes<HTMLFormElement>>;
57
57
  export {};
58
- //# sourceMappingURL=NiceLoginForm.d.ts.map
@@ -35,4 +35,3 @@ export interface NiceOAuthButtonsProps {
35
35
  * {@link NiceOAuthButtons} — OAuth login/registration buttons for popular providers.
36
36
  */
37
37
  export declare const NiceOAuthButtons: React.ForwardRefExoticComponent<NiceOAuthButtonsProps & React.RefAttributes<HTMLDivElement>>;
38
- //# sourceMappingURL=NiceOAuthButtons.d.ts.map
@@ -20,4 +20,3 @@ export declare function calcPasswordStrength(password: string): PasswordStrength
20
20
  * with color-coded levels and text labels.
21
21
  */
22
22
  export declare const NicePasswordStrength: React.ForwardRefExoticComponent<NicePasswordStrengthProps & React.RefAttributes<HTMLDivElement>>;
23
- //# sourceMappingURL=NicePasswordStrength.d.ts.map
@@ -39,4 +39,3 @@ export interface NiceRegistrationFormProps {
39
39
  * strength meter, terms acceptance, and optional OAuth footer.
40
40
  */
41
41
  export declare const NiceRegistrationForm: React.ForwardRefExoticComponent<NiceRegistrationFormProps & React.RefAttributes<HTMLFormElement>>;
42
- //# sourceMappingURL=NiceRegistrationForm.d.ts.map
@@ -35,4 +35,3 @@ export interface NiceTokenManagementProps {
35
35
  * once after creation. Supports scopes and expiration.
36
36
  */
37
37
  export declare const NiceTokenManagement: React.ForwardRefExoticComponent<NiceTokenManagementProps & React.RefAttributes<HTMLDivElement>>;
38
- //# sourceMappingURL=NiceTokenManagement.d.ts.map
@@ -31,4 +31,3 @@ export interface NiceTwoFaSetupProps {
31
31
  * QR code display, secret key, verification code input, and recovery codes.
32
32
  */
33
33
  export declare const NiceTwoFaSetup: React.ForwardRefExoticComponent<NiceTwoFaSetupProps & React.RefAttributes<HTMLDivElement>>;
34
- //# sourceMappingURL=NiceTwoFaSetup.d.ts.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=NiceCaptcha.test.d.ts.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=NiceChangePassword.test.d.ts.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=NiceLoginForm.test.d.ts.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=NiceOAuthButtons.test.d.ts.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=NicePasswordStrength.test.d.ts.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=NiceRegistrationForm.test.d.ts.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=NiceTokenManagement.test.d.ts.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=NiceTwoFaSetup.test.d.ts.map
@@ -1 +0,0 @@
1
- //# sourceMappingURL=setup.d.ts.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=useAuth.test.d.ts.map
package/dist/index.cjs CHANGED
@@ -1,3 +1,2 @@
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
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
- //# sourceMappingURL=index.cjs.map
package/dist/index.d.ts CHANGED
@@ -16,4 +16,3 @@ export { NiceOAuthButtons } from './NiceOAuthButtons';
16
16
  export type { OAuthProvider, NiceOAuthButtonsProps } from './NiceOAuthButtons';
17
17
  export { NiceTokenManagement } from './NiceTokenManagement';
18
18
  export type { ApiToken, NiceTokenManagementProps } from './NiceTokenManagement';
19
- //# sourceMappingURL=index.d.ts.map
package/dist/index.mjs CHANGED
@@ -483,82 +483,103 @@ const oe = O(
483
483
  }
484
484
  );
485
485
  oe.displayName = "NiceChangePassword";
486
- const de = O(({
487
- secret: i,
488
- qrCodeUrl: t,
489
- issuer: c,
490
- accountName: n,
491
- onVerify: r,
492
- loading: l = !1,
493
- error: o,
494
- onCancel: p,
495
- recoveryCodes: d,
496
- step: $ = "setup",
497
- onStepChange: s,
498
- className: C,
499
- style: b
500
- }, x) => {
501
- const [g, F] = _(""), [h, m] = _(!1), [f, T] = _(!1), N = w((S) => {
502
- S.preventDefault(), g.length >= 6 && (r == null || r(g));
503
- }, [g, r]), P = `otpauth://totp/${c ? `${c}:` : ""}${n ?? "user"}?secret=${i}${c ? `&issuer=${c}` : ""}&digits=6&period=30`;
504
- return /* @__PURE__ */ a("div", { ref: x, className: `nice-2fa-setup${C ? ` ${C}` : ""}`, style: b, children: [
505
- /* @__PURE__ */ e("h3", { className: "nice-2fa-setup__title", children: "Two-Factor Authentication" }),
506
- $ === "setup" && /* @__PURE__ */ a("div", { className: "nice-2fa-setup__step", children: [
507
- /* @__PURE__ */ e("p", { className: "nice-2fa-setup__instruction", children: "Scan this QR code with your authenticator app (Google Authenticator, Authy, etc.):" }),
508
- t ? /* @__PURE__ */ e("img", { src: t, alt: "2FA QR Code", className: "nice-2fa-setup__qr" }) : /* @__PURE__ */ a("div", { className: "nice-2fa-setup__qr-placeholder", children: [
509
- /* @__PURE__ */ e("span", { children: "QR Code" }),
510
- /* @__PURE__ */ e("code", { className: "nice-2fa-setup__uri", children: P })
486
+ const de = O(
487
+ ({
488
+ secret: i,
489
+ qrCodeUrl: t,
490
+ issuer: c,
491
+ accountName: n,
492
+ onVerify: r,
493
+ loading: l = !1,
494
+ error: o,
495
+ onCancel: p,
496
+ recoveryCodes: d,
497
+ step: $ = "setup",
498
+ onStepChange: s,
499
+ className: C,
500
+ style: b
501
+ }, x) => {
502
+ const [g, F] = _(""), [h, m] = _(!1), [f, T] = _(!1), N = w(
503
+ (S) => {
504
+ S.preventDefault(), g.length >= 6 && (r == null || r(g));
505
+ },
506
+ [g, r]
507
+ ), P = `otpauth://totp/${c ? `${c}:` : ""}${n ?? "user"}?secret=${i}${c ? `&issuer=${c}` : ""}&digits=6&period=30`;
508
+ return /* @__PURE__ */ a("div", { ref: x, className: `nice-2fa-setup${C ? ` ${C}` : ""}`, style: b, children: [
509
+ /* @__PURE__ */ e("h3", { className: "nice-2fa-setup__title", children: "Two-Factor Authentication" }),
510
+ $ === "setup" && /* @__PURE__ */ a("div", { className: "nice-2fa-setup__step", children: [
511
+ /* @__PURE__ */ e("p", { className: "nice-2fa-setup__instruction", children: "Scan this QR code with your authenticator app (Google Authenticator, Authy, etc.):" }),
512
+ t ? /* @__PURE__ */ e("img", { src: t, alt: "2FA QR Code", className: "nice-2fa-setup__qr" }) : /* @__PURE__ */ a("div", { className: "nice-2fa-setup__qr-placeholder", children: [
513
+ /* @__PURE__ */ e("span", { children: "QR Code" }),
514
+ /* @__PURE__ */ e("code", { className: "nice-2fa-setup__uri", children: P })
515
+ ] }),
516
+ /* @__PURE__ */ a("div", { className: "nice-2fa-setup__secret", children: [
517
+ /* @__PURE__ */ e("span", { children: "Or enter manually: " }),
518
+ h ? /* @__PURE__ */ e("code", { className: "nice-2fa-setup__secret-key", children: i }) : /* @__PURE__ */ e("button", { type: "button", onClick: () => m(!0), children: "Show secret key" })
519
+ ] }),
520
+ /* @__PURE__ */ e(
521
+ "button",
522
+ {
523
+ type: "button",
524
+ className: "nice-btn nice-btn--primary",
525
+ onClick: () => s == null ? void 0 : s("verify"),
526
+ children: "Next — Verify"
527
+ }
528
+ )
511
529
  ] }),
512
- /* @__PURE__ */ a("div", { className: "nice-2fa-setup__secret", children: [
513
- /* @__PURE__ */ e("span", { children: "Or enter manually: " }),
514
- h ? /* @__PURE__ */ e("code", { className: "nice-2fa-setup__secret-key", children: i }) : /* @__PURE__ */ e("button", { type: "button", onClick: () => m(!0), children: "Show secret key" })
530
+ $ === "verify" && /* @__PURE__ */ a("form", { className: "nice-2fa-setup__step", onSubmit: N, children: [
531
+ /* @__PURE__ */ e("p", { className: "nice-2fa-setup__instruction", children: "Enter the 6-digit code from your authenticator app:" }),
532
+ o && /* @__PURE__ */ e("div", { className: "nice-2fa-setup__error", role: "alert", children: o }),
533
+ /* @__PURE__ */ e(
534
+ "input",
535
+ {
536
+ className: "nice-input nice-2fa-setup__code-input",
537
+ type: "text",
538
+ inputMode: "numeric",
539
+ maxLength: 6,
540
+ value: g,
541
+ onChange: (S) => F(S.target.value.replace(/\D/g, "").slice(0, 6)),
542
+ placeholder: "000000",
543
+ autoFocus: !0,
544
+ disabled: l,
545
+ autoComplete: "one-time-code"
546
+ }
547
+ ),
548
+ /* @__PURE__ */ a("div", { className: "nice-2fa-setup__actions", children: [
549
+ /* @__PURE__ */ e("button", { type: "button", className: "nice-btn", onClick: () => s == null ? void 0 : s("setup"), children: "Back" }),
550
+ /* @__PURE__ */ e(
551
+ "button",
552
+ {
553
+ type: "submit",
554
+ className: "nice-btn nice-btn--primary",
555
+ disabled: l || g.length < 6,
556
+ children: l ? "…" : "Verify"
557
+ }
558
+ )
559
+ ] })
515
560
  ] }),
516
- /* @__PURE__ */ e("button", { type: "button", className: "nice-btn nice-btn--primary", onClick: () => s == null ? void 0 : s("verify"), children: "Next — Verify" })
517
- ] }),
518
- $ === "verify" && /* @__PURE__ */ a("form", { className: "nice-2fa-setup__step", onSubmit: N, children: [
519
- /* @__PURE__ */ e("p", { className: "nice-2fa-setup__instruction", children: "Enter the 6-digit code from your authenticator app:" }),
520
- o && /* @__PURE__ */ e("div", { className: "nice-2fa-setup__error", role: "alert", children: o }),
521
- /* @__PURE__ */ e(
522
- "input",
523
- {
524
- className: "nice-input nice-2fa-setup__code-input",
525
- type: "text",
526
- inputMode: "numeric",
527
- maxLength: 6,
528
- value: g,
529
- onChange: (S) => F(S.target.value.replace(/\D/g, "").slice(0, 6)),
530
- placeholder: "000000",
531
- autoFocus: !0,
532
- disabled: l,
533
- autoComplete: "one-time-code"
534
- }
535
- ),
536
- /* @__PURE__ */ a("div", { className: "nice-2fa-setup__actions", children: [
537
- /* @__PURE__ */ e("button", { type: "button", className: "nice-btn", onClick: () => s == null ? void 0 : s("setup"), children: "Back" }),
538
- /* @__PURE__ */ e("button", { type: "submit", className: "nice-btn nice-btn--primary", disabled: l || g.length < 6, children: l ? "…" : "Verify" })
539
- ] })
540
- ] }),
541
- $ === "recovery" && d && /* @__PURE__ */ a("div", { className: "nice-2fa-setup__step", children: [
542
- /* @__PURE__ */ e("p", { className: "nice-2fa-setup__instruction", children: "Save these recovery codes in a safe place. Each code can only be used once:" }),
543
- /* @__PURE__ */ e("div", { className: "nice-2fa-setup__recovery-codes", children: d.map((S, E) => /* @__PURE__ */ e("code", { className: "nice-2fa-setup__recovery-code", children: S }, E)) }),
544
- /* @__PURE__ */ e(
545
- "button",
546
- {
547
- type: "button",
548
- className: "nice-btn",
549
- onClick: () => {
550
- var S;
551
- (S = navigator.clipboard) == null || S.writeText(d.join(`
561
+ $ === "recovery" && d && /* @__PURE__ */ a("div", { className: "nice-2fa-setup__step", children: [
562
+ /* @__PURE__ */ e("p", { className: "nice-2fa-setup__instruction", children: "Save these recovery codes in a safe place. Each code can only be used once:" }),
563
+ /* @__PURE__ */ e("div", { className: "nice-2fa-setup__recovery-codes", children: d.map((S, E) => /* @__PURE__ */ e("code", { className: "nice-2fa-setup__recovery-code", children: S }, E)) }),
564
+ /* @__PURE__ */ e(
565
+ "button",
566
+ {
567
+ type: "button",
568
+ className: "nice-btn",
569
+ onClick: () => {
570
+ var S;
571
+ (S = navigator.clipboard) == null || S.writeText(d.join(`
552
572
  `)), T(!0);
553
- },
554
- children: f ? "Copied!" : "Copy all codes"
555
- }
556
- ),
557
- p && /* @__PURE__ */ e("button", { type: "button", className: "nice-btn nice-btn--primary", onClick: p, children: "Done" })
558
- ] }),
559
- p && $ !== "recovery" && /* @__PURE__ */ e("button", { type: "button", className: "nice-2fa-setup__cancel", onClick: p, children: "Cancel" })
560
- ] });
561
- });
573
+ },
574
+ children: f ? "Copied!" : "Copy all codes"
575
+ }
576
+ ),
577
+ p && /* @__PURE__ */ e("button", { type: "button", className: "nice-btn nice-btn--primary", onClick: p, children: "Done" })
578
+ ] }),
579
+ p && $ !== "recovery" && /* @__PURE__ */ e("button", { type: "button", className: "nice-2fa-setup__cancel", onClick: p, children: "Cancel" })
580
+ ] });
581
+ }
582
+ );
562
583
  de.displayName = "NiceTwoFaSetup";
563
584
  const he = 500;
564
585
  function I(i, t) {
@@ -848,46 +869,48 @@ const ge = [
848
869
  { id: "discord", label: "Discord", icon: "💬", color: "#5865f2", textColor: "#fff" },
849
870
  { id: "spotify", label: "Spotify", icon: "🎵", color: "#1db954", textColor: "#fff" },
850
871
  { id: "github", label: "GitHub", icon: "🐙", color: "#24292e", textColor: "#fff" }
851
- ], _e = O(({
852
- providers: i = ge,
853
- onProviderClick: t,
854
- disabled: c = !1,
855
- loadingProvider: n,
856
- direction: r = "vertical",
857
- separatorText: l = "or continue with",
858
- showSeparator: o = !0,
859
- className: p,
860
- style: d
861
- }, $) => /* @__PURE__ */ a(
862
- "div",
863
- {
864
- ref: $,
865
- className: `nice-oauth nice-oauth--${r}${p ? ` ${p}` : ""}`,
866
- style: d,
867
- children: [
868
- o && /* @__PURE__ */ a("div", { className: "nice-oauth__separator", children: [
869
- /* @__PURE__ */ e("hr", {}),
870
- /* @__PURE__ */ e("span", { children: l }),
871
- /* @__PURE__ */ e("hr", {})
872
- ] }),
873
- /* @__PURE__ */ e("div", { className: "nice-oauth__buttons", children: i.map((s) => /* @__PURE__ */ a(
874
- "button",
875
- {
876
- type: "button",
877
- className: `nice-oauth__btn${n === s.id ? " nice-oauth__btn--loading" : ""}`,
878
- style: { backgroundColor: s.color, color: s.textColor },
879
- onClick: () => t == null ? void 0 : t(s.id),
880
- disabled: c || !!n,
881
- children: [
882
- s.icon && /* @__PURE__ */ e("span", { className: "nice-oauth__btn-icon", children: s.icon }),
883
- /* @__PURE__ */ e("span", { className: "nice-oauth__btn-label", children: n === s.id ? "…" : s.label })
884
- ]
885
- },
886
- s.id
887
- )) })
888
- ]
889
- }
890
- ));
872
+ ], _e = O(
873
+ ({
874
+ providers: i = ge,
875
+ onProviderClick: t,
876
+ disabled: c = !1,
877
+ loadingProvider: n,
878
+ direction: r = "vertical",
879
+ separatorText: l = "or continue with",
880
+ showSeparator: o = !0,
881
+ className: p,
882
+ style: d
883
+ }, $) => /* @__PURE__ */ a(
884
+ "div",
885
+ {
886
+ ref: $,
887
+ className: `nice-oauth nice-oauth--${r}${p ? ` ${p}` : ""}`,
888
+ style: d,
889
+ children: [
890
+ o && /* @__PURE__ */ a("div", { className: "nice-oauth__separator", children: [
891
+ /* @__PURE__ */ e("hr", {}),
892
+ /* @__PURE__ */ e("span", { children: l }),
893
+ /* @__PURE__ */ e("hr", {})
894
+ ] }),
895
+ /* @__PURE__ */ e("div", { className: "nice-oauth__buttons", children: i.map((s) => /* @__PURE__ */ a(
896
+ "button",
897
+ {
898
+ type: "button",
899
+ className: `nice-oauth__btn${n === s.id ? " nice-oauth__btn--loading" : ""}`,
900
+ style: { backgroundColor: s.color, color: s.textColor },
901
+ onClick: () => t == null ? void 0 : t(s.id),
902
+ disabled: c || !!n,
903
+ children: [
904
+ s.icon && /* @__PURE__ */ e("span", { className: "nice-oauth__btn-icon", children: s.icon }),
905
+ /* @__PURE__ */ e("span", { className: "nice-oauth__btn-label", children: n === s.id ? "…" : s.label })
906
+ ]
907
+ },
908
+ s.id
909
+ )) })
910
+ ]
911
+ }
912
+ )
913
+ );
891
914
  _e.displayName = "NiceOAuthButtons";
892
915
  const ye = O(
893
916
  function(t, c) {
@@ -1043,4 +1066,3 @@ export {
1043
1066
  J as calcPasswordStrength,
1044
1067
  ve as useAuth
1045
1068
  };
1046
- //# sourceMappingURL=index.mjs.map
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- .nice-captcha{--nice-captcha-bg: var(--bg-elevated, var(--bg-primary, #ffffff));--nice-captcha-fg: var(--text-primary, #111827);--nice-captcha-muted: var(--text-secondary, #6b7280);--nice-captcha-border: var(--border-color, #d1d5db);--nice-captcha-accent: var(--color-primary, #2563eb);--nice-captcha-ok: var(--color-success, #16a34a);--nice-captcha-err: var(--color-danger, #dc2626);--nice-captcha-radius: var(--nice-radius-md, 8px);display:inline-flex;flex-direction:column;gap:10px;box-sizing:border-box;min-width:260px;padding:14px;font-family:var(--nice-font-family, inherit);font-size:14px;color:var(--nice-captcha-fg);background:var(--nice-captcha-bg);border:1px solid var(--nice-captcha-border);border-radius:var(--nice-captcha-radius)}.nice-captcha--dark{--nice-captcha-bg: var(--bg-elevated, #1a1a1a);--nice-captcha-fg: var(--text-primary, #e5e7eb);--nice-captcha-muted: var(--text-secondary, #9ca3af);--nice-captcha-border: var(--border-color, #2a2a2a)}.nice-captcha--compact{min-width:0;padding:8px 10px;font-size:13px}.nice-captcha__placeholder{display:flex;flex-direction:column;gap:4px;align-items:center;justify-content:center;padding:18px;text-align:center;color:var(--nice-captcha-muted);border:1px dashed var(--nice-captcha-border);border-radius:var(--nice-captcha-radius)}.nice-captcha__placeholder span{font-weight:600;color:var(--nice-captcha-fg)}.nice-captcha__placeholder p{margin:0;font-size:12px}.nice-captcha__checkbox{display:flex;align-items:center;gap:10px;padding:8px 10px;font:inherit;color:inherit;text-align:left;cursor:pointer;background:transparent;border:1px solid var(--nice-captcha-border);border-radius:var(--nice-captcha-radius)}.nice-captcha__checkbox:disabled{cursor:default}.nice-captcha__box{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;font-size:14px;line-height:1;background:var(--bg-primary, #ffffff);border:2px solid var(--nice-captcha-border);border-radius:4px}.nice-captcha--dark .nice-captcha__box{background:var(--bg-primary, #0a0a0a)}.nice-captcha--verified .nice-captcha__box{color:#fff;background:var(--nice-captcha-ok);border-color:var(--nice-captcha-ok)}.nice-captcha__challenge{display:flex;flex-wrap:wrap;gap:8px;align-items:center}.nice-captcha__prompt{font-size:18px;font-weight:700;letter-spacing:.5px;-webkit-user-select:none;user-select:none}.nice-captcha__answer{flex:1 1 80px;min-width:70px}.nice-captcha__canvas{display:block;border:1px solid var(--nice-captcha-border);border-radius:4px}.nice-captcha__challenge--slider{flex-direction:column;align-items:stretch}.nice-captcha__slider-hint{font-size:12px;color:var(--nice-captcha-muted)}.nice-captcha__track{position:relative;display:flex;align-items:center}.nice-captcha__target{position:absolute;top:50%;width:2px;height:18px;background:var(--nice-captcha-accent);border-radius:1px;transform:translate(-1px,-50%);pointer-events:none}.nice-captcha__slider{width:100%;accent-color:var(--nice-captcha-accent)}.nice-captcha--verified .nice-captcha__slider{accent-color:var(--nice-captcha-ok)}.nice-captcha__footer{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:18px}.nice-captcha__message{flex:1;font-size:12px;color:var(--nice-captcha-muted)}.nice-captcha--error .nice-captcha__message{color:var(--nice-captcha-err)}.nice-captcha--verified .nice-captcha__message{color:var(--nice-captcha-ok)}.nice-captcha__refresh{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;font-size:16px;line-height:1;color:var(--nice-captcha-muted);cursor:pointer;background:transparent;border:1px solid var(--nice-captcha-border);border-radius:var(--nice-captcha-radius)}.nice-captcha__refresh:hover{color:var(--nice-captcha-fg);border-color:var(--nice-captcha-accent)}
1
+ .nice-captcha{--nice-captcha-bg: var(--nice-bg-elevated, var(--nice-bg-primary, #ffffff));--nice-captcha-fg: var(--nice-text-primary, #111827);--nice-captcha-muted: var(--nice-text-secondary, #6b7280);--nice-captcha-border: var(--nice-border-color, #d1d5db);--nice-captcha-accent: var(--nice-color-primary, #2563eb);--nice-captcha-ok: var(--nice-color-success, #16a34a);--nice-captcha-err: var(--nice-color-danger, #dc2626);--nice-captcha-radius: var(--nice-radius-md, 8px);display:inline-flex;flex-direction:column;gap:10px;box-sizing:border-box;min-width:260px;padding:14px;font-family:var(--nice-font-family, inherit);font-size:14px;color:var(--nice-captcha-fg);background:var(--nice-captcha-bg);border:1px solid var(--nice-captcha-border);border-radius:var(--nice-captcha-radius)}.nice-captcha--dark{--nice-captcha-bg: var(--nice-bg-elevated, #1a1a1a);--nice-captcha-fg: var(--nice-text-primary, #e5e7eb);--nice-captcha-muted: var(--nice-text-secondary, #9ca3af);--nice-captcha-border: var(--nice-border-color, #2a2a2a)}.nice-captcha--compact{min-width:0;padding:8px 10px;font-size:13px}.nice-captcha__placeholder{display:flex;flex-direction:column;gap:4px;align-items:center;justify-content:center;padding:18px;text-align:center;color:var(--nice-captcha-muted);border:1px dashed var(--nice-captcha-border);border-radius:var(--nice-captcha-radius)}.nice-captcha__placeholder span{font-weight:600;color:var(--nice-captcha-fg)}.nice-captcha__placeholder p{margin:0;font-size:12px}.nice-captcha__checkbox{display:flex;align-items:center;gap:10px;padding:8px 10px;font:inherit;color:inherit;text-align:left;cursor:pointer;background:transparent;border:1px solid var(--nice-captcha-border);border-radius:var(--nice-captcha-radius)}.nice-captcha__checkbox:disabled{cursor:default}.nice-captcha__box{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;font-size:14px;line-height:1;background:var(--nice-bg-primary, #ffffff);border:2px solid var(--nice-captcha-border);border-radius:4px}.nice-captcha--dark .nice-captcha__box{background:var(--nice-bg-primary, #0a0a0a)}.nice-captcha--verified .nice-captcha__box{color:#fff;background:var(--nice-captcha-ok);border-color:var(--nice-captcha-ok)}.nice-captcha__challenge{display:flex;flex-wrap:wrap;gap:8px;align-items:center}.nice-captcha__prompt{font-size:18px;font-weight:700;letter-spacing:.5px;-webkit-user-select:none;user-select:none}.nice-captcha__answer{flex:1 1 80px;min-width:70px}.nice-captcha__canvas{display:block;border:1px solid var(--nice-captcha-border);border-radius:4px}.nice-captcha__challenge--slider{flex-direction:column;align-items:stretch}.nice-captcha__slider-hint{font-size:12px;color:var(--nice-captcha-muted)}.nice-captcha__track{position:relative;display:flex;align-items:center}.nice-captcha__target{position:absolute;top:50%;width:2px;height:18px;background:var(--nice-captcha-accent);border-radius:1px;transform:translate(-1px,-50%);pointer-events:none}.nice-captcha__slider{width:100%;accent-color:var(--nice-captcha-accent)}.nice-captcha--verified .nice-captcha__slider{accent-color:var(--nice-captcha-ok)}.nice-captcha__footer{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:18px}.nice-captcha__message{flex:1;font-size:12px;color:var(--nice-captcha-muted)}.nice-captcha--error .nice-captcha__message{color:var(--nice-captcha-err)}.nice-captcha--verified .nice-captcha__message{color:var(--nice-captcha-ok)}.nice-captcha__refresh{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;font-size:16px;line-height:1;color:var(--nice-captcha-muted);cursor:pointer;background:transparent;border:1px solid var(--nice-captcha-border);border-radius:var(--nice-captcha-radius)}.nice-captcha__refresh:hover{color:var(--nice-captcha-fg);border-color:var(--nice-captcha-accent)}
package/dist/useAuth.d.ts CHANGED
@@ -79,4 +79,3 @@ export interface UseAuthConfig {
79
79
  * ```
80
80
  */
81
81
  export declare function useAuth(config?: UseAuthConfig): AuthState & AuthActions;
82
- //# sourceMappingURL=useAuth.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nice2dev/auth",
3
- "version": "1.1.5",
3
+ "version": "1.1.7",
4
4
  "description": "Nice2Dev Auth — Login, registration, OAuth, 2FA, captcha, password strength, token management for React",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",