401 - unauthorized access : Auth0 and azure - javascript

I have connected my Database to auth0 and when I try the connection is returns 401 unauthorized access. I have allowed auth into my firewall and the password is correct. How come it is returning this error when searching for username and password?
More info
in my easy tables I made them authenticated access only, do I have to do something to get around this?
function login(email, password, callback) {
//this example uses the "tedious" library
//more info here: http://pekim.github.io/tedious/index.html
var Connection = require('tedious#1.11.0').Connection;
var Request = require('tedious#1.11.0').Request;
var TYPES = require('tedious#1.11.0').TYPES;
var connection = new Connection({
userName: 'username',
password: 'pass',
server: 'server',
options: {
database: 'db',
encrypt: true,
rowCollectionOnRequestCompletion: true
}
});
var query = "SELECT Id, Email, Password " +
"FROM user WHERE Email = #Email";
connection.on('debug', function (text) {
// Uncomment next line in order to enable debugging messages
// console.log(text);
}).on('errorMessage', function (text) {
console.log(JSON.stringify(text, null, 2));
return callback(text);
}).on('infoMessage', function (text) {
// Uncomment next line in order to enable information messages
// console.log(JSON.stringify(text, null, 2));
});
connection.on('connect', function (err) {
if (err) { return callback(err); }
var request = new Request(query, function (err, rowCount, rows) {
if (err) {
callback(new Error(err));
} else if (rowCount < 1) {
callback(new WrongUsernameOrPasswordError(email));
} else {
bcrypt.compare(password, rows[0][2].value, function (err, isValid) {
if (err) { callback(new Error(err)); }
else if (!isValid) { callback(new WrongUsernameOrPasswordError(email)); }
else {
callback(null, {
user_id: rows[0][0].value,
email: rows[0][1].value
});
}
});
}
});
request.addParameter('Email', TYPES.VarChar, email);
connection.execSql(request);
});
}

Since you are using Azure Mobile App, which included the Node.js server SDK for your app. Then you don't need to install tedious to work with Azure SQL database. The SDK has already wrapped up mssql to do this. So basically you can use this code sample to connect your database.
var api = {
// an example of executing a SQL statement directly
get: (request, response, next) => {
var query = {
sql: 'UPDATE TodoItem SET complete = #completed',
parameters: [
{ name: 'completed', value: request.query.completed }
]
};
request.azureMobile.data.execute(query)
.then(function (results) {
response.json(results);
});
},
// an example of executing a stored procedure
post: (request, response, next) => {
var query = {
sql: 'EXEC completeAllStoredProcedure #completed',
parameters: [
{ name: 'completed', value: request.query.completed }
]
};
request.azureMobile.data.execute(query)
.then(function (results) {
response.json(results);
});
}
};
module.exports = api;
For more information, please refer to this documentation.

Related

Oracledb (NodeJS) working when I create a new pool each time but not without. Need it to use already created pool

