Using express session with mongoStore and database authentication - javascript

I have an object containing config values like so:
var db = {
name: "Auth",
port: "27017",
host: "localhost",
user: "testUser",
pass: "testPassword",
secret: "62y4q8C03l3t"
}
Now I'm using express-session with connect-mongostore to store session data in my MongoDB.
app.use(session({
resave: true,
secret: db.secret,
saveUninitialized: true,
store: new mongoStore({
"db" : db.name,
"host": db.host,
"port": db.port,
"username": db.user,
"password": db.pass
})
}));
Previously I had no authentication on my Mongo databases and this worked fine. However, I have just got authentication working on my databases, and now get the following error message on the above:
sessions <MongoError: not authorized for query on Auth.system.indexes>

What roles do your user have on the Auth database? To access the indexes, the readWrite role is not enough, you should have the dbAdmin role.

Related

Next-Auth Redis Adapter support for user session persistence?

I was going through the next-auth documentation but didn't find any mention of connecting to custom configured Redis without the use of Upstash for a persistent session store.
My use case is straightforward. I am using Nginx as a load balancer between multiple nodes for my nextJS application and I would like to persist the session if in case the user logs in and refreshes the page as Nginx switches between nodes.
For e.g My Nginx config
server {
listen 80;
server_name _;
location / {
proxy_pass http://backend;
}
}
upstream backend {
ip_hash;
server <nextjs_app_ip_1>:8000;
server <nextjs_app_ip_2>:8000;
}
As you can see from the example Nginx config, there are multiple upstream server pointers here that require user session persistence.
I am using the credentials provider of next-auth as I have a Django-based auth system already available.
I did see the implementation of the next-auth adapter with Upstash. However, I have my own custom server running with Redis.
I tried connecting to Redis using ioredis which works fine as it is connected. However, I am not sure how can I use Redis here with next-auth to persist session and validate at the same time?
For e.g In express, you have a session store which you can pass your Redis Client with and it should automatically take care of persistence. Is there anything I can do to replicate the same behavior in my case?
For e.g In Express
App.use(session({
store: new RedisStore({ client: redisClient }),
secret: 'secret$%^134',
resave: false,
saveUninitialized: false,
cookie: {
secure: false, // if true only transmit cookie over https
httpOnly: false, // if true prevent client side JS from reading the cookie
maxAge: 1000 * 60 * 10 // session max age in miliseconds
}
}))
My Code:
import CredentialsProvider from "next-auth/providers/credentials";
import {UpstashRedisAdapter} from "#next-auth/upstash-redis-adapter";
import Redis from 'ioredis';
const redis = new Redis(process.env.REDIS_URL); //points to my custom redis docker container
export const authOptions = {
providers: [CredentialsProvider({
name: 'auth',
credentials: {
email: {
label: 'email',
type: 'text',
placeholder: 'jsmith#example.com'
},
password: {
label: 'Password',
type: 'password'
}
},
async authorize(credentials, req) {
const payload = {
email: credentials.email,
password: credentials.password
};
const res = await fetch(`my-auth-system-url`, {
method: 'POST',
body: JSON.stringify(payload),
headers: {
'Content-Type': 'application/json'
}
});
const user = await res.json();
console.log("user", user);
if (!res.ok) {
throw new Error(user.exception);
}
// If no error and we have user data, return it
if (res.ok && user) {
return user;
}
// Return null if user data could not be retrieved
return null;
}
})],
adapter: UpstashRedisAdapter(redis),
pages: {
signIn: '/login'
},
jwt: {
secret: process.env.SECRET,
encryption: true
},
callbacks: {
jwt: async({token, user}) => {
user && (token.user = user)
return token
},
session: async({session, token}) => {
session.user = token.user
return session
},
async redirect({baseUrl}) {
return `${baseUrl}/`
}
},
session: {
strategy: "jwt",
maxAge: 3000
},
secret: process.env.SECRET,
debug: true
}
export default NextAuth(authOptions)
Thank you so much for the help.

why cant i send emails using nodemailer and nodejs?

I'm trying to send email using node.js and nodemailer but when I'm pressing the submit button its just loading and loading and in the end gives me a "504 Gateway Timeout Error" in the server, and "page is not working" locally.
I'm using the following code:
app.post("/postmail", function (req, res) {
var transporter = nodemailer.createTransport({
host: "smtp.mailtrap.io",
port: 2525,
secure: false,
debug: true,
auth: {
user: "xxx",
password: "xxx",
},
});
var message = {
from: "a#b", // Sender address
to: "b#c", // List of recipients
subject: "Design Your Model S | Tesla", // Subject line
text: "Have the most fun you can in a car. Get your Tesla today!", // Plain text body
};
transporter.sendMail(message, function (err, info) {
if (err) {
console.log(err);
} else {
console.log(info);
res.render("landing");
}
});
});
I must also mention that, I tried multiple smtp servers with multiple ports and configuration.
does someone know what to do?
thanks
cuase all of the smtp providers use tls/ssl for secuirity reasons. try to use secure configuration:
var transporter = nodemailer.createTransport({
host: 'smtp.mailtrap.io',
port: 465,
secure: true,
debug: true,
auth: {
user: 'xxx',
password: 'xxx'
}
});

How to solve the database connection error [SequelizeConnectionError]? [duplicate]

