lib/oauth.js (56 lines of code) (raw):
/**
* Copyright 2018, Google LLC
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
const config = require('../config');
const Datastore = require('@google-cloud/datastore');
const datastore = new Datastore();
const path = require('path');
const pify = require('pify');
const fs = require('fs');
const google = require('googleapis');
const gmail = google.gmail('v1');
// Retrieve OAuth2 config
const clientSecretPath = path.join(path.dirname(__dirname), 'client_secret.json');
const clientSecretJson = JSON.parse(fs.readFileSync(clientSecretPath));
const oauth2Client = new google.auth.OAuth2(
clientSecretJson.web.client_id,
clientSecretJson.web.client_secret,
`${config.GCF_BASE_URL}/oauth2callback`
);
exports.client = oauth2Client;
/**
* Helper function to get the current user's email address
*/
exports.getEmailAddress = (t) => {
return pify(gmail.users.getProfile)({
auth: oauth2Client,
userId: 'me'
}).then(x => x.emailAddress);
};
/**
* Helper function to fetch a user's OAuth 2.0 access token
* Can fetch current tokens from Datastore, or create new ones
*/
exports.fetchToken = (emailAddress) => {
return datastore.get(datastore.key(['oauth2Token', emailAddress]))
.then((tokens) => {
const token = tokens[0];
// Check for new users
if (!token) {
throw new Error(config.UNKNOWN_USER_MESSAGE);
}
// Validate token
if (!token.expiry_date || token.expiry_date < Date.now() + 60000) {
oauth2Client.credentials.refresh_token =
oauth2Client.credentials.refresh_token || token.refresh_token;
return new Promise((resolve, reject) => { // Pify and oauth2client don't mix
oauth2Client.refreshAccessToken((err, response) => {
if (err) {
return reject(err);
}
return resolve();
});
})
.then(() => {
return exports.saveToken(emailAddress);
});
} else {
oauth2Client.credentials = token;
return Promise.resolve();
}
});
};
/**
* Helper function to save an OAuth 2.0 access token to Datastore
*/
exports.saveToken = (emailAddress) => {
return datastore.save({
key: datastore.key(['oauth2Token', emailAddress]),
data: oauth2Client.credentials
});
};