Last active
January 13, 2021 17:34
-
-
Save juyal-ahmed/58fc9c79ead0a7457e67acb0a6003748 to your computer and use it in GitHub Desktop.
OAuth2 google authentication and saving information on MongoDB database and later use the token / refreshtoken to retrieve profile information.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Admin/GmailController | |
* | |
* @description :: Server-side logic for managing admin/gmails | |
* @help :: See http://sailsjs.org/#!/documentation/concepts/Controllers | |
Help Links: | |
https://github.com/mscdex/node-imap | |
https://github.com/pipedrive/inbox | |
https://github.com/google/google-api-nodejs-client | |
*/ | |
var inbox = require("inbox"); | |
module.exports = { | |
createNewLabel: function(req, res) { | |
var LoggedInUserID = req.session.User.id; | |
GmailService.createNewLabel(LoggedInUserID, req, res, function(data) { | |
res.json(data); | |
}); | |
}, | |
getListsOfMailboxes: function(req, res) { | |
var LoggedInUserID = req.session.User.id; | |
GmailService.getListsOfMailboxes(LoggedInUserID, req, res, function(data) { | |
res.json(data); | |
}); | |
}, | |
oauth2callback: function(req, res) { | |
var code = req.param('code'); | |
if (code) { | |
console.log("Code"); | |
console.log(code); | |
req.oauth2Client.getToken(code, function (err, tokens) { | |
console.log("Tokens"); | |
console.log(tokens); | |
if (err) { | |
res.json({ | |
'err': err | |
}); | |
} else { | |
req.oauth2Client.setCredentials(tokens); | |
/* | |
console.log(tokens); | |
{ | |
access_token: 'ya29.C84BdZYHvjHSohDLkc_-3t_j00N4_7RoUAh8Aq9ERyZMSydRR-amSLg5qZ8kB05NSoxI', | |
token_type: 'Bearer', | |
id_token: 'eyJhbGciOiJSUzI1NiIsImNDcxNmZmNjA2ZjFhNmE1YTA3NDFkOTYifQ.eyJpc3MiOitpZCI6IjhlYjlhZDZjODc5MWRkMDhkJhY2NvdW50cy5nb29nbGUuY29tIiwiYXRfaGFzaCI6Iks4eFY0UktrcjAMDc3MTQ5MjItdXRmcTM1anBhdnZsdG5ucm00MWZnMHU4MGZzakgxNXRoV1BDVmciLCJhdWQiOiI2Nzg0vMHA0MXUuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMDk2Mzg3MjU5Njg1NjYwNTMyNzYiLCJhenAiOiI2Nzg0MDc3MTQ5MjItdXRmcTM1anBhdnZsdG5ucm00MWZc2VyY29udGVudC5jb20iLCJpYXQiOjE0NjE4MzQ4NjksInMHU4MGZvMHA0MXUuYXBwcy5nb29nbGV1mV4cCI6MTQ2MTgzODQ2OX0.sCGQ27Ev7tIAQi9pHIGP-sb6RocD-VMBO60Qyi8nG6jqctyS1ZZXDulvd1xmR5JCs9F8ZwKeSryCnX-7dAlXxG1T-vtugUKlHbpIkiPJK7LtiC0TJ8ihlZen03JqkQ6xHDun9t0htx8DwfOWx7MFMBxlB-zG0EhlBhsDSLni7zKVtsxatR1KHMQlnpEtWw7Kxp2TAmLIvAg5pKka2lVO2G-TKiBjo0Nq0lCgAIHzS992mgeShXB_ECCWekehCZt0LFHSE-n0ahOVaVQhoh7Pku_JIKZEnm0G6e9YbkXn9nkX6RxWTck57FVqE7iBY09bsJQgqsvp90DQl5Off3WvRQ', | |
expiry_date: 1461838469589, | |
refresh_token: '1/iz28CZ4aDzxfS1gsiv-qbsjWjNsSX4p0DMCRzyFta80' | |
} | |
*/ | |
//for storing email address to DB reading profile | |
req.plus.people.get({ userId: 'me', auth: req.oauth2Client }, function (err, profile) { | |
if (err) { | |
res.json({ | |
'err': err | |
}); | |
} else { | |
//Saving access token and refresh token to DB | |
var LoggedInUserID = req.session.User.id; | |
User.findOne(LoggedInUserID, function foundCB(err, loggedInUser) { | |
if (loggedInUser) { | |
User.update(LoggedInUserID, { | |
gmail_address: profile.emails[0].value, | |
access_token: tokens.access_token, | |
token_type: tokens.token_type, | |
id_token: tokens.id_token, | |
refresh_token: tokens.refresh_token | |
}, function(err) { | |
if (err) console.log(err); | |
res.redirect('/admin/gmail/index'); | |
}); | |
} else { | |
req.session.destroy(); | |
res.redirect('/admin/session/new'); | |
} | |
}); | |
} | |
}); | |
} | |
}); | |
} else { | |
res.redirect('/admin/gmail/index'); | |
} | |
}, | |
index: function(req, res) { | |
var LoggedInUserID = req.session.User.id; | |
User.findOne(LoggedInUserID, function froundCB(err, loggedInUser) { | |
//Checking the user already requested and granted app permission with google authentication | |
if (loggedInUser.access_token && loggedInUser.refresh_token) { | |
//Already refresh token available in DB | |
req.oauth2Client.setCredentials({ | |
access_token: loggedInUser.access_token, | |
refresh_token: loggedInUser.refresh_token | |
}); | |
req.oauth2Client.refreshAccessToken(function(err, tokens) { | |
req.oauth2Client.setCredentials({ | |
access_token: tokens.access_token, | |
refresh_token: tokens.refresh_token | |
}); | |
User.update(LoggedInUserID, { | |
access_token: tokens.access_token, | |
token_type: tokens.token_type, | |
id_token: tokens.id_token, | |
refresh_token: tokens.refresh_token | |
}, function(err) { | |
if (err) console.log(err); | |
req.plus.people.get({ userId: 'me', auth: req.oauth2Client }, function (err, profile) { | |
if (err) { | |
res.json({ | |
'err': err | |
}); | |
} else { | |
req.gmail.users.getProfile({ userId: 'me', auth: req.oauth2Client }, function (err, data) { | |
if (err) { | |
res.json({ | |
'err': err | |
}); | |
} else { | |
res.view({ | |
'allParams': req.allParams(), | |
'profile': profile, | |
'gmail_profile': data, | |
'folder': 'inbox' | |
}); | |
} | |
}); | |
} | |
}); | |
}); | |
}); | |
} else { | |
//different view with asking for google authentication and grant app access permission | |
res.view("admin/gmail/permission", { | |
'url': req.googleAuthUrl | |
}); | |
} | |
}); | |
} | |
}; | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = { | |
getListsOfMailboxes: function(LoggedInUserID, req, res, next) { | |
User.findOne(LoggedInUserID, function froundCB(err, loggedInUser) { | |
req.oauth2Client.setCredentials({ | |
access_token: loggedInUser.access_token, | |
refresh_token: loggedInUser.refresh_token | |
}); | |
req.gmail.users.labels.list({ userId: 'me', auth: req.oauth2Client }, function (err, data) { | |
if (err) console.log(err); | |
console.log("GmailService getListsOfMailboxes: "); | |
console.log(data); | |
next(data); | |
}); | |
}); | |
}, | |
createNewLabel: function(LoggedInUserID, req, res, next) { | |
User.findOne(LoggedInUserID, function froundCB(err, loggedInUser) { | |
req.oauth2Client.setCredentials({ | |
access_token: loggedInUser.access_token, | |
refresh_token: loggedInUser.refresh_token | |
}); | |
req.gmail.users.labels.create({ resource: {name: req.param('label'), messageListVisibility: 'show', labelListVisibility: 'labelShow'}, userId: 'me', auth: req.oauth2Client }, function (err, data) { | |
if (err) console.log(err); | |
req.gmail.users.labels.list({ userId: 'me', auth: req.oauth2Client }, function (err, data) { | |
if (err) console.log(err); | |
console.log("GmailService createNewLabel: "); | |
console.log(data); | |
next(data); | |
}); | |
}); | |
}); | |
} | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Help Links: | |
https://github.com/google/google-api-nodejs-client | |
https://developers.google.com/gmail/api/v1/reference/users/labels/create#parameters | |
So far seems this policy is working properly with Google Plus profile information! | |
*/ | |
var google = require('googleapis'); | |
module.exports = function(req, res, next) { | |
var CLIENT_ID = sails.config.email.google_app_client_id; | |
var CLIENT_SECRET = sails.config.email.google_app_secret; | |
var REDIRECT_URL = req.protocol + '://' + req.get('host') + '/admin/gmail/oauth2callback'; | |
var OAuth2Client = google.auth.OAuth2; | |
req.google = google; | |
req.plus = google.plus('v1'); | |
req.gmail = google.gmail('v1'); | |
req.oauth2Client = new OAuth2Client(CLIENT_ID, CLIENT_SECRET, REDIRECT_URL); | |
req.googleAuthUrl = req.oauth2Client.generateAuthUrl({ | |
approval_prompt: 'force', // will return a refresh token each time | |
access_type: 'offline', // will return a refresh token because we are going to access the api later with this refresh token | |
scope: [ | |
'https://www.googleapis.com/auth/plus.me', // can be a space-delimited string or an array of scopes | |
'https://www.googleapis.com/auth/plus.profile.emails.read', | |
'https://mail.google.com/', | |
'https://www.googleapis.com/auth/gmail.modify', | |
'https://www.googleapis.com/auth/gmail.insert', | |
'https://www.googleapis.com/auth/gmail.send', | |
'https://www.googleapis.com/auth/gmail.labels', | |
'https://www.googleapis.com/auth/gmail.compose', | |
'https://www.googleapis.com/auth/drive' | |
] | |
}); | |
return next(); | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports.policies = { | |
'admin/gmail': { | |
'*': ['oauth2'], | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var $admin = 'admin'; //admin mount path | |
module.exports.routes = { | |
'GET /admin/gmail': $admin + '/GmailController.index', | |
'GET /admin/gmail/index': $admin + '/GmailController.index', | |
'GET /admin/gmail/oauth2callback': $admin + '/GmailController.oauth2callback', | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* User.js | |
* | |
* @description :: TODO: You might write a short summary of how this model works and what it represents here. | |
* @docs :: http://sailsjs.org/#!documentation/models | |
*/ | |
//var sc = require("simplecrypt")(); | |
module.exports = { | |
schema: true, | |
attributes: { | |
user_group:{ | |
model: "UserGroup", | |
required: true | |
}, | |
username: { | |
type: "string", | |
required: true | |
}, | |
email: { | |
type: "string", | |
required: true | |
}, | |
first_name: { | |
type: "string", | |
required: true | |
}, | |
last_name: { | |
type: "string", | |
required: true | |
}, | |
password: { | |
type: "string", | |
required: true | |
}, | |
sex: { | |
type: "string" | |
}, | |
date_of_birth: { | |
type: "string" | |
}, | |
about: { | |
type: "string" | |
}, | |
address_line_1: { | |
type: "string" | |
}, | |
address_line_2: { | |
type: "string" | |
}, | |
country: { | |
type: "string" | |
}, | |
city: { | |
type: "string" | |
}, | |
state: { | |
type: "string" | |
}, | |
zip: { | |
type: "string" | |
}, | |
phone: { | |
type: "string" | |
}, | |
website: { | |
type: "string" | |
}, | |
online: { | |
type: 'boolean', | |
defaultsTo: false | |
}, | |
conversations: { | |
collection: "Conversations", | |
via: "users" | |
}, | |
meetings: { | |
collection: "Meeting", | |
via: "participants" | |
}, | |
current_active_socket_id: { | |
type: "string" | |
}, | |
avatarUrl: { | |
type: "string" | |
}, | |
gravatarUrl: { | |
type: "string" | |
}, | |
avatarFd: { | |
type: "string" | |
}, | |
gmail_address: { | |
type: "string" | |
}, | |
access_token: { | |
type: "text" | |
}, | |
refresh_token: { | |
type: "text" | |
}, | |
id_token: { | |
type: "text" | |
}, | |
token_type: { | |
type: "string" | |
}, | |
toJSON: function(){ | |
var obj = this.toObject(); | |
delete obj.password; | |
delete obj.confirmation; | |
delete obj._csrf; | |
return obj; | |
} | |
}, | |
beforeCreate: function(values, next) { | |
if ( !values.user_group || values.user_group == 'Select User Group' ) { | |
return next({err: ["Please select a user group for this user account."]}); | |
} | |
if (!values.password || values.password != values.confirmation ) { | |
return next({err: ["Password doesn't match password confirmation."]}); | |
} | |
//values.password = sc.encrypt(values.password); | |
//values.online = true; | |
next(); | |
}, | |
beforeUpdate: function(values, next) { | |
/*if ( ( values.id ) && ( values.user_group ) && values.user_group == 'Select User Group' ) { | |
return next({err: ["Please select a user group for this user account."]}); | |
} | |
if ( ( values.id ) && ( values.password || values.confirmation ) && values.password != values.confirmation ) { | |
return next({err: ["Password doesn't match password confirmation."]}); | |
}*/ | |
//values.password = sc.encrypt(values.password); | |
//values.online = true; | |
next(); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment