@sqrzro/auth 2.0.0-r19.8 → 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 +71 -0
  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
@@ -1,5 +1,5 @@
1
1
 
2
2
  
3
- > @sqrzro/auth@2.0.0-r19.7 build /Users/richard/Sites/sqrzro/packages/auth
4
- > tsc -p tsconfig.json
3
+ > @sqrzro/auth@4.0.0-alpha.0 build /Users/richard/Sites/@sqrzro/sqrzro/packages/auth
4
+ > tsc
5
5
 
@@ -0,0 +1,71 @@
1
+
2
+ > @sqrzro/auth@2.0.0-r19.14 dev /Users/richard/Sites/@sqrzro/sqrzro/packages/auth
3
+ > tsc --watch
4
+
5
+ [10:06:07 AM] Starting compilation in watch mode...
6
+
7
+ [10:06:11 AM] Found 0 errors. Watching for file changes.
8
+
9
+ [10:06:14 AM] File change detected. Starting incremental compilation...
10
+
11
+ src/components/LogoutButton/server.ts:3:31 - error TS7016: Could not find a declaration file for module '@sqrzro/server/auth'. '/Users/richard/Sites/@sqrzro/sqrzro/packages/server/dist/auth/index.js' implicitly has an 'any' type.
12
+ Try `npm i --save-dev @types/sqrzro__server` if it exists or add a new declaration (.d.ts) file containing `declare module '@sqrzro/server/auth';`
13
+
14
+ 3 import { deleteSession } from '@sqrzro/server/auth';
15
+    ~~~~~~~~~~~~~~~~~~~~~
16
+
17
+ src/components/Password/index.tsx:1:31 - error TS7016: Could not find a declaration file for module '@sqrzro/server/auth'. '/Users/richard/Sites/@sqrzro/sqrzro/packages/server/dist/auth/index.js' implicitly has an 'any' type.
18
+ Try `npm i --save-dev @types/sqrzro__server` if it exists or add a new declaration (.d.ts) file containing `declare module '@sqrzro/server/auth';`
19
+
20
+ 1 import { validateReset } from '@sqrzro/server/auth';
21
+    ~~~~~~~~~~~~~~~~~~~~~
22
+
23
+ src/forms/LoginForm/server.ts:3:45 - error TS7016: Could not find a declaration file for module '@sqrzro/server/auth'. '/Users/richard/Sites/@sqrzro/sqrzro/packages/server/dist/auth/index.js' implicitly has an 'any' type.
24
+ Try `npm i --save-dev @types/sqrzro__server` if it exists or add a new declaration (.d.ts) file containing `declare module '@sqrzro/server/auth';`
25
+
26
+ 3 import { createSession, validateUser } from '@sqrzro/server/auth';
27
+    ~~~~~~~~~~~~~~~~~~~~~
28
+
29
+ src/forms/LoginForm/server.ts:4:42 - error TS7016: Could not find a declaration file for module '@sqrzro/server/forms'. '/Users/richard/Sites/@sqrzro/sqrzro/packages/server/dist/forms/index.js' implicitly has an 'any' type.
30
+ Try `npm i --save-dev @types/sqrzro__server` if it exists or add a new declaration (.d.ts) file containing `declare module '@sqrzro/server/forms';`
31
+
32
+ 4 import { FormResponse, submitForm } from '@sqrzro/server/forms';
33
+    ~~~~~~~~~~~~~~~~~~~~~~
34
+
35
+ src/forms/PasswordForm/server.ts:3:29 - error TS7016: Could not find a declaration file for module '@sqrzro/server/auth'. '/Users/richard/Sites/@sqrzro/sqrzro/packages/server/dist/auth/index.js' implicitly has an 'any' type.
36
+ Try `npm i --save-dev @types/sqrzro__server` if it exists or add a new declaration (.d.ts) file containing `declare module '@sqrzro/server/auth';`
37
+
38
+ 3 import { createReset } from '@sqrzro/server/auth';
39
+    ~~~~~~~~~~~~~~~~~~~~~
40
+
41
+ src/forms/PasswordForm/server.ts:4:42 - error TS7016: Could not find a declaration file for module '@sqrzro/server/forms'. '/Users/richard/Sites/@sqrzro/sqrzro/packages/server/dist/forms/index.js' implicitly has an 'any' type.
42
+ Try `npm i --save-dev @types/sqrzro__server` if it exists or add a new declaration (.d.ts) file containing `declare module '@sqrzro/server/forms';`
43
+
44
+ 4 import { FormResponse, submitForm } from '@sqrzro/server/forms';
45
+    ~~~~~~~~~~~~~~~~~~~~~~
46
+
47
+ src/forms/PasswordResetForm/server.ts:3:41 - error TS7016: Could not find a declaration file for module '@sqrzro/server/auth'. '/Users/richard/Sites/@sqrzro/sqrzro/packages/server/dist/auth/index.js' implicitly has an 'any' type.
48
+ Try `npm i --save-dev @types/sqrzro__server` if it exists or add a new declaration (.d.ts) file containing `declare module '@sqrzro/server/auth';`
49
+
50
+ 3 import { updatePasswordWithToken } from '@sqrzro/server/auth';
51
+    ~~~~~~~~~~~~~~~~~~~~~
52
+
53
+ src/forms/PasswordResetForm/server.ts:4:42 - error TS7016: Could not find a declaration file for module '@sqrzro/server/forms'. '/Users/richard/Sites/@sqrzro/sqrzro/packages/server/dist/forms/index.js' implicitly has an 'any' type.
54
+ Try `npm i --save-dev @types/sqrzro__server` if it exists or add a new declaration (.d.ts) file containing `declare module '@sqrzro/server/forms';`
55
+
56
+ 4 import { FormResponse, submitForm } from '@sqrzro/server/forms';
57
+    ~~~~~~~~~~~~~~~~~~~~~~
58
+
59
+ src/handle-proxy.ts:1:33 - error TS7016: Could not find a declaration file for module '@sqrzro/server/auth'. '/Users/richard/Sites/@sqrzro/sqrzro/packages/server/dist/auth/index.js' implicitly has an 'any' type.
60
+ Try `npm i --save-dev @types/sqrzro__server` if it exists or add a new declaration (.d.ts) file containing `declare module '@sqrzro/server/auth';`
61
+
62
+ 1 import { validateSession } from '@sqrzro/server/auth';
63
+    ~~~~~~~~~~~~~~~~~~~~~
64
+
65
+ [10:06:14 AM] Found 9 errors. Watching for file changes.
66
+
67
+ [10:06:16 AM] File change detected. Starting incremental compilation...
68
+
69
+ [10:06:17 AM] Found 0 errors. Watching for file changes.
70
+
71
+  ELIFECYCLE  Command failed.
@@ -1,34 +1,6 @@
1
- import type { ClassNameProps } from '@sqrzro/components';
2
- import type { ScopeObject } from '../../server';
3
- export interface AuthClassNames {
4
- actions: string;
5
- footer: string;
6
- form: string;
7
- link: string;
8
- logo: string;
9
- root: string;
10
- panel: string;
11
- title: string;
1
+ interface AuthProps {
2
+ params: Promise<Record<string, string>>;
3
+ searchParams: Promise<Record<string, string>>;
12
4
  }
13
- export interface AuthProps extends ClassNameProps<AuthClassNames> {
14
- logo?: React.ReactElement;
15
- onLogin?: () => Promise<void>;
16
- onPassword?: (email: string, token: string) => Promise<boolean>;
17
- params: {
18
- auth: string[];
19
- };
20
- scopes?: Partial<ScopeObject>;
21
- searchParams: {
22
- email?: string;
23
- r?: string;
24
- token?: string;
25
- };
26
- }
27
- /**
28
- *
29
- * A note on `classNames`: As `Auth` needs to run on the server (as some of its children require
30
- * sessions etc), using the `getClassNames` pattern won't work, as it currently only works for
31
- * client components. So we have to pass the classNames directly to the component.
32
- */
33
- declare function Auth({ classNames, logo, onLogin, onPassword, params: { auth }, searchParams, }: Readonly<AuthProps>): Promise<React.ReactElement>;
5
+ declare function Auth({ params, searchParams }: Readonly<AuthProps>): React.ReactElement;
34
6
  export default Auth;
@@ -1,46 +1,25 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { tw } from '@sqrzro/components';
2
+ import { Suspense } from 'react';
3
3
  import { notFound } from 'next/navigation';
4
- import LoginForm from '../LoginForm';
5
- import MFAPage from '../MFAPage';
6
- import PasswordPage from '../PasswordPage';
7
- import { registerAuthEvents } from '../../server';
8
- /**
9
- * To make it easier for consumers to use Auth in their projects, this auth component uses a
10
- * Catch-All Segment to handle the rendering of all Auth pages. This function is used to determine
11
- * which page to render based on the route.
12
- *
13
- * More information on Catch-All Segments can be found here:
14
- * https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes#catch-all-segments
15
- *
16
- * @param route
17
- * @param props
18
- * @returns
19
- */
20
- function getPage(route, props) {
21
- switch (route) {
22
- case 'mfa':
23
- return _jsx(MFAPage, { ...props });
24
- case 'password':
25
- return _jsx(PasswordPage, { ...props });
26
- default:
27
- return _jsx(LoginForm, { ...props });
28
- }
29
- }
30
- /**
31
- *
32
- * A note on `classNames`: As `Auth` needs to run on the server (as some of its children require
33
- * sessions etc), using the `getClassNames` pattern won't work, as it currently only works for
34
- * client components. So we have to pass the classNames directly to the component.
35
- */
36
- async function Auth({ classNames, logo, onLogin, onPassword, params: { auth }, searchParams, }) {
37
- if (auth.length > 1) {
4
+ import LoginForm from '../../forms/LoginForm';
5
+ import Password from '../Password';
6
+ async function AuthComponent({ params, searchParams, }) {
7
+ const awaitedParams = await params;
8
+ if (!Array.isArray(awaitedParams.auth) || awaitedParams.auth.length !== 1) {
38
9
  return notFound();
39
10
  }
40
- await registerAuthEvents({ login: onLogin, password: onPassword });
41
- return (_jsxs("div", { className: tw(classNames?.root), children: [_jsx("div", { className: tw(classNames?.logo), children: logo }), _jsx("div", { className: tw(classNames?.panel), children: getPage(auth[0], {
42
- classNames,
43
- searchParams,
44
- }) })] }));
11
+ if (awaitedParams.auth[0] === 'login') {
12
+ return _jsx(LoginForm, {});
13
+ }
14
+ if (awaitedParams.auth[0] === 'mfa') {
15
+ return _jsx("div", { children: "[MFA NOT DONE]" });
16
+ }
17
+ if (awaitedParams.auth[0] === 'password') {
18
+ return _jsx(Password, { searchParams: searchParams });
19
+ }
20
+ return notFound();
21
+ }
22
+ function Auth({ params, searchParams }) {
23
+ return (_jsxs("div", { children: ["AUTH PAGE HEADER", _jsx(Suspense, { children: _jsx(AuthComponent, { params: params, searchParams: searchParams }) })] }));
45
24
  }
46
25
  export default Auth;
@@ -0,0 +1,6 @@
1
+ interface AuthComponentProps {
2
+ params: Promise<Record<string, string>>;
3
+ searchParams: Promise<Record<string, string>>;
4
+ }
5
+ declare function AuthComponent({ params, searchParams, }: Readonly<AuthComponentProps>): Promise<React.ReactElement>;
6
+ export default AuthComponent;
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { notFound } from 'next/navigation';
3
+ import LoginForm from '../../forms/LoginForm';
4
+ import Password from '../Password';
5
+ async function AuthComponent({ params, searchParams, }) {
6
+ const awaitedParams = await params;
7
+ if (!Array.isArray(awaitedParams.auth) || awaitedParams.auth.length !== 1) {
8
+ return notFound();
9
+ }
10
+ if (awaitedParams.auth[0] === 'login') {
11
+ return _jsx(LoginForm, {});
12
+ }
13
+ if (awaitedParams.auth[0] === 'mfa') {
14
+ return _jsx("div", { children: "[MFA NOT DONE]" });
15
+ }
16
+ if (awaitedParams.auth[0] === 'password') {
17
+ return _jsx(Password, { searchParams: searchParams });
18
+ }
19
+ return notFound();
20
+ }
21
+ export default AuthComponent;
@@ -3,7 +3,8 @@ export interface LoginFormProps {
3
3
  classNames?: Partial<AuthClassNames>;
4
4
  searchParams: {
5
5
  r?: string;
6
+ session?: string;
6
7
  };
7
8
  }
8
- declare function LoginForm({ classNames, searchParams }: Readonly<LoginFormProps>): React.ReactElement;
9
+ declare function LoginForm({ classNames, searchParams }: Readonly<LoginFormProps>): React.ReactElement | null;
9
10
  export default LoginForm;
@@ -1,13 +1,32 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { Fragment } from 'react';
3
+ import { Fragment, useEffect } from 'react';
4
+ import { usePathname } from 'next/navigation';
4
5
  import { Form, FormSubmit, Link, PasswordFormField, TextFormField, tw } from '@sqrzro/components';
5
6
  import useLoginForm from '../../hooks/useLoginForm';
6
- import { submitLoginForm } from '../../server';
7
+ import { setUserSession, submitLoginForm } from '../../server';
7
8
  function LoginForm({ classNames, searchParams }) {
9
+ const pathname = usePathname();
8
10
  const { fieldProps, formData, formProps, isLoading } = useLoginForm(submitLoginForm, {
9
11
  redirect: searchParams.r,
10
12
  });
11
- return (_jsxs(Fragment, { children: [_jsx("h1", { className: tw('text-center', classNames?.title), children: "Sign in to continue" }), _jsxs(Form, { ...formProps, classNames: { root: classNames?.form }, children: [_jsx(TextFormField, { ...fieldProps('email'), type: "email", hasAssistiveError: true }), _jsx(PasswordFormField, { ...fieldProps('password'), hasAssistiveError: true }), _jsx("div", { className: tw(classNames?.actions), children: _jsx(FormSubmit, { isLoading: isLoading, children: "Sign In" }) }), _jsx("footer", { className: tw('text-center', classNames?.footer), children: _jsx(Link, { className: classNames?.link, href: `/auth/password${formData.email ? `?email=${formData.email}` : ''}`, children: "Forgot Password?" }) })] })] }));
13
+ async function handleSession() {
14
+ if (searchParams.session) {
15
+ void setUserSession(searchParams.session);
16
+ setTimeout(() => {
17
+ window.location.href = pathname;
18
+ }, 500);
19
+ }
20
+ }
21
+ useEffect(() => {
22
+ if (searchParams.session) {
23
+ void handleSession();
24
+ }
25
+ }, []);
26
+ // If a session is provided, show a loading page while the session is being redirected
27
+ if (searchParams.session) {
28
+ return _jsx("h1", { className: tw('text-center', classNames?.title), children: "Authenticating..." });
29
+ }
30
+ return (_jsxs(Fragment, { children: [_jsx("h1", { className: tw('text-center', classNames?.title), children: "Sign in to continue" }), _jsxs(Form, { ...formProps, classNames: { root: classNames?.form }, children: [_jsx(TextFormField, { ...fieldProps('email'), hasAssistiveError: true }), _jsx(PasswordFormField, { ...fieldProps('password'), hasAssistiveError: true }), _jsx("div", { className: tw(classNames?.actions), children: _jsx(FormSubmit, { isFullWidth: true, isLoading: isLoading, children: "Sign In" }) }), _jsx("footer", { className: tw('text-center', classNames?.footer), children: _jsx(Link, { className: classNames?.link, href: `/auth/password${formData.email ? `?email=${formData.email}` : ''}`, children: "Forgot Password?" }) })] })] }));
12
31
  }
13
32
  export default LoginForm;
@@ -1,6 +1,5 @@
1
1
  export interface LogoutButtonProps {
2
2
  children?: React.ReactElement | string;
3
- redirectTo?: string;
4
3
  }
5
- declare function LogoutButton({ children, redirectTo, }: Readonly<LogoutButtonProps>): React.ReactElement;
4
+ declare function LogoutButton({ children }: Readonly<LogoutButtonProps>): React.ReactElement;
6
5
  export default LogoutButton;
@@ -1,15 +1,9 @@
1
1
  'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- import { useRouter } from 'next/navigation';
4
- import { logout } from '../../server';
5
- function LogoutButton({ children = 'Log out', redirectTo, }) {
6
- const router = useRouter();
7
- async function handleLogout() {
8
- await logout();
9
- router.push(redirectTo || '/');
10
- // It seems necessary to refresh to ensure the user is redirected to the login page
11
- router.refresh();
12
- }
13
- return (_jsx("form", { action: handleLogout, className: "contents", children: _jsx("button", { type: "submit", children: children }) }));
3
+ import { useTransition } from 'react';
4
+ import handle from './server';
5
+ function LogoutButton({ children = 'Log out' }) {
6
+ const [isLoading, startTransition] = useTransition();
7
+ return (_jsx("button", { disabled: isLoading, onClick: () => startTransition(handle), children: children }));
14
8
  }
15
9
  export default LogoutButton;
@@ -0,0 +1,2 @@
1
+ declare function handle(): Promise<void>;
2
+ export default handle;
@@ -0,0 +1,8 @@
1
+ 'use server';
2
+ import { deleteSession } from '@sqrzro/server/auth';
3
+ import { redirect } from 'next/navigation';
4
+ async function handle() {
5
+ await deleteSession();
6
+ return redirect('/auth/login');
7
+ }
8
+ export default handle;
@@ -14,6 +14,6 @@ function MFAForm({ classNames, searchParams }) {
14
14
  setDelayedKey(key);
15
15
  }
16
16
  }, [isLoading, key]);
17
- return (_jsxs(Form, { ...formProps, classNames: { root: classNames?.form }, children: [_jsx(CodeFormField, { ...fieldProps('token'), isDisabled: isLoading, onFinalChange: submitForm, hasAssistiveError: true, hasAssistiveLabel: true, isAutoFocus: true }, delayedKey), _jsx("div", { className: "sr-only", children: _jsx(FormSubmit, { children: "Verify" }) })] }));
17
+ return (_jsxs(Form, { ...formProps, classNames: { root: classNames?.form }, children: [_jsx(CodeFormField, { ...fieldProps('token'), isDisabled: isLoading, onFinalChange: submitForm, hasAssistiveError: true, hasAssistiveLabel: true, isAutoFocus: true }, delayedKey), _jsx("div", { className: "sr-only", children: _jsx(FormSubmit, { isFullWidth: true, children: "Verify" }) })] }));
18
18
  }
19
19
  export default MFAForm;
@@ -0,0 +1,5 @@
1
+ interface PasswordProps {
2
+ searchParams: Promise<Record<string, string>>;
3
+ }
4
+ declare function Password({ searchParams }: Readonly<PasswordProps>): Promise<React.ReactElement>;
5
+ export default Password;
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { validateReset } from '@sqrzro/server/auth';
3
+ import PasswordForm from '../../forms/PasswordForm';
4
+ import PasswordResetForm from '../../forms/PasswordResetForm';
5
+ async function Password({ searchParams }) {
6
+ const awaitedSearchParams = await searchParams;
7
+ if (awaitedSearchParams.token) {
8
+ const validated = await validateReset('PASSWORD', awaitedSearchParams.token);
9
+ if (validated) {
10
+ return _jsx(PasswordResetForm, { token: awaitedSearchParams.token });
11
+ }
12
+ else {
13
+ return _jsx("div", { children: "Invalid or Expired Token" });
14
+ }
15
+ }
16
+ return _jsx(PasswordForm, {});
17
+ }
18
+ export default Password;
@@ -23,6 +23,6 @@ function PasswordForm({ classNames, email }) {
23
23
  setFormData('email', '');
24
24
  setSentCount(0);
25
25
  }
26
- return (_jsxs(Fragment, { children: [_jsx("div", { className: tw(sentCount === 0 ? 'block' : 'hidden'), children: _jsxs(Form, { ...formProps, classNames: { root: classNames?.form }, children: [_jsx("h1", { className: classNames?.title, children: "Reset Your Password" }), _jsx("p", { className: "text-sm", children: "Enter the email address associated with your account and we'll send you a link to reset your password." }), _jsx(TextFormField, { ...fieldProps('email'), type: "email", hasAssistiveLabel: true }), _jsx("div", { className: tw(classNames?.actions), children: _jsx(FormSubmit, { isLoading: isLoading, children: "Send Email" }) }), _jsx("footer", { className: tw('text-center', classNames?.footer), children: _jsx(Link, { className: classNames?.link, href: "/auth/login", children: "Back" }) })] }) }), _jsx("div", { className: tw(sentCount > 0 ? 'flex' : 'hidden'), children: _jsxs("div", { className: tw(classNames?.form), children: [_jsx("h1", { className: classNames?.title, children: "Check Your Email" }), sentCount === 1 ? (_jsxs(Fragment, { children: [_jsxs("p", { className: "text-sm", children: ["If ", _jsx("strong", { children: formData.email }), " matches an email we have on file, then we've sent you an email containing further instructions for resetting your password."] }), _jsxs("p", { className: "text-sm", children: ["If you haven't received an email in 5 minutes, check your spam,", ' ', _jsx(Link, { className: classNames?.link, onClick: handleResend, children: "resend" }), ", or", ' ', _jsx(Link, { className: classNames?.link, onClick: handleReset, children: "try a different email address" }), "."] })] })) : (_jsxs(Fragment, { children: [_jsxs("p", { className: "text-sm", children: ["We've resent password reset instructions to", ' ', _jsx("strong", { children: formData.email }), ", if it is an email we have on file."] }), _jsxs("p", { className: "text-sm", children: ["Please check again. If you still haven't received an email,", ' ', _jsx(Link, { className: classNames?.link, onClick: handleReset, children: "try a different email address" }), "."] })] }))] }) })] }));
26
+ return (_jsxs(Fragment, { children: [_jsx("div", { className: tw(sentCount === 0 ? 'block' : 'hidden'), children: _jsxs(Form, { ...formProps, classNames: { root: classNames?.form }, children: [_jsx("h1", { className: classNames?.title, children: "Reset Your Password" }), _jsx("p", { className: "text-sm", children: "Enter the email address associated with your account and we'll send you a link to reset your password." }), _jsx(TextFormField, { ...fieldProps('email'), type: "email", hasAssistiveLabel: true }), _jsx("div", { className: tw(classNames?.actions), children: _jsx(FormSubmit, { isFullWidth: true, isLoading: isLoading, children: "Send Email" }) }), _jsx("footer", { className: tw('text-center', classNames?.footer), children: _jsx(Link, { className: classNames?.link, href: "/auth/login", children: "Back" }) })] }) }), _jsx("div", { className: tw(sentCount > 0 ? 'flex' : 'hidden'), children: _jsxs("div", { className: tw(classNames?.form), children: [_jsx("h1", { className: classNames?.title, children: "Check Your Email" }), sentCount === 1 ? (_jsxs(Fragment, { children: [_jsxs("p", { className: "text-sm", children: ["If ", _jsx("strong", { children: formData.email }), " matches an email we have on file, then we've sent you an email containing further instructions for resetting your password."] }), _jsxs("p", { className: "text-sm", children: ["If you haven't received an email in 5 minutes, check your spam,", ' ', _jsx(Link, { className: classNames?.link, onClick: handleResend, children: "resend" }), ", or", ' ', _jsx(Link, { className: classNames?.link, onClick: handleReset, children: "try a different email address" }), "."] })] })) : (_jsxs(Fragment, { children: [_jsxs("p", { className: "text-sm", children: ["We've resent password reset instructions to", ' ', _jsx("strong", { children: formData.email }), ", if it is an email we have on file."] }), _jsxs("p", { className: "text-sm", children: ["Please check again. If you still haven't received an email,", ' ', _jsx(Link, { className: classNames?.link, onClick: handleReset, children: "try a different email address" }), "."] })] }))] }) })] }));
27
27
  }
