Skip to content

Commit

Permalink
feat: add limiter and change route names
Browse files Browse the repository at this point in the history
  • Loading branch information
limwa committed Jan 21, 2025
1 parent 293c3f8 commit 80bcdc8
Show file tree
Hide file tree
Showing 14 changed files with 132 additions and 69 deletions.
3 changes: 2 additions & 1 deletion website/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ LINKEDIN_CLIENT_SECRET=********
# Frontend
INERTIA_PUBLIC_TZ=Europe/Lisbon
INERTIA_PUBLIC_EVENT_COUNTDOWN_DATE=2025-04-11
INERTIA_PUBLIC_APP_URL=http://127.0.0.1:3333
INERTIA_PUBLIC_APP_URL=http://127.0.0.1:3333
LIMITER_STORE=redis
1 change: 1 addition & 0 deletions website/adonisrc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export default defineConfig({
() => import('@adonisjs/mail/mail_provider'),
() => import('@tuyau/core/tuyau_provider'),
() => import('@adonisjs/ally/ally_provider'),
() => import('@adonisjs/limiter/limiter_provider')
],

/*
Expand Down
43 changes: 9 additions & 34 deletions website/app/controllers/authentication_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,10 @@ import Account from '#models/account'
import { socialAccountLoginValidator } from '#validators/account'
import User from '#models/user'
import type { HttpContext } from '@adonisjs/core/http'
import { registerWithCredentialsValidator, createUserValidatorErrorMessage } from '#validators/authentication'
import type { UserService } from '#services/user_service'
import { registerWithCredentialsValidator } from '#validators/authentication'
import { UserService } from '#services/auth_service'
import { inject } from '@adonisjs/core'

// async function getOrCreate(search: Pick<Account, 'provider' | 'providerId'>) {
// const account = await Account.firstOrCreate({
// provider: search.provider,
// providerId: search.providerId,
// })

// return account
// }

export default class AuthenticationController {
async login({ request, auth, response, session }: HttpContext) {
const { email, password } = request.only(['email', 'password'])
Expand All @@ -33,33 +24,17 @@ export default class AuthenticationController {
}

@inject()
async register({ request, auth, response, session }: HttpContext, userService: UserService) {
async register({ request, auth, response }: HttpContext, userService: UserService) {
const { email, password } = await request.validateUsing(registerWithCredentialsValidator)

userService.createUserWithCredentials(email, password)
const accountWithEmail = await Account.findByCredentials(email)
if (accountWithEmail) {
session.flash('errors', { oauth: 'Este e-mail já está em uso' })
return response.redirect().toRoute('view.register')
}

try {

const user = await User.create({ email })

// await Account.create({
// id: email,
// password: password,
// user_id: user.id,
// })
const user = await userService.createUserWithCredentials(email, password)
await auth.use('web').login(user)

await auth.use('web').login(user)
return response.redirect().toRoute('auth.email-confirmation.show')
}

response.redirect('/')
} catch (error) {
session.flash('errors', { oauth: 'Ocorreu um erro no registo' })
return response.redirect().toRoute('view.register')
}
async showEmailConfirmation({ inertia }: HttpContext) {
return inertia.render('email_confirmation')
}

async verify({ request, view }: HttpContext) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import UserCreated from '#events/user_created'
import User from '#models/user'
import app from '@adonisjs/core/services/app'
import db from '@adonisjs/lucid/services/db'

export class UserService {
async createUserWithCredentials(email: string, password: string) {
const db = await app.container.make("lucid.db")

const committedUser = await db.transaction(async (trx) => {
const user = await User.create({ email }, { client: trx })
await user.related('accounts').create({ id: `credentials:${email}`, password })

return user
})

Expand Down
31 changes: 31 additions & 0 deletions website/config/limiter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import env from '#start/env'
import { defineConfig, stores } from '@adonisjs/limiter'

const limiterConfig = defineConfig({
default: env.get('LIMITER_STORE'),

stores: {

/**
* Redis store to save rate limiting data inside a
* redis database.
*
* It is recommended to use a separate database for
* the limiter connection.
*/
redis: stores.redis({}),


/**
* Memory store could be used during
* testing
*/
memory: stores.memory({})
},
})

export default limiterConfig

declare module '@adonisjs/limiter/types' {
export interface LimitersList extends InferLimiters<typeof limiterConfig> {}
}
16 changes: 8 additions & 8 deletions website/inertia/components/navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Link } from '@inertiajs/react'
import { Button } from '~/components/ui/button'
import { Link } from '@tuyau/inertia/react'
import { Button, buttonVariants } from '~/components/ui/button'
import { cn } from '~/lib/utils'

/*
import { Menu } from "lucide-react";
Expand Down Expand Up @@ -28,6 +29,7 @@ type PageRoute = {
*/

