diff --git a/components/ComponentShield.js b/components/ComponentShield.js
new file mode 100644
index 0000000..dc28209
--- /dev/null
+++ b/components/ComponentShield.js
@@ -0,0 +1,15 @@
+import React from 'react';
+
+export function ComponentShield({
+ RBAC,
+ showIf,
+ userRole,
+ children,
+ showForRole,
+ fallback = null,
+}) {
+ if (RBAC) return <>{showForRole.includes(userRole) ? children : null}>;
+ if (showIf) return <>{children}>;
+
+ return <>{fallback}>;
+}
diff --git a/components/NextShield.js b/components/NextShield.js
index 11892e0..01ba8d9 100644
--- a/components/NextShield.js
+++ b/components/NextShield.js
@@ -1,7 +1,7 @@
import React, { useEffect } from 'react';
-import { verifyPath, getAccessRoute } from '../libs/routes';
import { useGetUser } from '../modules/auth/auth.query';
+import { verifyPath, getAccessRoute } from '../libs/routes';
export function NextShield({
RBAC,
diff --git a/consts/HTTP.js b/constants/HTTP.js
similarity index 100%
rename from consts/HTTP.js
rename to constants/HTTP.js
diff --git a/modules/auth/auth.query.js b/modules/auth/auth.query.js
index 904d446..fd302ba 100644
--- a/modules/auth/auth.query.js
+++ b/modules/auth/auth.query.js
@@ -1,6 +1,92 @@
-import { useQuery } from 'react-query';
-import { getUser } from './auth.service';
+import { useRouter } from 'next/router';
+import { useMutation, useQuery } from 'react-query';
+
+import {
+ login,
+ getUser,
+ confirm,
+ register,
+ resetPassword,
+ resetPasswordRequest,
+} from './auth.service';
+import { setUsername } from '../../utils/storage';
export const useGetUser = (username) => {
return useQuery(['getUser', username], getUser);
};
+
+export const useLogin = () => {
+ const router = useRouter();
+ return useMutation(login, {
+ onSuccess: (_, { username }) => {
+ setUsername(username);
+ router.reload();
+ },
+ });
+};
+
+export const useRegister = () => {
+ const router = useRouter();
+
+ return useMutation(register, {
+ onSuccess: (data, { username }) => {
+ if (!data.success) return;
+ setUsername(username);
+ router.push(
+ {
+ pathname: '/confirm',
+ query: { username },
+ },
+ '/confirm'
+ );
+ },
+ });
+};
+
+export const useConfirm = () => {
+ const router = useRouter();
+
+ return useMutation(confirm, {
+ onSuccess: () => {
+ router.push(
+ {
+ pathname: '/login',
+ query: { confirmed: true },
+ },
+ '/login'
+ );
+ },
+ });
+};
+
+export const useResetPassword = () => {
+ const router = useRouter();
+
+ return useMutation(resetPassword, {
+ onSuccess: () => {
+ router.push(
+ {
+ pathname: '/login',
+ query: { reset: true },
+ },
+ '/login'
+ );
+ },
+ });
+};
+
+export const useResetPasswordRequest = () => {
+ const router = useRouter();
+
+ return useMutation(resetPasswordRequest, {
+ onSuccess: (data) => {
+ router.push(
+ {
+ pathname: '/password/reset',
+ query: { username: data.username },
+ },
+ '/password/reset'
+ );
+ },
+ });
+};
diff --git a/modules/auth/auth.service.js b/modules/auth/auth.service.js
index cdd1453..6bda04a 100644
--- a/modules/auth/auth.service.js
+++ b/modules/auth/auth.service.js
@@ -1,5 +1,5 @@
-import { httpMethodEnums } from '../../consts/HTTP';
import { getUsername } from '../../utils/storage';
+import { httpMethodEnums } from '../../constants/HTTP';
export const getUser = async () => {
const username = getUsername();
@@ -10,3 +10,97 @@ export const getUser = async () => {
return res.json();
};
+
+export const login = async (values) => {
+ try {
+ const res = await fetch('/api/login', {
+ method: httpMethodEnums.POST,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(values),
+ });
+ if (!res.ok) throw res;
+ return res.json();
+ } catch (error) {
+ const { message } = await error.json();
+
+ throw new Error(message.split(`:`)[1]);
+ }
+};
+
+export const register = async (values) => {
+ try {
+ const res = await fetch('/api/register', {
+ method: httpMethodEnums.POST,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(values),
+ });
+
+ if (!res.ok) throw res;
+
+ return res.json();
+ } catch (error) {
+ const { message } = await error.json();
+
+ throw new Error(message.split(`:`)[1]);
+ }
+};
+
+export const confirm = async (values) => {
+ try {
+ const res = await fetch('/api/confirm', {
+ method: httpMethodEnums.POST,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(values),
+ });
+ if (!res.ok) throw res;
+ } catch (error) {
+ const { message } = await error.json();
+
+ throw new Error(message.split(`:`)[1]);
+ }
+};
+
+export const resetPassword = async (values) => {
+ try {
+ const res = await fetch('/api/password/reset', {
+ method: httpMethodEnums.POST,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(values),
+ });
+
+ if (!res.ok) throw res;
+
+ return res.json();
+ } catch (error) {
+ const { message } = await error.json();
+
+ throw new Error(message.split(`:`)[1]);
+ }
+};
+
+export const resetPasswordRequest = async (values) => {
+ try {
+ const res = await fetch('/api/password/reset_code', {
+ method: httpMethodEnums.POST,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(values),
+ });
+ if (!res.ok) throw res;
+
+ return res.json();
+ } catch (error) {
+ const { message } = await error.json();
+
+ throw new Error(message.split(`:`)[1]);
+ }
+};
diff --git a/modules/bookmark/bookmark.service.js b/modules/bookmark/bookmark.service.js
index 271e325..3876a91 100644
--- a/modules/bookmark/bookmark.service.js
+++ b/modules/bookmark/bookmark.service.js
@@ -1,4 +1,4 @@
-import { httpMethodEnums } from '../../consts/HTTP';
+import { httpMethodEnums } from '../../constants/HTTP';
export const getBookmarkById = async ({ queryKey }) => {
console.log({ queryKey });
diff --git a/pages/api/bookmarks/[id]/index.js b/pages/api/bookmarks/[id]/index.js
index e2b670f..214bf2e 100644
--- a/pages/api/bookmarks/[id]/index.js
+++ b/pages/api/bookmarks/[id]/index.js
@@ -4,7 +4,7 @@ import {
UpdateCommand,
} from '@aws-sdk/lib-dynamodb';
-import { httpMethodEnums } from '../../../../consts/HTTP';
+import { httpMethodEnums } from '../../../../constants/HTTP';
import { ddbDocClient } from '../../../../libs/ddbDocClient';
const { TABLE_NAME } = process.env;
diff --git a/pages/api/bookmarks/create.js b/pages/api/bookmarks/create.js
index ef7a34d..4065021 100644
--- a/pages/api/bookmarks/create.js
+++ b/pages/api/bookmarks/create.js
@@ -1,7 +1,7 @@
import { nanoid } from 'nanoid';
import { PutCommand } from '@aws-sdk/lib-dynamodb';
-import { httpMethodEnums } from '../../../consts/HTTP';
+import { httpMethodEnums } from '../../../constants/HTTP';
import { ddbDocClient } from '../../../libs/ddbDocClient';
const { TABLE_NAME } = process.env;
diff --git a/pages/api/register.js b/pages/api/register.js
index bf115fe..56b512b 100644
--- a/pages/api/register.js
+++ b/pages/api/register.js
@@ -17,7 +17,9 @@ export default async function handler(req, res) {
try {
const response = await cognitoClient.send(signUpCommand);
- return res.status(response['$metadata'].httpStatusCode).send();
+ return res
+ .status(response['$metadata'].httpStatusCode)
+ .send({ success: true, message: 'User registered successfully' });
} catch (err) {
console.log(err);
return res
diff --git a/pages/confirm.js b/pages/confirm.js
index 94ef3cb..9357616 100644
--- a/pages/confirm.js
+++ b/pages/confirm.js
@@ -1,19 +1,17 @@
-import { useRouter } from 'next/router';
-import { Button, Col, Form, Input, Row } from 'antd';
+import { Button, Col, Form, Input, Row, Typography } from 'antd';
-import useRegister from '../hooks/useRegister';
-import { useState } from 'react';
+import { getUsername } from '../utils/storage';
+import { useConfirm } from '../modules/auth/auth.query';
-export default function Confirm() {
- const router = useRouter();
- const { username = 'shipon2285@gmail.com' } = router.query;
- const [loading, setLoading] = useState();
+const { Text } = Typography;
- const { confirm } = useRegister();
+export default function Confirm() {
+ const { mutate, isLoading, error } = useConfirm();
const handleSubmit = async (values) => {
- setLoading(true);
- confirm({ ...values, username }, setLoading);
+ const username = getUsername();
+ if (!username) return;
+ mutate({ ...values, username });
};
return (
@@ -28,13 +26,14 @@ export default function Confirm() {
+ {error?.message && {error.message}}
diff --git a/pages/login.js b/pages/login.js
index 94fc133..6965e4e 100644
--- a/pages/login.js
+++ b/pages/login.js
@@ -1,23 +1,16 @@
import { useRouter } from 'next/router';
-import { useState } from 'react';
import { Button, Col, Form, Input, Row, Typography } from 'antd';
-import useAuth from '../hooks/useAuth';
+import { useLogin } from '../modules/auth/auth.query';
const { Text } = Typography;
export default function Login() {
const router = useRouter();
- const [loading, setLoading] = useState();
- const { login } = useAuth();
+ const { mutate, isLoading } = useLogin();
const { success } = router.query;
- const handleSubmit = async (values) => {
- setLoading(true);
- await login({ ...values }, setLoading);
- };
-
return (
@@ -32,7 +25,7 @@ export default function Login() {
)}
-
@@ -41,11 +34,11 @@ export default function Login() {
diff --git a/pages/register.js b/pages/register.js
index 5b2b823..12dc0ce 100644
--- a/pages/register.js
+++ b/pages/register.js
@@ -1,17 +1,10 @@
-import { useState } from 'react';
import { Button, Col, Form, Input, Row, Typography } from 'antd';
-
-import useRegister from '../hooks/useRegister';
+import { useRegister } from '../modules/auth/auth.query';
const { Text } = Typography;
export default function Register() {
- const { register } = useRegister();
- const [loading, setLoading] = useState();
-
- const handleSubmit = (values) => {
- register(values, setLoading);
- };
+ const { mutate, isLoading, error, data } = useRegister();
return (
@@ -20,7 +13,7 @@ export default function Register() {
style={{
padding: '10px',
}}>
-
@@ -36,11 +29,12 @@ export default function Register() {
size='large'
type='primary'
htmlType='submit'
- loading={loading}>
+ loading={isLoading}>
Submit
Already have an account? Log in
+ {error?.message && {error.message}}