@lalternative/auth 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.d.ts +1 -1
- package/dist/index.d.ts +19 -13
- package/dist/index.js +416 -244
- package/dist/index.js.map +1 -1
- package/dist/{invitation-aZz_6M7B.d.ts → invitation-BUqM_BF8.d.ts} +1 -1
- package/dist/server.d.ts +3 -3
- package/dist/{types-BEldQPou.d.ts → types-SieiPwdd.d.ts} +87 -11
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -138,8 +138,38 @@ function AuthSubmit({
|
|
|
138
138
|
// src/components/login-form.tsx
|
|
139
139
|
import { useState as useState2 } from "react";
|
|
140
140
|
|
|
141
|
+
// src/components/auth-alert.tsx
|
|
142
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
143
|
+
function AuthAlert({ children, tone = "error" }) {
|
|
144
|
+
return /* @__PURE__ */ jsx3(
|
|
145
|
+
"div",
|
|
146
|
+
{
|
|
147
|
+
role: tone === "error" ? "alert" : "status",
|
|
148
|
+
"aria-live": tone === "error" ? "assertive" : "polite",
|
|
149
|
+
className: children ? [
|
|
150
|
+
"rounded-xl border px-3.5 py-3 text-sm leading-snug",
|
|
151
|
+
tone === "error" ? "border-destructive/25 bg-destructive/10 text-destructive" : "border-emerald-500/25 bg-emerald-500/10 text-emerald-700 dark:text-emerald-400"
|
|
152
|
+
].join(" ") : void 0,
|
|
153
|
+
children
|
|
154
|
+
}
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// src/components/auth-heading.tsx
|
|
159
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
160
|
+
function AuthHeading({
|
|
161
|
+
title,
|
|
162
|
+
subtitle,
|
|
163
|
+
titleClassName = "text-2xl font-semibold tracking-tight"
|
|
164
|
+
}) {
|
|
165
|
+
return /* @__PURE__ */ jsxs3("header", { className: "space-y-1.5 text-center", children: [
|
|
166
|
+
/* @__PURE__ */ jsx4("h1", { className: `leading-tight text-foreground ${titleClassName}`, children: title }),
|
|
167
|
+
subtitle && /* @__PURE__ */ jsx4("p", { className: "text-balance text-sm leading-relaxed text-muted-foreground", children: subtitle })
|
|
168
|
+
] });
|
|
169
|
+
}
|
|
170
|
+
|
|
141
171
|
// src/components/social-buttons.tsx
|
|
142
|
-
import { jsx as
|
|
172
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
143
173
|
var LABELS = {
|
|
144
174
|
google: "Continuer avec Google",
|
|
145
175
|
github: "Continuer avec GitHub"
|
|
@@ -153,60 +183,67 @@ function SocialButtons({
|
|
|
153
183
|
}) {
|
|
154
184
|
if (providers.length === 0) return null;
|
|
155
185
|
const copy = { ...LABELS, ...labels };
|
|
156
|
-
return /* @__PURE__ */
|
|
157
|
-
/* @__PURE__ */
|
|
158
|
-
/* @__PURE__ */
|
|
159
|
-
/* @__PURE__ */
|
|
160
|
-
/* @__PURE__ */
|
|
186
|
+
return /* @__PURE__ */ jsxs4("div", { className: "space-y-4", children: [
|
|
187
|
+
/* @__PURE__ */ jsxs4("div", { "aria-hidden": "true", className: "flex items-center gap-3", children: [
|
|
188
|
+
/* @__PURE__ */ jsx5("span", { className: "h-px flex-1 bg-border" }),
|
|
189
|
+
/* @__PURE__ */ jsx5("span", { className: "text-[11px] uppercase tracking-[0.14em] text-muted-foreground", children: separator }),
|
|
190
|
+
/* @__PURE__ */ jsx5("span", { className: "h-px flex-1 bg-border" })
|
|
161
191
|
] }),
|
|
162
|
-
/* @__PURE__ */
|
|
163
|
-
"
|
|
192
|
+
/* @__PURE__ */ jsx5(
|
|
193
|
+
"div",
|
|
164
194
|
{
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
195
|
+
className: providers.length > 1 ? "grid gap-2.5 sm:grid-cols-2" : "grid gap-2.5",
|
|
196
|
+
children: providers.map((provider) => /* @__PURE__ */ jsxs4(
|
|
197
|
+
"button",
|
|
198
|
+
{
|
|
199
|
+
type: "button",
|
|
200
|
+
onClick: () => onSelect(provider),
|
|
201
|
+
disabled,
|
|
202
|
+
"aria-label": copy[provider] ?? provider,
|
|
203
|
+
className: [
|
|
204
|
+
"flex h-[52px] w-full items-center justify-center gap-2.5 rounded-xl sm:h-11",
|
|
205
|
+
"border border-input bg-background text-base font-medium text-foreground sm:text-sm",
|
|
206
|
+
"transition-[background-color,border-color,transform] duration-150 ease-out",
|
|
207
|
+
"hover:border-foreground/20 hover:bg-accent active:translate-y-px",
|
|
208
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
209
|
+
"disabled:pointer-events-none disabled:opacity-55"
|
|
210
|
+
].join(" "),
|
|
211
|
+
children: [
|
|
212
|
+
/* @__PURE__ */ jsx5(ProviderMark, { provider }),
|
|
213
|
+
/* @__PURE__ */ jsx5("span", { className: providers.length > 1 ? "sm:hidden" : "", children: copy[provider] ?? provider })
|
|
214
|
+
]
|
|
215
|
+
},
|
|
216
|
+
provider
|
|
217
|
+
))
|
|
218
|
+
}
|
|
219
|
+
)
|
|
183
220
|
] });
|
|
184
221
|
}
|
|
185
222
|
function ProviderMark({ provider }) {
|
|
186
223
|
if (provider === "google") {
|
|
187
|
-
return /* @__PURE__ */
|
|
188
|
-
/* @__PURE__ */
|
|
224
|
+
return /* @__PURE__ */ jsxs4("svg", { width: "17", height: "17", viewBox: "0 0 18 18", "aria-hidden": "true", children: [
|
|
225
|
+
/* @__PURE__ */ jsx5(
|
|
189
226
|
"path",
|
|
190
227
|
{
|
|
191
228
|
fill: "#4285F4",
|
|
192
229
|
d: "M17.64 9.2c0-.64-.06-1.25-.16-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.72v2.26h2.92c1.7-1.57 2.68-3.88 2.68-6.62Z"
|
|
193
230
|
}
|
|
194
231
|
),
|
|
195
|
-
/* @__PURE__ */
|
|
232
|
+
/* @__PURE__ */ jsx5(
|
|
196
233
|
"path",
|
|
197
234
|
{
|
|
198
235
|
fill: "#34A853",
|
|
199
236
|
d: "M9 18c2.43 0 4.47-.8 5.96-2.18l-2.92-2.26c-.8.54-1.84.86-3.04.86-2.34 0-4.32-1.58-5.02-3.7H.96v2.33A9 9 0 0 0 9 18Z"
|
|
200
237
|
}
|
|
201
238
|
),
|
|
202
|
-
/* @__PURE__ */
|
|
239
|
+
/* @__PURE__ */ jsx5(
|
|
203
240
|
"path",
|
|
204
241
|
{
|
|
205
242
|
fill: "#FBBC05",
|
|
206
243
|
d: "M3.98 10.72a5.4 5.4 0 0 1 0-3.44V4.95H.96a9 9 0 0 0 0 8.1l3.02-2.33Z"
|
|
207
244
|
}
|
|
208
245
|
),
|
|
209
|
-
/* @__PURE__ */
|
|
246
|
+
/* @__PURE__ */ jsx5(
|
|
210
247
|
"path",
|
|
211
248
|
{
|
|
212
249
|
fill: "#EA4335",
|
|
@@ -215,11 +252,11 @@ function ProviderMark({ provider }) {
|
|
|
215
252
|
)
|
|
216
253
|
] });
|
|
217
254
|
}
|
|
218
|
-
return /* @__PURE__ */
|
|
255
|
+
return /* @__PURE__ */ jsx5("svg", { width: "17", height: "17", viewBox: "0 0 16 16", fill: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsx5("path", { d: "M8 0a8 8 0 0 0-2.53 15.59c.4.07.55-.17.55-.38l-.01-1.49c-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82a7.4 7.4 0 0 1 4 0c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48l-.01 2.2c0 .21.15.46.55.38A8 8 0 0 0 8 0Z" }) });
|
|
219
256
|
}
|
|
220
257
|
|
|
221
258
|
// src/components/login-form.tsx
|
|
222
|
-
import { jsx as
|
|
259
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
223
260
|
var DEFAULTS = {
|
|
224
261
|
title: "Connexion",
|
|
225
262
|
subtitle: "Content de te revoir. Entre tes identifiants pour continuer.",
|
|
@@ -248,13 +285,17 @@ function LoginForm({
|
|
|
248
285
|
socialProviders = [],
|
|
249
286
|
coreTokenUrl = "/api/auth/core-token",
|
|
250
287
|
labels,
|
|
288
|
+
titleClassName,
|
|
289
|
+
error: externalError,
|
|
251
290
|
authClient
|
|
252
291
|
}) {
|
|
253
292
|
const t = { ...DEFAULTS, ...labels };
|
|
254
293
|
const [email, setEmail] = useState2("");
|
|
255
294
|
const [password, setPassword] = useState2("");
|
|
256
|
-
const [
|
|
295
|
+
const [ownError, setOwnError] = useState2();
|
|
257
296
|
const [isPending, setIsPending] = useState2(false);
|
|
297
|
+
const error = ownError ?? externalError;
|
|
298
|
+
const setError = setOwnError;
|
|
258
299
|
const handleSubmit = async (e) => {
|
|
259
300
|
e.preventDefault();
|
|
260
301
|
if (!email.trim()) {
|
|
@@ -300,21 +341,18 @@ function LoginForm({
|
|
|
300
341
|
);
|
|
301
342
|
}
|
|
302
343
|
};
|
|
303
|
-
return /* @__PURE__ */
|
|
304
|
-
/* @__PURE__ */
|
|
305
|
-
|
|
306
|
-
/* @__PURE__ */ jsx4("p", { className: "text-balance text-sm leading-relaxed text-muted-foreground", children: t.subtitle })
|
|
307
|
-
] }),
|
|
308
|
-
error && /* @__PURE__ */ jsx4(
|
|
309
|
-
"div",
|
|
344
|
+
return /* @__PURE__ */ jsxs5("div", { className: "space-y-7", children: [
|
|
345
|
+
/* @__PURE__ */ jsx6(
|
|
346
|
+
AuthHeading,
|
|
310
347
|
{
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
348
|
+
title: t.title,
|
|
349
|
+
subtitle: t.subtitle,
|
|
350
|
+
titleClassName
|
|
314
351
|
}
|
|
315
352
|
),
|
|
316
|
-
/* @__PURE__ */
|
|
317
|
-
|
|
353
|
+
/* @__PURE__ */ jsx6(AuthAlert, { children: error }),
|
|
354
|
+
/* @__PURE__ */ jsxs5("form", { onSubmit: handleSubmit, className: "space-y-5", noValidate: true, children: [
|
|
355
|
+
/* @__PURE__ */ jsx6(
|
|
318
356
|
AuthField,
|
|
319
357
|
{
|
|
320
358
|
label: t.emailPlaceholder,
|
|
@@ -330,7 +368,7 @@ function LoginForm({
|
|
|
330
368
|
invalid: !!error
|
|
331
369
|
}
|
|
332
370
|
),
|
|
333
|
-
/* @__PURE__ */
|
|
371
|
+
/* @__PURE__ */ jsx6(
|
|
334
372
|
AuthField,
|
|
335
373
|
{
|
|
336
374
|
label: t.passwordPlaceholder,
|
|
@@ -341,7 +379,7 @@ function LoginForm({
|
|
|
341
379
|
disabled: isPending,
|
|
342
380
|
autoComplete: "current-password",
|
|
343
381
|
invalid: !!error,
|
|
344
|
-
hint: /* @__PURE__ */
|
|
382
|
+
hint: /* @__PURE__ */ jsx6(
|
|
345
383
|
"a",
|
|
346
384
|
{
|
|
347
385
|
href: forgotPasswordUrl,
|
|
@@ -351,7 +389,7 @@ function LoginForm({
|
|
|
351
389
|
)
|
|
352
390
|
}
|
|
353
391
|
),
|
|
354
|
-
/* @__PURE__ */
|
|
392
|
+
/* @__PURE__ */ jsx6(
|
|
355
393
|
AuthSubmit,
|
|
356
394
|
{
|
|
357
395
|
pending: isPending,
|
|
@@ -361,7 +399,7 @@ function LoginForm({
|
|
|
361
399
|
}
|
|
362
400
|
)
|
|
363
401
|
] }),
|
|
364
|
-
/* @__PURE__ */
|
|
402
|
+
/* @__PURE__ */ jsx6(
|
|
365
403
|
SocialButtons,
|
|
366
404
|
{
|
|
367
405
|
providers: socialProviders,
|
|
@@ -369,10 +407,10 @@ function LoginForm({
|
|
|
369
407
|
disabled: isPending
|
|
370
408
|
}
|
|
371
409
|
),
|
|
372
|
-
/* @__PURE__ */
|
|
410
|
+
/* @__PURE__ */ jsxs5("p", { className: "text-center text-sm text-muted-foreground", children: [
|
|
373
411
|
t.noAccount,
|
|
374
412
|
" ",
|
|
375
|
-
/* @__PURE__ */
|
|
413
|
+
/* @__PURE__ */ jsx6(
|
|
376
414
|
"a",
|
|
377
415
|
{
|
|
378
416
|
href: registerUrl,
|
|
@@ -386,7 +424,7 @@ function LoginForm({
|
|
|
386
424
|
|
|
387
425
|
// src/components/register-form.tsx
|
|
388
426
|
import { useState as useState3 } from "react";
|
|
389
|
-
import { jsx as
|
|
427
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
390
428
|
var MIN_PASSWORD_LENGTH = 8;
|
|
391
429
|
var DEFAULTS2 = {
|
|
392
430
|
title: "Cr\xE9er un compte",
|
|
@@ -411,14 +449,18 @@ function RegisterForm({
|
|
|
411
449
|
socialCallbackUrl = "/",
|
|
412
450
|
socialProviders = [],
|
|
413
451
|
labels,
|
|
452
|
+
titleClassName,
|
|
453
|
+
error: externalError,
|
|
414
454
|
authClient
|
|
415
455
|
}) {
|
|
416
456
|
const t = { ...DEFAULTS2, ...labels };
|
|
417
457
|
const [name, setName] = useState3("");
|
|
418
458
|
const [email, setEmail] = useState3("");
|
|
419
459
|
const [password, setPassword] = useState3("");
|
|
420
|
-
const [
|
|
460
|
+
const [ownError, setOwnError] = useState3();
|
|
421
461
|
const [isPending, setIsPending] = useState3(false);
|
|
462
|
+
const error = ownError ?? externalError;
|
|
463
|
+
const setError = setOwnError;
|
|
422
464
|
const tooShort = password.length > 0 && password.length < MIN_PASSWORD_LENGTH;
|
|
423
465
|
const handleSubmit = async (e) => {
|
|
424
466
|
e.preventDefault();
|
|
@@ -464,21 +506,18 @@ function RegisterForm({
|
|
|
464
506
|
setError(err instanceof Error ? err.message : t.signUpFailed);
|
|
465
507
|
}
|
|
466
508
|
};
|
|
467
|
-
return /* @__PURE__ */
|
|
468
|
-
/* @__PURE__ */
|
|
469
|
-
|
|
470
|
-
/* @__PURE__ */ jsx5("p", { className: "text-balance text-sm leading-relaxed text-muted-foreground", children: t.subtitle })
|
|
471
|
-
] }),
|
|
472
|
-
error && /* @__PURE__ */ jsx5(
|
|
473
|
-
"div",
|
|
509
|
+
return /* @__PURE__ */ jsxs6("div", { className: "space-y-7", children: [
|
|
510
|
+
/* @__PURE__ */ jsx7(
|
|
511
|
+
AuthHeading,
|
|
474
512
|
{
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
513
|
+
title: t.title,
|
|
514
|
+
subtitle: t.subtitle,
|
|
515
|
+
titleClassName
|
|
478
516
|
}
|
|
479
517
|
),
|
|
480
|
-
/* @__PURE__ */
|
|
481
|
-
|
|
518
|
+
/* @__PURE__ */ jsx7(AuthAlert, { children: error }),
|
|
519
|
+
/* @__PURE__ */ jsxs6("form", { onSubmit: handleSubmit, className: "space-y-5", noValidate: true, children: [
|
|
520
|
+
/* @__PURE__ */ jsx7(
|
|
482
521
|
AuthField,
|
|
483
522
|
{
|
|
484
523
|
label: t.namePlaceholder,
|
|
@@ -490,7 +529,7 @@ function RegisterForm({
|
|
|
490
529
|
autoComplete: "name"
|
|
491
530
|
}
|
|
492
531
|
),
|
|
493
|
-
/* @__PURE__ */
|
|
532
|
+
/* @__PURE__ */ jsx7(
|
|
494
533
|
AuthField,
|
|
495
534
|
{
|
|
496
535
|
label: t.emailPlaceholder,
|
|
@@ -505,7 +544,7 @@ function RegisterForm({
|
|
|
505
544
|
spellCheck: false
|
|
506
545
|
}
|
|
507
546
|
),
|
|
508
|
-
/* @__PURE__ */
|
|
547
|
+
/* @__PURE__ */ jsx7(
|
|
509
548
|
AuthField,
|
|
510
549
|
{
|
|
511
550
|
label: t.passwordPlaceholder,
|
|
@@ -519,10 +558,10 @@ function RegisterForm({
|
|
|
519
558
|
invalid: tooShort
|
|
520
559
|
}
|
|
521
560
|
),
|
|
522
|
-
/* @__PURE__ */
|
|
523
|
-
legal && /* @__PURE__ */
|
|
561
|
+
/* @__PURE__ */ jsx7(AuthSubmit, { pending: isPending, pendingLabel: t.submitPending, children: t.submit }),
|
|
562
|
+
legal && /* @__PURE__ */ jsx7("p", { className: "text-center text-xs leading-relaxed text-muted-foreground", children: legal })
|
|
524
563
|
] }),
|
|
525
|
-
/* @__PURE__ */
|
|
564
|
+
/* @__PURE__ */ jsx7(
|
|
526
565
|
SocialButtons,
|
|
527
566
|
{
|
|
528
567
|
providers: socialProviders,
|
|
@@ -530,10 +569,10 @@ function RegisterForm({
|
|
|
530
569
|
disabled: isPending
|
|
531
570
|
}
|
|
532
571
|
),
|
|
533
|
-
/* @__PURE__ */
|
|
572
|
+
/* @__PURE__ */ jsxs6("p", { className: "text-center text-sm text-muted-foreground", children: [
|
|
534
573
|
t.haveAccount,
|
|
535
574
|
" ",
|
|
536
|
-
/* @__PURE__ */
|
|
575
|
+
/* @__PURE__ */ jsx7(
|
|
537
576
|
"a",
|
|
538
577
|
{
|
|
539
578
|
href: loginUrl,
|
|
@@ -547,12 +586,83 @@ function RegisterForm({
|
|
|
547
586
|
|
|
548
587
|
// src/components/verify-email-form.tsx
|
|
549
588
|
import { useState as useState4 } from "react";
|
|
550
|
-
|
|
589
|
+
|
|
590
|
+
// src/components/auth-otp-field.tsx
|
|
591
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
592
|
+
var OTP_LENGTH = 6;
|
|
593
|
+
function AuthOtpField({
|
|
594
|
+
label,
|
|
595
|
+
value,
|
|
596
|
+
onChange,
|
|
597
|
+
disabled = false,
|
|
598
|
+
invalid = false,
|
|
599
|
+
id
|
|
600
|
+
}) {
|
|
601
|
+
return /* @__PURE__ */ jsxs7("div", { className: "space-y-2", children: [
|
|
602
|
+
/* @__PURE__ */ jsx8(
|
|
603
|
+
"label",
|
|
604
|
+
{
|
|
605
|
+
htmlFor: id,
|
|
606
|
+
className: "block text-sm font-medium leading-none text-foreground",
|
|
607
|
+
children: label
|
|
608
|
+
}
|
|
609
|
+
),
|
|
610
|
+
/* @__PURE__ */ jsx8(
|
|
611
|
+
"input",
|
|
612
|
+
{
|
|
613
|
+
id,
|
|
614
|
+
type: "text",
|
|
615
|
+
inputMode: "numeric",
|
|
616
|
+
pattern: "[0-9]*",
|
|
617
|
+
maxLength: OTP_LENGTH,
|
|
618
|
+
value,
|
|
619
|
+
onChange: (e) => onChange(e.target.value.replace(/\D/g, "")),
|
|
620
|
+
required: true,
|
|
621
|
+
disabled,
|
|
622
|
+
autoComplete: "one-time-code",
|
|
623
|
+
"aria-invalid": invalid || void 0,
|
|
624
|
+
className: [
|
|
625
|
+
"h-[52px] w-full rounded-xl border bg-background px-4 sm:h-11",
|
|
626
|
+
"text-center font-mono text-lg tracking-[0.4em]",
|
|
627
|
+
"text-foreground",
|
|
628
|
+
"transition-[border-color,box-shadow] duration-150 ease-out",
|
|
629
|
+
"focus-visible:outline-none focus-visible:ring-[3px]",
|
|
630
|
+
invalid ? "border-destructive focus-visible:border-destructive focus-visible:ring-destructive/20" : "border-input focus-visible:border-ring focus-visible:ring-ring/15",
|
|
631
|
+
"disabled:cursor-not-allowed disabled:opacity-60"
|
|
632
|
+
].join(" ")
|
|
633
|
+
}
|
|
634
|
+
)
|
|
635
|
+
] });
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// src/components/verify-email-form.tsx
|
|
639
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
640
|
+
var DEFAULTS3 = {
|
|
641
|
+
title: "V\xE9rifie ton adresse",
|
|
642
|
+
subtitle: "Entre le code \xE0 6 chiffres envoy\xE9 \xE0",
|
|
643
|
+
subtitleNoEmail: "Entre le code \xE0 6 chiffres re\xE7u par e-mail.",
|
|
644
|
+
codePlaceholder: "Code de v\xE9rification",
|
|
645
|
+
submit: "V\xE9rifier",
|
|
646
|
+
submitPending: "V\xE9rification\u2026",
|
|
647
|
+
resend: "Renvoyer le code",
|
|
648
|
+
resendPending: "Envoi\u2026",
|
|
649
|
+
resent: "Un nouveau code vient de t'\xEAtre envoy\xE9.",
|
|
650
|
+
alreadyVerified: "Adresse d\xE9j\xE0 v\xE9rifi\xE9e ?",
|
|
651
|
+
login: "Se connecter",
|
|
652
|
+
codeRequired: "Entre le code \xE0 6 chiffres",
|
|
653
|
+
invalidCode: "Code invalide. R\xE9essaie.",
|
|
654
|
+
resendFailed: "L'envoi du code a \xE9chou\xE9",
|
|
655
|
+
missingEmail: "Adresse e-mail introuvable. Recommence l'inscription."
|
|
656
|
+
};
|
|
551
657
|
function VerifyEmailForm({
|
|
552
658
|
email,
|
|
553
659
|
onSuccess,
|
|
660
|
+
loginUrl = "/login",
|
|
661
|
+
labels,
|
|
662
|
+
titleClassName,
|
|
554
663
|
authClient
|
|
555
664
|
}) {
|
|
665
|
+
const t = { ...DEFAULTS3, ...labels };
|
|
556
666
|
const [otp, setOtp] = useState4("");
|
|
557
667
|
const [isVerifying, setIsVerifying] = useState4(false);
|
|
558
668
|
const [isResending, setIsResending] = useState4(false);
|
|
@@ -560,29 +670,29 @@ function VerifyEmailForm({
|
|
|
560
670
|
const [error, setError] = useState4();
|
|
561
671
|
const handleVerify = async (e) => {
|
|
562
672
|
e.preventDefault();
|
|
563
|
-
if (
|
|
564
|
-
setError(
|
|
673
|
+
if (otp.length < OTP_LENGTH) {
|
|
674
|
+
setError(t.codeRequired);
|
|
565
675
|
return;
|
|
566
676
|
}
|
|
567
677
|
setError(void 0);
|
|
678
|
+
setResendMessage(void 0);
|
|
568
679
|
setIsVerifying(true);
|
|
569
680
|
try {
|
|
570
681
|
const res = await authClient.emailOtp.verifyEmail({ email, otp });
|
|
571
|
-
console.log("[verify-email] response:", JSON.stringify(res?.data), "error:", JSON.stringify(res?.error));
|
|
572
682
|
if (res?.error) {
|
|
573
|
-
setError(res.error.message ??
|
|
683
|
+
setError(res.error.message ?? t.invalidCode);
|
|
574
684
|
return;
|
|
575
685
|
}
|
|
576
686
|
onSuccess?.();
|
|
577
687
|
} catch (err) {
|
|
578
|
-
setError(err instanceof Error ? err.message :
|
|
688
|
+
setError(err instanceof Error ? err.message : t.invalidCode);
|
|
579
689
|
} finally {
|
|
580
690
|
setIsVerifying(false);
|
|
581
691
|
}
|
|
582
692
|
};
|
|
583
693
|
const handleResend = async () => {
|
|
584
694
|
if (!email) {
|
|
585
|
-
setError(
|
|
695
|
+
setError(t.missingEmail);
|
|
586
696
|
return;
|
|
587
697
|
}
|
|
588
698
|
setError(void 0);
|
|
@@ -593,150 +703,167 @@ function VerifyEmailForm({
|
|
|
593
703
|
email,
|
|
594
704
|
type: "email-verification"
|
|
595
705
|
});
|
|
596
|
-
setResendMessage(
|
|
706
|
+
setResendMessage(t.resent);
|
|
597
707
|
} catch (err) {
|
|
598
|
-
setError(err instanceof Error ? err.message :
|
|
708
|
+
setError(err instanceof Error ? err.message : t.resendFailed);
|
|
599
709
|
} finally {
|
|
600
710
|
setIsResending(false);
|
|
601
711
|
}
|
|
602
712
|
};
|
|
603
|
-
return /* @__PURE__ */
|
|
604
|
-
/* @__PURE__ */
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
/* @__PURE__ */
|
|
615
|
-
/* @__PURE__ */
|
|
616
|
-
|
|
713
|
+
return /* @__PURE__ */ jsxs8("div", { className: "space-y-7", children: [
|
|
714
|
+
/* @__PURE__ */ jsx9(
|
|
715
|
+
AuthHeading,
|
|
716
|
+
{
|
|
717
|
+
title: t.title,
|
|
718
|
+
subtitle: email ? `${t.subtitle} ${email}.` : t.subtitleNoEmail,
|
|
719
|
+
titleClassName
|
|
720
|
+
}
|
|
721
|
+
),
|
|
722
|
+
/* @__PURE__ */ jsx9(AuthAlert, { children: error }),
|
|
723
|
+
/* @__PURE__ */ jsx9(AuthAlert, { tone: "success", children: resendMessage }),
|
|
724
|
+
/* @__PURE__ */ jsxs8("form", { onSubmit: handleVerify, className: "space-y-5", noValidate: true, children: [
|
|
725
|
+
/* @__PURE__ */ jsx9(
|
|
726
|
+
AuthOtpField,
|
|
617
727
|
{
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
pattern: "[0-9]*",
|
|
621
|
-
maxLength: 6,
|
|
728
|
+
id: "verify-email-otp",
|
|
729
|
+
label: t.codePlaceholder,
|
|
622
730
|
value: otp,
|
|
623
|
-
onChange:
|
|
624
|
-
|
|
625
|
-
required: true,
|
|
626
|
-
disabled: isVerifying,
|
|
627
|
-
autoComplete: "one-time-code",
|
|
628
|
-
className: "flex h-12 w-full rounded-md border border-input bg-background px-3 py-2 text-center text-lg tracking-[0.4em] font-mono ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50 disabled:cursor-not-allowed"
|
|
731
|
+
onChange: setOtp,
|
|
732
|
+
disabled: isVerifying
|
|
629
733
|
}
|
|
630
734
|
),
|
|
631
|
-
/* @__PURE__ */
|
|
632
|
-
|
|
735
|
+
/* @__PURE__ */ jsx9(
|
|
736
|
+
AuthSubmit,
|
|
633
737
|
{
|
|
634
|
-
|
|
635
|
-
disabled:
|
|
636
|
-
|
|
637
|
-
children:
|
|
738
|
+
pending: isVerifying,
|
|
739
|
+
disabled: otp.length < OTP_LENGTH,
|
|
740
|
+
pendingLabel: t.submitPending,
|
|
741
|
+
children: t.submit
|
|
638
742
|
}
|
|
639
|
-
)
|
|
640
|
-
|
|
743
|
+
)
|
|
744
|
+
] }),
|
|
745
|
+
/* @__PURE__ */ jsxs8("div", { className: "space-y-4 text-center text-sm text-muted-foreground", children: [
|
|
746
|
+
/* @__PURE__ */ jsx9(
|
|
641
747
|
"button",
|
|
642
748
|
{
|
|
643
749
|
type: "button",
|
|
644
750
|
onClick: handleResend,
|
|
645
751
|
disabled: isResending,
|
|
646
|
-
className: "
|
|
647
|
-
children: isResending ?
|
|
752
|
+
className: "rounded font-medium text-foreground underline underline-offset-4 decoration-foreground/25 transition-colors hover:decoration-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-55",
|
|
753
|
+
children: isResending ? t.resendPending : t.resend
|
|
648
754
|
}
|
|
649
|
-
)
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
)
|
|
755
|
+
),
|
|
756
|
+
/* @__PURE__ */ jsxs8("p", { children: [
|
|
757
|
+
t.alreadyVerified,
|
|
758
|
+
" ",
|
|
759
|
+
/* @__PURE__ */ jsx9(
|
|
760
|
+
"a",
|
|
761
|
+
{
|
|
762
|
+
href: loginUrl,
|
|
763
|
+
className: "rounded font-medium text-foreground underline underline-offset-4 decoration-foreground/25 transition-colors hover:decoration-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
764
|
+
children: t.login
|
|
765
|
+
}
|
|
766
|
+
)
|
|
767
|
+
] })
|
|
662
768
|
] })
|
|
663
769
|
] });
|
|
664
770
|
}
|
|
665
771
|
|
|
666
772
|
// src/components/forgot-password-form.tsx
|
|
667
773
|
import { useState as useState5 } from "react";
|
|
668
|
-
import { jsx as
|
|
774
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
775
|
+
var DEFAULTS4 = {
|
|
776
|
+
title: "Mot de passe oubli\xE9 ?",
|
|
777
|
+
subtitle: "Entre ton adresse e-mail et nous t'enverrons un code pour le r\xE9initialiser.",
|
|
778
|
+
emailPlaceholder: "Adresse e-mail",
|
|
779
|
+
submit: "Envoyer le code",
|
|
780
|
+
submitPending: "Envoi\u2026",
|
|
781
|
+
rememberPassword: "Tu t'en souviens finalement ?",
|
|
782
|
+
login: "Se connecter",
|
|
783
|
+
emailRequired: "Renseigne ton adresse e-mail",
|
|
784
|
+
sendFailed: "L'envoi du code a \xE9chou\xE9"
|
|
785
|
+
};
|
|
669
786
|
function ForgotPasswordForm({
|
|
670
787
|
onSuccess,
|
|
671
788
|
loginUrl = "/login",
|
|
789
|
+
labels,
|
|
790
|
+
titleClassName,
|
|
672
791
|
authClient
|
|
673
792
|
}) {
|
|
793
|
+
const t = { ...DEFAULTS4, ...labels };
|
|
674
794
|
const [email, setEmail] = useState5("");
|
|
675
795
|
const [error, setError] = useState5();
|
|
676
796
|
const [isPending, setIsPending] = useState5(false);
|
|
677
797
|
const handleSubmit = async (e) => {
|
|
678
798
|
e.preventDefault();
|
|
679
799
|
if (!email.trim()) {
|
|
680
|
-
setError(
|
|
800
|
+
setError(t.emailRequired);
|
|
681
801
|
return;
|
|
682
802
|
}
|
|
683
803
|
setError(void 0);
|
|
684
804
|
setIsPending(true);
|
|
685
805
|
try {
|
|
686
806
|
const res = await authClient.emailOtp.sendVerificationOtp({
|
|
687
|
-
email,
|
|
807
|
+
email: email.trim(),
|
|
688
808
|
type: "forget-password"
|
|
689
809
|
});
|
|
690
810
|
if (res?.error) {
|
|
691
|
-
setError(res.error.message ??
|
|
811
|
+
setError(res.error.message ?? t.sendFailed);
|
|
692
812
|
return;
|
|
693
813
|
}
|
|
694
|
-
onSuccess?.(email);
|
|
814
|
+
onSuccess?.(email.trim());
|
|
695
815
|
} catch (err) {
|
|
696
|
-
setError(err instanceof Error ? err.message :
|
|
816
|
+
setError(err instanceof Error ? err.message : t.sendFailed);
|
|
697
817
|
} finally {
|
|
698
818
|
setIsPending(false);
|
|
699
819
|
}
|
|
700
820
|
};
|
|
701
|
-
return /* @__PURE__ */
|
|
702
|
-
/* @__PURE__ */
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
821
|
+
return /* @__PURE__ */ jsxs9("div", { className: "space-y-7", children: [
|
|
822
|
+
/* @__PURE__ */ jsx10(
|
|
823
|
+
AuthHeading,
|
|
824
|
+
{
|
|
825
|
+
title: t.title,
|
|
826
|
+
subtitle: t.subtitle,
|
|
827
|
+
titleClassName
|
|
828
|
+
}
|
|
829
|
+
),
|
|
830
|
+
/* @__PURE__ */ jsx10(AuthAlert, { children: error }),
|
|
831
|
+
/* @__PURE__ */ jsxs9("form", { onSubmit: handleSubmit, className: "space-y-5", noValidate: true, children: [
|
|
832
|
+
/* @__PURE__ */ jsx10(
|
|
833
|
+
AuthField,
|
|
710
834
|
{
|
|
835
|
+
label: t.emailPlaceholder,
|
|
711
836
|
type: "email",
|
|
837
|
+
inputMode: "email",
|
|
712
838
|
value: email,
|
|
713
839
|
onChange: (e) => setEmail(e.target.value),
|
|
714
|
-
placeholder: "Email address",
|
|
715
840
|
required: true,
|
|
716
841
|
disabled: isPending,
|
|
717
842
|
autoComplete: "email",
|
|
718
|
-
|
|
843
|
+
autoCapitalize: "none",
|
|
844
|
+
spellCheck: false,
|
|
845
|
+
invalid: !!error
|
|
719
846
|
}
|
|
720
847
|
),
|
|
721
|
-
/* @__PURE__ */
|
|
722
|
-
|
|
848
|
+
/* @__PURE__ */ jsx10(
|
|
849
|
+
AuthSubmit,
|
|
723
850
|
{
|
|
724
|
-
|
|
725
|
-
disabled:
|
|
726
|
-
|
|
727
|
-
children:
|
|
851
|
+
pending: isPending,
|
|
852
|
+
disabled: !email.trim(),
|
|
853
|
+
pendingLabel: t.submitPending,
|
|
854
|
+
children: t.submit
|
|
728
855
|
}
|
|
729
856
|
)
|
|
730
857
|
] }),
|
|
731
|
-
/* @__PURE__ */
|
|
732
|
-
|
|
858
|
+
/* @__PURE__ */ jsxs9("p", { className: "text-center text-sm text-muted-foreground", children: [
|
|
859
|
+
t.rememberPassword,
|
|
733
860
|
" ",
|
|
734
|
-
/* @__PURE__ */
|
|
861
|
+
/* @__PURE__ */ jsx10(
|
|
735
862
|
"a",
|
|
736
863
|
{
|
|
737
864
|
href: loginUrl,
|
|
738
|
-
className: "font-medium text-foreground underline underline-offset-4 hover:
|
|
739
|
-
children:
|
|
865
|
+
className: "rounded font-medium text-foreground underline underline-offset-4 decoration-foreground/25 transition-colors hover:decoration-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
866
|
+
children: t.login
|
|
740
867
|
}
|
|
741
868
|
)
|
|
742
869
|
] })
|
|
@@ -745,13 +872,37 @@ function ForgotPasswordForm({
|
|
|
745
872
|
|
|
746
873
|
// src/components/reset-password-form.tsx
|
|
747
874
|
import { useState as useState6 } from "react";
|
|
748
|
-
import { jsx as
|
|
875
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
876
|
+
var MIN_PASSWORD_LENGTH2 = 8;
|
|
877
|
+
var DEFAULTS5 = {
|
|
878
|
+
title: "Nouveau mot de passe",
|
|
879
|
+
subtitle: "Entre le code \xE0 6 chiffres re\xE7u par e-mail et ton nouveau mot de passe.",
|
|
880
|
+
codePlaceholder: "Code de v\xE9rification",
|
|
881
|
+
passwordPlaceholder: "Nouveau mot de passe",
|
|
882
|
+
passwordHint: `Au moins ${MIN_PASSWORD_LENGTH2} caract\xE8res.`,
|
|
883
|
+
confirmPlaceholder: "Confirme le mot de passe",
|
|
884
|
+
submit: "R\xE9initialiser",
|
|
885
|
+
submitPending: "R\xE9initialisation\u2026",
|
|
886
|
+
resend: "Renvoyer le code",
|
|
887
|
+
resendPending: "Envoi\u2026",
|
|
888
|
+
resent: "Un nouveau code vient de t'\xEAtre envoy\xE9.",
|
|
889
|
+
rememberPassword: "Tu t'en souviens finalement ?",
|
|
890
|
+
login: "Se connecter",
|
|
891
|
+
codeRequired: "Entre le code \xE0 6 chiffres",
|
|
892
|
+
passwordTooShort: `Le mot de passe doit faire au moins ${MIN_PASSWORD_LENGTH2} caract\xE8res`,
|
|
893
|
+
passwordMismatch: "Les deux mots de passe ne correspondent pas",
|
|
894
|
+
resetFailed: "La r\xE9initialisation a \xE9chou\xE9",
|
|
895
|
+
resendFailed: "L'envoi du code a \xE9chou\xE9"
|
|
896
|
+
};
|
|
749
897
|
function ResetPasswordForm({
|
|
750
898
|
email,
|
|
751
899
|
onSuccess,
|
|
752
900
|
loginUrl = "/login",
|
|
901
|
+
labels,
|
|
902
|
+
titleClassName,
|
|
753
903
|
authClient
|
|
754
904
|
}) {
|
|
905
|
+
const t = { ...DEFAULTS5, ...labels };
|
|
755
906
|
const [otp, setOtp] = useState6("");
|
|
756
907
|
const [password, setPassword] = useState6("");
|
|
757
908
|
const [confirmPassword, setConfirmPassword] = useState6("");
|
|
@@ -759,21 +910,24 @@ function ResetPasswordForm({
|
|
|
759
910
|
const [isResetting, setIsResetting] = useState6(false);
|
|
760
911
|
const [isResending, setIsResending] = useState6(false);
|
|
761
912
|
const [resendMessage, setResendMessage] = useState6();
|
|
913
|
+
const tooShort = password.length > 0 && password.length < MIN_PASSWORD_LENGTH2;
|
|
914
|
+
const mismatch = confirmPassword.length > 0 && confirmPassword !== password;
|
|
762
915
|
const handleSubmit = async (e) => {
|
|
763
916
|
e.preventDefault();
|
|
764
|
-
if (
|
|
765
|
-
setError(
|
|
917
|
+
if (otp.length < OTP_LENGTH) {
|
|
918
|
+
setError(t.codeRequired);
|
|
766
919
|
return;
|
|
767
920
|
}
|
|
768
|
-
if (password.length <
|
|
769
|
-
setError(
|
|
921
|
+
if (password.length < MIN_PASSWORD_LENGTH2) {
|
|
922
|
+
setError(t.passwordTooShort);
|
|
770
923
|
return;
|
|
771
924
|
}
|
|
772
925
|
if (password !== confirmPassword) {
|
|
773
|
-
setError(
|
|
926
|
+
setError(t.passwordMismatch);
|
|
774
927
|
return;
|
|
775
928
|
}
|
|
776
929
|
setError(void 0);
|
|
930
|
+
setResendMessage(void 0);
|
|
777
931
|
setIsResetting(true);
|
|
778
932
|
try {
|
|
779
933
|
const res = await fetch("/api/auth/email-otp/reset-password", {
|
|
@@ -783,14 +937,12 @@ function ResetPasswordForm({
|
|
|
783
937
|
});
|
|
784
938
|
if (!res.ok) {
|
|
785
939
|
const body = await res.json().catch(() => null);
|
|
786
|
-
setError(body?.message ??
|
|
940
|
+
setError(body?.message ?? t.resetFailed);
|
|
787
941
|
return;
|
|
788
942
|
}
|
|
789
943
|
onSuccess?.();
|
|
790
944
|
} catch (err) {
|
|
791
|
-
setError(
|
|
792
|
-
err instanceof Error ? err.message : "Failed to reset password"
|
|
793
|
-
);
|
|
945
|
+
setError(err instanceof Error ? err.message : t.resetFailed);
|
|
794
946
|
} finally {
|
|
795
947
|
setIsResetting(false);
|
|
796
948
|
}
|
|
@@ -804,125 +956,145 @@ function ResetPasswordForm({
|
|
|
804
956
|
email,
|
|
805
957
|
type: "forget-password"
|
|
806
958
|
});
|
|
807
|
-
setResendMessage(
|
|
959
|
+
setResendMessage(t.resent);
|
|
808
960
|
} catch (err) {
|
|
809
|
-
setError(err instanceof Error ? err.message :
|
|
961
|
+
setError(err instanceof Error ? err.message : t.resendFailed);
|
|
810
962
|
} finally {
|
|
811
963
|
setIsResending(false);
|
|
812
964
|
}
|
|
813
965
|
};
|
|
814
|
-
return /* @__PURE__ */
|
|
815
|
-
/* @__PURE__ */
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
"input",
|
|
966
|
+
return /* @__PURE__ */ jsxs10("div", { className: "space-y-7", children: [
|
|
967
|
+
/* @__PURE__ */ jsx11(
|
|
968
|
+
AuthHeading,
|
|
969
|
+
{
|
|
970
|
+
title: t.title,
|
|
971
|
+
subtitle: t.subtitle,
|
|
972
|
+
titleClassName
|
|
973
|
+
}
|
|
974
|
+
),
|
|
975
|
+
/* @__PURE__ */ jsx11(AuthAlert, { children: error }),
|
|
976
|
+
/* @__PURE__ */ jsx11(AuthAlert, { tone: "success", children: resendMessage }),
|
|
977
|
+
/* @__PURE__ */ jsxs10("form", { onSubmit: handleSubmit, className: "space-y-5", noValidate: true, children: [
|
|
978
|
+
/* @__PURE__ */ jsx11(
|
|
979
|
+
AuthOtpField,
|
|
829
980
|
{
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
pattern: "[0-9]*",
|
|
833
|
-
maxLength: 6,
|
|
981
|
+
id: "reset-password-otp",
|
|
982
|
+
label: t.codePlaceholder,
|
|
834
983
|
value: otp,
|
|
835
|
-
onChange:
|
|
836
|
-
|
|
837
|
-
required: true,
|
|
838
|
-
disabled: isResetting,
|
|
839
|
-
autoComplete: "one-time-code",
|
|
840
|
-
className: "flex h-12 w-full rounded-md border border-input bg-background px-3 py-2 text-center text-lg tracking-[0.4em] font-mono ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50 disabled:cursor-not-allowed"
|
|
984
|
+
onChange: setOtp,
|
|
985
|
+
disabled: isResetting
|
|
841
986
|
}
|
|
842
987
|
),
|
|
843
|
-
/* @__PURE__ */
|
|
844
|
-
|
|
988
|
+
/* @__PURE__ */ jsx11(
|
|
989
|
+
AuthField,
|
|
845
990
|
{
|
|
991
|
+
label: t.passwordPlaceholder,
|
|
846
992
|
type: "password",
|
|
847
993
|
value: password,
|
|
848
994
|
onChange: (e) => setPassword(e.target.value),
|
|
849
|
-
placeholder: "New password",
|
|
850
995
|
required: true,
|
|
851
996
|
disabled: isResetting,
|
|
852
997
|
autoComplete: "new-password",
|
|
853
|
-
|
|
998
|
+
description: t.passwordHint,
|
|
999
|
+
invalid: tooShort
|
|
854
1000
|
}
|
|
855
1001
|
),
|
|
856
|
-
/* @__PURE__ */
|
|
857
|
-
|
|
1002
|
+
/* @__PURE__ */ jsx11(
|
|
1003
|
+
AuthField,
|
|
858
1004
|
{
|
|
1005
|
+
label: t.confirmPlaceholder,
|
|
859
1006
|
type: "password",
|
|
860
1007
|
value: confirmPassword,
|
|
861
1008
|
onChange: (e) => setConfirmPassword(e.target.value),
|
|
862
|
-
placeholder: "Confirm new password",
|
|
863
1009
|
required: true,
|
|
864
1010
|
disabled: isResetting,
|
|
865
1011
|
autoComplete: "new-password",
|
|
866
|
-
|
|
1012
|
+
invalid: mismatch
|
|
867
1013
|
}
|
|
868
1014
|
),
|
|
869
|
-
/* @__PURE__ */
|
|
870
|
-
|
|
1015
|
+
/* @__PURE__ */ jsx11(
|
|
1016
|
+
AuthSubmit,
|
|
871
1017
|
{
|
|
872
|
-
|
|
873
|
-
disabled:
|
|
874
|
-
|
|
875
|
-
children:
|
|
1018
|
+
pending: isResetting,
|
|
1019
|
+
disabled: otp.length < OTP_LENGTH || !password || !confirmPassword,
|
|
1020
|
+
pendingLabel: t.submitPending,
|
|
1021
|
+
children: t.submit
|
|
876
1022
|
}
|
|
877
|
-
)
|
|
878
|
-
|
|
1023
|
+
)
|
|
1024
|
+
] }),
|
|
1025
|
+
/* @__PURE__ */ jsxs10("div", { className: "space-y-4 text-center text-sm text-muted-foreground", children: [
|
|
1026
|
+
/* @__PURE__ */ jsx11(
|
|
879
1027
|
"button",
|
|
880
1028
|
{
|
|
881
1029
|
type: "button",
|
|
882
1030
|
onClick: handleResend,
|
|
883
1031
|
disabled: isResending,
|
|
884
|
-
className: "
|
|
885
|
-
children: isResending ?
|
|
1032
|
+
className: "rounded font-medium text-foreground underline underline-offset-4 decoration-foreground/25 transition-colors hover:decoration-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-55",
|
|
1033
|
+
children: isResending ? t.resendPending : t.resend
|
|
886
1034
|
}
|
|
887
|
-
)
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
)
|
|
1035
|
+
),
|
|
1036
|
+
/* @__PURE__ */ jsxs10("p", { children: [
|
|
1037
|
+
t.rememberPassword,
|
|
1038
|
+
" ",
|
|
1039
|
+
/* @__PURE__ */ jsx11(
|
|
1040
|
+
"a",
|
|
1041
|
+
{
|
|
1042
|
+
href: loginUrl,
|
|
1043
|
+
className: "rounded font-medium text-foreground underline underline-offset-4 decoration-foreground/25 transition-colors hover:decoration-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
1044
|
+
children: t.login
|
|
1045
|
+
}
|
|
1046
|
+
)
|
|
1047
|
+
] })
|
|
900
1048
|
] })
|
|
901
1049
|
] });
|
|
902
1050
|
}
|
|
903
1051
|
|
|
904
1052
|
// src/components/auth-layout.tsx
|
|
905
|
-
import { jsx as
|
|
1053
|
+
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
906
1054
|
function AuthLayout({
|
|
907
1055
|
logo,
|
|
908
|
-
|
|
909
|
-
subtitle,
|
|
1056
|
+
panel,
|
|
910
1057
|
children,
|
|
911
1058
|
footer
|
|
912
1059
|
}) {
|
|
913
|
-
return /* @__PURE__ */
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
1060
|
+
return /* @__PURE__ */ jsx12("div", { className: "flex min-h-dvh flex-col bg-background px-5 pb-10 pt-12 sm:items-center sm:bg-muted/40 sm:px-6 sm:py-16", children: /* @__PURE__ */ jsxs11(
|
|
1061
|
+
"div",
|
|
1062
|
+
{
|
|
1063
|
+
className: `mx-auto w-full ${panel ? "max-w-4xl" : "max-w-[420px]"}`,
|
|
1064
|
+
children: [
|
|
1065
|
+
/* @__PURE__ */ jsxs11(
|
|
1066
|
+
"div",
|
|
1067
|
+
{
|
|
1068
|
+
className: [
|
|
1069
|
+
"sm:overflow-hidden sm:rounded-2xl sm:border sm:border-border/70 sm:bg-card sm:shadow-lg sm:shadow-black/5",
|
|
1070
|
+
panel ? "md:grid md:grid-cols-2" : ""
|
|
1071
|
+
].filter(Boolean).join(" "),
|
|
1072
|
+
children: [
|
|
1073
|
+
/* @__PURE__ */ jsxs11("div", { className: "sm:p-8", children: [
|
|
1074
|
+
logo && /* @__PURE__ */ jsx12("div", { className: "mb-7 flex justify-center", children: logo }),
|
|
1075
|
+
children
|
|
1076
|
+
] }),
|
|
1077
|
+
panel && // Decorative: it must never carry information the form does not,
|
|
1078
|
+
// so it is hidden from assistive tech rather than described.
|
|
1079
|
+
/* @__PURE__ */ jsx12(
|
|
1080
|
+
"div",
|
|
1081
|
+
{
|
|
1082
|
+
"aria-hidden": "true",
|
|
1083
|
+
className: "hidden bg-muted md:block [&>*]:h-full [&>*]:w-full [&>img]:object-cover",
|
|
1084
|
+
children: panel
|
|
1085
|
+
}
|
|
1086
|
+
)
|
|
1087
|
+
]
|
|
1088
|
+
}
|
|
1089
|
+
),
|
|
1090
|
+
footer && /* @__PURE__ */ jsx12("div", { className: "mt-6 text-center text-xs leading-relaxed text-muted-foreground", children: footer })
|
|
1091
|
+
]
|
|
1092
|
+
}
|
|
1093
|
+
) });
|
|
922
1094
|
}
|
|
923
1095
|
|
|
924
1096
|
// src/components/invitation-notice.tsx
|
|
925
|
-
import { jsx as
|
|
1097
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
926
1098
|
function defaultSupportEmail() {
|
|
927
1099
|
if (typeof window === "undefined") return void 0;
|
|
928
1100
|
const host = window.location.hostname;
|
|
@@ -942,15 +1114,15 @@ function InvitationNotice({
|
|
|
942
1114
|
action
|
|
943
1115
|
}) {
|
|
944
1116
|
const contact = supportEmail ?? defaultSupportEmail();
|
|
945
|
-
return /* @__PURE__ */
|
|
946
|
-
/* @__PURE__ */
|
|
947
|
-
/* @__PURE__ */
|
|
948
|
-
/* @__PURE__ */
|
|
1117
|
+
return /* @__PURE__ */ jsxs12("div", { className: "space-y-8", children: [
|
|
1118
|
+
/* @__PURE__ */ jsxs12("div", { children: [
|
|
1119
|
+
/* @__PURE__ */ jsx13("h1", { className: "text-2xl font-bold tracking-tight", children: title }),
|
|
1120
|
+
/* @__PURE__ */ jsx13("p", { className: "mt-1 text-sm text-muted-foreground", children: REASON_MESSAGE[reason] ?? REASON_MESSAGE.unknown })
|
|
949
1121
|
] }),
|
|
950
|
-
contact ? /* @__PURE__ */
|
|
1122
|
+
contact ? /* @__PURE__ */ jsxs12("p", { className: "text-sm text-muted-foreground", children: [
|
|
951
1123
|
"\xC9crivez-nous \xE0",
|
|
952
1124
|
" ",
|
|
953
|
-
/* @__PURE__ */
|
|
1125
|
+
/* @__PURE__ */ jsx13(
|
|
954
1126
|
"a",
|
|
955
1127
|
{
|
|
956
1128
|
href: `mailto:${contact}`,
|