Followed a tutorial to get this working for stored procedures inside of Oracle. I have my GET/SELECT statements working correctly where based on the user making the GET call it changes the pool so that the SELECTs are from the correct user.
Pool creations that work for GET/SELECT
async function initialize() {
await oracledb.createPool({
user: 'user1',
password: 'pass1',
connectString: 'oracledb.website/dev',
poolAlias: 'pool1'
});
await oracledb.createPool({
user: 'user2',
password: 'pass2',
connectString: 'oracledb.website/dev',
poolAlias: 'pool2'
});
}
The tutorial I followed for stored procedures can be found here: https://blogs.oracle.com/opal/using-dbmsoutput-with-nodejs-and-node-oracledb
You will see that in this example he has a new pool being created for every request.
oracledb.createPool(
dbconfig,
function(err, pool) {
if (err)
console.error(err.message)
else
doit(pool);
});
var doit = function(pool) {
Note that the dbConfig used above is an array like:
dbconfig.hrPool.user = 'user3';
dbconfig.hrPool.password = 'pass3';
dbconfig.hrPool.connectString = 'oracle.site/dev';
This will cause issues if you specify a poolAlias and you will quickly end up trying to create a pool alias that already exists with an error like:
"NJS-046: poolAlias "pool1" already exists in the connection pool cache.
I have attempted to update this code myself but I am not familiar enough with asyc/waterfalls/callbacks to get it to keep going.
What I attempted is below (it never actually runs anything):
return new Promise(async (resolve, reject) => {
async.waterfall(
[
function(cb) {
oracledb.getConnection('pool1');
},
enableDbmsOutput,
createDbmsOutput,
fetchDbmsOutputLine
],
function (err, conn, cb) {
if (err) {
console.error("In waterfall error cb: ==>", err, "<== THIS IS WHERE THE ORACLE ERROR WILL SHOW!");
// Release the Oracle Connection
conn.release(function (err) {
if (err) console.error(err.message);
});
}
}
);
var enableDbmsOutput = function (conn, cb) {
conn.execute(
"BEGIN DBMS_OUTPUT.ENABLE(NULL); END;",
function(err) { return cb(err, conn); });
};
var createDbmsOutput = function (conn, cb) {
console.log('I NEVER MAKE IT HERE')
conn.execute(query
,function(err) { return cb(err, conn); });
};
var fetchDbmsOutputLine = function (conn, cb) {
conn.execute(
"BEGIN DBMS_OUTPUT.GET_LINE(:ln, :st); END;",
{ ln: { dir: oracledb.BIND_OUT, type: oracledb.STRING, maxSize: 32767 },
st: { dir: oracledb.BIND_OUT, type: oracledb.NUMBER } },
function(err, result) {
if (err) {
return cb(err, conn);
} else if (result.outBinds.st == 1) {
return cb(null, conn); // no more output
} else {
resolve(result);
return fetchDbmsOutputLine(conn, cb);
}
});
};
})
}
Would really appreciate any help!
The blog you quoted is a command-line script and only creates a pool once. That happens at the start of the script. It also is an old blog post. All its async module calls and JS callbacks should/would now be replaced by Node.js's newer async/await syntax. Also avoid using Promise() directly - code gets too confusing.
Since you are creating some kind of web listener, you should create the pool during app start up, but not for each web request.
Check the node-oracledb example webapp.js.
async function init() {
try {
await oracledb.createPool({
user: dbConfig.user,
password: dbConfig.password,
connectString: dbConfig.connectString
});
// Create HTTP server and listen on port httpPort
const server = http.createServer();
server.on('error', (err) => {
console.log('HTTP server problem: ' + err);
});
server.on('request', (request, response) => {
handleRequest(request, response);
});
await server.listen(httpPort);
console.log("Server is running at http://localhost:" + httpPort);
} catch (err) {
console.error("init() error: " + err.message);
}
}
async function handleRequest(request, response) {
... // Your code to handle each web request goes here.
}
init();
You may also wait to review the PL/SQL procedure example plsqlproc.js.

ExpressJS variable undefined

I have an ExpressJS app that when a user makes a POST request to a route, it should lookup the ID in the MongoDB using req.params.formId
I have some console.log statements tfor debugging and so I can see what info is being returned.
The route should lookup the ID passed and when it finds it, use the req.body data and also a field from the MongoDB document but this just seems to return as undefined
Here is the code for the route:
app.post("/api/v1/forms/:formId", (req, res) => {
const { name, email, message } = req.body;
console.log(req.body);
Form.findById(req.params.formId, Form.recipient, err => {
if (err) {
res.send(err);
} else {
const formRecipient = Form.recipient;
const newForm = {
name,
email,
message,
recipient: formRecipient
};
console.log(newForm);
const mailer = new Mailer(newForm, contactFormTemplate(newForm));
try {
mailer.send();
res.send(req.body);
} catch (err) {
res.send(err);
}
}
});
});
So an example, if I make a POST request to localhost:5000/api/v1/forms/5ad90544883a6e34ec738c19 the console.log of newForm shows { name: ' Mr Tester',
email: 'person#example.com',
message: 'Hi there',
recipient: undefined }
The forms Mongoose schema has a field named recipient
the correct way is to provide the fields you want to get as the second argument:
Form.findById(req.params.formId, 'recipient', (err, form) => {
if (err) {
// error handling code
} else {
const formRecipient = form.recipient;
}
...
});
here's the Docs

