@drawboard/authagonal-login 0.1.1
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/README.md +73 -0
- package/dist/assets/index-Bn-ws4eD.js +11 -0
- package/dist/assets/index-CDKtEFn6.css +1 -0
- package/dist/branding.json +8 -0
- package/dist/favicon.svg +1 -0
- package/dist/icons.svg +24 -0
- package/dist/index.html +14 -0
- package/index.html +13 -0
- package/package.json +53 -0
- package/public/branding.json +8 -0
- package/public/favicon.svg +1 -0
- package/public/icons.svg +24 -0
- package/src/App.tsx +20 -0
- package/src/api.ts +87 -0
- package/src/branding.ts +36 -0
- package/src/components/AuthLayout.tsx +65 -0
- package/src/i18n/de.json +51 -0
- package/src/i18n/en.json +51 -0
- package/src/i18n/es.json +51 -0
- package/src/i18n/fr.json +51 -0
- package/src/i18n/index.ts +37 -0
- package/src/i18n/pt.json +51 -0
- package/src/i18n/vi.json +51 -0
- package/src/i18n/zh-Hans.json +51 -0
- package/src/index.ts +28 -0
- package/src/main.tsx +19 -0
- package/src/pages/ForgotPasswordPage.tsx +100 -0
- package/src/pages/LoginPage.tsx +308 -0
- package/src/pages/ResetPasswordPage.tsx +228 -0
- package/src/styles.css +339 -0
- package/src/types.ts +46 -0
- package/tsconfig.app.json +28 -0
- package/tsconfig.json +7 -0
- package/vite.config.ts +27 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--color-primary:#2563eb}*,:before,:after{box-sizing:border-box;margin:0;padding:0}body{color:#111827;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background-color:#f3f4f6;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;line-height:1.5}.auth-container{justify-content:center;align-items:center;min-height:100vh;padding:16px;display:flex}.auth-card{background:#fff;border-radius:8px;width:100%;max-width:420px;padding:32px;box-shadow:0 1px 3px #0000001a,0 1px 2px #0000000f}.auth-logo{text-align:center;margin-bottom:24px}.auth-logo h1{color:#111827;letter-spacing:-.025em;font-size:24px;font-weight:700}.auth-logo-img{object-fit:contain;max-width:100%;max-height:48px}.auth-title{color:#111827;margin-bottom:8px;font-size:20px;font-weight:600}.auth-subtitle{color:#6b7280;margin-bottom:20px;font-size:14px}.form-group{margin-bottom:16px}.form-group label{color:#374151;margin-bottom:6px;font-size:14px;font-weight:500;display:block}input{color:#111827;background-color:#fff;border:1px solid #d1d5db;border-radius:6px;width:100%;padding:12px;font-size:16px;transition:border-color .15s,box-shadow .15s}input::placeholder{color:#9ca3af}input:focus{border-color:var(--color-primary);box-shadow:0 0 0 3px color-mix(in srgb, var(--color-primary) 15%, transparent);outline:none}.btn-primary{background-color:var(--color-primary);color:#fff;cursor:pointer;text-align:center;border:none;border-radius:6px;width:100%;padding:12px;font-size:16px;font-weight:500;transition:background-color .15s;display:block}.btn-primary:hover:not(:disabled){background-color:color-mix(in srgb, var(--color-primary) 85%, black)}.btn-primary:disabled{opacity:.5;cursor:not-allowed}.btn-secondary{color:#374151;cursor:pointer;text-align:center;background-color:#fff;border:1px solid #d1d5db;border-radius:6px;width:100%;padding:12px;font-size:16px;font-weight:500;transition:background-color .15s,border-color .15s;display:block}.btn-secondary:hover{background-color:#f9fafb;border-color:#9ca3af}.btn-loading{justify-content:center;align-items:center;gap:8px;display:inline-flex}.spinner{border:2px solid #ffffff4d;border-top-color:#fff;border-radius:50%;width:16px;height:16px;animation:.6s linear infinite spin;display:inline-block}@keyframes spin{to{transform:rotate(360deg)}}.alert-error{color:#991b1b;background-color:#fef2f2;border:1px solid #fecaca;border-radius:6px;margin-bottom:16px;padding:12px;font-size:14px}.alert-success{color:#166534;background-color:#f0fdf4;border:1px solid #bbf7d0;border-radius:6px;margin-bottom:16px;padding:12px;font-size:14px}.link{color:var(--color-primary);font-size:14px;font-weight:500;text-decoration:none}.link:hover{text-decoration:underline}.form-footer{text-align:center;margin-top:16px}.sso-notice{margin-bottom:16px}.sso-notice p{color:#6b7280;margin-bottom:12px;font-size:14px}.sso-checking{color:#6b7280;margin-bottom:16px;font-size:14px}.external-providers{margin-bottom:8px}.btn-provider{color:#374151;cursor:pointer;background-color:#fff;border:1px solid #d1d5db;border-radius:6px;justify-content:center;align-items:center;gap:10px;width:100%;margin-bottom:8px;padding:12px;font-size:16px;font-weight:500;transition:background-color .15s,border-color .15s;display:flex}.btn-provider:hover{background-color:#f9fafb;border-color:#9ca3af}.provider-icon{flex-shrink:0}.divider{color:#9ca3af;align-items:center;gap:12px;margin:16px 0;font-size:13px;display:flex}.divider:before,.divider:after{content:"";background-color:#e5e7eb;flex:1;height:1px}.language-picker{border-top:1px solid #e5e7eb;flex-wrap:wrap;justify-content:center;gap:4px;margin-top:24px;padding-top:16px;display:flex}.language-btn{color:#9ca3af;cursor:pointer;background:0 0;border:none;border-radius:4px;padding:4px 8px;font-size:12px}.language-btn:hover{color:#374151;background-color:#f3f4f6}.language-btn.active{color:var(--color-primary);font-weight:600}.password-requirements{background-color:#f9fafb;border-radius:6px;margin-bottom:16px;padding:12px;list-style:none}.password-requirements li{align-items:center;gap:6px;padding:2px 0;font-size:13px;display:flex}.password-requirements li.met{color:#166534}.password-requirements li.unmet{color:#991b1b}.password-requirements .req-icon{text-align:center;flex-shrink:0;width:16px;font-size:12px}
|
package/dist/favicon.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="46" fill="none" viewBox="0 0 48 46"><path fill="#863bff" d="M25.946 44.938c-.664.845-2.021.375-2.021-.698V33.937a2.26 2.26 0 0 0-2.262-2.262H10.287c-.92 0-1.456-1.04-.92-1.788l7.48-10.471c1.07-1.497 0-3.578-1.842-3.578H1.237c-.92 0-1.456-1.04-.92-1.788L10.013.474c.214-.297.556-.474.92-.474h28.894c.92 0 1.456 1.04.92 1.788l-7.48 10.471c-1.07 1.498 0 3.579 1.842 3.579h11.377c.943 0 1.473 1.088.89 1.83L25.947 44.94z" style="fill:#863bff;fill:color(display-p3 .5252 .23 1);fill-opacity:1"/><mask id="a" width="48" height="46" x="0" y="0" maskUnits="userSpaceOnUse" style="mask-type:alpha"><path fill="#000" d="M25.842 44.938c-.664.844-2.021.375-2.021-.698V33.937a2.26 2.26 0 0 0-2.262-2.262H10.183c-.92 0-1.456-1.04-.92-1.788l7.48-10.471c1.07-1.498 0-3.579-1.842-3.579H1.133c-.92 0-1.456-1.04-.92-1.787L9.91.473c.214-.297.556-.474.92-.474h28.894c.92 0 1.456 1.04.92 1.788l-7.48 10.471c-1.07 1.498 0 3.578 1.842 3.578h11.377c.943 0 1.473 1.088.89 1.832L25.843 44.94z" style="fill:#000;fill-opacity:1"/></mask><g mask="url(#a)"><g filter="url(#b)"><ellipse cx="5.508" cy="14.704" fill="#ede6ff" rx="5.508" ry="14.704" style="fill:#ede6ff;fill:color(display-p3 .9275 .9033 1);fill-opacity:1" transform="matrix(.00324 1 1 -.00324 -4.47 31.516)"/></g><g filter="url(#c)"><ellipse cx="10.399" cy="29.851" fill="#ede6ff" rx="10.399" ry="29.851" style="fill:#ede6ff;fill:color(display-p3 .9275 .9033 1);fill-opacity:1" transform="matrix(.00324 1 1 -.00324 -39.328 7.883)"/></g><g filter="url(#d)"><ellipse cx="5.508" cy="30.487" fill="#7e14ff" rx="5.508" ry="30.487" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.814 -25.913 -14.639)scale(1 -1)"/></g><g filter="url(#e)"><ellipse cx="5.508" cy="30.599" fill="#7e14ff" rx="5.508" ry="30.599" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.814 -32.644 -3.334)scale(1 -1)"/></g><g filter="url(#f)"><ellipse cx="5.508" cy="30.599" fill="#7e14ff" rx="5.508" ry="30.599" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="matrix(.00324 1 1 -.00324 -34.34 30.47)"/></g><g filter="url(#g)"><ellipse cx="14.072" cy="22.078" fill="#ede6ff" rx="14.072" ry="22.078" style="fill:#ede6ff;fill:color(display-p3 .9275 .9033 1);fill-opacity:1" transform="rotate(93.35 24.506 48.493)scale(-1 1)"/></g><g filter="url(#h)"><ellipse cx="3.47" cy="21.501" fill="#7e14ff" rx="3.47" ry="21.501" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.009 28.708 47.59)scale(-1 1)"/></g><g filter="url(#i)"><ellipse cx="3.47" cy="21.501" fill="#7e14ff" rx="3.47" ry="21.501" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.009 28.708 47.59)scale(-1 1)"/></g><g filter="url(#j)"><ellipse cx=".387" cy="8.972" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(39.51 .387 8.972)"/></g><g filter="url(#k)"><ellipse cx="47.523" cy="-6.092" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 47.523 -6.092)"/></g><g filter="url(#l)"><ellipse cx="41.412" cy="6.333" fill="#47bfff" rx="5.971" ry="9.665" style="fill:#47bfff;fill:color(display-p3 .2799 .748 1);fill-opacity:1" transform="rotate(37.892 41.412 6.333)"/></g><g filter="url(#m)"><ellipse cx="-1.879" cy="38.332" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 -1.88 38.332)"/></g><g filter="url(#n)"><ellipse cx="-1.879" cy="38.332" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 -1.88 38.332)"/></g><g filter="url(#o)"><ellipse cx="35.651" cy="29.907" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 35.651 29.907)"/></g><g filter="url(#p)"><ellipse cx="38.418" cy="32.4" fill="#47bfff" rx="5.971" ry="15.297" style="fill:#47bfff;fill:color(display-p3 .2799 .748 1);fill-opacity:1" transform="rotate(37.892 38.418 32.4)"/></g></g><defs><filter id="b" width="60.045" height="41.654" x="-19.77" y="16.149" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="7.659"/></filter><filter id="c" width="90.34" height="51.437" x="-54.613" y="-7.533" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="7.659"/></filter><filter id="d" width="79.355" height="29.4" x="-49.64" y="2.03" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="e" width="79.579" height="29.4" x="-45.045" y="20.029" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="f" width="79.579" height="29.4" x="-43.513" y="21.178" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="g" width="74.749" height="58.852" x="15.756" y="-17.901" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="7.659"/></filter><filter id="h" width="61.377" height="25.362" x="23.548" y="2.284" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="i" width="61.377" height="25.362" x="23.548" y="2.284" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="j" width="56.045" height="63.649" x="-27.636" y="-22.853" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="k" width="54.814" height="64.646" x="20.116" y="-38.415" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="l" width="33.541" height="35.313" x="24.641" y="-11.323" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="m" width="54.814" height="64.646" x="-29.286" y="6.009" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="n" width="54.814" height="64.646" x="-29.286" y="6.009" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="o" width="54.814" height="64.646" x="8.244" y="-2.416" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="p" width="39.409" height="43.623" x="18.713" y="10.588" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter></defs></svg>
|
package/dist/icons.svg
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<symbol id="bluesky-icon" viewBox="0 0 16 17">
|
|
3
|
+
<g clip-path="url(#bluesky-clip)"><path fill="#08060d" d="M7.75 7.735c-.693-1.348-2.58-3.86-4.334-5.097-1.68-1.187-2.32-.981-2.74-.79C.188 2.065.1 2.812.1 3.251s.241 3.602.398 4.13c.52 1.744 2.367 2.333 4.07 2.145-2.495.37-4.71 1.278-1.805 4.512 3.196 3.309 4.38-.71 4.987-2.746.608 2.036 1.307 5.91 4.93 2.746 2.72-2.746.747-4.143-1.747-4.512 1.702.189 3.55-.4 4.07-2.145.156-.528.397-3.691.397-4.13s-.088-1.186-.575-1.406c-.42-.19-1.06-.395-2.741.79-1.755 1.24-3.64 3.752-4.334 5.099"/></g>
|
|
4
|
+
<defs><clipPath id="bluesky-clip"><path fill="#fff" d="M.1.85h15.3v15.3H.1z"/></clipPath></defs>
|
|
5
|
+
</symbol>
|
|
6
|
+
<symbol id="discord-icon" viewBox="0 0 20 19">
|
|
7
|
+
<path fill="#08060d" d="M16.224 3.768a14.5 14.5 0 0 0-3.67-1.153c-.158.286-.343.67-.47.976a13.5 13.5 0 0 0-4.067 0c-.128-.306-.317-.69-.476-.976A14.4 14.4 0 0 0 3.868 3.77C1.546 7.28.916 10.703 1.231 14.077a14.7 14.7 0 0 0 4.5 2.306q.545-.748.965-1.587a9.5 9.5 0 0 1-1.518-.74q.191-.14.372-.293c2.927 1.369 6.107 1.369 8.999 0q.183.152.372.294-.723.437-1.52.74.418.838.963 1.588a14.6 14.6 0 0 0 4.504-2.308c.37-3.911-.63-7.302-2.644-10.309m-9.13 8.234c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.894 0 1.614.82 1.599 1.82.001 1-.705 1.82-1.6 1.82m5.91 0c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.893 0 1.614.82 1.599 1.82 0 1-.706 1.82-1.6 1.82"/>
|
|
8
|
+
</symbol>
|
|
9
|
+
<symbol id="documentation-icon" viewBox="0 0 21 20">
|
|
10
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="m15.5 13.333 1.533 1.322c.645.555.967.833.967 1.178s-.322.623-.967 1.179L15.5 18.333m-3.333-5-1.534 1.322c-.644.555-.966.833-.966 1.178s.322.623.966 1.179l1.534 1.321"/>
|
|
11
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M17.167 10.836v-4.32c0-1.41 0-2.117-.224-2.68-.359-.906-1.118-1.621-2.08-1.96-.599-.21-1.349-.21-2.848-.21-2.623 0-3.935 0-4.983.369-1.684.591-3.013 1.842-3.641 3.428C3 6.449 3 7.684 3 10.154v2.122c0 2.558 0 3.838.706 4.726q.306.383.713.671c.76.536 1.79.64 3.581.66"/>
|
|
12
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M3 10a2.78 2.78 0 0 1 2.778-2.778c.555 0 1.209.097 1.748-.047.48-.129.854-.503.982-.982.145-.54.048-1.194.048-1.749a2.78 2.78 0 0 1 2.777-2.777"/>
|
|
13
|
+
</symbol>
|
|
14
|
+
<symbol id="github-icon" viewBox="0 0 19 19">
|
|
15
|
+
<path fill="#08060d" fill-rule="evenodd" d="M9.356 1.85C5.05 1.85 1.57 5.356 1.57 9.694a7.84 7.84 0 0 0 5.324 7.44c.387.079.528-.168.528-.376 0-.182-.013-.805-.013-1.454-2.165.467-2.616-.935-2.616-.935-.349-.91-.864-1.143-.864-1.143-.71-.48.051-.48.051-.48.787.051 1.2.805 1.2.805.695 1.194 1.817.857 2.268.649.064-.507.27-.857.49-1.052-1.728-.182-3.545-.857-3.545-3.87 0-.857.31-1.558.8-2.104-.078-.195-.349-1 .077-2.078 0 0 .657-.208 2.14.805a7.5 7.5 0 0 1 1.946-.26c.657 0 1.328.092 1.946.26 1.483-1.013 2.14-.805 2.14-.805.426 1.078.155 1.883.078 2.078.502.546.799 1.247.799 2.104 0 3.013-1.818 3.675-3.558 3.87.284.247.528.714.528 1.454 0 1.052-.012 1.896-.012 2.156 0 .208.142.455.528.377a7.84 7.84 0 0 0 5.324-7.441c.013-4.338-3.48-7.844-7.773-7.844" clip-rule="evenodd"/>
|
|
16
|
+
</symbol>
|
|
17
|
+
<symbol id="social-icon" viewBox="0 0 20 20">
|
|
18
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M12.5 6.667a4.167 4.167 0 1 0-8.334 0 4.167 4.167 0 0 0 8.334 0"/>
|
|
19
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M2.5 16.667a5.833 5.833 0 0 1 8.75-5.053m3.837.474.513 1.035c.07.144.257.282.414.309l.93.155c.596.1.736.536.307.965l-.723.73a.64.64 0 0 0-.152.531l.207.903c.164.715-.213.991-.84.618l-.872-.52a.63.63 0 0 0-.577 0l-.872.52c-.624.373-1.003.094-.84-.618l.207-.903a.64.64 0 0 0-.152-.532l-.723-.729c-.426-.43-.289-.864.306-.964l.93-.156a.64.64 0 0 0 .412-.31l.513-1.034c.28-.562.735-.562 1.012 0"/>
|
|
20
|
+
</symbol>
|
|
21
|
+
<symbol id="x-icon" viewBox="0 0 19 19">
|
|
22
|
+
<path fill="#08060d" fill-rule="evenodd" d="M1.893 1.98c.052.072 1.245 1.769 2.653 3.77l2.892 4.114c.183.261.333.48.333.486s-.068.089-.152.183l-.522.593-.765.867-3.597 4.087c-.375.426-.734.834-.798.905a1 1 0 0 0-.118.148c0 .01.236.017.664.017h.663l.729-.83c.4-.457.796-.906.879-.999a692 692 0 0 0 1.794-2.038c.034-.037.301-.34.594-.675l.551-.624.345-.392a7 7 0 0 1 .34-.374c.006 0 .93 1.306 2.052 2.903l2.084 2.965.045.063h2.275c1.87 0 2.273-.003 2.266-.021-.008-.02-1.098-1.572-3.894-5.547-2.013-2.862-2.28-3.246-2.273-3.266.008-.019.282-.332 2.085-2.38l2-2.274 1.567-1.782c.022-.028-.016-.03-.65-.03h-.674l-.3.342a871 871 0 0 1-1.782 2.025c-.067.075-.405.458-.75.852a100 100 0 0 1-.803.91c-.148.172-.299.344-.99 1.127-.304.343-.32.358-.345.327-.015-.019-.904-1.282-1.976-2.808L6.365 1.85H1.8zm1.782.91 8.078 11.294c.772 1.08 1.413 1.973 1.425 1.984.016.017.241.02 1.05.017l1.03-.004-2.694-3.766L7.796 5.75 5.722 2.852l-1.039-.004-1.039-.004z" clip-rule="evenodd"/>
|
|
23
|
+
</symbol>
|
|
24
|
+
</svg>
|
package/dist/index.html
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Sign In — Authagonal</title>
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-Bn-ws4eD.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CDKtEFn6.css">
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<div id="root"></div>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
package/index.html
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Sign In — Authagonal</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="root"></div>
|
|
11
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@drawboard/authagonal-login",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Default login UI for Authagonal — runtime-configurable via branding.json",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "UNLICENSED",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/DrawboardLtd/authagonal.git",
|
|
10
|
+
"directory": "login-app"
|
|
11
|
+
},
|
|
12
|
+
"exports": {
|
|
13
|
+
".": "./src/index.ts",
|
|
14
|
+
"./styles.css": "./src/styles.css"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"src",
|
|
19
|
+
"public",
|
|
20
|
+
"index.html",
|
|
21
|
+
"vite.config.ts",
|
|
22
|
+
"tsconfig.json",
|
|
23
|
+
"tsconfig.app.json"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"dev": "vite",
|
|
27
|
+
"build": "tsc -b && vite build",
|
|
28
|
+
"lint": "eslint .",
|
|
29
|
+
"preview": "vite preview"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"i18next": "^25.1.3",
|
|
33
|
+
"i18next-browser-languagedetector": "^8.0.6",
|
|
34
|
+
"react": "^19.2.4",
|
|
35
|
+
"react-dom": "^19.2.4",
|
|
36
|
+
"react-i18next": "^15.5.2",
|
|
37
|
+
"react-router-dom": "^7.13.2"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@eslint/js": "^9.39.4",
|
|
41
|
+
"@types/node": "^24.12.0",
|
|
42
|
+
"@types/react": "^19.2.14",
|
|
43
|
+
"@types/react-dom": "^19.2.3",
|
|
44
|
+
"@vitejs/plugin-react": "^6.0.1",
|
|
45
|
+
"eslint": "^9.39.4",
|
|
46
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
47
|
+
"eslint-plugin-react-refresh": "^0.5.2",
|
|
48
|
+
"globals": "^17.4.0",
|
|
49
|
+
"typescript": "~5.9.3",
|
|
50
|
+
"typescript-eslint": "^8.57.0",
|
|
51
|
+
"vite": "^8.0.1"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="46" fill="none" viewBox="0 0 48 46"><path fill="#863bff" d="M25.946 44.938c-.664.845-2.021.375-2.021-.698V33.937a2.26 2.26 0 0 0-2.262-2.262H10.287c-.92 0-1.456-1.04-.92-1.788l7.48-10.471c1.07-1.497 0-3.578-1.842-3.578H1.237c-.92 0-1.456-1.04-.92-1.788L10.013.474c.214-.297.556-.474.92-.474h28.894c.92 0 1.456 1.04.92 1.788l-7.48 10.471c-1.07 1.498 0 3.579 1.842 3.579h11.377c.943 0 1.473 1.088.89 1.83L25.947 44.94z" style="fill:#863bff;fill:color(display-p3 .5252 .23 1);fill-opacity:1"/><mask id="a" width="48" height="46" x="0" y="0" maskUnits="userSpaceOnUse" style="mask-type:alpha"><path fill="#000" d="M25.842 44.938c-.664.844-2.021.375-2.021-.698V33.937a2.26 2.26 0 0 0-2.262-2.262H10.183c-.92 0-1.456-1.04-.92-1.788l7.48-10.471c1.07-1.498 0-3.579-1.842-3.579H1.133c-.92 0-1.456-1.04-.92-1.787L9.91.473c.214-.297.556-.474.92-.474h28.894c.92 0 1.456 1.04.92 1.788l-7.48 10.471c-1.07 1.498 0 3.578 1.842 3.578h11.377c.943 0 1.473 1.088.89 1.832L25.843 44.94z" style="fill:#000;fill-opacity:1"/></mask><g mask="url(#a)"><g filter="url(#b)"><ellipse cx="5.508" cy="14.704" fill="#ede6ff" rx="5.508" ry="14.704" style="fill:#ede6ff;fill:color(display-p3 .9275 .9033 1);fill-opacity:1" transform="matrix(.00324 1 1 -.00324 -4.47 31.516)"/></g><g filter="url(#c)"><ellipse cx="10.399" cy="29.851" fill="#ede6ff" rx="10.399" ry="29.851" style="fill:#ede6ff;fill:color(display-p3 .9275 .9033 1);fill-opacity:1" transform="matrix(.00324 1 1 -.00324 -39.328 7.883)"/></g><g filter="url(#d)"><ellipse cx="5.508" cy="30.487" fill="#7e14ff" rx="5.508" ry="30.487" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.814 -25.913 -14.639)scale(1 -1)"/></g><g filter="url(#e)"><ellipse cx="5.508" cy="30.599" fill="#7e14ff" rx="5.508" ry="30.599" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.814 -32.644 -3.334)scale(1 -1)"/></g><g filter="url(#f)"><ellipse cx="5.508" cy="30.599" fill="#7e14ff" rx="5.508" ry="30.599" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="matrix(.00324 1 1 -.00324 -34.34 30.47)"/></g><g filter="url(#g)"><ellipse cx="14.072" cy="22.078" fill="#ede6ff" rx="14.072" ry="22.078" style="fill:#ede6ff;fill:color(display-p3 .9275 .9033 1);fill-opacity:1" transform="rotate(93.35 24.506 48.493)scale(-1 1)"/></g><g filter="url(#h)"><ellipse cx="3.47" cy="21.501" fill="#7e14ff" rx="3.47" ry="21.501" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.009 28.708 47.59)scale(-1 1)"/></g><g filter="url(#i)"><ellipse cx="3.47" cy="21.501" fill="#7e14ff" rx="3.47" ry="21.501" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.009 28.708 47.59)scale(-1 1)"/></g><g filter="url(#j)"><ellipse cx=".387" cy="8.972" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(39.51 .387 8.972)"/></g><g filter="url(#k)"><ellipse cx="47.523" cy="-6.092" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 47.523 -6.092)"/></g><g filter="url(#l)"><ellipse cx="41.412" cy="6.333" fill="#47bfff" rx="5.971" ry="9.665" style="fill:#47bfff;fill:color(display-p3 .2799 .748 1);fill-opacity:1" transform="rotate(37.892 41.412 6.333)"/></g><g filter="url(#m)"><ellipse cx="-1.879" cy="38.332" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 -1.88 38.332)"/></g><g filter="url(#n)"><ellipse cx="-1.879" cy="38.332" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 -1.88 38.332)"/></g><g filter="url(#o)"><ellipse cx="35.651" cy="29.907" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 35.651 29.907)"/></g><g filter="url(#p)"><ellipse cx="38.418" cy="32.4" fill="#47bfff" rx="5.971" ry="15.297" style="fill:#47bfff;fill:color(display-p3 .2799 .748 1);fill-opacity:1" transform="rotate(37.892 38.418 32.4)"/></g></g><defs><filter id="b" width="60.045" height="41.654" x="-19.77" y="16.149" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="7.659"/></filter><filter id="c" width="90.34" height="51.437" x="-54.613" y="-7.533" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="7.659"/></filter><filter id="d" width="79.355" height="29.4" x="-49.64" y="2.03" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="e" width="79.579" height="29.4" x="-45.045" y="20.029" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="f" width="79.579" height="29.4" x="-43.513" y="21.178" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="g" width="74.749" height="58.852" x="15.756" y="-17.901" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="7.659"/></filter><filter id="h" width="61.377" height="25.362" x="23.548" y="2.284" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="i" width="61.377" height="25.362" x="23.548" y="2.284" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="j" width="56.045" height="63.649" x="-27.636" y="-22.853" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="k" width="54.814" height="64.646" x="20.116" y="-38.415" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="l" width="33.541" height="35.313" x="24.641" y="-11.323" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="m" width="54.814" height="64.646" x="-29.286" y="6.009" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="n" width="54.814" height="64.646" x="-29.286" y="6.009" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="o" width="54.814" height="64.646" x="8.244" y="-2.416" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="p" width="39.409" height="43.623" x="18.713" y="10.588" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter></defs></svg>
|
package/public/icons.svg
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<symbol id="bluesky-icon" viewBox="0 0 16 17">
|
|
3
|
+
<g clip-path="url(#bluesky-clip)"><path fill="#08060d" d="M7.75 7.735c-.693-1.348-2.58-3.86-4.334-5.097-1.68-1.187-2.32-.981-2.74-.79C.188 2.065.1 2.812.1 3.251s.241 3.602.398 4.13c.52 1.744 2.367 2.333 4.07 2.145-2.495.37-4.71 1.278-1.805 4.512 3.196 3.309 4.38-.71 4.987-2.746.608 2.036 1.307 5.91 4.93 2.746 2.72-2.746.747-4.143-1.747-4.512 1.702.189 3.55-.4 4.07-2.145.156-.528.397-3.691.397-4.13s-.088-1.186-.575-1.406c-.42-.19-1.06-.395-2.741.79-1.755 1.24-3.64 3.752-4.334 5.099"/></g>
|
|
4
|
+
<defs><clipPath id="bluesky-clip"><path fill="#fff" d="M.1.85h15.3v15.3H.1z"/></clipPath></defs>
|
|
5
|
+
</symbol>
|
|
6
|
+
<symbol id="discord-icon" viewBox="0 0 20 19">
|
|
7
|
+
<path fill="#08060d" d="M16.224 3.768a14.5 14.5 0 0 0-3.67-1.153c-.158.286-.343.67-.47.976a13.5 13.5 0 0 0-4.067 0c-.128-.306-.317-.69-.476-.976A14.4 14.4 0 0 0 3.868 3.77C1.546 7.28.916 10.703 1.231 14.077a14.7 14.7 0 0 0 4.5 2.306q.545-.748.965-1.587a9.5 9.5 0 0 1-1.518-.74q.191-.14.372-.293c2.927 1.369 6.107 1.369 8.999 0q.183.152.372.294-.723.437-1.52.74.418.838.963 1.588a14.6 14.6 0 0 0 4.504-2.308c.37-3.911-.63-7.302-2.644-10.309m-9.13 8.234c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.894 0 1.614.82 1.599 1.82.001 1-.705 1.82-1.6 1.82m5.91 0c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.893 0 1.614.82 1.599 1.82 0 1-.706 1.82-1.6 1.82"/>
|
|
8
|
+
</symbol>
|
|
9
|
+
<symbol id="documentation-icon" viewBox="0 0 21 20">
|
|
10
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="m15.5 13.333 1.533 1.322c.645.555.967.833.967 1.178s-.322.623-.967 1.179L15.5 18.333m-3.333-5-1.534 1.322c-.644.555-.966.833-.966 1.178s.322.623.966 1.179l1.534 1.321"/>
|
|
11
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M17.167 10.836v-4.32c0-1.41 0-2.117-.224-2.68-.359-.906-1.118-1.621-2.08-1.96-.599-.21-1.349-.21-2.848-.21-2.623 0-3.935 0-4.983.369-1.684.591-3.013 1.842-3.641 3.428C3 6.449 3 7.684 3 10.154v2.122c0 2.558 0 3.838.706 4.726q.306.383.713.671c.76.536 1.79.64 3.581.66"/>
|
|
12
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M3 10a2.78 2.78 0 0 1 2.778-2.778c.555 0 1.209.097 1.748-.047.48-.129.854-.503.982-.982.145-.54.048-1.194.048-1.749a2.78 2.78 0 0 1 2.777-2.777"/>
|
|
13
|
+
</symbol>
|
|
14
|
+
<symbol id="github-icon" viewBox="0 0 19 19">
|
|
15
|
+
<path fill="#08060d" fill-rule="evenodd" d="M9.356 1.85C5.05 1.85 1.57 5.356 1.57 9.694a7.84 7.84 0 0 0 5.324 7.44c.387.079.528-.168.528-.376 0-.182-.013-.805-.013-1.454-2.165.467-2.616-.935-2.616-.935-.349-.91-.864-1.143-.864-1.143-.71-.48.051-.48.051-.48.787.051 1.2.805 1.2.805.695 1.194 1.817.857 2.268.649.064-.507.27-.857.49-1.052-1.728-.182-3.545-.857-3.545-3.87 0-.857.31-1.558.8-2.104-.078-.195-.349-1 .077-2.078 0 0 .657-.208 2.14.805a7.5 7.5 0 0 1 1.946-.26c.657 0 1.328.092 1.946.26 1.483-1.013 2.14-.805 2.14-.805.426 1.078.155 1.883.078 2.078.502.546.799 1.247.799 2.104 0 3.013-1.818 3.675-3.558 3.87.284.247.528.714.528 1.454 0 1.052-.012 1.896-.012 2.156 0 .208.142.455.528.377a7.84 7.84 0 0 0 5.324-7.441c.013-4.338-3.48-7.844-7.773-7.844" clip-rule="evenodd"/>
|
|
16
|
+
</symbol>
|
|
17
|
+
<symbol id="social-icon" viewBox="0 0 20 20">
|
|
18
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M12.5 6.667a4.167 4.167 0 1 0-8.334 0 4.167 4.167 0 0 0 8.334 0"/>
|
|
19
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M2.5 16.667a5.833 5.833 0 0 1 8.75-5.053m3.837.474.513 1.035c.07.144.257.282.414.309l.93.155c.596.1.736.536.307.965l-.723.73a.64.64 0 0 0-.152.531l.207.903c.164.715-.213.991-.84.618l-.872-.52a.63.63 0 0 0-.577 0l-.872.52c-.624.373-1.003.094-.84-.618l.207-.903a.64.64 0 0 0-.152-.532l-.723-.729c-.426-.43-.289-.864.306-.964l.93-.156a.64.64 0 0 0 .412-.31l.513-1.034c.28-.562.735-.562 1.012 0"/>
|
|
20
|
+
</symbol>
|
|
21
|
+
<symbol id="x-icon" viewBox="0 0 19 19">
|
|
22
|
+
<path fill="#08060d" fill-rule="evenodd" d="M1.893 1.98c.052.072 1.245 1.769 2.653 3.77l2.892 4.114c.183.261.333.48.333.486s-.068.089-.152.183l-.522.593-.765.867-3.597 4.087c-.375.426-.734.834-.798.905a1 1 0 0 0-.118.148c0 .01.236.017.664.017h.663l.729-.83c.4-.457.796-.906.879-.999a692 692 0 0 0 1.794-2.038c.034-.037.301-.34.594-.675l.551-.624.345-.392a7 7 0 0 1 .34-.374c.006 0 .93 1.306 2.052 2.903l2.084 2.965.045.063h2.275c1.87 0 2.273-.003 2.266-.021-.008-.02-1.098-1.572-3.894-5.547-2.013-2.862-2.28-3.246-2.273-3.266.008-.019.282-.332 2.085-2.38l2-2.274 1.567-1.782c.022-.028-.016-.03-.65-.03h-.674l-.3.342a871 871 0 0 1-1.782 2.025c-.067.075-.405.458-.75.852a100 100 0 0 1-.803.91c-.148.172-.299.344-.99 1.127-.304.343-.32.358-.345.327-.015-.019-.904-1.282-1.976-2.808L6.365 1.85H1.8zm1.782.91 8.078 11.294c.772 1.08 1.413 1.973 1.425 1.984.016.017.241.02 1.05.017l1.03-.004-2.694-3.766L7.796 5.75 5.722 2.852l-1.039-.004-1.039-.004z" clip-rule="evenodd"/>
|
|
23
|
+
</symbol>
|
|
24
|
+
</svg>
|
package/src/App.tsx
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
|
|
2
|
+
import AuthLayout from './components/AuthLayout';
|
|
3
|
+
import LoginPage from './pages/LoginPage';
|
|
4
|
+
import ForgotPasswordPage from './pages/ForgotPasswordPage';
|
|
5
|
+
import ResetPasswordPage from './pages/ResetPasswordPage';
|
|
6
|
+
|
|
7
|
+
export default function App() {
|
|
8
|
+
return (
|
|
9
|
+
<BrowserRouter>
|
|
10
|
+
<AuthLayout>
|
|
11
|
+
<Routes>
|
|
12
|
+
<Route path="/login" element={<LoginPage />} />
|
|
13
|
+
<Route path="/forgot-password" element={<ForgotPasswordPage />} />
|
|
14
|
+
<Route path="/reset-password" element={<ResetPasswordPage />} />
|
|
15
|
+
<Route path="*" element={<Navigate to="/login" replace />} />
|
|
16
|
+
</Routes>
|
|
17
|
+
</AuthLayout>
|
|
18
|
+
</BrowserRouter>
|
|
19
|
+
);
|
|
20
|
+
}
|
package/src/api.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { LoginResponse, ApiError, SessionResponse, SsoCheckResponse, ProvidersResponse, PasswordPolicyResponse } from './types';
|
|
2
|
+
|
|
3
|
+
const API_URL = import.meta.env.VITE_API_URL || '';
|
|
4
|
+
|
|
5
|
+
class ApiRequestError extends Error {
|
|
6
|
+
public error: string;
|
|
7
|
+
public retryAfter?: number;
|
|
8
|
+
public redirectUrl?: string;
|
|
9
|
+
|
|
10
|
+
constructor(apiError: ApiError) {
|
|
11
|
+
super(apiError.message || apiError.error);
|
|
12
|
+
this.name = 'ApiRequestError';
|
|
13
|
+
this.error = apiError.error;
|
|
14
|
+
this.retryAfter = apiError.retryAfter;
|
|
15
|
+
this.redirectUrl = apiError.redirectUrl;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async function api<T>(path: string, options?: RequestInit): Promise<T> {
|
|
20
|
+
const url = `${API_URL}${path}`;
|
|
21
|
+
|
|
22
|
+
const response = await fetch(url, {
|
|
23
|
+
...options,
|
|
24
|
+
credentials: 'include',
|
|
25
|
+
headers: {
|
|
26
|
+
'Content-Type': 'application/json',
|
|
27
|
+
...options?.headers,
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
if (!response.ok) {
|
|
32
|
+
let apiError: ApiError;
|
|
33
|
+
try {
|
|
34
|
+
apiError = await response.json() as ApiError;
|
|
35
|
+
} catch {
|
|
36
|
+
apiError = { error: 'unknown_error', message: `Request failed with status ${response.status}` };
|
|
37
|
+
}
|
|
38
|
+
throw new ApiRequestError(apiError);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return response.json() as Promise<T>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function login(email: string, password: string): Promise<LoginResponse> {
|
|
45
|
+
return api<LoginResponse>('/api/auth/login', {
|
|
46
|
+
method: 'POST',
|
|
47
|
+
body: JSON.stringify({ email, password }),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function logout(): Promise<{ success: true }> {
|
|
52
|
+
return api<{ success: true }>('/api/auth/logout', {
|
|
53
|
+
method: 'POST',
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function forgotPassword(email: string): Promise<{ success: true }> {
|
|
58
|
+
return api<{ success: true }>('/api/auth/forgot-password', {
|
|
59
|
+
method: 'POST',
|
|
60
|
+
body: JSON.stringify({ email }),
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function resetPassword(token: string, newPassword: string): Promise<{ success: true }> {
|
|
65
|
+
return api<{ success: true }>('/api/auth/reset-password', {
|
|
66
|
+
method: 'POST',
|
|
67
|
+
body: JSON.stringify({ token, newPassword }),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function getSession(): Promise<SessionResponse> {
|
|
72
|
+
return api<SessionResponse>('/api/auth/session');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function ssoCheck(email: string): Promise<SsoCheckResponse> {
|
|
76
|
+
return api<SsoCheckResponse>(`/api/auth/sso-check?email=${encodeURIComponent(email)}`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function getProviders(): Promise<ProvidersResponse> {
|
|
80
|
+
return api<ProvidersResponse>('/api/auth/providers');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function getPasswordPolicy(): Promise<PasswordPolicyResponse> {
|
|
84
|
+
return api<PasswordPolicyResponse>('/api/auth/password-policy');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export { ApiRequestError };
|
package/src/branding.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface BrandingConfig {
|
|
4
|
+
appName: string;
|
|
5
|
+
logoUrl: string | null;
|
|
6
|
+
primaryColor: string;
|
|
7
|
+
supportEmail: string | null;
|
|
8
|
+
showForgotPassword: boolean;
|
|
9
|
+
customCssUrl: string | null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const defaults: BrandingConfig = {
|
|
13
|
+
appName: 'Authagonal',
|
|
14
|
+
logoUrl: null,
|
|
15
|
+
primaryColor: '#2563eb',
|
|
16
|
+
supportEmail: null,
|
|
17
|
+
showForgotPassword: true,
|
|
18
|
+
customCssUrl: null,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export async function loadBranding(): Promise<BrandingConfig> {
|
|
22
|
+
try {
|
|
23
|
+
const response = await fetch('/branding.json');
|
|
24
|
+
if (!response.ok) return defaults;
|
|
25
|
+
const json = await response.json();
|
|
26
|
+
return { ...defaults, ...json };
|
|
27
|
+
} catch {
|
|
28
|
+
return defaults;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const BrandingContext = createContext<BrandingConfig>(defaults);
|
|
33
|
+
|
|
34
|
+
export function useBranding(): BrandingConfig {
|
|
35
|
+
return useContext(BrandingContext);
|
|
36
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { useEffect, type ReactNode } from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import { useBranding } from '../branding';
|
|
4
|
+
|
|
5
|
+
// Ensure i18n is initialized when AuthLayout is used (including by npm consumers)
|
|
6
|
+
import '../i18n';
|
|
7
|
+
|
|
8
|
+
interface AuthLayoutProps {
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const LANGUAGES: { code: string; label: string }[] = [
|
|
13
|
+
{ code: 'en', label: 'English' },
|
|
14
|
+
{ code: 'zh-Hans', label: '中文' },
|
|
15
|
+
{ code: 'de', label: 'Deutsch' },
|
|
16
|
+
{ code: 'fr', label: 'Français' },
|
|
17
|
+
{ code: 'es', label: 'Español' },
|
|
18
|
+
{ code: 'vi', label: 'Tiếng Việt' },
|
|
19
|
+
{ code: 'pt', label: 'Português' },
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
export default function AuthLayout({ children }: AuthLayoutProps) {
|
|
23
|
+
const branding = useBranding();
|
|
24
|
+
const { i18n } = useTranslation();
|
|
25
|
+
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
document.documentElement.style.setProperty('--color-primary', branding.primaryColor);
|
|
28
|
+
|
|
29
|
+
if (branding.customCssUrl) {
|
|
30
|
+
const link = document.createElement('link');
|
|
31
|
+
link.rel = 'stylesheet';
|
|
32
|
+
link.href = branding.customCssUrl;
|
|
33
|
+
link.id = 'branding-css';
|
|
34
|
+
document.head.appendChild(link);
|
|
35
|
+
return () => { link.remove(); };
|
|
36
|
+
}
|
|
37
|
+
}, [branding]);
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<div className="auth-container">
|
|
41
|
+
<div className="auth-card">
|
|
42
|
+
<div className="auth-logo">
|
|
43
|
+
{branding.logoUrl ? (
|
|
44
|
+
<img src={branding.logoUrl} alt={branding.appName} className="auth-logo-img" />
|
|
45
|
+
) : (
|
|
46
|
+
<h1>{branding.appName}</h1>
|
|
47
|
+
)}
|
|
48
|
+
</div>
|
|
49
|
+
{children}
|
|
50
|
+
<div className="language-picker">
|
|
51
|
+
{LANGUAGES.map((lang) => (
|
|
52
|
+
<button
|
|
53
|
+
key={lang.code}
|
|
54
|
+
type="button"
|
|
55
|
+
className={`language-btn${i18n.language === lang.code || i18n.language?.startsWith(lang.code) ? ' active' : ''}`}
|
|
56
|
+
onClick={() => i18n.changeLanguage(lang.code)}
|
|
57
|
+
>
|
|
58
|
+
{lang.label}
|
|
59
|
+
</button>
|
|
60
|
+
))}
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
);
|
|
65
|
+
}
|
package/src/i18n/de.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"signIn": "Anmelden",
|
|
3
|
+
"email": "E-Mail",
|
|
4
|
+
"password": "Passwort",
|
|
5
|
+
"emailPlaceholder": "you@example.com",
|
|
6
|
+
"passwordPlaceholder": "Passwort eingeben",
|
|
7
|
+
"signingIn": "Anmeldung läuft...",
|
|
8
|
+
"forgotPassword": "Passwort vergessen?",
|
|
9
|
+
"ssoChecking": "Anmeldeoptionen werden überprüft...",
|
|
10
|
+
"ssoNotice": "Ihre Organisation verwendet Single Sign-On",
|
|
11
|
+
"continueWithSso": "Weiter mit SSO",
|
|
12
|
+
"errorInvalidCredentials": "Ungültige E-Mail-Adresse oder ungültiges Passwort",
|
|
13
|
+
"errorLockedOut": "Konto gesperrt. Versuchen Sie es in {{seconds}} Sekunden erneut",
|
|
14
|
+
"errorEmailNotConfirmed": "Bitte überprüfen Sie Ihre E-Mail, um Ihr Konto zu bestätigen",
|
|
15
|
+
"errorSsoRequired": "Für dieses Konto ist Single Sign-On erforderlich",
|
|
16
|
+
"errorEmailRequired": "E-Mail ist erforderlich",
|
|
17
|
+
"errorPasswordRequired": "Passwort ist erforderlich",
|
|
18
|
+
"errorUnexpected": "Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es erneut.",
|
|
19
|
+
"resetYourPassword": "Passwort zurücksetzen",
|
|
20
|
+
"resetSubtitle": "Geben Sie Ihre E-Mail-Adresse ein und wir senden Ihnen einen Link zum Zurücksetzen Ihres Passworts.",
|
|
21
|
+
"sending": "Wird gesendet...",
|
|
22
|
+
"sendResetLink": "Link zum Zurücksetzen senden",
|
|
23
|
+
"backToSignIn": "Zurück zur Anmeldung",
|
|
24
|
+
"checkYourEmail": "Überprüfen Sie Ihre E-Mail",
|
|
25
|
+
"resetEmailSent": "Falls ein Konto mit dieser E-Mail-Adresse existiert, erhalten Sie in Kürze einen Link zum Zurücksetzen.",
|
|
26
|
+
"setNewPassword": "Neues Passwort festlegen",
|
|
27
|
+
"newPassword": "Neues Passwort",
|
|
28
|
+
"newPasswordPlaceholder": "Neues Passwort eingeben",
|
|
29
|
+
"confirmPassword": "Passwort bestätigen",
|
|
30
|
+
"confirmPasswordPlaceholder": "Neues Passwort bestätigen",
|
|
31
|
+
"resetting": "Wird zurückgesetzt...",
|
|
32
|
+
"resetPassword": "Passwort zurücksetzen",
|
|
33
|
+
"passwordResetSuccess": "Passwort erfolgreich zurückgesetzt",
|
|
34
|
+
"passwordResetSuccessMessage": "Ihr Passwort wurde zurückgesetzt. Sie können sich jetzt mit Ihrem neuen Passwort anmelden.",
|
|
35
|
+
"invalidLink": "Ungültiger Link",
|
|
36
|
+
"invalidOrExpiredLink": "Dieser Link zum Zurücksetzen ist ungültig oder abgelaufen.",
|
|
37
|
+
"requestNewResetLink": "Neuen Link zum Zurücksetzen anfordern",
|
|
38
|
+
"passwordNotMeetRequirements": "Passwort erfüllt nicht die Anforderungen",
|
|
39
|
+
"passwordsDoNotMatch": "Passwörter stimmen nicht überein",
|
|
40
|
+
"passwordWeakError": "Passwort erfüllt nicht die Stärkeanforderungen",
|
|
41
|
+
"signInTitle": "Anmelden — {{appName}}",
|
|
42
|
+
"ruleMinLength": "Mindestens {{count}} Zeichen",
|
|
43
|
+
"ruleUppercase": "Großbuchstabe",
|
|
44
|
+
"ruleLowercase": "Kleinbuchstabe",
|
|
45
|
+
"ruleDigit": "Zahl",
|
|
46
|
+
"ruleSpecialChar": "Sonderzeichen",
|
|
47
|
+
"continueWith": "Weiter mit {{provider}}",
|
|
48
|
+
"or": "oder",
|
|
49
|
+
"signedInAs": "Angemeldet als {{name}}",
|
|
50
|
+
"signedInMessage": "Sie sind bereits authentifiziert."
|
|
51
|
+
}
|
package/src/i18n/en.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"signIn": "Sign in",
|
|
3
|
+
"email": "Email",
|
|
4
|
+
"password": "Password",
|
|
5
|
+
"emailPlaceholder": "you@example.com",
|
|
6
|
+
"passwordPlaceholder": "Enter your password",
|
|
7
|
+
"signingIn": "Signing in...",
|
|
8
|
+
"forgotPassword": "Forgot password?",
|
|
9
|
+
"ssoChecking": "Checking sign-in options...",
|
|
10
|
+
"ssoNotice": "Your organization uses single sign-on",
|
|
11
|
+
"continueWithSso": "Continue with SSO",
|
|
12
|
+
"errorInvalidCredentials": "Invalid email or password",
|
|
13
|
+
"errorLockedOut": "Account locked. Try again in {{seconds}} seconds",
|
|
14
|
+
"errorEmailNotConfirmed": "Please check your email to verify your account",
|
|
15
|
+
"errorSsoRequired": "Single sign-on is required for this account",
|
|
16
|
+
"errorEmailRequired": "Email is required",
|
|
17
|
+
"errorPasswordRequired": "Password is required",
|
|
18
|
+
"errorUnexpected": "An unexpected error occurred. Please try again.",
|
|
19
|
+
"resetYourPassword": "Reset your password",
|
|
20
|
+
"resetSubtitle": "Enter your email address and we'll send you a link to reset your password.",
|
|
21
|
+
"sending": "Sending...",
|
|
22
|
+
"sendResetLink": "Send reset link",
|
|
23
|
+
"backToSignIn": "Back to sign in",
|
|
24
|
+
"checkYourEmail": "Check your email",
|
|
25
|
+
"resetEmailSent": "If an account exists with that email, you'll receive a reset link shortly.",
|
|
26
|
+
"setNewPassword": "Set new password",
|
|
27
|
+
"newPassword": "New password",
|
|
28
|
+
"newPasswordPlaceholder": "Enter new password",
|
|
29
|
+
"confirmPassword": "Confirm password",
|
|
30
|
+
"confirmPasswordPlaceholder": "Confirm new password",
|
|
31
|
+
"resetting": "Resetting...",
|
|
32
|
+
"resetPassword": "Reset password",
|
|
33
|
+
"passwordResetSuccess": "Password reset successfully",
|
|
34
|
+
"passwordResetSuccessMessage": "Your password has been reset. You can now sign in with your new password.",
|
|
35
|
+
"invalidLink": "Invalid link",
|
|
36
|
+
"invalidOrExpiredLink": "This reset link is invalid or has expired.",
|
|
37
|
+
"requestNewResetLink": "Request a new reset link",
|
|
38
|
+
"passwordNotMeetRequirements": "Password does not meet the requirements",
|
|
39
|
+
"passwordsDoNotMatch": "Passwords do not match",
|
|
40
|
+
"passwordWeakError": "Password does not meet strength requirements",
|
|
41
|
+
"signInTitle": "Sign In — {{appName}}",
|
|
42
|
+
"ruleMinLength": "At least {{count}} characters",
|
|
43
|
+
"ruleUppercase": "Uppercase letter",
|
|
44
|
+
"ruleLowercase": "Lowercase letter",
|
|
45
|
+
"ruleDigit": "Number",
|
|
46
|
+
"ruleSpecialChar": "Special character",
|
|
47
|
+
"continueWith": "Continue with {{provider}}",
|
|
48
|
+
"or": "or",
|
|
49
|
+
"signedInAs": "Signed in as {{name}}",
|
|
50
|
+
"signedInMessage": "You are already authenticated."
|
|
51
|
+
}
|
package/src/i18n/es.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"signIn": "Iniciar sesión",
|
|
3
|
+
"email": "Correo electrónico",
|
|
4
|
+
"password": "Contraseña",
|
|
5
|
+
"emailPlaceholder": "you@example.com",
|
|
6
|
+
"passwordPlaceholder": "Ingrese su contraseña",
|
|
7
|
+
"signingIn": "Iniciando sesión...",
|
|
8
|
+
"forgotPassword": "¿Olvidaste tu contraseña?",
|
|
9
|
+
"ssoChecking": "Verificando opciones de inicio de sesión...",
|
|
10
|
+
"ssoNotice": "Su organización utiliza inicio de sesión único",
|
|
11
|
+
"continueWithSso": "Continuar con SSO",
|
|
12
|
+
"errorInvalidCredentials": "Correo electrónico o contraseña no válidos",
|
|
13
|
+
"errorLockedOut": "Cuenta bloqueada. Inténtelo de nuevo en {{seconds}} segundos",
|
|
14
|
+
"errorEmailNotConfirmed": "Revise su correo electrónico para verificar su cuenta",
|
|
15
|
+
"errorSsoRequired": "Se requiere inicio de sesión único para esta cuenta",
|
|
16
|
+
"errorEmailRequired": "El correo electrónico es obligatorio",
|
|
17
|
+
"errorPasswordRequired": "La contraseña es obligatoria",
|
|
18
|
+
"errorUnexpected": "Se produjo un error inesperado. Por favor, inténtelo de nuevo.",
|
|
19
|
+
"resetYourPassword": "Restablecer su contraseña",
|
|
20
|
+
"resetSubtitle": "Ingrese su dirección de correo electrónico y le enviaremos un enlace para restablecer su contraseña.",
|
|
21
|
+
"sending": "Enviando...",
|
|
22
|
+
"sendResetLink": "Enviar enlace de restablecimiento",
|
|
23
|
+
"backToSignIn": "Volver al inicio de sesión",
|
|
24
|
+
"checkYourEmail": "Revise su correo electrónico",
|
|
25
|
+
"resetEmailSent": "Si existe una cuenta con ese correo electrónico, recibirá un enlace de restablecimiento en breve.",
|
|
26
|
+
"setNewPassword": "Establecer nueva contraseña",
|
|
27
|
+
"newPassword": "Nueva contraseña",
|
|
28
|
+
"newPasswordPlaceholder": "Ingrese la nueva contraseña",
|
|
29
|
+
"confirmPassword": "Confirmar contraseña",
|
|
30
|
+
"confirmPasswordPlaceholder": "Confirme la nueva contraseña",
|
|
31
|
+
"resetting": "Restableciendo...",
|
|
32
|
+
"resetPassword": "Restablecer contraseña",
|
|
33
|
+
"passwordResetSuccess": "Contraseña restablecida exitosamente",
|
|
34
|
+
"passwordResetSuccessMessage": "Su contraseña ha sido restablecida. Ahora puede iniciar sesión con su nueva contraseña.",
|
|
35
|
+
"invalidLink": "Enlace no válido",
|
|
36
|
+
"invalidOrExpiredLink": "Este enlace de restablecimiento no es válido o ha expirado.",
|
|
37
|
+
"requestNewResetLink": "Solicitar un nuevo enlace de restablecimiento",
|
|
38
|
+
"passwordNotMeetRequirements": "La contraseña no cumple con los requisitos",
|
|
39
|
+
"passwordsDoNotMatch": "Las contraseñas no coinciden",
|
|
40
|
+
"passwordWeakError": "La contraseña no cumple con los requisitos de seguridad",
|
|
41
|
+
"signInTitle": "Iniciar sesión — {{appName}}",
|
|
42
|
+
"ruleMinLength": "Al menos {{count}} caracteres",
|
|
43
|
+
"ruleUppercase": "Letra mayúscula",
|
|
44
|
+
"ruleLowercase": "Letra minúscula",
|
|
45
|
+
"ruleDigit": "Número",
|
|
46
|
+
"ruleSpecialChar": "Carácter especial",
|
|
47
|
+
"continueWith": "Continuar con {{provider}}",
|
|
48
|
+
"or": "o",
|
|
49
|
+
"signedInAs": "Conectado como {{name}}",
|
|
50
|
+
"signedInMessage": "Ya est\u00e1s autenticado."
|
|
51
|
+
}
|