From 2ba1dd7f2635c28c6d56da58be804b7c9169c54c Mon Sep 17 00:00:00 2001 From: Sebastian Sauerer Date: Sun, 13 Mar 2022 14:07:03 +0100 Subject: [PATCH 1/2] refactor: improve the auth component --- client/components/auth/auth.module.css | 14 ++-- client/components/auth/index.tsx | 93 +++++++++++--------------- 2 files changed, 45 insertions(+), 62 deletions(-) diff --git a/client/components/auth/auth.module.css b/client/components/auth/auth.module.css index 84d4695a..b1e32989 100644 --- a/client/components/auth/auth.module.css +++ b/client/components/auth/auth.module.css @@ -5,17 +5,17 @@ } .form { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - width: 100%; + display: grid; + place-items: center; } .formGroup { - margin-bottom: 1rem; + display: flex; + flex-direction: column; + place-items: center; + gap: 10px; } -.formHeader { +.formContentSpace { margin-bottom: 1rem; } diff --git a/client/components/auth/index.tsx b/client/components/auth/index.tsx index d619f2ae..d62ad75c 100644 --- a/client/components/auth/index.tsx +++ b/client/components/auth/index.tsx @@ -1,5 +1,5 @@ import { FormEvent, useState } from 'react' -import { Button, Card, Input, Text } from '@geist-ui/core' +import { Button, Input, Text, useToasts } from '@geist-ui/core' import styles from './auth.module.css' import { useRouter } from 'next/router' import Link from '../Link' @@ -9,15 +9,11 @@ const Auth = ({ page }: { page: "signup" | "signin" }) => { const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); - const [error, setError] = useState(''); + const { setToast } = useToasts(); const signingIn = page === 'signin' - const NO_EMPTY_SPACE_REGEX = /^\S*$/; - const handleJson = (json: any) => { - if (json.error) return setError(json.error.message) - localStorage.setItem('drift-token', json.token) localStorage.setItem('drift-userid', json.userId) router.push('/') @@ -27,12 +23,6 @@ const Auth = ({ page }: { page: "signup" | "signin" }) => { const handleSubmit = async (e: FormEvent) => { e.preventDefault() - if (!username.match(NO_EMPTY_SPACE_REGEX)) - return setError("Username can't be empty") - - if (!password.match(NO_EMPTY_SPACE_REGEX)) - return setError("Password can't be empty") - const reqOpts = { method: 'POST', headers: { @@ -50,58 +40,51 @@ const Auth = ({ page }: { page: "signup" | "signin" }) => { handleJson(json) } catch (err: any) { - setError(err.message || "Something went wrong") + setToast({ text: "Something went wrong", type: 'error' }) } } return (
-
+

{signingIn ? 'Sign In' : 'Sign Up'}

- -
- setUsername(event.target.value)} - placeholder="Username" - required - label='Username' - /> -
-
- setPassword(event.target.value)} - placeholder="Password" - required - label='Password' - /> -
-
- -
-
- {signingIn ? ( - - Don't have an account?{" "} - Sign up - - ) : ( - - Already have an account?{" "} - Sign in - - )} -
- {error && {error}} -
+
+ setUsername(event.target.value)} + placeholder="Username" + required + scale={4 / 3} + /> + setPassword(event.target.value)} + placeholder="Password" + required + scale={4 / 3} + /> + +
+
+ {signingIn ? ( + + Don't have an account?{" "} + Sign up + + ) : ( + + Already have an account?{" "} + Sign in + + )} +
From a361b16293d3ec8d0319d8e6cb90d9058b933409 Mon Sep 17 00:00:00 2001 From: Sebastian Sauerer Date: Sun, 13 Mar 2022 20:57:55 +0100 Subject: [PATCH 2/2] enhance auth workflow by adding a better error message and by validating the auth payload on server side --- client/components/auth/auth.module.css | 3 ++- client/components/auth/index.tsx | 11 ++++++++++- server/src/routes/auth.ts | 17 ++++++++++------- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/client/components/auth/auth.module.css b/client/components/auth/auth.module.css index b1e32989..4398333a 100644 --- a/client/components/auth/auth.module.css +++ b/client/components/auth/auth.module.css @@ -18,4 +18,5 @@ .formContentSpace { margin-bottom: 1rem; -} + text-align: center; +} \ No newline at end of file diff --git a/client/components/auth/index.tsx b/client/components/auth/index.tsx index d62ad75c..0ab50213 100644 --- a/client/components/auth/index.tsx +++ b/client/components/auth/index.tsx @@ -1,14 +1,19 @@ import { FormEvent, useState } from 'react' -import { Button, Input, Text, useToasts } from '@geist-ui/core' +import { Button, Input, Text, useToasts, Note } from '@geist-ui/core' import styles from './auth.module.css' import { useRouter } from 'next/router' import Link from '../Link' +const NO_EMPTY_SPACE_REGEX = /^\S*$/; +const ERROR_MESSAGE = "Provide a non empty username and a password with at least 6 characters"; + const Auth = ({ page }: { page: "signup" | "signin" }) => { const router = useRouter(); const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); + const [errorMsg, setErrorMsg] = useState(''); + const { setToast } = useToasts(); const signingIn = page === 'signin' @@ -23,6 +28,9 @@ const Auth = ({ page }: { page: "signup" | "signin" }) => { const handleSubmit = async (e: FormEvent) => { e.preventDefault() + if (!NO_EMPTY_SPACE_REGEX.test(username) || password.length < 6) return setErrorMsg(ERROR_MESSAGE) + else setErrorMsg(''); + const reqOpts = { method: 'POST', headers: { @@ -85,6 +93,7 @@ const Auth = ({ page }: { page: "signup" | "signin" }) => { )}
+ {errorMsg && {errorMsg}} diff --git a/server/src/routes/auth.ts b/server/src/routes/auth.ts index 64794364..fd75a59a 100644 --- a/server/src/routes/auth.ts +++ b/server/src/routes/auth.ts @@ -1,18 +1,23 @@ import { Router } from 'express' -// import { Movie } from '../models/Post' import { genSalt, hash, compare } from "bcrypt" import { User } from '../../lib/models/User' import { sign } from 'jsonwebtoken' import config from '../../lib/config' import jwt from '../../lib/middleware/jwt' +const NO_EMPTY_SPACE_REGEX = /^\S*$/ + export const auth = Router() +const validateAuthPayload = (username: string, password: string): void => { + if (!NO_EMPTY_SPACE_REGEX.test(username) || password.length < 6) { + throw new Error("Authentication data does not fulfill requirements") + } +} + auth.post('/signup', async (req, res, next) => { try { - if (!req.body.username || !req.body.password) { - throw new Error("Please provide a username and password") - } + validateAuthPayload(req.body.username, req.body.password) const username = req.body.username.toLowerCase(); @@ -39,9 +44,7 @@ auth.post('/signup', async (req, res, next) => { auth.post('/signin', async (req, res, next) => { try { - if (!req.body.username || !req.body.password) { - throw new Error("Missing username or password") - } + validateAuthPayload(req.body.username, req.body.password) const username = req.body.username.toLowerCase(); const user = await User.findOne({ where: { username: username } });