Skip to content

Commit

Permalink
Merge branch 'release/0.3.0' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
prisca-c committed May 7, 2024
2 parents c31a8f0 + 3a34735 commit 83c8146
Show file tree
Hide file tree
Showing 47 changed files with 2,384 additions and 157 deletions.
12 changes: 11 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,19 @@ HOST=localhost
LOG_LEVEL=info
APP_KEY=lTtQy5-Mp2Vl-lhSrc92tBLhWitA7JK8
NODE_ENV=development

SESSION_DRIVER=cookie

DB_HOST=127.0.0.1
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=
DB_DATABASE=
DB_DATABASE=

REDIS_PASSWORD=
REDIS_HOST=127.0.0.1
REDIS_PORT=6379

TWITCH_CLIENT_ID=
TWITCH_CLIENT_SECRET=
TWITCH_CALLBACK_URL=
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ yarn-error.log

# Platform specific
.DS_Store
/data/
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
# Change Log

## [UNRELEASED]

## [0.3.0] - 2024-05-07

- Add `TailwindCSS` to the project.
- Setup `Redis` to handle session storage.
- Add `docker-compose.yaml` to the project to handle PostgreSQL and Redis in development environment.
- Setup `OAuth2` authentication's controller and routes (Twitch for now).
- Add i18n handling on frontend with `react-i18next`.
- Setup default layout to pages.

## [0.2.0] - 2024-05-01

### Added

- ~~Add i18n handling to the project with `next-intl`.~~
- Switch project from `NextJS` to `AdonisJS`.

## [0.1.1] - 2024-04-25

### Added
6 changes: 4 additions & 2 deletions adonisrc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ export default defineConfig({
() => import('@adonisjs/lucid/database_provider'),
() => import('@adonisjs/auth/auth_provider'),
() => import('@adonisjs/inertia/inertia_provider'),
() => import('@adonisjs/i18n/i18n_provider')
() => import('@adonisjs/i18n/i18n_provider'),
() => import('@adonisjs/redis/redis_provider'),
() => import('@adonisjs/ally/ally_provider')
],

/*
Expand Down Expand Up @@ -97,7 +99,7 @@ export default defineConfig({
{
pattern: 'resources/lang/**/*.{json,yaml,yml}',
reloadServer: false,
}
},
],

assetsBundler: false,
Expand Down
50 changes: 50 additions & 0 deletions app/controllers/auth_controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import type { HttpContext } from '@adonisjs/core/http'
import User from '#models/user'
import Provider from '#models/provider'
import { DateTime } from 'luxon'

export default class AuthController {
async redirect({ ally, params }: HttpContext) {
const providerParams = params.provider
const socialProvider = ally.use(providerParams)
return await socialProvider.redirect()
}

async callback({ ally, auth, response, params, session }: HttpContext) {
const providerParams = params.provider
const socialProvider = ally.use(providerParams)

if (
socialProvider.accessDenied() ||
socialProvider.stateMisMatch() ||
socialProvider.hasError()
) {
return response.redirect('/login')
}

const socialUser = await socialProvider.user()

if (socialUser) {
const provider = await Provider.findByOrFail('name', providerParams)
await User.firstOrCreate(
{ email: socialUser.email },
{
email: socialUser.email,
username: socialUser.nickName,
avatarUrl: socialUser.avatarUrl,
providerId: provider.id,
}
)

const user = await User.findByOrFail('email', socialUser.email)
await auth.use('web').login(user)

user.lastSessionId = session.sessionId
user.lastSessionAt = DateTime.now()
await user.save()

return response.redirect('/')
}
return response.redirect('/')
}
}
7 changes: 7 additions & 0 deletions app/controllers/home_controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { HttpContext } from '@adonisjs/core/http'

export default class HomeController {
handle({ inertia }: HttpContext) {
return inertia.render('home')
}
}
7 changes: 7 additions & 0 deletions app/controllers/login_controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { HttpContext } from '@adonisjs/core/http'

export default class LoginController {
handle({ inertia }: HttpContext) {
return inertia.render('login')
}
}
2 changes: 1 addition & 1 deletion app/middleware/auth_middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ export default class AuthMiddleware {
await ctx.auth.authenticateUsing(options.guards, { loginRoute: this.redirectTo })
return next()
}
}
}
2 changes: 1 addition & 1 deletion app/middleware/detect_user_locale_middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,4 @@ declare module '@adonisjs/core/http' {
export interface HttpContext {
i18n: I18n
}
}
}
2 changes: 1 addition & 1 deletion app/middleware/guest_middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ export default class GuestMiddleware {

return next()
}
}
}
19 changes: 19 additions & 0 deletions app/models/provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { DateTime } from 'luxon'
import { BaseModel, column } from '@adonisjs/lucid/orm'
import type { Opaque } from '@poppinss/utils/types'

export type ProviderId = Opaque<number, 'ProviderId'>

