@insforge/react 0.3.5 → 0.4.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/README.md +485 -604
- package/dist/atoms.cjs +818 -0
- package/dist/atoms.cjs.map +1 -0
- package/dist/atoms.d.cts +222 -0
- package/dist/atoms.d.ts +72 -237
- package/dist/atoms.js +382 -456
- package/dist/atoms.js.map +1 -1
- package/dist/components.cjs +2254 -0
- package/dist/components.cjs.map +1 -0
- package/dist/{components.d.mts → components.d.cts} +10 -32
- package/dist/components.d.ts +9 -31
- package/dist/components.js +1046 -1180
- package/dist/components.js.map +1 -1
- package/dist/forms.cjs +1287 -0
- package/dist/forms.cjs.map +1 -0
- package/dist/forms.d.cts +138 -0
- package/dist/forms.d.ts +115 -162
- package/dist/forms.js +728 -921
- package/dist/forms.js.map +1 -1
- package/dist/{hooks.mjs → hooks.cjs} +15 -13
- package/dist/hooks.cjs.map +1 -0
- package/dist/{hooks.d.mts → hooks.d.cts} +1 -1
- package/dist/hooks.js +9 -15
- package/dist/hooks.js.map +1 -1
- package/dist/index.cjs +2674 -0
- package/dist/index.cjs.map +1 -0
- package/dist/{index.d.mts → index.d.cts} +10 -10
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1093 -1235
- package/dist/index.js.map +1 -1
- package/dist/{lib.mjs → lib.cjs} +13 -11
- package/dist/lib.cjs.map +1 -0
- package/dist/{lib.d.mts → lib.d.cts} +1 -8
- package/dist/lib.d.ts +1 -8
- package/dist/lib.js +4 -17
- package/dist/lib.js.map +1 -1
- package/dist/{router.mjs → router.cjs} +14 -16
- package/dist/router.cjs.map +1 -0
- package/dist/router.js +10 -16
- package/dist/router.js.map +1 -1
- package/dist/styles.css +655 -2
- package/dist/types.cjs +4 -0
- package/dist/{types.mjs.map → types.cjs.map} +1 -1
- package/dist/{types.d.mts → types.d.cts} +2 -2
- package/dist/types.d.ts +2 -2
- package/dist/types.js +0 -1
- package/package.json +106 -98
- package/dist/atoms.d.mts +0 -387
- package/dist/atoms.mjs +0 -861
- package/dist/atoms.mjs.map +0 -1
- package/dist/components.mjs +0 -2327
- package/dist/components.mjs.map +0 -1
- package/dist/forms.d.mts +0 -185
- package/dist/forms.mjs +0 -1468
- package/dist/forms.mjs.map +0 -1
- package/dist/hooks.mjs.map +0 -1
- package/dist/index.mjs +0 -2724
- package/dist/index.mjs.map +0 -1
- package/dist/lib.mjs.map +0 -1
- package/dist/router.mjs.map +0 -1
- package/dist/types.mjs +0 -3
- package/src/styles.css +0 -15
- /package/dist/{router.d.mts → router.d.cts} +0 -0
package/README.md
CHANGED
|
@@ -1,604 +1,485 @@
|
|
|
1
|
-
# @insforge/react
|
|
2
|
-
|
|
3
|
-
**Complete authentication solution for React applications.** Production-ready components with full business logic included.
|
|
4
|
-
|
|
5
|
-
## Why @insforge/react?
|
|
6
|
-
|
|
7
|
-
✅ **5-Minute Setup** - One provider + one line of router config = done
|
|
8
|
-
✅ **Built-in Auth UI** - Use deployed auth pages (like Next.js middleware)
|
|
9
|
-
✅ **Framework Agnostic** - Works with any React framework
|
|
10
|
-
✅ **Full TypeScript** - Complete type safety out of the box
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import
|
|
38
|
-
import '
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
import {
|
|
55
|
-
import
|
|
56
|
-
import
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
- Visiting `/sign-
|
|
77
|
-
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
{ path: '/sign-
|
|
154
|
-
{ path: '/
|
|
155
|
-
{ path: '/
|
|
156
|
-
{ path: '/
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
- `<
|
|
189
|
-
- `<
|
|
190
|
-
- `<
|
|
191
|
-
- `<
|
|
192
|
-
- `<
|
|
193
|
-
- `<
|
|
194
|
-
- `<
|
|
195
|
-
- `<
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
- `<
|
|
200
|
-
- `<
|
|
201
|
-
- `<
|
|
202
|
-
- `<
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
const {
|
|
212
|
-
const {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
/>
|
|
339
|
-
|
|
340
|
-
<
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
<h1>Dashboard</h1>
|
|
487
|
-
|
|
488
|
-
{/* Simple protection */}
|
|
489
|
-
<Protect redirectTo="/sign-in">
|
|
490
|
-
<UserContent />
|
|
491
|
-
</Protect>
|
|
492
|
-
|
|
493
|
-
{/* Role-based protection */}
|
|
494
|
-
<Protect
|
|
495
|
-
redirectTo="/unauthorized"
|
|
496
|
-
condition={(user) => user.role === 'admin'}
|
|
497
|
-
>
|
|
498
|
-
<AdminPanel />
|
|
499
|
-
</Protect>
|
|
500
|
-
</div>
|
|
501
|
-
);
|
|
502
|
-
}
|
|
503
|
-
```
|
|
504
|
-
|
|
505
|
-
---
|
|
506
|
-
|
|
507
|
-
## TypeScript
|
|
508
|
-
|
|
509
|
-
Full TypeScript support with exported types:
|
|
510
|
-
|
|
511
|
-
```tsx
|
|
512
|
-
import type {
|
|
513
|
-
InsforgeUser,
|
|
514
|
-
SignInProps,
|
|
515
|
-
SignUpProps,
|
|
516
|
-
ForgotPasswordProps,
|
|
517
|
-
ResetPasswordProps,
|
|
518
|
-
VerifyEmailProps,
|
|
519
|
-
SignInAppearance,
|
|
520
|
-
SignUpAppearance,
|
|
521
|
-
ForgotPasswordAppearance,
|
|
522
|
-
ResetPasswordAppearance,
|
|
523
|
-
UserButtonProps,
|
|
524
|
-
ProtectProps,
|
|
525
|
-
ConditionalProps,
|
|
526
|
-
InsforgeCallbackProps,
|
|
527
|
-
SignInFormProps,
|
|
528
|
-
SignUpFormProps,
|
|
529
|
-
ForgotPasswordFormProps,
|
|
530
|
-
ResetPasswordFormProps,
|
|
531
|
-
VerifyEmailStatusProps,
|
|
532
|
-
AuthFormFieldProps,
|
|
533
|
-
OAuthProvider,
|
|
534
|
-
EmailAuthConfig,
|
|
535
|
-
InsforgeProviderProps,
|
|
536
|
-
GetInsforgeRoutesConfig,
|
|
537
|
-
} from '@insforge/react';
|
|
538
|
-
```
|
|
539
|
-
|
|
540
|
-
---
|
|
541
|
-
|
|
542
|
-
## OAuth Providers
|
|
543
|
-
|
|
544
|
-
Built-in support for 10+ OAuth providers:
|
|
545
|
-
- Google
|
|
546
|
-
- GitHub
|
|
547
|
-
- Discord
|
|
548
|
-
- Apple
|
|
549
|
-
- Microsoft
|
|
550
|
-
- Facebook
|
|
551
|
-
- LinkedIn
|
|
552
|
-
- Instagram
|
|
553
|
-
- TikTok
|
|
554
|
-
- Spotify
|
|
555
|
-
- X (Twitter)
|
|
556
|
-
|
|
557
|
-
Providers are auto-detected from your backend configuration.
|
|
558
|
-
|
|
559
|
-
---
|
|
560
|
-
|
|
561
|
-
## Validation Utilities
|
|
562
|
-
|
|
563
|
-
```tsx
|
|
564
|
-
import { emailSchema, cn } from '@insforge/react/lib';
|
|
565
|
-
|
|
566
|
-
// Validate email with Zod
|
|
567
|
-
const result = emailSchema.safeParse('user@example.com');
|
|
568
|
-
|
|
569
|
-
// Merge Tailwind classes
|
|
570
|
-
const className = cn('px-4 py-2', 'bg-blue-500', conditionalClass);
|
|
571
|
-
```
|
|
572
|
-
|
|
573
|
-
---
|
|
574
|
-
|
|
575
|
-
## Available Atomic Components
|
|
576
|
-
|
|
577
|
-
Low-level building blocks for complete customization:
|
|
578
|
-
|
|
579
|
-
- `<AuthBranding />` - Insforge branding footer
|
|
580
|
-
- `<AuthContainer />` - Main container wrapper
|
|
581
|
-
- `<AuthHeader />` - Title and subtitle display
|
|
582
|
-
- `<AuthErrorBanner />` - Error message display
|
|
583
|
-
- `<AuthFormField />` - Standard input field
|
|
584
|
-
- `<AuthPasswordField />` - Password input with features
|
|
585
|
-
- `<AuthPasswordStrengthIndicator />` - Password checklist
|
|
586
|
-
- `<AuthSubmitButton />` - Submit button with states
|
|
587
|
-
- `<AuthLink />` - Call-to-action link
|
|
588
|
-
- `<AuthDivider />` - Visual separator
|
|
589
|
-
- `<AuthOAuthButton />` - Single OAuth provider button
|
|
590
|
-
- `<AuthOAuthProviders />` - Smart OAuth grid
|
|
591
|
-
- `<AuthVerificationCodeInput />` - 6-digit OTP input
|
|
592
|
-
- `<AuthEmailVerificationStep />` - Email verification step with countdown and resend
|
|
593
|
-
|
|
594
|
-
---
|
|
595
|
-
|
|
596
|
-
## Support
|
|
597
|
-
|
|
598
|
-
- **Documentation**: https://docs.insforge.dev
|
|
599
|
-
- **GitHub Issues**: https://github.com/InsForge/InsForge/issues
|
|
600
|
-
- **Discord Community**: https://discord.com/invite/DvBtaEc9Jz
|
|
601
|
-
|
|
602
|
-
## License
|
|
603
|
-
|
|
604
|
-
MIT © Insforge
|
|
1
|
+
# @insforge/react
|
|
2
|
+
|
|
3
|
+
**Complete authentication solution for React applications.** Production-ready components with full business logic included.
|
|
4
|
+
|
|
5
|
+
## Why @insforge/react?
|
|
6
|
+
|
|
7
|
+
✅ **5-Minute Setup** - One provider + one line of router config = done
|
|
8
|
+
✅ **Built-in Auth UI** - Use deployed auth pages (like Next.js middleware)
|
|
9
|
+
✅ **Framework Agnostic** - Works with any React framework
|
|
10
|
+
✅ **Full TypeScript** - Complete type safety out of the box
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
Get authentication working in your React app in 5 minutes.
|
|
17
|
+
|
|
18
|
+
### 1. Install
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install @insforge/react
|
|
22
|
+
# or
|
|
23
|
+
yarn add @insforge/react
|
|
24
|
+
# or
|
|
25
|
+
pnpm add @insforge/react
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 2. Setup Provider
|
|
29
|
+
|
|
30
|
+
Wrap your app with `InsforgeProvider`:
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
// src/main.tsx (Vite) or src/index.tsx (CRA)
|
|
34
|
+
import { StrictMode } from 'react';
|
|
35
|
+
import { createRoot } from 'react-dom/client';
|
|
36
|
+
import { InsforgeProvider } from '@insforge/react';
|
|
37
|
+
import '@insforge/react/styles.css';
|
|
38
|
+
import App from './App';
|
|
39
|
+
|
|
40
|
+
createRoot(document.getElementById('root')!).render(
|
|
41
|
+
<StrictMode>
|
|
42
|
+
<InsforgeProvider baseUrl={import.meta.env.VITE_INSFORGE_BASE_URL}>
|
|
43
|
+
<App />
|
|
44
|
+
</InsforgeProvider>
|
|
45
|
+
</StrictMode>
|
|
46
|
+
);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 3. Configure Router (Built-in Auth)
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
// src/App.tsx
|
|
53
|
+
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
|
|
54
|
+
import { getInsforgeRoutes } from '@insforge/react/router';
|
|
55
|
+
import Home from './pages/Home';
|
|
56
|
+
import Dashboard from './pages/Dashboard';
|
|
57
|
+
|
|
58
|
+
const router = createBrowserRouter([
|
|
59
|
+
{ path: '/', element: <Home /> },
|
|
60
|
+
|
|
61
|
+
...getInsforgeRoutes({
|
|
62
|
+
baseUrl: import.meta.env.VITE_INSFORGE_BASE_URL,
|
|
63
|
+
builtInAuth: true
|
|
64
|
+
}),
|
|
65
|
+
|
|
66
|
+
{ path: '/dashboard', element: <Dashboard /> }
|
|
67
|
+
]);
|
|
68
|
+
|
|
69
|
+
export default function App() {
|
|
70
|
+
return <RouterProvider router={router} />;
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**What this does:**
|
|
75
|
+
- Visiting `/sign-in` → Redirects to `your-project.insforge.app/auth/sign-in`
|
|
76
|
+
- Visiting `/sign-up` → Redirects to `your-project.insforge.app/auth/sign-up`
|
|
77
|
+
- After auth → Redirects back to `/auth/callback` → Goes to dashboard
|
|
78
|
+
|
|
79
|
+
### 4. Add Auth UI to Your Pages
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
// src/pages/Home.tsx
|
|
83
|
+
import { SignedIn, SignedOut, UserButton } from '@insforge/react';
|
|
84
|
+
|
|
85
|
+
export default function Home() {
|
|
86
|
+
return (
|
|
87
|
+
<div>
|
|
88
|
+
<nav>
|
|
89
|
+
<SignedOut>
|
|
90
|
+
<a href="/sign-in">Sign In</a>
|
|
91
|
+
</SignedOut>
|
|
92
|
+
|
|
93
|
+
<SignedIn>
|
|
94
|
+
<UserButton afterSignOutUrl="/" />
|
|
95
|
+
</SignedIn>
|
|
96
|
+
</nav>
|
|
97
|
+
|
|
98
|
+
<h1>Welcome to My App!</h1>
|
|
99
|
+
</div>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**That's it!** 🎉 You now have production-ready authentication.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Router Configuration Options
|
|
109
|
+
|
|
110
|
+
### Built-in Auth (Recommended)
|
|
111
|
+
|
|
112
|
+
Uses your deployed Insforge auth pages (includes all flows):
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
...getInsforgeRoutes({
|
|
116
|
+
baseUrl: 'https://your-project.insforge.app',
|
|
117
|
+
builtInAuth: true, // Default
|
|
118
|
+
paths: {
|
|
119
|
+
signIn: '/sign-in', // Sign in page
|
|
120
|
+
signUp: '/sign-up', // Sign up page
|
|
121
|
+
verifyEmail: '/verify-email', // Email verification page
|
|
122
|
+
forgotPassword: '/forgot-password', // Request password reset
|
|
123
|
+
resetPassword: '/reset-password', // Reset password with token
|
|
124
|
+
callback: '/auth/callback' // OAuth callback handler
|
|
125
|
+
}
|
|
126
|
+
})
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Custom UI Components
|
|
130
|
+
|
|
131
|
+
Use package components with your own styling:
|
|
132
|
+
|
|
133
|
+
```tsx
|
|
134
|
+
import {
|
|
135
|
+
SignIn,
|
|
136
|
+
SignUp,
|
|
137
|
+
ForgotPassword,
|
|
138
|
+
ResetPassword,
|
|
139
|
+
VerifyEmail
|
|
140
|
+
} from '@insforge/react';
|
|
141
|
+
|
|
142
|
+
const router = createBrowserRouter([
|
|
143
|
+
{ path: '/', element: <Home /> },
|
|
144
|
+
|
|
145
|
+
// Still need callback route for OAuth
|
|
146
|
+
...getInsforgeRoutes({
|
|
147
|
+
baseUrl: import.meta.env.VITE_INSFORGE_BASE_URL,
|
|
148
|
+
builtInAuth: false // Don't redirect to deployed UI
|
|
149
|
+
}),
|
|
150
|
+
|
|
151
|
+
// Use package components for complete auth flows
|
|
152
|
+
{ path: '/sign-in', element: <SignIn afterSignInUrl="/dashboard" /> },
|
|
153
|
+
{ path: '/sign-up', element: <SignUp afterSignUpUrl="/dashboard" /> },
|
|
154
|
+
{ path: '/forgot-password', element: <ForgotPassword backToSignInUrl="/sign-in" /> },
|
|
155
|
+
{ path: '/reset-password', element: <ResetPassword token={searchParams.get('token')} /> },
|
|
156
|
+
{ path: '/verify-email', element: <VerifyEmail token={searchParams.get('token')} /> }
|
|
157
|
+
]);
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Fully Custom UI
|
|
161
|
+
|
|
162
|
+
Build your own auth pages from scratch:
|
|
163
|
+
|
|
164
|
+
```tsx
|
|
165
|
+
import { useAuth } from '@insforge/react';
|
|
166
|
+
|
|
167
|
+
function CustomSignIn() {
|
|
168
|
+
const { signIn } = useAuth();
|
|
169
|
+
|
|
170
|
+
const handleSubmit = async (e) => {
|
|
171
|
+
e.preventDefault();
|
|
172
|
+
await signIn(email, password);
|
|
173
|
+
navigate('/dashboard');
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
return <form onSubmit={handleSubmit}>...</form>;
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Core Features
|
|
183
|
+
|
|
184
|
+
### Components
|
|
185
|
+
|
|
186
|
+
**Pre-built with Business Logic:**
|
|
187
|
+
- `<SignIn />` - Complete sign-in with email/password & OAuth
|
|
188
|
+
- `<SignUp />` - Registration with password validation & email verification
|
|
189
|
+
- `<ForgotPassword />` - Request password reset with email validation
|
|
190
|
+
- `<ResetPassword />` - Reset password with token validation
|
|
191
|
+
- `<VerifyEmail />` - Verify email with automatic token handling
|
|
192
|
+
- `<UserButton />` - User dropdown with sign-out
|
|
193
|
+
- `<Protect />` - Route protection wrapper
|
|
194
|
+
- `<SignedIn>` / `<SignedOut>` - Conditional rendering
|
|
195
|
+
- `<InsforgeCallback />` - OAuth callback handler
|
|
196
|
+
|
|
197
|
+
**Form Components (Pure UI):**
|
|
198
|
+
- `<SignInForm />` - Sign-in UI without logic
|
|
199
|
+
- `<SignUpForm />` - Sign-up UI without logic
|
|
200
|
+
- `<ForgotPasswordForm />` - Password reset request UI
|
|
201
|
+
- `<ResetPasswordForm />` - Password reset with token UI
|
|
202
|
+
- `<VerifyEmailStatus />` - Email verification status UI
|
|
203
|
+
|
|
204
|
+
**Atomic Components (14 total):**
|
|
205
|
+
- `<AuthContainer />`, `<AuthHeader />`, `<AuthFormField />`, `<AuthPasswordField />`, `<AuthEmailVerificationStep />`, etc.
|
|
206
|
+
|
|
207
|
+
### Hooks
|
|
208
|
+
|
|
209
|
+
```tsx
|
|
210
|
+
const { signIn, signUp, signOut, isSignedIn, isLoaded } = useAuth();
|
|
211
|
+
const { user, updateUser, isLoaded } = useUser();
|
|
212
|
+
const { oauthProviders, authConfig, isLoaded } = usePublicAuthConfig();
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Customization
|
|
218
|
+
|
|
219
|
+
### Text Customization
|
|
220
|
+
|
|
221
|
+
All components support full text customization:
|
|
222
|
+
|
|
223
|
+
```tsx
|
|
224
|
+
<SignIn
|
|
225
|
+
title="Welcome Back!"
|
|
226
|
+
subtitle="We're happy to see you again"
|
|
227
|
+
emailLabel="Your Email Address"
|
|
228
|
+
emailPlaceholder="you@company.com"
|
|
229
|
+
passwordLabel="Your Password"
|
|
230
|
+
submitButtonText="Login Now"
|
|
231
|
+
loadingButtonText="Signing you in..."
|
|
232
|
+
signUpText="New to our platform?"
|
|
233
|
+
signUpLinkText="Create an account"
|
|
234
|
+
dividerText="or continue with"
|
|
235
|
+
/>
|
|
236
|
+
|
|
237
|
+
<ForgotPassword
|
|
238
|
+
title="Reset Your Password"
|
|
239
|
+
subtitle="Enter your email to receive a reset code"
|
|
240
|
+
emailLabel="Email Address"
|
|
241
|
+
submitButtonText="Send Reset Code"
|
|
242
|
+
backToSignInText="Remember your password?"
|
|
243
|
+
successTitle="Check Your Email"
|
|
244
|
+
successMessage="We've sent a reset code to your inbox"
|
|
245
|
+
/>
|
|
246
|
+
```
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## Advanced Usage
|
|
250
|
+
|
|
251
|
+
### Complete Component with Custom Logic
|
|
252
|
+
|
|
253
|
+
```tsx
|
|
254
|
+
import { SignInForm, useAuth } from '@insforge/react';
|
|
255
|
+
import { useState } from 'react';
|
|
256
|
+
|
|
257
|
+
function CustomSignIn() {
|
|
258
|
+
const { signIn } = useAuth();
|
|
259
|
+
const [email, setEmail] = useState('');
|
|
260
|
+
const [password, setPassword] = useState('');
|
|
261
|
+
const [error, setError] = useState('');
|
|
262
|
+
const [loading, setLoading] = useState(false);
|
|
263
|
+
|
|
264
|
+
const handleSubmit = async (e: React.FormEvent) => {
|
|
265
|
+
e.preventDefault();
|
|
266
|
+
setLoading(true);
|
|
267
|
+
setError('');
|
|
268
|
+
|
|
269
|
+
try {
|
|
270
|
+
await signIn(email, password);
|
|
271
|
+
// Custom success logic
|
|
272
|
+
} catch (err) {
|
|
273
|
+
setError(err.message);
|
|
274
|
+
} finally {
|
|
275
|
+
setLoading(false);
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
return (
|
|
280
|
+
<SignInForm
|
|
281
|
+
email={email}
|
|
282
|
+
password={password}
|
|
283
|
+
onEmailChange={setEmail}
|
|
284
|
+
onPasswordChange={setPassword}
|
|
285
|
+
onSubmit={handleSubmit}
|
|
286
|
+
error={error}
|
|
287
|
+
loading={loading}
|
|
288
|
+
availableProviders={['google', 'github']}
|
|
289
|
+
onOAuthClick={(provider) => {
|
|
290
|
+
// Custom OAuth logic
|
|
291
|
+
}}
|
|
292
|
+
/>
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### Build from Atomic Components
|
|
298
|
+
|
|
299
|
+
```tsx
|
|
300
|
+
import {
|
|
301
|
+
AuthContainer,
|
|
302
|
+
AuthHeader,
|
|
303
|
+
AuthFormField,
|
|
304
|
+
AuthPasswordField,
|
|
305
|
+
AuthSubmitButton,
|
|
306
|
+
AuthErrorBanner,
|
|
307
|
+
AuthDivider,
|
|
308
|
+
AuthOAuthProviders,
|
|
309
|
+
AuthLink,
|
|
310
|
+
} from '@insforge/react';
|
|
311
|
+
|
|
312
|
+
function CompletelyCustomAuth() {
|
|
313
|
+
return (
|
|
314
|
+
<AuthContainer>
|
|
315
|
+
<AuthHeader
|
|
316
|
+
title="Welcome to MyApp"
|
|
317
|
+
subtitle="Sign in to continue"
|
|
318
|
+
/>
|
|
319
|
+
|
|
320
|
+
<AuthErrorBanner error={error} />
|
|
321
|
+
|
|
322
|
+
<form onSubmit={handleSubmit}>
|
|
323
|
+
<AuthFormField
|
|
324
|
+
id="email"
|
|
325
|
+
type="email"
|
|
326
|
+
label="Email"
|
|
327
|
+
value={email}
|
|
328
|
+
onChange={(e) => setEmail(e.target.value)}
|
|
329
|
+
/>
|
|
330
|
+
|
|
331
|
+
<AuthPasswordField
|
|
332
|
+
id="password"
|
|
333
|
+
label="Password"
|
|
334
|
+
value={password}
|
|
335
|
+
onChange={(e) => setPassword(e.target.value)}
|
|
336
|
+
authConfig={config}
|
|
337
|
+
showStrengthIndicator
|
|
338
|
+
/>
|
|
339
|
+
|
|
340
|
+
<AuthSubmitButton isLoading={loading}>
|
|
341
|
+
Sign In
|
|
342
|
+
</AuthSubmitButton>
|
|
343
|
+
</form>
|
|
344
|
+
|
|
345
|
+
<AuthDivider text="or" />
|
|
346
|
+
|
|
347
|
+
<AuthOAuthProviders
|
|
348
|
+
providers={['google', 'github', 'discord']}
|
|
349
|
+
onClick={handleOAuth}
|
|
350
|
+
loading={oauthLoading}
|
|
351
|
+
/>
|
|
352
|
+
|
|
353
|
+
<AuthLink
|
|
354
|
+
text="Don't have an account?"
|
|
355
|
+
linkText="Sign up"
|
|
356
|
+
href="/sign-up"
|
|
357
|
+
/>
|
|
358
|
+
</AuthContainer>
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
### Route Protection
|
|
364
|
+
|
|
365
|
+
```tsx
|
|
366
|
+
import { Protect } from '@insforge/react';
|
|
367
|
+
|
|
368
|
+
function Dashboard() {
|
|
369
|
+
return (
|
|
370
|
+
<div>
|
|
371
|
+
<h1>Dashboard</h1>
|
|
372
|
+
|
|
373
|
+
{/* Simple protection */}
|
|
374
|
+
<Protect redirectTo="/sign-in">
|
|
375
|
+
<UserContent />
|
|
376
|
+
</Protect>
|
|
377
|
+
|
|
378
|
+
{/* Role-based protection */}
|
|
379
|
+
<Protect
|
|
380
|
+
redirectTo="/unauthorized"
|
|
381
|
+
condition={(user) => user.role === 'admin'}
|
|
382
|
+
>
|
|
383
|
+
<AdminPanel />
|
|
384
|
+
</Protect>
|
|
385
|
+
</div>
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
## TypeScript
|
|
393
|
+
|
|
394
|
+
Full TypeScript support with exported types:
|
|
395
|
+
|
|
396
|
+
```tsx
|
|
397
|
+
import type {
|
|
398
|
+
InsforgeUser,
|
|
399
|
+
SignInProps,
|
|
400
|
+
SignUpProps,
|
|
401
|
+
ForgotPasswordProps,
|
|
402
|
+
ResetPasswordProps,
|
|
403
|
+
VerifyEmailProps,
|
|
404
|
+
UserButtonProps,
|
|
405
|
+
ProtectProps,
|
|
406
|
+
ConditionalProps,
|
|
407
|
+
InsforgeCallbackProps,
|
|
408
|
+
SignInFormProps,
|
|
409
|
+
SignUpFormProps,
|
|
410
|
+
ForgotPasswordFormProps,
|
|
411
|
+
ResetPasswordFormProps,
|
|
412
|
+
VerifyEmailStatusProps,
|
|
413
|
+
AuthFormFieldProps,
|
|
414
|
+
OAuthProvider,
|
|
415
|
+
AuthConfig,
|
|
416
|
+
InsforgeProviderProps,
|
|
417
|
+
GetInsforgeRoutesConfig,
|
|
418
|
+
} from '@insforge/react';
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
|
|
423
|
+
## OAuth Providers
|
|
424
|
+
|
|
425
|
+
Built-in support for 10+ OAuth providers:
|
|
426
|
+
- Google
|
|
427
|
+
- GitHub
|
|
428
|
+
- Discord
|
|
429
|
+
- Apple
|
|
430
|
+
- Microsoft
|
|
431
|
+
- Facebook
|
|
432
|
+
- LinkedIn
|
|
433
|
+
- Instagram
|
|
434
|
+
- TikTok
|
|
435
|
+
- Spotify
|
|
436
|
+
- X (Twitter)
|
|
437
|
+
|
|
438
|
+
Providers are auto-detected from your backend configuration.
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## Validation Utilities
|
|
443
|
+
|
|
444
|
+
```tsx
|
|
445
|
+
import { emailSchema, cn } from '@insforge/react/lib';
|
|
446
|
+
|
|
447
|
+
// Validate email with Zod
|
|
448
|
+
const result = emailSchema.safeParse('user@example.com');
|
|
449
|
+
|
|
450
|
+
// Merge Tailwind classes
|
|
451
|
+
const className = cn('px-4 py-2', 'bg-blue-500', conditionalClass);
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
---
|
|
455
|
+
|
|
456
|
+
## Available Atomic Components
|
|
457
|
+
|
|
458
|
+
Low-level building blocks for complete customization:
|
|
459
|
+
|
|
460
|
+
- `<AuthBranding />` - Insforge branding footer
|
|
461
|
+
- `<AuthContainer />` - Main container wrapper
|
|
462
|
+
- `<AuthHeader />` - Title and subtitle display
|
|
463
|
+
- `<AuthErrorBanner />` - Error message display
|
|
464
|
+
- `<AuthFormField />` - Standard input field
|
|
465
|
+
- `<AuthPasswordField />` - Password input with features
|
|
466
|
+
- `<AuthPasswordStrengthIndicator />` - Password checklist
|
|
467
|
+
- `<AuthSubmitButton />` - Submit button with states
|
|
468
|
+
- `<AuthLink />` - Call-to-action link
|
|
469
|
+
- `<AuthDivider />` - Visual separator
|
|
470
|
+
- `<AuthOAuthButton />` - Single OAuth provider button
|
|
471
|
+
- `<AuthOAuthProviders />` - Smart OAuth grid
|
|
472
|
+
- `<AuthVerificationCodeInput />` - 6-digit OTP input
|
|
473
|
+
- `<AuthEmailVerificationStep />` - Email verification step with countdown and resend
|
|
474
|
+
|
|
475
|
+
---
|
|
476
|
+
|
|
477
|
+
## Support
|
|
478
|
+
|
|
479
|
+
- **Documentation**: https://docs.insforge.dev
|
|
480
|
+
- **GitHub Issues**: https://github.com/InsForge/InsForge/issues
|
|
481
|
+
- **Discord Community**: https://discord.com/invite/DvBtaEc9Jz
|
|
482
|
+
|
|
483
|
+
## License
|
|
484
|
+
|
|
485
|
+
MIT © Insforge
|