Skip to content

Commit

Permalink
feat: email and password length validation on backend
Browse files Browse the repository at this point in the history
  • Loading branch information
tomaspalma committed Jan 19, 2025
1 parent ebf0f8a commit d81c77d
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 79 deletions.
26 changes: 13 additions & 13 deletions website/app/controllers/authentication_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Account from '#models/account'
import { socialAccountLoginValidator } from '#validators/account'
import User from '#models/user'
import type { HttpContext } from '@adonisjs/core/http'
import { createUserValidator, createUserValidatorErrorMessage } from '#validators/authentication'

async function getOrCreate(search: Pick<Account, 'provider' | 'providerId'>) {
const account = await Account.firstOrCreate({
Expand All @@ -25,25 +26,23 @@ export default class AuthenticationController {
response.redirect('/')
} catch (error) {
session.flash('errorsBag', { oauth: 'Email ou palavra-passe incorretos' })
response.redirect().back()
return response.redirect().back()
}
}

async register({ request, auth, response, session }: HttpContext) {
const { email, password, confirmPassword } = request.only([
'email',
'password',
'confirmPassword',
])
try {
await request.validateUsing(createUserValidator)
} catch (error) {
session.flash('errorsBag', { oauth: createUserValidatorErrorMessage(error) })
return response.redirect().toRoute('view.register')
}

const { email, password } = request.only(['email', 'password'])

if (await User.query().where('email', email).first()) {
session.flash('errorsBag', { oauth: 'Este e-mail já está em uso' })
response.redirect().back()
}

if (confirmPassword !== password) {
session.flash('errorsBag', { oauth: 'Palavras-passes não coincidem' })
response.redirect().back()
return response.redirect().toRoute('view.register')
}

try {
Expand All @@ -60,7 +59,8 @@ export default class AuthenticationController {

response.redirect('/')
} catch (error) {
console.log(error)
session.flash('errorsBag', { oauth: 'Ocorreu um erro no registo' })
return response.redirect().toRoute('view.register')
}
}

Expand Down
22 changes: 22 additions & 0 deletions website/app/validators/authentication.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import vine from '@vinejs/vine'
import { VineValidationError } from '../../types/validation.js'

export const createUserValidator = vine.compile(
vine.object({
email: vine.string().email(),
password: vine.string().minLength(8).confirmed(),
})
)

export const createUserValidatorErrorMessage = (error: VineValidationError) => {
const rule = error.messages[0].rule

switch (rule) {
case 'email':
return 'E-mail inválido'
case 'minLength':
return 'Palavra-passe tem de ter no mínimo 8 caratéres'
case 'confirmed':
return 'Palavras-passe não coincidem'
}
}
63 changes: 31 additions & 32 deletions website/inertia/pages/login.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Link } from '@tuyau/inertia/react'
import { Button, buttonVariants } from '~/components/ui/button'
import { Button } from '~/components/ui/button'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '~/components/ui/card'
import { Input } from '~/components/ui/input'
import { Label } from '~/components/ui/label'
import { Separator } from '~/components/ui/separator'
import { useError } from '~/hooks/use_error'
import { useForm } from '@inertiajs/react'
import { cn } from '~/lib/utils'
Expand All @@ -27,7 +26,7 @@ export default function Login() {
<AppLayout title="Iniciar Sessão">
<div className="flex items-center justify-center w-full mt-16">
<div className="flex flex-col gap-6 max-w-sm">
<Card className={cn(oauthError && 'border-red-600')}>
<Card className={cn(oauthError && 'border-2 border-red-600')}>
<CardHeader>
<CardTitle className="text-2xl text-enei-blue">Iniciar Sessão</CardTitle>
<CardDescription>
Expand Down Expand Up @@ -71,34 +70,34 @@ export default function Login() {
<Button type="submit" className="w-full bg-enei-blue">
Iniciar Sessão
</Button>
<div className="flex gap-2 items-center">
<Separator className="shrink" />
<p className="text-sm text-muted-foreground min-w-max">Ou</p>
<Separator className="shrink" />
</div>
<div className="grid grid-cols-3 gap-2">
<Link
route="auth.google.initiate"
className={cn(buttonVariants({ variant: 'outline' }), 'w-full')}
>
<span className="sr-only">Iniciar Sessão com o</span> Google
{/* <Google className="h-5 w-5" /> */}
</Link>
<Link
route="auth.github.initiate"
className={cn(buttonVariants({ variant: 'outline' }), 'w-full')}
>
<span className="sr-only">Iniciar Sessão com o</span> Github
{/* <Github className="h-5 w-5" /> */}
</Link>
<Link
route="auth.linkedin.initiate"
className={cn(buttonVariants({ variant: 'outline' }), 'w-full')}
>
<span className="sr-only">Iniciar Sessão com o</span> LinkedIn
{/* <LinkedIn className="h-5 w-5" /> */}
</Link>
</div>
{/* <div className="flex gap-2 items-center"> */}
{/* <Separator className="shrink" /> */}
{/* <p className="text-sm text-muted-foreground min-w-max">Ou</p> */}
{/* <Separator className="shrink" /> */}
{/* </div> */}
{/* <div className="grid grid-cols-3 gap-2"> */}
{/* <Link */}
{/* route="auth.google.initiate" */}
{/* className={cn(buttonVariants({ variant: 'outline' }), 'w-full')} */}
{/* > */}
{/* <span className="sr-only">Iniciar Sessão com o</span> Google */}
{/* {/* <Google className="h-5 w-5" /> */}
{/* </Link> */}
{/* <Link */}
{/* route="auth.github.initiate" */}
{/* className={cn(buttonVariants({ variant: 'outline' }), 'w-full')} */}
{/* > */}
{/* <span className="sr-only">Iniciar Sessão com o</span> Github */}
{/* {/* <Github className="h-5 w-5" /> */}
{/* </Link> */}
{/* <Link */}
{/* route="auth.linkedin.initiate" */}
{/* className={cn(buttonVariants({ variant: 'outline' }), 'w-full')} */}
{/* > */}
{/* <span className="sr-only">Iniciar Sessão com o</span> LinkedIn */}
{/* {/* <LinkedIn className="h-5 w-5" /> */}
{/* </Link> */}
{/* </div> */}
</div>
</div>
<div className="mt-4 text-center text-sm">
Expand All @@ -108,9 +107,9 @@ export default function Login() {
</Link>
</div>
</form>
{oauthError && <p className="text-sm text-red-600 text-center mt-4">{oauthError}</p>}
</CardContent>
</Card>
{oauthError && <p className="text-sm text-red-600 text-center">{oauthError}</p>}
</div>
</div>
</AppLayout>
Expand Down
66 changes: 32 additions & 34 deletions website/inertia/pages/register.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { Link } from '@tuyau/inertia/react'
import { Button, buttonVariants } from '~/components/ui/button'
import { Button } from '~/components/ui/button'
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '~/components/ui/card'
import { Input } from '~/components/ui/input'
import { Label } from '~/components/ui/label'
import { Separator } from '~/components/ui/separator'
import { useError } from '~/hooks/use_error'
import { useForm } from '@inertiajs/react'
import { cn } from '~/lib/utils'
Expand All @@ -28,7 +26,7 @@ export default function Login() {
<AppLayout title="Criar conta">
<div className="flex items-center justify-center w-full mt-24">
<div className="flex flex-col gap-6 max-w-sm">
<Card className={cn(oauthError && 'border-red-600')}>
<Card className={cn(oauthError && 'border-2 border-red-600')}>
<CardHeader>
<CardTitle className="text-2xl text-enei-blue">Criar conta</CardTitle>
<CardDescription>
Expand All @@ -42,7 +40,7 @@ export default function Login() {
<Label htmlFor="email">E-mail</Label>
<Input
id="email"
type="email"
type="text"
placeholder="[email protected]"
value={data.email}
onChange={(e) => setData('email', e.target.value)}
Expand Down Expand Up @@ -80,40 +78,40 @@ export default function Login() {
<Button type="submit" className="w-full bg-enei-blue">
Criar conta
</Button>
<div className="flex gap-2 items-center">
<Separator className="shrink" />
<p className="text-sm text-muted-foreground min-w-max">Ou</p>
<Separator className="shrink" />
</div>
<div className="grid grid-cols-3 gap-2">
<Link
route="auth.google.initiate"
className={cn(buttonVariants({ variant: 'outline' }), 'w-full')}
>
<span className="sr-only">Iniciar Sessão com o</span> Google
{/* <Google className="h-5 w-5" /> */}
</Link>
<Link
route="auth.github.initiate"
className={cn(buttonVariants({ variant: 'outline' }), 'w-full')}
>
<span className="sr-only">Iniciar Sessão com o</span> Github
{/* <Github className="h-5 w-5" /> */}
</Link>
<Link
route="auth.linkedin.initiate"
className={cn(buttonVariants({ variant: 'outline' }), 'w-full')}
>
<span className="sr-only">Iniciar Sessão com o</span> LinkedIn
{/* <LinkedIn className="h-5 w-5" /> */}
</Link>
</div>
{/* <div className="flex gap-2 items-center"> */}
{/* <Separator className="shrink" /> */}
{/* <p className="text-sm text-muted-foreground min-w-max">Ou</p> */}
{/* <Separator className="shrink" /> */}
{/* </div> */}
{/* <div className="grid grid-cols-3 gap-2"> */}
{/* <Link */}
{/* route="auth.google.initiate" */}
{/* className={cn(buttonVariants({ variant: 'outline' }), 'w-full')} */}
{/* > */}
{/* <span className="sr-only">Iniciar Sessão com o</span> Google */}
{/* {/* <Google className="h-5 w-5" /> */}
{/* </Link> */}
{/* <Link */}
{/* route="auth.github.initiate" */}
{/* className={cn(buttonVariants({ variant: 'outline' }), 'w-full')} */}
{/* > */}
{/* <span className="sr-only">Iniciar Sessão com o</span> Github */}
{/* {/* <Github className="h-5 w-5" /> */}
{/* </Link> */}
{/* <Link */}
{/* route="auth.linkedin.initiate" */}
{/* className={cn(buttonVariants({ variant: 'outline' }), 'w-full')} */}
{/* > */}
{/* <span className="sr-only">Iniciar Sessão com o</span> LinkedIn */}
{/* {/* <LinkedIn className="h-5 w-5" /> */}
{/* </Link> */}
{/* </div> */}
</div>
</div>
</form>
{oauthError && <p className="text-sm text-red-600 text-center mt-4">{oauthError}</p>}
</CardContent>
</Card>
{oauthError && <p className="text-sm text-red-600 text-center">{oauthError}</p>}
</div>
</div>
</AppLayout>
Expand Down
14 changes: 14 additions & 0 deletions website/types/validation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Types declared for error formats in the validators using vine
*/

export type VineValidationError = {
code: string
messages: Array<VineValidationErrorMessage>
}

export type VineValidationErrorMessage = {
rule: string
message: string
field: string
}

0 comments on commit d81c77d

Please sign in to comment.