diff --git a/app/Controllers/Http/AuthController.ts b/app/Controllers/Http/AuthController.ts index a5080b6..e8269eb 100644 --- a/app/Controllers/Http/AuthController.ts +++ b/app/Controllers/Http/AuthController.ts @@ -60,4 +60,55 @@ export default class AuthController { return { user } } + public async twitter ({ally, auth}: HttpContextContract) { + const twitter = ally.use('twitter') + const twitterUser = await twitter.user() + + const user = await User.firstOrCreate({ + email: twitterUser.email, + }, { + email: twitterUser.email, + username: twitterUser.name, + isConfirmed: twitterUser.emailVerificationState === 'verified' + }) + + await auth.use('web').login(user) + + return { user } + } + + public async github ({ally, auth}: HttpContextContract) { + const github = ally.use('github') + const githubUser = await github.user() + + const user = await User.firstOrCreate({ + email: githubUser.email, + }, { + email: githubUser.email, + username: githubUser.name, + isConfirmed: githubUser.emailVerificationState === 'verified' + }) + + await auth.use('web').login(user) + + return { user } + } + + public async google ({ally, auth}: HttpContextContract) { + const google = ally.use('google') + const googleUser = await google.user() + + const user = await User.firstOrCreate({ + email: googleUser.email, + }, { + email: googleUser.email, + username: googleUser.name, + isConfirmed: googleUser.emailVerificationState === 'verified' + }) + + await auth.use('web').login(user) + + return { user } + } + } diff --git a/app/Controllers/Http/GoldenMessagesController.ts b/app/Controllers/Http/GoldenMessagesController.ts new file mode 100644 index 0000000..9b16633 --- /dev/null +++ b/app/Controllers/Http/GoldenMessagesController.ts @@ -0,0 +1,20 @@ +import {HttpContextContract} from "@ioc:Adonis/Core/HttpContext"; +import GoldenMessage from "../../Models/GoldenMessage"; +import StoreValidator from "../../Validators/goldenmessages/StoreValidator"; + +export default class GoldenMessagesController { + + public async index () { + return GoldenMessage.query().orderBy('created_at', 'desc') + } + + public async store ({request}: HttpContextContract) { + const data = await request.validate(StoreValidator) + return await GoldenMessage.create(data) + } + + public async show ({params}: HttpContextContract) { + return await GoldenMessage.findOrFail(params.id) + } + +} diff --git a/app/Validators/goldenmessages/StoreValidator.ts b/app/Validators/goldenmessages/StoreValidator.ts new file mode 100644 index 0000000..10463d6 --- /dev/null +++ b/app/Validators/goldenmessages/StoreValidator.ts @@ -0,0 +1,24 @@ +import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext' +import {rules, schema} from '@ioc:Adonis/Core/Validator' + +export default class StoreValidator { + constructor (private ctx: HttpContextContract) { + } + + public schema = schema.create({ + user_id: schema.number( [ + rules.required(), + rules.unique({table: 'golden_messages', column: 'user_id'}), + rules.exists({ table: 'users', column: 'id'}) + ]), + message: schema.string({}, [ + rules.required() + ]) + }) + + public cacheKey = this.ctx.routeKey + + public messages = { + required: 'Le champ {{field}} doit ĂȘtre valide !', + } +} diff --git a/config/ally.ts b/config/ally.ts index afbbfd5..a95ab49 100644 --- a/config/ally.ts +++ b/config/ally.ts @@ -27,7 +27,7 @@ const allyConfig: AllyConfig = { driver: 'github', clientId: Env.get('GITHUB_CLIENT_ID'), clientSecret: Env.get('GITHUB_CLIENT_SECRET'), - callbackUrl: 'http://localhost:3333/github', + callbackUrl: 'http://localhost:5555/github', }, /* |-------------------------------------------------------------------------- @@ -38,7 +38,7 @@ const allyConfig: AllyConfig = { driver: 'twitter', clientId: Env.get('TWITTER_CLIENT_ID'), clientSecret: Env.get('TWITTER_CLIENT_SECRET'), - callbackUrl: 'http://localhost:3333/twitter', + callbackUrl: 'http://localhost:5555/twitter', }, /* |-------------------------------------------------------------------------- @@ -49,7 +49,7 @@ const allyConfig: AllyConfig = { driver: 'google', clientId: Env.get('GOOGLE_CLIENT_ID'), clientSecret: Env.get('GOOGLE_CLIENT_SECRET'), - callbackUrl: 'http://localhost:3333/google', + callbackUrl: 'http://localhost:5555/google', }, } diff --git a/config/auth.ts b/config/auth.ts index 1209c01..557179b 100644 --- a/config/auth.ts +++ b/config/auth.ts @@ -17,8 +17,69 @@ import { AuthConfig } from '@ioc:Adonis/Addons/Auth' | */ const authConfig: AuthConfig = { - guard: 'api', + guard: 'web', guards: { + /* + |-------------------------------------------------------------------------- + | Web Guard + |-------------------------------------------------------------------------- + | + | Web guard uses classic old school sessions for authenticating users. + | If you are building a standard web application, it is recommended to + | use web guard with session driver + | + */ + web: { + driver: 'session', + + provider: { + /* + |-------------------------------------------------------------------------- + | Driver + |-------------------------------------------------------------------------- + | + | Name of the driver + | + */ + driver: 'lucid', + + /* + |-------------------------------------------------------------------------- + | Identifier key + |-------------------------------------------------------------------------- + | + | The identifier key is the unique key on the model. In most cases specifying + | the primary key is the right choice. + | + */ + identifierKey: 'id', + + /* + |-------------------------------------------------------------------------- + | Uids + |-------------------------------------------------------------------------- + | + | Uids are used to search a user against one of the mentioned columns. During + | login, the auth module will search the user mentioned value against one + | of the mentioned columns to find their user record. + | + */ + uids: ['email'], + + /* + |-------------------------------------------------------------------------- + | Model + |-------------------------------------------------------------------------- + | + | The model to use for fetching or finding users. The model is imported + | lazily since the config files are read way earlier in the lifecycle + | of booting the app and the models may not be in a usable state at + | that time. + | + */ + model: () => import('App/Models/User'), + }, + }, /* |-------------------------------------------------------------------------- | OAT Guard diff --git a/contracts/auth.ts b/contracts/auth.ts index 90916e2..a498628 100644 --- a/contracts/auth.ts +++ b/contracts/auth.ts @@ -55,6 +55,19 @@ declare module '@ioc:Adonis/Addons/Auth' { | */ interface GuardsList { + /* + |-------------------------------------------------------------------------- + | Web Guard + |-------------------------------------------------------------------------- + | + | The web guard uses sessions for maintaining user login state. It uses + | the `user` provider for fetching user details. + | + */ + web: { + implementation: SessionGuardContract<'user', 'web'>, + config: SessionGuardConfig<'user'>, + }, /* |-------------------------------------------------------------------------- | OAT Guard diff --git a/start/routes.ts b/start/routes.ts index 6229c25..d450797 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -75,4 +75,8 @@ Route.group(() => { Route.post('/api/login', 'AuthController.loginApi') Route.post('/api/logout', 'AuthController.logoutApi') + + Route.get('/twitter', 'AuthController.twitter') + Route.get('/github', 'AuthController.github') + Route.get('/google', 'AuthController.google') }).prefix('auth')