28
28
  export default PasswordForm;
@@ -15,6 +15,6 @@ function PasswordResetForm({ classNames, token, }) {
15
15
  },
16
16
  toasts: { success: false },
17
17
  });
18
- return (_jsxs(Form, { ...formProps, classNames: { root: classNames?.form }, children: [_jsx("h1", { className: classNames?.title, children: "Reset Your Password" }), _jsx("div", { className: "relative", children: _jsx(PasswordFormField, { ...fieldProps('password', 'New Password') }) }), _jsx("div", { className: "mt-8", children: _jsx(FormSubmit, { isLoading: isLoading, children: "Reset Password" }) })] }));
18
+ return (_jsxs(Form, { ...formProps, classNames: { root: classNames?.form }, children: [_jsx("h1", { className: classNames?.title, children: "Reset Your Password" }), _jsx("div", { className: "relative", children: _jsx(PasswordFormField, { ...fieldProps('password', 'New Password') }) }), _jsx("div", { className: "mt-8", children: _jsx(FormSubmit, { isFullWidth: true, isLoading: isLoading, children: "Reset Password" }) })] }));
19
19
  }
20
20
  export default PasswordResetForm;
@@ -0,0 +1,2 @@
1
+ declare function LoginForm(): React.ReactElement | null;
2
+ export default LoginForm;
@@ -0,0 +1,13 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Fragment } from 'react';
4
+ import { Form, FormSubmit, Link, PasswordFormField, TextFormField } from '@sqrzro/components';
5
+ import { useForm } from '@sqrzro/hooks';
6
+ import { handleSubmit } from './server';
7
+ function LoginForm() {
8
+ const { fieldProps, formData, formProps } = useForm({
9
+ onSubmit: handleSubmit,
10
+ });
11
+ return (_jsx(Fragment, { children: _jsxs(Form, { ...formProps, children: [_jsx(TextFormField, { ...fieldProps('email'), hasAssistiveError: true }), _jsx(PasswordFormField, { ...fieldProps('password'), hasAssistiveError: true }), _jsx(FormSubmit, { isFullWidth: true, children: "Sign In" }), _jsx("footer", { children: _jsx(Link, { href: `/auth/password${formData.email ? `?email=${formData.email}` : ''}`, children: "Forgot Password?" }) })] }) }));
12
+ }
13
+ export default LoginForm;
@@ -0,0 +1,2 @@
1
+ declare function LoginForm(): React.ReactElement | null;
2
+ export default LoginForm;
@@ -0,0 +1,13 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Fragment } from 'react';
4
+ import { Link } from '@sqrzro/ui/components';
5
+ import { Form, FormSubmit, PasswordFormField, TextFormField, useForm } from '@sqrzro/ui/forms';
6
+ import submit from './server';
7
+ function LoginForm() {
8
+ const { fieldProps, formData, formProps } = useForm({
9
+ onSubmit: submit,
10
+ });
11
+ return (_jsx(Fragment, { children: _jsxs(Form, { ...formProps, children: [_jsx(TextFormField, { ...fieldProps('email'), hasAssistiveError: true }), _jsx(PasswordFormField, { ...fieldProps('password'), hasAssistiveError: true }), _jsx(FormSubmit, { children: "Sign In" }), _jsx("footer", { children: _jsx(Link, { href: `/auth/password${formData.email ? `?email=${formData.email}` : ''}`, children: "Forgot Password?" }) })] }) }));
12
+ }
13
+ export default LoginForm;
@@ -0,0 +1,5 @@
1
+ export interface LoginFormFields {
2
+ email: string;
3
+ password: string;
4
+ redirect?: string;
5
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ import { FormResponse } from '@sqrzro/server/forms';
2
+ import type { LoginFormFields } from './interfaces';
3
+ declare function submit(formData: LoginFormFields): FormResponse<void>;
4
+ export default submit;
@@ -0,0 +1,25 @@
1
+ 'use server';
2
+ import { createSession, validateUser } from '@sqrzro/server/auth';
3
+ import { submitForm } from '@sqrzro/server/forms';
4
+ import { redirect } from 'next/navigation';
5
+ import { z } from 'zod';
6
+ const schema = z
7
+ .object({
8
+ email: z.email(),
9
+ password: z.string(),
10
+ redirect: z.string().optional(),
11
+ })
12
+ .required({ email: true, password: true });
13
+ async function fn(data) {
14
+ const userID = await validateUser(data.email, data.password);
15
+ await createSession(userID);
16
+ redirect('/');
17
+ }
18
+ async function submit(formData) {
19
+ return submitForm({
20
+ fn,
21
+ formData,
22
+ schema,
23
+ });
24
+ }
25
+ export default submit;
@@ -0,0 +1,2 @@
1
+ declare function PasswordForm(): React.ReactElement | null;
2
+ export default PasswordForm;
@@ -0,0 +1,13 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Fragment } from 'react';
4
+ import { Form, FormSubmit, TextFormField } from '@sqrzro/components';
5
+ import { useForm } from '@sqrzro/hooks';
6
+ import { handleSubmit } from './server';
7
+ function PasswordForm() {
8
+ const { fieldProps, formProps } = useForm({
9
+ onSubmit: handleSubmit,
10
+ });
11
+ return (_jsx(Fragment, { children: _jsxs(Form, { ...formProps, children: [_jsx(TextFormField, { ...fieldProps('email'), hasAssistiveError: true }), _jsx(FormSubmit, { isFullWidth: true, children: "Send Email" })] }) }));
12
+ }
13
+ export default PasswordForm;
@@ -0,0 +1,2 @@
1
+ declare function PasswordForm(): React.ReactElement | null;
2
+ export default PasswordForm;
@@ -0,0 +1,12 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Fragment } from 'react';
4
+ import { Form, FormSubmit, TextFormField, useForm } from '@sqrzro/ui/forms';
5
+ import submit from './server';
6
+ function PasswordForm() {
7
+ const { fieldProps, formProps } = useForm({
8
+ onSubmit: submit,
9
+ });
10
+ return (_jsx(Fragment, { children: _jsxs(Form, { ...formProps, children: [_jsx(TextFormField, { ...fieldProps('email'), hasAssistiveError: true }), _jsx(FormSubmit, { isFullWidth: true, children: "Send Email" })] }) }));
11
+ }
12
+ export default PasswordForm;
@@ -0,0 +1,3 @@
1
+ export interface PasswordFormFields {
2
+ email: string;
3
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ import { FormResponse } from '@sqrzro/server/forms';
2
+ import type { PasswordFormFields } from './interfaces';
3
+ declare function submit(formData: PasswordFormFields): FormResponse<void>;
4
+ export default submit;
@@ -0,0 +1,21 @@
1
+ 'use server';
2
+ import { createReset } from '@sqrzro/server/auth';
3
+ import { submitForm } from '@sqrzro/server/forms';
4
+ import { z } from 'zod';
5
+ const schema = z
6
+ .object({
7
+ email: z.email(),
8
+ })
9
+ .required({ email: true });
10
+ async function fn(data) {
11
+ const token = await createReset('PASSWORD', data.email);
12
+ console.log(token);
13
+ }
14
+ async function submit(formData) {
15
+ return submitForm({
16
+ fn,
17
+ formData,
18
+ schema,
19
+ });
20
+ }
21
+ export default submit;
@@ -0,0 +1,5 @@
1
+ interface PasswordResetFormProps {
2
+ token: string;
3
+ }
4
+ declare function PasswordResetForm({ token }: Readonly<PasswordResetFormProps>): React.ReactElement | null;
5
+ export default PasswordResetForm;
@@ -0,0 +1,14 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Fragment } from 'react';
4
+ import { Form, FormSubmit, TextFormField } from '@sqrzro/components';
5
+ import { useForm } from '@sqrzro/hooks';
6
+ import { handleSubmit } from './server';
7
+ function PasswordResetForm({ token }) {
8
+ const { fieldProps, formProps } = useForm({
9
+ defaults: { token },
10
+ onSubmit: handleSubmit,
11
+ });
12
+ return (_jsx(Fragment, { children: _jsxs(Form, { ...formProps, children: [_jsx(TextFormField, { ...fieldProps('password'), hasAssistiveError: true }), _jsx(FormSubmit, { isFullWidth: true, children: "Reset Password" })] }) }));
13
+ }
14
+ export default PasswordResetForm;
@@ -0,0 +1,5 @@
1
+ interface PasswordResetFormProps {
2
+ token: string;
3
+ }
4
+ declare function PasswordResetForm({ token }: Readonly<PasswordResetFormProps>): React.ReactElement | null;
5
+ export default PasswordResetForm;
@@ -0,0 +1,13 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Fragment } from 'react';
4
+ import { Form, FormSubmit, PasswordFormField, useForm } from '@sqrzro/ui/forms';
5
+ import submit from './server';
6
+ function PasswordResetForm({ token }) {
7
+ const { fieldProps, formProps } = useForm({
8
+ defaults: { token },
9
+ onSubmit: submit,
10
+ });
11
+ return (_jsx(Fragment, { children: _jsxs(Form, { ...formProps, children: [_jsx(PasswordFormField, { ...fieldProps('password') }), _jsx(FormSubmit, { isFullWidth: true, children: "Reset Password" })] }) }));
12
+ }
13
+ export default PasswordResetForm;
@@ -0,0 +1,4 @@
1
+ export interface PasswordResetFormFields {
2
+ password: string;
3
+ token: string;
4
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ import { FormResponse } from '@sqrzro/server/forms';
2
+ import type { PasswordResetFormFields } from './interfaces';
3
+ declare function submit(formData: PasswordResetFormFields): FormResponse<void>;
4
+ export default submit;
@@ -0,0 +1,23 @@
1
+ 'use server';
2
+ import { updatePasswordWithToken } from '@sqrzro/server/auth';
3
+ import { submitForm } from '@sqrzro/server/forms';
4
+ import { redirect } from 'next/navigation';
5
+ import { z } from 'zod';
6
+ const schema = z
7
+ .object({
8
+ password: z.string(),
9
+ token: z.string().regex(/[A-Za-z0-9]{48}/u),
10
+ })
11
+ .required({ password: true, token: true });
12
+ async function fn(data) {
13
+ await updatePasswordWithToken(data.token, data.password);
14
+ return redirect('/auth/login');
15
+ }
16
+ async function submit(formData) {
17
+ return submitForm({
18
+ fn,
19
+ formData,
20
+ schema,
21
+ });
22
+ }
23
+ export default submit;
@@ -0,0 +1,4 @@
1
+ import { NextResponse } from 'next/server';
2
+ import type { NextRequest } from 'next/server';
3
+ declare function handleProxy(request: NextRequest): Promise<NextResponse>;
4
+ export default handleProxy;