@sqrzro/auth 2.0.0-r19.9 → 4.0.0-alpha.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.
Files changed (81) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/.turbo/turbo-dev.log +45 -46
  3. package/dist/components/Auth/index.d.ts +4 -32
  4. package/dist/components/Auth/index.js +19 -40
  5. package/dist/components/AuthComponent/index.d.ts +6 -0
  6. package/dist/components/AuthComponent/index.js +21 -0
  7. package/dist/components/LoginForm/index.d.ts +2 -1
  8. package/dist/components/LoginForm/index.js +22 -3
  9. package/dist/components/LogoutButton/index.d.ts +1 -2
  10. package/dist/components/LogoutButton/index.js +5 -11
  11. package/dist/components/LogoutButton/server.d.ts +2 -0
  12. package/dist/components/LogoutButton/server.js +8 -0
  13. package/dist/components/MFAForm/index.js +1 -1
  14. package/dist/components/Password/index.d.ts +5 -0
  15. package/dist/components/Password/index.js +18 -0
  16. package/dist/components/PasswordForm/index.js +1 -1
  17. package/dist/components/PasswordResetForm/index.js +1 -1
  18. package/dist/forms/LoginForm/client.d.ts +2 -0
  19. package/dist/forms/LoginForm/client.js +13 -0
  20. package/dist/forms/LoginForm/index.d.ts +2 -0
  21. package/dist/forms/LoginForm/index.js +13 -0
  22. package/dist/forms/LoginForm/interfaces.d.ts +5 -0
  23. package/dist/forms/LoginForm/interfaces.js +1 -0
  24. package/dist/forms/LoginForm/server.d.ts +4 -0
  25. package/dist/forms/LoginForm/server.js +25 -0
  26. package/dist/forms/PasswordForm/client.d.ts +2 -0
  27. package/dist/forms/PasswordForm/client.js +13 -0
  28. package/dist/forms/PasswordForm/index.d.ts +2 -0
  29. package/dist/forms/PasswordForm/index.js +12 -0
  30. package/dist/forms/PasswordForm/interfaces.d.ts +3 -0
  31. package/dist/forms/PasswordForm/interfaces.js +1 -0
  32. package/dist/forms/PasswordForm/server.d.ts +4 -0
  33. package/dist/forms/PasswordForm/server.js +21 -0
  34. package/dist/forms/PasswordResetForm/client.d.ts +5 -0
  35. package/dist/forms/PasswordResetForm/client.js +14 -0
  36. package/dist/forms/PasswordResetForm/index.d.ts +5 -0
  37. package/dist/forms/PasswordResetForm/index.js +13 -0
  38. package/dist/forms/PasswordResetForm/interfaces.d.ts +4 -0
  39. package/dist/forms/PasswordResetForm/interfaces.js +1 -0
  40. package/dist/forms/PasswordResetForm/server.d.ts +4 -0
  41. package/dist/forms/PasswordResetForm/server.js +23 -0
  42. package/dist/handle-proxy.d.ts +4 -0
  43. package/dist/handle-proxy.js +17 -0
  44. package/dist/hooks/useLoginForm.js +3 -0
  45. package/dist/index.d.ts +1 -5
  46. package/dist/index.js +1 -2
  47. package/dist/interfaces.d.ts +10 -0
  48. package/dist/interfaces.js +1 -0
  49. package/dist/proxy.d.ts +0 -0
  50. package/dist/proxy.js +1 -0
  51. package/dist/server.d.ts +6 -1
  52. package/dist/server.js +12 -3
  53. package/package.json +14 -11
  54. package/src/components/Auth/index.tsx +31 -75
  55. package/src/components/LogoutButton/index.tsx +7 -19
  56. package/src/components/LogoutButton/server.ts +11 -0
  57. package/src/components/Password/index.tsx +26 -0
  58. package/src/forms/LoginForm/index.tsx +33 -0
  59. package/src/forms/LoginForm/interfaces.ts +5 -0
  60. package/src/forms/LoginForm/server.ts +33 -0
  61. package/src/forms/PasswordForm/index.tsx +24 -0
  62. package/src/forms/PasswordForm/interfaces.ts +3 -0
  63. package/src/forms/PasswordForm/server.ts +28 -0
  64. package/src/forms/PasswordResetForm/index.tsx +29 -0
  65. package/src/forms/PasswordResetForm/interfaces.ts +4 -0
  66. package/src/forms/PasswordResetForm/server.ts +30 -0
  67. package/src/handle-proxy.ts +23 -0
  68. package/src/index.ts +1 -7
  69. package/src/interfaces.ts +10 -0
  70. package/tsconfig.json +6 -5
  71. package/src/components/LoginForm/index.tsx +0 -44
  72. package/src/components/MFAForm/index.tsx +0 -47
  73. package/src/components/MFAPage/index.tsx +0 -54
  74. package/src/components/MFASetup/index.tsx +0 -43
  75. package/src/components/MFASetupForm/index.tsx +0 -78
  76. package/src/components/PasswordForm/index.tsx +0 -113
  77. package/src/components/PasswordPage/index.tsx +0 -20
  78. package/src/components/PasswordResetForm/index.tsx +0 -45
  79. package/src/hooks/useLoginForm.ts +0 -33
  80. package/src/hooks/useMFAForm.ts +0 -56
  81. package/src/server.ts +0 -100
