Files
absens-api/app/core/services/authGoogle.service.js

128 lines
3.4 KiB
JavaScript

const db = require('../../../models/migration')
const { OAuth2Client } = require("google-auth-library");
const dotenv = require('dotenv');
dotenv.config();
const googleClientId = process.env.GOOGLE_CLIENT_ID;
const jwt = require('jsonwebtoken')
exports.loginWithGoogle = async (req, res) => {
const t = await db.sequelize.transaction();
try {
const {name, email, google_token } = req.body;
if (!email || !google_token) {
await t.rollback();
return responses.failed(res, 400, 'Email and Google token are required');
}
const client = new OAuth2Client(googleClientId);
const ticket = await client.verifyIdToken({
idToken: google_token,
audience: googleClientId,
});
const payload = ticket.getPayload();
const googleName = payload.name;
const googleAvatar = payload.picture;
if (
payload.iss !== 'accounts.google.com' &&
payload.iss !== 'https://accounts.google.com'
) {
await t.rollback();
return responses.failed(res, 400, 'Invalid token issuer');
}
if (payload.email !== email) {
await t.rollback();
return responses.failed(res, 400, 'Email mismatch');
}
let findUser = await db.User.findOne({
where: { email: email },
});
let isFirstLogin = false;
if (!findUser) {
findUser = await db.User.create({
email: email,
name: googleName,
avatar: googleAvatar,
status: 'ACTIVE',
login_via: 'GOOGLE',
}, { transaction: t });
const user_id = findUser.id;
await db.Branch.create({
name: 'Personal',
initial_balance: 0,
current_balance: 0,
created_by: user_id,
user_id: user_id
}, { transaction: t });
await db.Category.create({
name: 'Umum',
transaction_type: 'income',
icons: '💵',
user_id: user_id
}, { transaction: t });
await db.Wallet.create({
name: 'Dompet',
current_balance: 0,
type: 'Cash',
user_id: user_id
}, { transaction: t });
isFirstLogin = true;
} else {
isFirstLogin = findUser.last_login === null;
}
const tokenJwt = jwt.sign(
{
id: findUser.id,
},
process.env.JWT_SECRET_KEY
);
const data = {
is_google_login: true,
token: tokenJwt,
user_data: {
id: findUser.id,
name: findUser.name || googleName,
avatar: findUser.avatar || googleAvatar,
username: findUser.username,
email: findUser.email,
},
google_ticket: ticket,
};
await t.commit();
return res
.status(200)
.json({ success: true, message: 'Login successful', data });
} catch (error) {
await t.rollback()
console.error('Error logging in with Google:', error);
return res
.status(500)
.json({ success: false, message: error.message });
}
};