How To Use Variables Down A Promise Chain

I am using nodejs with express framework and mongodb/mongoose to store my data.
I have a register function which does 4 things. Creates a user, creates a token, assigns the token to the user and finally sends an email.
I initially did this using callbacks which worked fine. Im trying to use promises now i have required bluebird to do this. However when one promise is complete i need to use that returned variable in the next promise.
Register Function
module.exports.register = function(req, res) {
var input = req.body;
var newUser = new User ({
username: input.username,
email: input.email,
password: input.password,
active: false
});
var promise = newUser.save();
promise.then(function(user) {
return createToken('new', null, user._id);
}).then(function(token) {
user.tokens.push(token._id);
return user.save();
}).then(function(user) {
//Do Email Stuff
}).catch(function(err) {
return res.json("Could Not Register");
});
}
Create Token Function
var createToken = function(type, expiry, userid) {
var token = uuid.v4();
return new Promise(function(resolve, reject) {
var newToken = Token({
type:type,
token: token,
expiry: expiry,
user: userid
});
var promise = newToken.save();
promise.then(function(token) {
resolve(token);
}).catch(function(err) {
reject(err);
});
});
};
So where im doing "user.tokens.push" it can't find the user. ive read in bluebird that i can use somethign called binding? and then use "this". Could anyone show me how to do this properly.
Also if there is an an error in each promise i'd like the catch method to be dynamic. Instead of just "Could not register" it would be "Could Not Save User" or "Could Not Save Token" depending on which promise failed.
And if theres a way to make this even cleaner let me know.
there's no shame in using a var in the scope of the register function to store the value of user for later use
module.exports.register = function(req, res) {
var input = req.body;
var newUser = new User ({
username: input.username,
email: input.email,
password: input.password,
active: false
});
var sUser; // store user in this var
newUser.save()
.then(function(user) {
sUser = user; // save value user to use later on
return createToken('new', null, user._id);
}).then(function(token) {
sUser.tokens.push(token._id); // sUser is user, huzzah
return sUser.save();
}).then(function(user) {
//Do Email Stuff
}).catch(function(err) {
// use the content of err to return a meaningful error
return res.json("something more meaningful based on the content of err");
});
}
You should also avoid the new Promise antipattern in createToken
var createToken = function(type, expiry, userid) {
var token = uuid.v4();
var newToken = Token({
type:type,
token: token,
expiry: expiry,
user: userid
});
return newToken.save();
};
That produces an identical result to your code
another way would be to send user to the createToken function and rewrite your code like this
module.exports.register = function(req, res) {
var input = req.body;
var newUser = new User ({
username: input.username,
email: input.email,
password: input.password,
active: false
});
newUser.save()
.then(function(user) {
return createToken('new', null, user);
}, function(err) { // optionally change errors to meaningful error messages
throw "newUser.save failed";
}).then(function(user) {
//Do Email Stuff
// you could throw "email failed" if there's an error
}).catch(function(err) {
// err could be "newUser.save failed", "newToken.save failed", "email failed"
// use the content of err to return a meaningful error
return res.json("something more meaningful based on the content of err");
});
}
var createToken = function(type, expiry, user) {
var token = uuid.v4();
var newToken = Token({
type:type,
token: token,
expiry: expiry,
user: user._id
});
return newToken.save()
.then(function(token) {
user.tokens.push(token._id);
return user.save();
}) // you could add the following to make the errors suited to you
.catch(function(err) {
throw "newToken.save failed";
});
};