package/src/index.ts CHANGED
@@ -1,10 +1,4 @@
1
1
  export { default as Auth } from './components/Auth';
2
- export type { AuthClassNames, AuthProps } from './components/Auth';
3
-
4
- export type { MFASetupProps } from './components/MFASetup';
5
- export { default as MFASetup } from './components/MFASetup';
6
-
7
2
  export { default as LogoutButton } from './components/LogoutButton';
8
3
 
9
- export type { UseMFAFormArgs, UseMFAFormReturn } from './hooks/useMFAForm';
10
- export { default as useMFAForm } from './hooks/useMFAForm';
4
+ export { default as handleProxy } from './handle-proxy';
@@ -0,0 +1,10 @@
1
+ export interface AuthClassNames {
2
+ actions: string;
3
+ footer: string;
4
+ form: string;
5
+ link: string;
6
+ logo: string;
7
+ root: string;
8
+ panel: string;
9
+ title: string;
10
+ }
package/tsconfig.json CHANGED
@@ -4,15 +4,16 @@
4
4
  "declaration": true,
5
5
  "esModuleInterop": true,
6
6
  "importHelpers": true,
7
+ "lib": ["ESNext"],
7
8
  "jsx": "react-jsx",
8
- "lib": ["DOM", "ESNext"],
9
9
  "module": "ESNext",
10
- "moduleResolution": "node",
10
+ "moduleResolution": "bundler",
11
11
  "outDir": "dist",
12
12
  "resolveJsonModule": true,
13
13
  "skipLibCheck": true,
14
- "target": "ESNext"
14
+ "strict": true,
15
+ "target": "esnext"
15
16
  },
16
- "include": ["next-env.d.ts", "src/**/*"],
17
- "exclude": ["node_modules"]
17
+ "include": ["**/*.ts"],
18
+ "exclude": ["dist", "./*.d.ts", "node_modules"]
18
19
  }