I am trying to connect to a PostgreSQL Database that I've set up in Heroku.
const { Sequelize, DataTypes, Model } = require("sequelize");
// DB Configuration
const sequelize = new Sequelize({
database: "[won't show db]",
username: "[won't show username]",
password: "[won't show password]",
host: "ec2-54-221-195-148.compute-1.amazonaws.com",
port: 5432,
dialect: "postgres",
dialectOptions: {
ssl: true,
},
});
And this is what I am getting as the output:
SequelizeConnectionError: self signed certificate
This is due to an (accidental) breaking change in node-postgres version 8 (see this GitHub issue).
The solution is to pass rejectUnauthorized: false to the sequelize connection parameters inside of dialectOptions>ssl, as described here by GitHub user jsanta, bypassing the SSL certificate check (which is okay when connecting to a trusted server over a secure connection such as on your local host or between your own servers in the same network):
const sequelize = new Sequelize({
database: "xxxxx",
username: "xxxxx",
password: "xxxxx",
host: "xxxxx",
port: 5432,
dialect: "postgres",
dialectOptions: {
ssl: {
require: true,
rejectUnauthorized: false // <<<<<<< YOU NEED THIS
}
},
});
in my case none of the above works, I use the connection string method to apply pg configurations, so I set the query param sslmode=no-verify and I got it works
example
postgres://myuser:mypassword#myhost:5432/mydatabasename?sslmode=no-verify
It works for me (on sequelize config.json file):
"dialect": "postgres",
"dialectOptions": {
"ssl": {
"require": true,
"rejectUnauthorized": false
}
}
This works for me, in the config.json file
"development": {
"username": "dummy",
"password": "dummy",
"database": "dummy",
"host": "dummy",
"dialect": "postgres",
"dialectOptions":{
"ssl": {
"require": true,
"rejectUnauthorized": false
}
}
}
add the following in your code...
dbRDS=false

SequelizeConnectionError: self signed certificate

I am trying to connect to a PostgreSQL Database that I've set up in Heroku.
const { Sequelize, DataTypes, Model } = require("sequelize");
// DB Configuration
const sequelize = new Sequelize({
database: "[won't show db]",
username: "[won't show username]",
password: "[won't show password]",
host: "ec2-54-221-195-148.compute-1.amazonaws.com",
port: 5432,
dialect: "postgres",
dialectOptions: {
ssl: true,
},
});
And this is what I am getting as the output:
SequelizeConnectionError: self signed certificate
This is due to an (accidental) breaking change in node-postgres version 8 (see this GitHub issue).
The solution is to pass rejectUnauthorized: false to the sequelize connection parameters inside of dialectOptions>ssl, as described here by GitHub user jsanta, bypassing the SSL certificate check (which is okay when connecting to a trusted server over a secure connection such as on your local host or between your own servers in the same network):
const sequelize = new Sequelize({
database: "xxxxx",
username: "xxxxx",
password: "xxxxx",
host: "xxxxx",
port: 5432,
dialect: "postgres",
dialectOptions: {
ssl: {
require: true,
rejectUnauthorized: false // <<<<<<< YOU NEED THIS
}
},
});
in my case none of the above works, I use the connection string method to apply pg configurations, so I set the query param sslmode=no-verify and I got it works
example
postgres://myuser:mypassword#myhost:5432/mydatabasename?sslmode=no-verify
It works for me (on sequelize config.json file):
"dialect": "postgres",
"dialectOptions": {
"ssl": {
"require": true,
"rejectUnauthorized": false
}
}
This works for me, in the config.json file
"development": {
"username": "dummy",
"password": "dummy",
"database": "dummy",
"host": "dummy",
"dialect": "postgres",
"dialectOptions":{
"ssl": {
"require": true,
"rejectUnauthorized": false
}
}
}
add the following in your code...
dbRDS=false

Cannot access the record from mongo db after authentication at server side

First, I started the mongod. Then on mongo, created the user name, password, roles to the database, here is the code
> use testProjectDB
switched to db testProjectDB
>
db.getUsers()[{
"_id": "testProjectDB.user",
"user": "user",
"db": "testProjectDB",
"roles": [{
"role": "readWrite",
"db": "testProjectDB"
}]
}]
At server side, authentication given as,
var mongoose = require('mongoose');
var url = "mongodb://user:pwd#localhost:27017?authMechanism=DEFAULT&authSource=testProjectDB";
mongoose.connect(url);
var connection = mongoose.connection;
connection.on('error', function() {
throw new Error('unable to connect to database at ' + url);
});
the db validates the user and password, but i cannot access the record form the database,as a beginner to mongo db authentication at server side, i could not it figure out, kindly please help me out
You can use following procedure to enable auth on stand-alone mongodb deployment:
Create an administrator user
use admin
db.createUser(
{
user: "userAdmin",
pwd: "xxxxx",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
Modify mongod.conf file to enable auth
security:
authorization: enabled
Restart mongod service:
sudo service mongod restart
Connect and authenticate as the user administrator
mongo
use admin db.auth("userAdmin", "xxxxx")
Create additional users as needed for your deployment:
use yourdb
db.createUser(
{
user: ""testuser"",
pwd: ""xxxxxx"",
roles: [ { role: ""readWrite"", db: "yourdb" }
]
}
)
Your mongodb connection string should look like this:
mongodb://user:password#localhost:27017/testProjectDB
Additionally, you can monitor mongodb logs for any auth related info or to check if there is any issue:
tailf /var/log/mongodb/mongod.log

Categories

Resources