export default class Provider extends BaseModel {
@column({ isPrimary: true })
declare id: ProviderId

@column()
declare name: string

@column.dateTime({ autoCreate: true })
declare createdAt: DateTime

@column.dateTime({ autoCreate: true, autoUpdate: true })
declare updatedAt: DateTime
}
30 changes: 24 additions & 6 deletions app/models/user.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,48 @@
import { DateTime } from 'luxon'
import type { DateTime } from 'luxon'
import hash from '@adonisjs/core/services/hash'
import { compose } from '@adonisjs/core/helpers'
import { BaseModel, column } from '@adonisjs/lucid/orm'
import { withAuthFinder } from '@adonisjs/auth/mixins/lucid'
import type { Opaque } from '@poppinss/utils/types'

const AuthFinder = withAuthFinder(() => hash.use('scrypt'), {
uids: ['email'],
uids: ['username', 'email'],
passwordColumnName: 'password',
})

export type UserId = Opaque<string, 'UserId'>

export default class User extends compose(BaseModel, AuthFinder) {
@column({ isPrimary: true })
declare id: number
declare id: UserId

@column()
declare fullName: string | null
declare username: string

@column()
declare email: string

@column()
declare password: string
declare emailVerifiedAt: DateTime | null

@column()
declare avatarUrl: string | null

@column()
declare providerId: number

@column()
declare password: string | null

@column()
declare lastSessionId: string | null

@column()
declare lastSessionAt: DateTime | null

@column.dateTime({ autoCreate: true })
declare createdAt: DateTime

@column.dateTime({ autoCreate: true, autoUpdate: true })
declare updatedAt: DateTime | null
}
}
17 changes: 17 additions & 0 deletions config/ally.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import env from '#start/env'
import { defineConfig } from '@adonisjs/ally'
import { twitch } from '@rlanz/ally-twitch'

const allyConfig = defineConfig({
twitch: twitch({
clientId: env.get('TWITCH_CLIENT_ID'),
clientSecret: env.get('TWITCH_CLIENT_SECRET'),
callbackUrl: env.get('TWITCH_CALLBACK_URL'),
}),
})

export default allyConfig

declare module '@adonisjs/ally/types' {
interface SocialProviders extends InferSocialProviders<typeof allyConfig> {}
}
4 changes: 2 additions & 2 deletions config/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const authConfig = defineConfig({
web: sessionGuard({
useRememberMeTokens: false,
provider: sessionUserProvider({
model: () => import('#models/user')
model: () => import('#models/user'),
}),
}),
},
Expand All @@ -25,4 +25,4 @@ declare module '@adonisjs/auth/types' {
}
declare module '@adonisjs/core/types' {
interface EventsList extends InferAuthEvents<Authenticators> {}
}
}
2 changes: 1 addition & 1 deletion config/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ const dbConfig = defineConfig({
},
})

export default dbConfig
export default dbConfig
6 changes: 3 additions & 3 deletions config/inertia.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ export default defineConfig({
*/
ssr: {
enabled: true,
entrypoint: 'inertia/app/ssr.tsx'
}
})
entrypoint: 'inertia/app/ssr.tsx',
},
})
36 changes: 36 additions & 0 deletions config/redis.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import env from '#start/env'
import { defineConfig } from '@adonisjs/redis'
import { InferConnections } from '@adonisjs/redis/types'

const redisConfig = defineConfig({
connection: 'main',

connections: {
/*
|--------------------------------------------------------------------------
| The default connection
|--------------------------------------------------------------------------
|
| The main connection you want to use to execute redis commands. The same
| connection will be used by the session provider, if you rely on the
| redis driver.
|
*/
main: {
host: env.get('REDIS_HOST'),
port: env.get('REDIS_PORT'),
password: env.get('REDIS_PASSWORD', ''),
db: 0,
keyPrefix: '',
retryStrategy(times) {
return times > 10 ? null : times * 50
},
},
},
})

export default redisConfig

declare module '@adonisjs/redis/types' {
export interface RedisConnections extends InferConnections<typeof redisConfig> {}
}
4 changes: 4 additions & 0 deletions config/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ const sessionConfig = defineConfig({
*/
stores: {
cookie: stores.cookie(),

redis: stores.redis({
connection: 'main',
}),
},
})

Expand Down
31 changes: 31 additions & 0 deletions database/migrations/1714403715625_create_providers_table.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { BaseSchema } from '@adonisjs/lucid/schema'
import { DateTime } from 'luxon'

export default class extends BaseSchema {
protected tableName = 'providers'

async up() {
this.schema.createTable(this.tableName, (table) => {
table.increments('id')
table.string('name').unique().notNullable()
table.timestamp('created_at', { useTz: true })
table.timestamp('updated_at', { useTz: true })
})

const providers = ['twitch', 'youtube', 'kick', 'discord']

this.defer(async () => {
for (const provider of providers) {
await this.db.insertQuery().table(this.tableName).insert({
name: provider,
created_at: DateTime.now(),
updated_at: DateTime.now(),
})
}
})
}

async down() {
this.schema.dropTable(this.tableName)
}
}
Loading

0 comments on commit 83c8146

Please sign in to comment.