Retrieve customer email from ID contained in webhook in Parse.com

I have an App using Parse.com as a backend and an external site that acts as my payment gateway. Upon receiving the customer/subscription webhook data from Stripe I wish to lookup the users email so I can then run a Cloud Code function and change their user status to 'paid'
My webhook receiver is:
Parse.Cloud.define("update_user", function(request, response) {
var data = request.params["data"]
var customer = data.object.customer;
response.success'Working' + request);
});
And I am able to get an email back from stripe from the customer ID using:
Parse.Cloud.define("pay", function(request, response) {
Stripe.initialize(STRIPE_SECRET_KEY);
console.log(JSON.stringify(request.params));
Stripe.Customers.retrieve(
customerId, {
success:function(results) {
console.log(results["email"]);
// alert(results["email"]);
response.success(results);
},
error:function(error) {
response.error("Error:" +error);
}
}
);
});
I need help turning this into a complete function that is run on receipt of every webhook from Stripe. I am also struggling with options for fallback if this does not work for whatever reason.
EDIT
Taking parts of the first answer and I now have:
Parse.Cloud.define("update_user", function(request, response) {
Stripe.initialize(STRIPE_SECRET_KEY);
var data = request.params["data"]
var customerId = data.object.customer;
get_stripe_customer(customerId, 100).then(function(stripeResponse) {
response.success(stripeResponse);
}, function(error) {
response.error(error);
});
});
function get_stripe_customer (customerId) {
Stripe.initialize(STRIPE_SECRET_KEY);
return Stripe.Customers.retrieve(
customerId, {
success:function(results) {
console.log(results["email"]);
},
error:function(error) {
}
}
);
};
My knowledge is really falling down on the Promise side of things and also the callback (success:, error, request response) etc further reading would be appreciated.
This is now working
Out of interest I did this:
Parse.Cloud.define("update_user", function(request, response) {
var data = request.params["data"]
var customerId = data.object.customer;
get_stripe_customer(customerId, 100).then(function(stripeResponse) {
return set_user_status(username, stripeResponse);
}).then(function(username) {
response.success(username);
}, function(error) {
response.error(error);
});
});
function get_stripe_customer (customerId) {
Stripe.initialize(STRIPE_SECRET_KEY);
return Stripe.Customers.retrieve(
customerId, {
success:function(results) {
// console.log(results["email"]);
},
error:function(error) {
}
}
);
};
function set_user_status(stripeResponse) {
Parse.Cloud.useMasterKey();
var emailquery = new Parse.Query(Parse.User);
emailquery.equalTo("username", stripeResponse['email']); // find all the women
return emailquery.first({
success: function(results) {
alert('running set_user_status success');
var user = results;
user.set("tier", "paid");
user.save();
},
error:function(error) {
console.log('error finding user');
}
});
};
open to improvements...
EDIT - I (#danh) cleaned it up a bit. A few notes:
used promises throughout. much easier to read and handle errors
get_stripe_customer requires only one param (that 100 was my idea to charge $100)
set_user_status appears to need only user email as param, which apparently is in the stripeResponse
set_user_status returns a promise to save the user. that will be fulfilled with the user object, not the username
be sure you're clear on how to identify the user. stripe apparently provides email address, but in your user query (in set_user_status) you compare email to "username". some systems set username == email. make sure yours does or change that query.
Parse.Cloud.define("update_user", function(request, response) {
var data = request.params["data"]
var customerId = data.object.customer;
get_stripe_customer(customerId).then(function(stripeResponse) {
var email = stripeResponse.email;
return set_user_status(email);
}).then(function(user) {
response.success(user);
}, function(error) {
response.error(error);
});
});
function get_stripe_customer(customerId) {
Stripe.initialize(STRIPE_SECRET_KEY);
return Stripe.Customers.retrieve(customerId).then(function(results) {
// console.log(results["email"]);
return results;
});
};
function set_user_status(email) {
Parse.Cloud.useMasterKey();
var emailquery = new Parse.Query(Parse.User);
emailquery.equalTo("username", email); // find all the women
return emailquery.first().then(function(user) {
user.set("tier", "paid");
return user.save();
}, function(error) {
console.log('error finding user ' + error.message);
return error;
});
}
Did a quick skim of the docs pertaining to stripe, and it looks like the steps are: (1) make a stripe REST-api call from your client side to get a token, (2) pass that token to a cloud function, (3) call stripe from the parse cloud to finish paying. I understand that you'd like to include a (4) fourth step wherein the transaction is recorded in the data for the paying user.
From the client (assuming a JS client):
var token = // we've retrieved this from Stripe's REST api
Parse.Cloud.run("pay", { stripeToken: token }).then(function(result) {
// success
}, function(error) {
// error
});
On the server:
Parse.Cloud.define("pay", function(request, response) {
var user = request.user;
var stripeToken = request.params.stripeToken;
payStripeWithToken(stripeToken, 100).then(function(stripeResponse) {
return updateUserWithStripeResult(user, stripeResponse);
}).then(function(user) {
response.success(user);
}, function(error) {
response.error(error);
});
});
Now we need only to build promise-returning functions called payStripeWithToken and updateUserWithStripeResult.
// return a promise to pay stripe per their api
function payStripeWithToken(stripeToken, dollarAmt) {
Stripe.initialize(STRIPE_SECRET_KEY); // didn't see this in the docs, borrowed from your code
return Stripe.Charges.create({
amount: dollarAmt * 10, // expressed in cents
currency: "usd",
card: stripeToken //the token id should be sent from the client
});
// caller does the success/error handling
}
// return a promise to update user with stripeResponse
function updateUserWithStripeResult(user, stripeResponse) {
var transactionId = // dig this out of the stripeResponse if you need it
user.set("paid", true);
user.set("transactionId", transactionId);
return user.save();
}

How do you make multiple database calls from a single connection/transaction with Node.js and Tedious

I am attempting to use NodeJS with the Tedious (http://pekim.github.io/tedious/) sql server plugin to make multiple database calls. My intent is to:
1. Open a connection
2. Start a transaction
3. Make multiple database (stored procedure) calls, which will not return any data.
4. Commit transaction (or roll back on error).
5. Close connection
Here is an example .js file, (without using a transaction) for NodeJS where I am attempting to make multiple database calls and it is failing with the error "Requests can only be made in the LoggedIn state, not the SentClientRequest state." Nothing I try resolves this issue.
Does anyone know how to resolve this?
var Connection = require('tedious').Connection;
var Request = require('tedious').Request;
var config = {
userName: 'login',
password: 'password',
server: '127.0.0.1',
options: { rowCollectionOnDone: true }
};
var max = 1;
for (var i = 0; i < max; i++) {
var connection = new Connection(config);
function executeStatement() {
request = new Request("select 42, 'hello world'", function (err, rowCount) {
if (err) {
console.log(err);
} else {
console.log(rowCount + ' rows');
}
});
request.on('row', function (columns) {
columns.forEach(function (column) {
console.log(column.value);
});
});
request.on('doneInProc', function (rowCount, more, rows) {
});
request.on('doneProc', function (rowCount, more, rows) {
console.log('statement completed!')
connection.execSql(request);
});
request.on('returnStatus', function (status) {
console.log('statement completed!')
});
connection.execSql(request);
}
connection.on('connect', function (err) {
// If no error, then good to go...
executeStatement();
});
}
console.log('Done!');
You're trying to execute a statement on a connection that is not established. You're missing an error handler before you call executeStatement.
connection.on('connect', function (err) {
if (err) {
console.log(err); // replace with your code
return;
};
// If no error, then good to go...
executeStatement();
});
Edit:
How to execute multiple statements in a transaction in serial:
var statements = ["select 1", "select 2", "select 3"];
var transaction = new sql.Transaction(connection);
transaction.begin(function(err) {
// ... error checks
async.mapSeries(statements, function(statement, next) {
var request = new sql.Request(transaction);
request.query(statement, next);
}, function(err, results) {
// ... error checks
transaction.commit(function(err, recordset) {
// ... error checks
console.log("Transaction commited.");
});
});
});
You should use tedious connection pools to create a pool of multiple connections.
For node js, a npm module is available at : https://www.npmjs.com/package/tedious-connection-pool
For every new value inside for loop you can acquire a new connection and use connection.reset on doneInProc event.
The case which you have been doing is performing 1st iteration of for loop correctly(LoggedIn State) and as you have proceeded without closing or releasing the connection you are using same connection object (SentClientRequest state).
Hence the same object is at final state when the code reaches second iteration of for loop.
Hope it resolves your issue
you can use Tedious Connection pools https://github.com/pekim/tedious-connection-pool
As #zevsuld and #mannutech said, tedious-connection-pool will enable multiple connections, and prevent erring out when simultaneous requests come into your server.
Below is a generic example that allows you to write multiple queries within one connection pool, and expose them for use in your api. I'm just adding this in case others come along who are trying to accomplish this type of implementation.
const ConnectionPool = require('tedious-connection-pool');
const path = require('path');
require('dotenv').config({
path: path.join(__dirname, '../../.env')
})
let Request = require('tedious').Request;
let poolConfig = {
min: 10,
max: 50,
log: true
}
let connectionConfig = {
userName: process.env.user,
password: process.env.password,
server: process.env.server
};
//create the pool
let pool = new ConnectionPool(poolConfig, connectionConfig);
pool.on('error', function(err) {
console.error(err);
});
// At this point in the code, we have established a connection pool. If you run node, you'll see it log out all then connections to your database.
// Let's add some methods which your server might use in fulfilling requests to various endpoints.
let query1 = (cb, res, query) => {
// acquire a connection:
pool.acquire(function(err, connection) {
if (err) {
console.error(err);
return;
} else {
// form your query
let sql_query = `SELECT column1, colum2 from TABLE WHERE column1 LIKE '${query.param}%%' ORDER BY column1 ASC`
// use the connection as usual:
request = new Request(sql_query, (err, rowCount) => {
if (err) {
console.log(err);
return;
} else {
// console.log('rowCount:', rowCount);
}
//release the connection back to the pool when finished
connection.release();
});
let records = [];
request.on("row", function(columns) {
let rowArray = [];
columns.forEach(function(column) {
rowArray.push(column.value);
});
records.push(rowArray);
});
request.on("doneInProc", function() {
cb(records, res);
});
// lastly exectue the request on the open connection.
connection.execSql(request);
}
});
};
let query2 = (cb, res, query) => {
// acquire a connection:
pool.acquire(function(err, connection) {
if (err) {
console.error(err);
return;
} else {
// form your query
let sql_query = `SELECT column3, colum4 from TABLE2 WHERE column3 LIKE '${query.param}%%' ORDER BY column3 ASC`;
// use the connection as usual:
request = new Request(sql_query, (err, rowCount) => {
if (err) {
console.log(err);
return;
} else {
// console.log('rowCount:', rowCount);
}
//release the connection back to the pool when finished
connection.release();
});
let records = [];
request.on("row", function(columns) {
let rowArray = [];
columns.forEach(function(column) {
rowArray.push(column.value);
});
records.push(rowArray);
});
request.on("doneInProc", function() {
cb(records, res);
});
// lastly exectue the request on the open connection.
connection.execSql(request);
}
});
};
// Let's expose these two functions to the rest of your API:
module.exports = {
query1,
query2
}

Categories