export default function NavBar() {

/*
const navButtonStyle =
"font-space-grotesk uppercase group inline-flex h-9 w-max items-center justify-center text-base font-bold text-enei-beige focus:outline-none disabled:pointer-events-none";
Expand All @@ -48,14 +50,12 @@ export default function NavBar() {
return (
<>
<nav className="py-5 px-6 sm:px-12 md:px-24 lg:px-36 flex flex-row justify-between items-center flex-grow md:flex-grow-0">
<Link href="/">
<Link route="pages:home">
<img className="w-28 max-md:w-24" src="/images/logo-white.svg" alt="Logótipo da SINF" />
</Link>
<Button className="bg-enei-beige text-enei-blue">
<Link href="/login">
<span>Login</span>
</Link>
</Button>
<Link route="pages:auth.login" className={cn(buttonVariants(), "bg-enei-beige text-enei-blue")}>
<span>Login</span>
</Link>
{/*
<NavigationMenu className="hidden sm:block">
<NavigationMenuList className="gap-5">
Expand Down
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export default function Login() {
</div>
<div className="mt-4 text-center text-sm">
Ainda não tens conta?{' '}
<Link route="view.register">
<Link route="pages:auth.register">
<span className="underline">Regista-te</span>
</Link>
</div>
Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"@adonisjs/core": "^6.17.0",
"@adonisjs/cors": "^2.2.1",
"@adonisjs/inertia": "^2.1.0",
"@adonisjs/limiter": "^2.3.3",
"@adonisjs/lucid": "^21.5.1",
"@adonisjs/mail": "^9.2.2",
"@adonisjs/session": "^7.5.0",
Expand Down
27 changes: 27 additions & 0 deletions website/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions website/start/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ const env = await defineEnv(new URL('../', import.meta.url), 'INERTIA_PUBLIC_',
//RESEND_API_KEY: vine.string(),
//BREVO_API_KEY: vine.string()

/*
|----------------------------------------------------------
| Variables for configuring the limiter package
|----------------------------------------------------------
*/
LIMITER_STORE: vine.enum(['redis', 'memory'] as const),

/*
|----------------------------------------------------------
| Variables for configuring the social authentication
Expand Down
16 changes: 16 additions & 0 deletions website/start/limiter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
|--------------------------------------------------------------------------
| Define HTTP limiters
|--------------------------------------------------------------------------
|
| The "limiter.define" method creates an HTTP middleware to apply rate
| limits on a route or a group of routes. Feel free to define as many
| throttle middleware as needed.
|
*/

import limiter from '@adonisjs/limiter/services/main'

export const throttle = limiter.define('global', () => {
return limiter.allowRequests(10).every('1 minute')
})
48 changes: 27 additions & 21 deletions website/start/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,66 +12,72 @@ import { middleware } from '#start/kernel'
const AuthenticationController = () => import('#controllers/authentication_controller')
const TicketsController = () => import('#controllers/tickets_controller')

router.on('/').renderInertia('home')
router.on('/').renderInertia('home').as('pages:home')
router.get('/tickets', [TicketsController, 'index'])
router.on('/tickets/:id/checkout').renderInertia('payments').as('checkout')

router
.on('/login')
.renderInertia('login')
.use(middleware.redirectIfAuthenticated())
.as('view.login')

router
.on('/register')
.renderInertia('register')
.use(middleware.redirectIfAuthenticated())
.as('view.register')

router
.group(() => {
router
.on('/login')
.renderInertia('auth/login')
.as('pages:auth.login')
.use(middleware.redirectIfAuthenticated())

router
.post('/login', [AuthenticationController, 'login'])
.as('auth.login')
.as('actions:auth.login')
.use(middleware.redirectIfAuthenticated())

router
.on('/register')
.renderInertia('auth/register')
.as('pages:auth.register')
.use(middleware.redirectIfAuthenticated())

router
.post('/register', [AuthenticationController, 'register'])
.as('auth.register')
.as('actions:auth.register')
.use(middleware.redirectIfAuthenticated())

router
.get('/email-confirmation', [AuthenticationController, 'showEmailConfirmation'])
.as('pages:auth.email-confirmation')
.use(middleware.auth())

router
.route('/verify', ['GET', 'POST'], [AuthenticationController, 'verify'])
.as('actions:auth.verify')
.middleware(middleware.automaticSubmit())

// Github
router
.get('/github/initiate', [AuthenticationController, 'initiateGithubLogin'])
.as('auth.github.initiate')
.as('actions:auth.github.initiate')

router
.get('/github/callback', [AuthenticationController, 'callbackForGithubLogin'])
.middleware(middleware.verifySocialCallback({ provider: 'github' }))
.as('auth.github.callback')
.as('actions:auth.github.callback')

// Google
router
.get('/google/initiate', [AuthenticationController, 'initiateGoogleLogin'])
.as('auth.google.initiate')
.as('actions:auth.google.initiate')

router
.get('/google/callback', [AuthenticationController, 'callbackForGoogleLogin'])
.middleware(middleware.verifySocialCallback({ provider: 'google' }))
.as('auth.google.callback')
.as('actions:auth.google.callback')

// LinkedIn
router
.get('/linkedin/initiate', [AuthenticationController, 'initiateLinkedinLogin'])
.as('auth.linkedin.initiate')
.as('actions:auth.linkedin.initiate')

router
.get('/linkedin/callback', [AuthenticationController, 'callbackForLinkedinLogin'])
.middleware(middleware.verifySocialCallback({ provider: 'linkedin' }))
.as('auth.linkedin.callback')
.as('actions:auth.linkedin.callback')
})
.prefix('/auth')

0 comments on commit 80bcdc8

Please sign in to comment.