mirror of
https://github.com/Sonny93/my-links.git
synced 2025-12-08 22:53:25 +00:00
feat: add auth via google
This commit is contained in:
7
app/controllers/apps_controller.ts
Normal file
7
app/controllers/apps_controller.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { HttpContext } from '@adonisjs/core/http';
|
||||
|
||||
export default class AppsController {
|
||||
index({ inertia }: HttpContext) {
|
||||
return inertia.render('home');
|
||||
}
|
||||
}
|
||||
56
app/controllers/users_controller.ts
Normal file
56
app/controllers/users_controller.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import User from '#models/user';
|
||||
import type { HttpContext } from '@adonisjs/core/http';
|
||||
import logger from '@adonisjs/core/services/logger';
|
||||
|
||||
export default class UsersController {
|
||||
private redirectTo = '/';
|
||||
|
||||
google = ({ ally }: HttpContext) => ally.use('google').redirect();
|
||||
|
||||
async callbackAuth({ ally, auth, response, session }: HttpContext) {
|
||||
const google = ally.use('google');
|
||||
if (google.accessDenied()) {
|
||||
// TODO: translate error messages + show them in UI
|
||||
session.flash('flash', 'Access was denied');
|
||||
return response.redirect(this.redirectTo);
|
||||
}
|
||||
|
||||
if (google.stateMisMatch()) {
|
||||
session.flash('flash', 'Request expired. Retry again');
|
||||
return response.redirect(this.redirectTo);
|
||||
}
|
||||
|
||||
if (google.hasError()) {
|
||||
session.flash('flash', google.getError() || 'Something went wrong');
|
||||
return response.redirect(this.redirectTo);
|
||||
}
|
||||
|
||||
const { email, id: providerId, name, nickName, avatarUrl, token } = await google.user();
|
||||
const user = await User.updateOrCreate(
|
||||
{
|
||||
email,
|
||||
},
|
||||
{
|
||||
email,
|
||||
providerId,
|
||||
name,
|
||||
nickName,
|
||||
avatarUrl,
|
||||
token,
|
||||
}
|
||||
);
|
||||
|
||||
await auth.use('web').login(user);
|
||||
session.flash('flash', 'Successfully authenticated');
|
||||
logger.info(`[${user.email}] auth success`);
|
||||
|
||||
response.redirect('/');
|
||||
}
|
||||
|
||||
async logout({ auth, response, session }: HttpContext) {
|
||||
await auth.use('web').logout();
|
||||
session.flash('flash', 'Successfully disconnected');
|
||||
logger.info(`[${auth.user?.email}] disconnected successfully`);
|
||||
response.redirect('/');
|
||||
}
|
||||
}
|
||||
5
app/models/app_base_model.ts
Normal file
5
app/models/app_base_model.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { BaseModel, CamelCaseNamingStrategy } from '@adonisjs/lucid/orm';
|
||||
|
||||
export default class AppBaseModel extends BaseModel {
|
||||
static namingStrategy = new CamelCaseNamingStrategy();
|
||||
}
|
||||
@@ -1,30 +1,53 @@
|
||||
import type { GoogleToken } from '@adonisjs/ally/types';
|
||||
import { beforeCreate, column } from '@adonisjs/lucid/orm';
|
||||
import { 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 { v4 as uuidv4 } from 'uuid';
|
||||
import AppBaseModel from './app_base_model.js';
|
||||
|
||||
const AuthFinder = withAuthFinder(() => hash.use('scrypt'), {
|
||||
uids: ['email'],
|
||||
passwordColumnName: 'password',
|
||||
});
|
||||
export default class User extends AppBaseModel {
|
||||
static selfAssignPrimaryKey = true;
|
||||
|
||||
export default class User extends compose(BaseModel, AuthFinder) {
|
||||
@column({ isPrimary: true })
|
||||
declare id: number;
|
||||
|
||||
@column()
|
||||
declare fullName: string | null;
|
||||
declare id: string; // UUID
|
||||
|
||||
@column()
|
||||
declare email: string;
|
||||
|
||||
@column()
|
||||
declare password: string;
|
||||
declare name: string;
|
||||
|
||||
@column.dateTime({ autoCreate: true })
|
||||
@column({ serializeAs: 'nickName' })
|
||||
declare nickName: string; // public username
|
||||
|
||||
@column({ serializeAs: 'avatarUrl' })
|
||||
declare avatarUrl: string;
|
||||
|
||||
declare isAdmin: boolean;
|
||||
|
||||
@column({ serializeAs: null })
|
||||
declare token: GoogleToken;
|
||||
|
||||
@column({ serializeAs: null })
|
||||
declare providerId: string;
|
||||
|
||||
@column.dateTime({
|
||||
autoCreate: true,
|
||||
serialize: (value: DateTime) => value.toISODate(),
|
||||
serializeAs: 'createdAt',
|
||||
})
|
||||
declare createdAt: DateTime;
|
||||
|
||||
@column.dateTime({ autoCreate: true, autoUpdate: true })
|
||||
declare updatedAt: DateTime | null;
|
||||
@column.dateTime({
|
||||
autoCreate: true,
|
||||
autoUpdate: true,
|
||||
serialize: (value: DateTime) => value.toISODate(),
|
||||
serializeAs: 'updatedAt',
|
||||
})
|
||||
declare updatedAt: DateTime;
|
||||
|
||||
@beforeCreate()
|
||||
static assignUuid(user: User) {
|
||||
user.id = uuidv4();
|
||||
user.isAdmin = false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user