I am using Google OAuth to authenticate users via a node.js script called user.js which is run on my AWS Instance (a VM) which calls a Amazon DocumentDB Mongo Database. The database is still fresh, I have not created any databases or users within it. What is happening is whenever I browse to the Google URL to authenticate, script times out in connecting to the Amazon DocumentDB. However if I try to connect manually to the DB from the AWS Instance, it connects just fine.
I have allowed port 27017 into the database:
This is the error I receive when I try to browse to my Google OAuth:
MongooseError: Operation `users.findOne()` buffering timed out after 10000ms
at Timeout.<anonymous> (/home/ubuntu/JobApply-Pro/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:185:23)
at listOnTimeout (node:internal/timers:573:17)
at process.processTimers (node:internal/timers:514:7)
This is my user.js file:
const express = require('express');
const bcrypt = require('bcryptjs');
const rateLimit = require('express-rate-limit');
const session = require('express-session');
const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth20').Strategy;
const { body, validationResult } = require('express-validator');
const fs = require('fs');
const path = require('path');
const router = express.Router();
const User = require('../models/user');
const mongoose = require('mongoose');
const MONGO_URI = 'mongodb://username:password@aws-documentdb-cluster-url:27017/jobapplypro';
// SSL options for mongoose connection
const sslOptions = {
ssl: true,
sslValidate: true,
sslCA: [fs.readFileSync(path.resolve(__dirname, '../certs/global-bundle.pem'))],
useNewUrlParser: true,
useUnifiedTopology: true
};
mongoose.connect(MONGO_URI, sslOptions)
.then(() => {
console.log('Connected to the Database.');
})
.catch((error) => {
console.error(`Error on connecting to the database: ${error}`);
});
// Additional logging
mongoose.connection.on('connected', function() {
console.log('Mongoose connection is open');
});
mongoose.connection.on('error', function(err) {
console.log('Mongoose connection has occured ' + err + ' error');
});
mongoose.connection.on('disconnected', function() {
console.log('Mongoose connection is disconnected');
});
process.on('SIGINT', function() {
mongoose.connection.close(function() {
console.log('Mongoose connection is disconnected due to application termination');
process.exit(0)
});
});
// Session management
router.use(session({
secret: '[hidden]',
resave: false,
saveUninitialized: true
}));
// Passport setup
router.use(passport.initialize());
router.use(passport.session());
passport.use(new GoogleStrategy({
clientID: '816672868893-0atl08ucn7m2hh3gftdsem0i3belv86q.apps.googleusercontent.com',
clientSecret: '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',
callbackURL: 'http://app.jobapplypro.infinitisoftwaresolutions.com:5000/user/google/callback'
},
async function(accessToken, refreshToken, profile, done) {
try {
let user = await User.findOne({ googleId: profile.id });
if (!user) {
user = new User({
googleId: profile.id,
// add other properties if needed
});
await user.save();
}
done(null, user);
} catch (err) {
done(err, null);
}
}
));
// Route for initiating Google OAuth
router.get('/google',
passport.authenticate('google', { scope: ['profile', 'email'] }));
// Google OAuth callback route
router.get('/google/callback',
passport.authenticate('google', { failureRedirect: '/login' }),
function(req, res) {
// Successful authentication, redirect home.
res.redirect('/');
});
// Similarly, setup strategies and routes for Apple and Outlook OAuth
// Rate limiting
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 requests per windowMs
});
// Apply the rate limit to all requests
router.use(limiter);
// Get all users
router.get('/', async (req, res) => {
// Add your own error handling here
});
// Get one user
router.get('/:id', getUser, (req, res) => {
// Add your own error handling here
});
// Create one user
router.post('/',
// Add input validation
body('password').isLength({ min: 5 }).withMessage('Password must be at least 5 characters long'),
body('email').isEmail().withMessage('Email must be a valid email address'),
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
// Hash the password
const hashedPassword = await bcrypt.hash(req.body.password, 10);
const user = new User({
email: req.body.email,
password: hashedPassword,
// add other properties here
});
try {
const newUser = await user.save();
res.status(201).json(newUser);
} catch(err) {
res.status(400).json({ message: err.message });
}
}
);
// Update a user
router.put('/:id', getUser, async (req, res) => {
// Update user properties here
try {
const updatedUser = await res.user.save();
res.json(updatedUser);
} catch(err) {
res.status(400).json({ message: err.message });
}
});
// Middleware function for getting user by ID
async function getUser(req, res, next) {
let user;
try {
user = await User.findById(req.params.id);
if (user == null) {
return res.status(404).json({ message: 'Cannot find user' });
}
} catch(err) {
return res.status(500).json({ message: err.message });
}
res.user = user;
next();
}
module.exports = router;
and this is my successful manual connection showing my AWS Instance is able to reach the DocumentDB instance:
$ mongo --host aws-documentdb-cluster-url:27017 -u username -p 'password' --tls --tlsCAFile ./certs/global-bundle.pem
MongoDB shell version v4.4.22
connecting to: mongodb://aws-documentdb-cluster-url:27017/?compressors=disabled&gssapiServiceName=mongodb
{"t":{"$date":"2023-07-13T03:54:18.346Z"},"s":"I", "c":"NETWORK", "id":5490002, "ctx":"thread1","msg":"Started a new thread for the timer service"}
Implicit session: session { "id" : UUID("7fb19d43-8475-498e-9125-931fd25de7b6") }
MongoDB server version: 5.0.0
WARNING: shell and server versions do not match
Warning: Non-Genuine MongoDB Detected
This server or service appears to be an emulation of MongoDB rather than an official MongoDB product.
Some documented MongoDB features may work differently, be entirely missing or incomplete, or have unexpected performance characteristics.
To learn more please visit: https://dochub.mongodb.org/core/non-genuine-mongodb-server-warning.
rs0:PRIMARY>
What is going wrong?
I am expecting a successful connection between my AWS instance and my AWS DocumentDB cluster using node.js