@@ -1,44 +0,0 @@
1
- 'use client';
2
-
3
- import { Fragment } from 'react';
4
-
5
- import { Form, FormSubmit, Link, PasswordFormField, TextFormField, tw } from '@sqrzro/components';
6
-
7
- import useLoginForm from '../../hooks/useLoginForm';
8
- import { submitLoginForm } from '../../server';
9
-
10
- import type { AuthClassNames } from '../Auth';
11
-
12
- export interface LoginFormProps {
13
- classNames?: Partial<AuthClassNames>;
14
- searchParams: { r?: string };
15
- }
16
-
17
- function LoginForm({ classNames, searchParams }: Readonly<LoginFormProps>): React.ReactElement {
18
- const { fieldProps, formData, formProps, isLoading } = useLoginForm(submitLoginForm, {
19
- redirect: searchParams.r,
20
- });
21
-
22
- return (
23
- <Fragment>
24
- <h1 className={tw('text-center', classNames?.title)}>Sign in to continue</h1>
25
- <Form {...formProps} classNames={{ root: classNames?.form }}>
26
- <TextFormField {...fieldProps('email')} hasAssistiveError />
27
- <PasswordFormField {...fieldProps('password')} hasAssistiveError />
28
- <div className={tw(classNames?.actions)}>
29
- <FormSubmit isLoading={isLoading}>Sign In</FormSubmit>
30
- </div>
31
- <footer className={tw('text-center', classNames?.footer)}>
32
- <Link
33
- className={classNames?.link}
34
- href={`/auth/password${formData.email ? `?email=${formData.email}` : ''}`}
35
- >
36
- Forgot Password?
37
- </Link>
38
- </footer>
39
- </Form>
40
- </Fragment>
41
- );
42
- }
43
-
44
- export default LoginForm;
@@ -1,47 +0,0 @@
1
- 'use client';
2
-
3
- import { CodeFormField, Form, FormSubmit } from '@sqrzro/components';
4
-
5
- import useMFAForm from '../../hooks/useMFAForm';
6
- import { submitMFAForm } from '../../server';
7
-
8
- import type { AuthClassNames } from '../Auth';
9
- import { useEffect, useState } from 'react';
10
-
11
- export interface MFAFormProps {
12
- classNames?: Partial<AuthClassNames>;
13
- searchParams: { r?: string };
14
- }
15
-
16
- function MFAForm({ classNames, searchParams }: Readonly<MFAFormProps>): React.ReactElement {
17
- const [delayedKey, setDelayedKey] = useState(0);
18
-
19
- const { formProps, fieldProps, isLoading, key, submitForm } = useMFAForm(submitMFAForm, {
20
- redirect: searchParams.r,
21
- });
22
-
23
- useEffect(() => {
24
- if (!isLoading) {
25
- setDelayedKey(key);
26
- }
27
- }, [isLoading, key]);
28
-
29
- return (
30
- <Form {...formProps} classNames={{ root: classNames?.form }}>
31
- <CodeFormField
32
- key={delayedKey}
33
- {...fieldProps('token')}
34
- isDisabled={isLoading}
35
- onFinalChange={submitForm}
36
- hasAssistiveError
37
- hasAssistiveLabel
38
- isAutoFocus
39
- />
40
- <div className="sr-only">
41
- <FormSubmit>Verify</FormSubmit>
42
- </div>
43
- </Form>
44
- );
45
- }
46
-
47
- export default MFAForm;
@@ -1,54 +0,0 @@
1
- import { Fragment } from 'react';
2
-
3
- import { tw } from '@sqrzro/components';
4
- import { notFound } from 'next/navigation';
5
-
6
- import type { AuthClassNames } from '../Auth';
7
- import MFAForm from '../MFAForm';
8
- import MFASetup from '../MFASetup';
9
-
10
- import { checkMFAEnabled, checkUserHasMFA, getSessionUser } from '../../server';
11
- import LogoutButton from '../LogoutButton';
12
-
13
- export interface MFAPageProps {
14
- classNames?: Partial<AuthClassNames>;
15
- searchParams: { r?: string };
16
- }
17
-
18
- async function MFAPage({
19
- classNames,
20
- searchParams,
21
- }: Readonly<MFAPageProps>): Promise<React.ReactElement> {
22
- if (!(await checkMFAEnabled())) {
23
- return notFound();
24
- }
25
-
26
- const user = await getSessionUser();
27
-
28
- if (!user) {
29
- return <div>Error</div>;
30
- }
31
-
32
- const userHasMFA = await checkUserHasMFA(user);
33
-
34
- if (!userHasMFA) {
35
- return <MFASetup classNames={classNames} searchParams={searchParams} />;
36
- }
37
-
38
- return (
39
- <Fragment>
40
- <h1 className={tw('text-center', classNames?.title)}>Multi-Factor Authentication</h1>
41
- <p className="text-center">
42
- To confirm your identity, enter the 6-digit code listed in your authentication app:
43
- </p>
44
- <MFAForm classNames={classNames} searchParams={searchParams} />
45
- <footer className={tw('text-center', classNames?.footer)}>
46
- <LogoutButton>
47
- <span className={classNames?.link}>Back</span>
48
- </LogoutButton>
49
- </footer>
50
- </Fragment>
51
- );
52
- }
53
-
54
- export default MFAPage;
@@ -1,43 +0,0 @@
1
- import { Fragment } from 'react';
2
-
3
- import { tw } from '@sqrzro/components';
4
-
5
- import { generateMFA, getSessionUser } from '../../server';
6
-
7
- import type { AuthClassNames } from '../Auth';
8
- import MFASetupForm from '../MFASetupForm';
9
-
10
- export interface MFASetupProps {
11
- classNames?: Partial<AuthClassNames>;
12
- searchParams: { r?: string };
13
- }
14
-
15
- async function MFASetup({
16
- classNames,
17
- searchParams,
18
- }: Readonly<MFASetupProps>): Promise<React.ReactElement> {
19
- if (!process.env.APP_NAME) {
20
- throw new Error('MFA secret could not be generated because APP_NAME is not defined');
21
- }
22
-
23
- const user = await getSessionUser();
24
-
25
- if (!user) {
26
- return <div>Error</div>;
27
- }
28
-
29
- const url = await generateMFA(process.env.APP_NAME, user.email);
30
-
31
- if (!url) {
32
- return <div>Error</div>;
33
- }
34
-
35
- return (
36
- <Fragment>
37
- <h1 className={tw('', classNames?.title)}>Multi-Factor Authentication</h1>
38
- <MFASetupForm classNames={classNames} searchParams={searchParams} url={url} />
39
- </Fragment>
40
- );
41
- }
42
-
43
- export default MFASetup;
@@ -1,78 +0,0 @@
1
- 'use client';
2
-
3
- import { Fragment, useState } from 'react';
4
-
5
- import { Button, Link, tw } from '@sqrzro/components';
6
-
7
- import type { AuthClassNames } from '../Auth';
8
- import LogoutButton from '../LogoutButton';
9
- import MFAForm from '../MFAForm';
10
-
11
- export interface MFASetupFormProps {
12
- classNames?: Partial<AuthClassNames>;
13
- searchParams: { r?: string };
14
- url: string;
15
- }
16
-
17
- function MFASetupForm({
18
- classNames,
19
- searchParams,
20
- url,
21
- }: Readonly<MFASetupFormProps>): React.ReactElement | null {
22
- const [step, setStep] = useState(1);
23
-
24
- function nextStep(): void {
25
- setStep(2);
26
- }
27
-
28
- function previousStep(event: React.MouseEvent): void {
29
- setStep(1);
30
- }
31
-
32
- if (step === 1) {
33
- return (
34
- <div className={tw(classNames?.form)}>
35
- <p>
36
- You&#39;ll need to setup an additional authentication step before you can
37
- continue.
38
- </p>
39
- <figure className="flex justify-center rounded border p-4">
40
- <img alt="qrcode" src={url} width="147" />
41
- </figure>
42
- <p>
43
- <strong>Step 1:</strong> Scan the QR code above in an authentication app like
44
- Google Authenticator or Authy.
45
- </p>
46
- <Button onClick={nextStep} variant="primary" isFullWidth>
47
- Continue
48
- </Button>
49
- <div className="text-center">
50
- <LogoutButton>
51
- <span className={classNames?.link}>Back</span>
52
- </LogoutButton>
53
- </div>
54
- </div>
55
- );
56
- }
57
-
58
- if (step === 2) {
59
- return (
60
- <div className={tw(classNames?.form)}>
61
- <p>
62
- <strong>Step 2:</strong> To confirm your identity, enter the 6-digit code listed
63
- in your authentication app:
64
- </p>
65
- <MFAForm classNames={classNames} searchParams={searchParams} />
66
- <div className="text-center">
67
- <button className={classNames?.link} onClick={previousStep} type="button">
68
- Scan QR code again
69
- </button>
70
- </div>
71
- </div>
72
- );
73
- }
74
-
75
- return null;
76
- }
77
-
78
- export default MFASetupForm;
@@ -1,113 +0,0 @@
1
- 'use client';
2
-
3
- import { Fragment, useState } from 'react';
4
-
5
- import { Form, FormSubmit, Link, TextFormField, tw } from '@sqrzro/components';
6
- import { useForm } from '@sqrzro/hooks';
7
-
8
- import { submitPasswordForm } from '../../server';
9
-
10
- import type { AuthClassNames } from '../Auth';
11
-
12
- interface PasswordFormFields {
13
- email: string;
14
- }
15
-
16
- interface PasswordFormProps {
17
- classNames?: Partial<AuthClassNames>;
18
- email?: string;
19
- }
20
-
21
- function PasswordForm({ classNames, email }: Readonly<PasswordFormProps>): React.ReactElement {
22
- const [sentCount, setSentCount] = useState(0);
23
-
24
- const { fieldProps, formData, formProps, isLoading, setFormData, submitForm } = useForm<
25
- PasswordFormFields,
26
- boolean
27
- >({
28
- defaults: { email },
29
- onSubmit: submitPasswordForm,
30
- onSuccess: () => {
31
- setSentCount(sentCount + 1);
32
- },
33
- toasts: { success: false },
34
- });
35
-
36
- function handleResend(event: React.MouseEvent<HTMLAnchorElement>): void {
37
- event.preventDefault();
38
- submitForm();
39
- }
40
-
41
- function handleReset(event: React.MouseEvent<HTMLAnchorElement>): void {
42
- event.preventDefault();
43
-
44
- setFormData('email', '');
45
- setSentCount(0);
46
- }
47
-
48
- return (
49
- <Fragment>
50
- <div className={tw(sentCount === 0 ? 'block' : 'hidden')}>
51
- <Form {...formProps} classNames={{ root: classNames?.form }}>
52
- <h1 className={classNames?.title}>Reset Your Password</h1>
53
- <p className="text-sm">
54
- Enter the email address associated with your account and we&#39;ll send you
55
- a link to reset your password.
56
- </p>
57
- <TextFormField {...fieldProps('email')} type="email" hasAssistiveLabel />
58
- <div className={tw(classNames?.actions)}>
59
- <FormSubmit isLoading={isLoading}>Send Email</FormSubmit>
60
- </div>
61
- <footer className={tw('text-center', classNames?.footer)}>
62
- <Link className={classNames?.link} href="/auth/login">
63
- Back
64
- </Link>
65
- </footer>
66
- </Form>
67
- </div>
68
-
69
- <div className={tw(sentCount > 0 ? 'flex' : 'hidden')}>
70
- <div className={tw(classNames?.form)}>
71
- <h1 className={classNames?.title}>Check Your Email</h1>
72
- {sentCount === 1 ? (
73
- <Fragment>
74
- <p className="text-sm">
75
- If <strong>{formData.email}</strong> matches an email we have on
76
- file, then we&#39;ve sent you an email containing further
77
- instructions for resetting your password.
78
- </p>
79
- <p className="text-sm">
80
- If you haven&#39;t received an email in 5 minutes, check your spam,{' '}
81
- <Link className={classNames?.link} onClick={handleResend}>
82
- resend
83
- </Link>
84
- , or{' '}
85
- <Link className={classNames?.link} onClick={handleReset}>
86
- try a different email address
87
- </Link>
88
- .
89
- </p>
90
- </Fragment>
91
- ) : (
92
- <Fragment>
93
- <p className="text-sm">
94
- We&#39;ve resent password reset instructions to{' '}
95
- <strong>{formData.email}</strong>, if it is an email we have on
96
- file.
97
- </p>
98
- <p className="text-sm">
99
- Please check again. If you still haven&#39;t received an email,{' '}
100
- <Link className={classNames?.link} onClick={handleReset}>
101
- try a different email address
102
- </Link>
103
- .
104
- </p>
105
- </Fragment>
106
- )}
107
- </div>
108
- </div>
109
- </Fragment>
110
- );
111
- }
112
-
113
- export default PasswordForm;
@@ -1,20 +0,0 @@
1
- import type { AuthClassNames } from '../Auth';
2
- import PasswordForm from '../PasswordForm';
3
- import PasswordResetForm from '../PasswordResetForm';
4
-
5
- interface PasswordPageProps {
6
- classNames?: Partial<AuthClassNames>;
7
- searchParams: { email?: string; token?: string };
8
- }
9
-
10
- function PasswordPage({
11
- classNames,
12
- searchParams,
13
- }: Readonly<PasswordPageProps>): React.ReactElement {
14
- if (searchParams.token) {
15
- return <PasswordResetForm classNames={classNames} token={searchParams.token} />;
16
- }
17
- return <PasswordForm classNames={classNames} email={searchParams.email} />;
18
- }
19
-
20
- export default PasswordPage;
@@ -1,45 +0,0 @@
1
- 'use client';
2
-
3
- import { Form, FormSubmit, PasswordFormField } from '@sqrzro/components';
4
- import { useForm } from '@sqrzro/hooks';
5
- import { useRouter } from 'next/navigation';
6
-
7
- import { submitPasswordResetForm } from '../../server';
8
-
9
- import type { AuthClassNames } from '../Auth';
10
-
11
- interface PasswordResetFormProps {
12
- classNames?: Partial<AuthClassNames>;
13
- token: string;
14
- }
15
-
16
- function PasswordResetForm({
17
- classNames,
18
- token,
19
- }: Readonly<PasswordResetFormProps>): React.ReactElement {
20
- const router = useRouter();
21
-
22
- const { fieldProps, formProps, isLoading } = useForm({
23
- defaults: { token },
24
- hiddenFields: ['token'],
25
- onSubmit: submitPasswordResetForm,
26
- onSuccess: (response) => {
27
- router.push(response || '/');
28
- },
29
- toasts: { success: false },
30
- });
31
-
32
- return (
33
- <Form {...formProps} classNames={{ root: classNames?.form }}>
34
- <h1 className={classNames?.title}>Reset Your Password</h1>
35
- <div className="relative">
36
- <PasswordFormField {...fieldProps('password', 'New Password')} />
37
- </div>
38
- <div className="mt-8">
39
- <FormSubmit isLoading={isLoading}>Reset Password</FormSubmit>
40
- </div>
41
- </Form>
42
- );
43
- }
44
-
45
- export default PasswordResetForm;
@@ -1,33 +0,0 @@
1
- 'use client';
2
-
3
- import { useForm } from '@sqrzro/hooks';
4
- import type { UseFormReturn } from '@sqrzro/hooks';
5
-
6
- import type { Errorable } from '@sqrzro/interfaces';
7
-
8
- interface NextRedirect {
9
- NEXT_REDIRECT: string;
10
- }
11
-
12
- export interface LoginFormFields {
13
- email: string;
14
- password: string;
15
- redirect: string;
16
- }
17
-
18
- interface UseLoginFormOptions {
19
- redirect?: string;
20
- }
21
-
22
- function useLoginForm(
23
- onSubmit: (formData: LoginFormFields) => Promise<Errorable<NextRedirect>>,
24
- { redirect }: UseLoginFormOptions = {}
25
- ): UseFormReturn<LoginFormFields> {
26
- return useForm({
27
- defaults: { redirect },
28
- onSubmit,
29
- toasts: { validation: 'Incorrect email or password', success: false },
30
- });
31
- }
32
-
33
- export default useLoginForm;
@@ -1,56 +0,0 @@
1
- 'use client';
2
-
3
- import { useEffect, useState } from 'react';
4
-
5
- import { useForm } from '@sqrzro/hooks';
6
- import type { UseFormArgs, UseFormReturn } from '@sqrzro/hooks';
7
- import { Errorable } from '@sqrzro/interfaces';
8
-
9
- interface NextRedirect {
10
- NEXT_REDIRECT: string;
11
- }
12
-
13
- interface MFAFormFields {
14
- redirect: string;
15
- token: string;
16
- }
17
-
18
- export interface UseMFAFormArgs {
19
- onSubmit: UseFormArgs<MFAFormFields, void>['onSubmit'];
20
- }
21
-
22
- export interface UseMFAFormReturn extends UseFormReturn<MFAFormFields> {
23
- key: number;
24
- }
25
-
26
- interface UseMFAFormOptions {
27
- redirect?: string;
28
- }
29
-
30
- function useLoginForm(
31
- onSubmit: (formData: MFAFormFields) => Promise<Errorable<NextRedirect>>,
32
- { redirect }: UseMFAFormOptions = {}
33
- ): UseMFAFormReturn {
34
- const [errorCount, setErrorCount] = useState(0);
35
-
36
- const form = useForm({
37
- defaults: { redirect },
38
- onSubmit,
39
- onValidationError: () => {
40
- setErrorCount((count) => count + 1);
41
- },
42
- toasts: {
43
- success: false,
44
- validation:
45
- "There seems to be an issue with the code you've entered. Please try again.",
46
- },
47
- });
48
-
49
- useEffect(() => {
50
- form.resetForm();
51
- }, [errorCount]);
52
-
53
- return { ...form, key: errorCount };
54
- }
55
-
56
- export default useLoginForm;
package/src/server.ts DELETED
@@ -1,100 +0,0 @@
1
- 'use server';
2
-
3
- import {
4
- handleLoginForm,
5
- handleLogout,
6
- handleMFAForm,
7
- handlePasswordForm,
8
- handlePasswordResetWithTokenForm,
9
- checkUserHasMFA as serverCheckUserHasMFA,
10
- generateMFA as serverGenerateMFA,
11
- getSessionUser as serverGetSessionUser,
12
- checkMFAEnabled as syncCheckMFAEnabled,
13
- } from '@sqrzro/server/auth';
14
- import type { LoginFormFields, UserObject } from '@sqrzro/server/auth';
15
- import type { NextRedirect } from '@sqrzro/server/forms';
16
- import type { Errorable } from '@sqrzro/interfaces';
17
-
18
- export type { ScopeObject } from '@sqrzro/server/auth';
19
-
20
- interface AuthEventObject {
21
- login?: () => Promise<void>;
22
- password?: (email: string, token: string) => Promise<boolean>;
23
- }
24
-
25
- const authEvents: AuthEventObject = {};
26
-
27
- export async function registerAuthEvents(events: AuthEventObject): Promise<void> {
28
- if (events.login) {
29
- authEvents.login = events.login;
30
- }
31
- if (events.password) {
32
- authEvents.password = events.password;
33
- }
34
- return Promise.resolve();
35
- }
36
-
37
- /*
38
- * Functions re-exported from @sqrzro/server/auth
39
- *
40
- * NextJS may complain about these functions not being async if they are exported directly from the
41
- * @sqrzro/server/auth module, so we re-export them here to be on the safe side.
42
- */
43
-
44
- export async function checkUserHasMFA(user: UserObject): Promise<boolean> {
45
- return serverCheckUserHasMFA(user);
46
- }
47
-
48
- export async function generateMFA(name: string, email?: string): Promise<string | null> {
49
- return serverGenerateMFA(name, email);
50
- }
51
-
52
- export async function getSessionUser(): Promise<UserObject | null> {
53
- return serverGetSessionUser();
54
- }
55
-
56
- // This function is synchronous, so we need to wrap it in a promise so it can be exported properly.
57
- export async function checkMFAEnabled(): Promise<boolean> {
58
- return Promise.resolve(syncCheckMFAEnabled());
59
- }
60
-
61
- interface MFAFormFields {
62
- token: string;
63
- }
64
-
65
- interface PasswordFormFields {
66
- email: string;
67
- }
68
-
69
- interface PasswordResetFormFields {
70
- password: string;
71
- token: string;
72
- }
73
-
74
- export async function submitLoginForm(formData: LoginFormFields): Promise<Errorable<NextRedirect>> {
75
- return handleLoginForm(formData, authEvents.login);
76
- }
77
-
78
- export async function submitMFAForm(formData: MFAFormFields): Promise<Errorable<NextRedirect>> {
79
- return handleMFAForm(formData);
80
- }
81
-
82
- async function sendPasswordResetMail(email: string, token: string): Promise<boolean> {
83
- return authEvents.password?.(email, token) || false;
84
- }
85
-
86
- export async function submitPasswordForm(
87
- formData: PasswordFormFields
88
- ): Promise<Errorable<boolean>> {
89
- return handlePasswordForm(formData, sendPasswordResetMail);
90
- }
91
-
92
- export async function submitPasswordResetForm(
93
- formData: PasswordResetFormFields
94
- ): Promise<Errorable<string>> {
95
- return handlePasswordResetWithTokenForm(formData);
96
- }
97
-
98
- export async function logout(): Promise<void> {
99
- return handleLogout();
100
- }