Skip to content

Commit fef6d51

Browse files
Merge pull request #1 from bleriotnoguia/develop
Develop
2 parents 56c01df + 98deeba commit fef6d51

42 files changed

Lines changed: 2231 additions & 364 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,7 @@ DB_HOST=127.0.0.1
99
DB_PORT=3306
1010
DB_USER=root
1111
DB_PASSWORD=root
12-
DB_DATABASE=app
12+
DB_DATABASE=app
13+
GITHUB_CLIENT_ID=
14+
GITHUB_CLIENT_SECRET=
15+
GITHUB_CALLBACK_URL=

adonisrc.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ export default defineConfig({
3737
() => import('@adonisjs/cors/cors_provider'),
3838
() => import('@adonisjs/lucid/database_provider'),
3939
() => import('@adonisjs/auth/auth_provider'),
40-
() => import('@adonisjs/inertia/inertia_provider')
40+
() => import('@adonisjs/inertia/inertia_provider'),
41+
() => import('@adonisjs/ally/ally_provider'),
4142
],
4243

4344
/*
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { HttpContext } from '@adonisjs/core/http'
2+
import { articleValidator } from '#validators/article_validator'
3+
import Article from '#models/article'
4+
import { DateTime } from 'luxon'
5+
6+
export default class ArticlesController {
7+
async index({ inertia, request }: HttpContext) {
8+
const page = request.input('page', 1)
9+
const articles = await Article.query()
10+
.preload('author')
11+
.where('is_published', true)
12+
.orderBy('published_at', 'desc')
13+
.paginate(page, 10)
14+
15+
return inertia.render('articles/index', {
16+
articles: articles.toJSON(),
17+
})
18+
}
19+
20+
async create({ inertia }: HttpContext) {
21+
return inertia.render('articles/create')
22+
}
23+
24+
async store({ request, auth, response }: HttpContext) {
25+
const data = await articleValidator.validate(request.all())
26+
const article = new Article()
27+
28+
article.title = data.title
29+
article.content = data.content
30+
article.excerpt = data.excerpt
31+
article.isPublished = data.isPublished || false
32+
article.authorId = auth.user!.id
33+
if (data.isPublished) {
34+
article.publishedAt = DateTime.now()
35+
}
36+
37+
await article.generateSlug()
38+
await article.save()
39+
40+
return response.redirect().toRoute('articles.show', { slug: article.slug })
41+
}
42+
43+
async show({ inertia, params }: HttpContext) {
44+
const article = await Article.query().where('slug', params.slug).preload('author').firstOrFail()
45+
46+
return inertia.render('articles/[slug]', { article })
47+
}
48+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { HttpContext } from '@adonisjs/core/http'
2+
import User from '#models/user'
3+
import type { GithubDriver } from '@adonisjs/ally/drivers/github'
4+
5+
export default class GithubController {
6+
async redirect({ ally }: HttpContext) {
7+
return (ally.use('github') as GithubDriver).redirect()
8+
}
9+
10+
async callback({ ally, auth, response }: HttpContext) {
11+
const github = ally.use('github') as GithubDriver
12+
13+
/**
14+
* User has explicitly cancelled the login flow
15+
*/
16+
if (github.accessDenied()) {
17+
return response.redirect().toRoute('login')
18+
}
19+
20+
/**
21+
* OAuth state verification failed. This happens when the
22+
* CSRF cookie gets expired or request is forged
23+
*/
24+
if (github.stateMisMatch()) {
25+
return response.redirect().toRoute('login')
26+
}
27+
28+
/**
29+
* GitHub responded with some error
30+
*/
31+
if (github.hasError()) {
32+
return response.redirect().toRoute('login')
33+
}
34+
35+
/**
36+
* Get user details from GitHub
37+
*/
38+
const githubUser = await github.user()
39+
40+
/**
41+
* Find or create user by GitHub ID
42+
*/
43+
const user = await User.firstOrCreate(
44+
{
45+
githubId: githubUser.id,
46+
},
47+
{
48+
username: githubUser.nickName,
49+
name: githubUser.name,
50+
email: githubUser.email!,
51+
avatar: githubUser.avatarUrl,
52+
githubId: githubUser.id,
53+
}
54+
)
55+
56+
/**
57+
* Login user using the web guard
58+
*/
59+
await auth.use('web').login(user)
60+
return response.redirect().toRoute('dashboard')
61+
}
62+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { loginValidator } from '#validators/login_validator'
2+
import { HttpContext } from '@adonisjs/core/http'
3+
import User from '#models/user'
4+
import { errors } from '@adonisjs/auth'
5+
export default class LoginController {
6+
async show({ inertia }: HttpContext) {
7+
return inertia.render('auth/login')
8+
}
9+
10+
async login({ request, auth, response, session }: HttpContext) {
11+
const data = await loginValidator.validate(request.all())
12+
const user = await User.verifyCredentials(data.email, data.password)
13+
14+
try {
15+
await auth.use('web').login(user)
16+
return response.redirect().toRoute('dashboard')
17+
} catch (error) {
18+
if (error instanceof errors.E_INVALID_CREDENTIALS) {
19+
session.flash('errors', { form: 'Invalid credentials' })
20+
return response.redirect().back()
21+
}
22+
throw error
23+
}
24+
}
25+
26+
async logout({ auth, response }: HttpContext) {
27+
await auth.use('web').logout()
28+
return response.redirect().toRoute('login')
29+
}
30+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { HttpContext } from '@adonisjs/core/http'
2+
import User from '#models/user'
3+
import { registerValidator } from '#validators/register_validator'
4+
5+
export default class RegisterController {
6+
async show({ inertia }: HttpContext) {
7+
return inertia.render('auth/register')
8+
}
9+
10+
async store({ request, auth, response }: HttpContext) {
11+
const data = await registerValidator.validate(request.all())
12+
13+
const user = await User.create(data)
14+
await auth.use('web').login(user)
15+
16+
return response.redirect().toRoute('dashboard')
17+
}
18+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { HttpContext } from '@adonisjs/core/http'
2+
import User from '#models/user'
3+
import Article from '#models/article'
4+
5+
export default class ProfileController {
6+
async show({ params, inertia }: HttpContext) {
7+
const user = await User.findByOrFail('username', params.username.replace('@', ''))
8+
const articles = await Article.query()
9+
.where('author_id', user.id)
10+
.where('is_published', true)
11+
.orderBy('created_at', 'desc')
12+
.preload('author')
13+
14+
return inertia.render('profile/show', {
15+
profile: {
16+
...user.serialize(),
17+
articles: articles,
18+
},
19+
})
20+
}
21+
}

app/middleware/auth_middleware.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ export default class AuthMiddleware {
2222
await ctx.auth.authenticateUsing(options.guards, { loginRoute: this.redirectTo })
2323
return next()
2424
}
25-
}
25+
}

app/middleware/container_bindings_middleware.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ export default class ContainerBindingsMiddleware {
1313
handle(ctx: HttpContext, next: NextFn) {
1414
ctx.containerResolver.bindValue(HttpContext, ctx)
1515
ctx.containerResolver.bindValue(Logger, ctx.logger)
16-
1716
return next()
1817
}
1918
}

app/middleware/guest_middleware.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export default class GuestMiddleware {
1313
/**
1414
* The URL to redirect to when user is logged-in
1515
*/
16-
redirectTo = '/'
16+
redirectTo = '/dashboard'
1717

1818
async handle(
1919
ctx: HttpContext,
@@ -25,7 +25,6 @@ export default class GuestMiddleware {
2525
return ctx.response.redirect(this.redirectTo, true)
2626
}
2727
}
28-
2928
return next()
3029
}
31-
}
30+
}

0 commit comments

Comments
 (0)