Node js ACL export issue - node.js

I have recently started development of a Node js application with user authentication and authorization. I have successfully implemented the user authentication with passport js but having an issue with the user authorization using node acl.
security.js file looks like this
var node_acl = require('acl'),
acl;
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/claim_app', function (err, db) {
var mongoBackend = new node_acl.mongodbBackend(db, 'acl');
acl = new node_acl(mongoBackend);
console.log(acl);
set_roles();
});
function set_roles() {
acl.allow([{
roles: 'admin',
allows: [{
resources: '/api/conf',
permissions: '*'
}
]
}, {
roles: 'user',
allows: [{
resources: 'photos',
permissions: ['view', 'edit', 'delete']
}]
}, {
roles: 'guest',
allows: []
}]);
}
module.exports = acl;
but when I try to use above with require('./src/config/security'), always getting as undefined. what is the reason for this behaviour.
Thanks.

Related

How to get the Authorization code in the node OIDC provider

I implemented node-OIDC-Provider in Node JS I got Id-token but I need authorize-code. So, when I hit this Api(http://localhost:3000/auth?client_id=oidcCLIENT&response_type=code&scope=openid&redirect_uri=http://localhost:3000) it throwing an error('http://localhost:3000/?error=invalid_request&error_description=Authorization%20Server%20policy%20requires%20PKCE%20to%20be%20used%20for%20this%20request'). How to fix this error and get the authorization code
Sample.js
const { Provider } = require('oidc-provider');
var express = require('express')
var app = express()
const oidc = new Provider('http://localhost:3000', {
clients: [
{
client_id: 'oidcCLIENT',
client_secret: '...',
grant_types: ['refresh_token', 'authorization_code'],
redirect_uris: ['http://localhost:3000'],
}
],
interactions: {
url(ctx, interaction) { // eslint-disable-line no-unused-vars
return `/interaction/${interaction.uid}`;
},
},
cookies: {
keys: ['some secret key', 'and also the old rotated away some time ago', 'and one more'],
},
claims: {
address: ['address'],
email: ['email', 'email_verified'],
phone: ['phone_number', 'phone_number_verified'],
profile: ['birthdate', 'family_name', 'gender', 'given_name', 'locale', 'middle_name', 'name',
'nickname', 'picture', 'preferred_username', 'profile', 'updated_at', 'website', 'zoneinfo'],
},
features: {
devInteractions: { enabled: false }, // defaults to true
deviceFlow: { enabled: true }, // defaults to false
revocation: { enabled: true }, // defaults to false
},
jwks: {
keys: [
{
d: 'VEZOsY07JTFzGTqv6cC2Y32vsfChind2I_TTuvV225_-0zrSej3XLRg8iE_u0-3GSgiGi4WImmTwmEgLo4Qp3uEcxCYbt4NMJC7fwT2i3dfRZjtZ4yJwFl0SIj8TgfQ8ptwZbFZUlcHGXZIr4nL8GXyQT0CK8wy4COfmymHrrUoyfZA154ql_OsoiupSUCRcKVvZj2JHL2KILsq_sh_l7g2dqAN8D7jYfJ58MkqlknBMa2-zi5I0-1JUOwztVNml_zGrp27UbEU60RqV3GHjoqwI6m01U7K0a8Q_SQAKYGqgepbAYOA-P4_TLl5KC4-WWBZu_rVfwgSENwWNEhw8oQ',
dp: 'E1Y-SN4bQqX7kP-bNgZ_gEv-pixJ5F_EGocHKfS56jtzRqQdTurrk4jIVpI-ZITA88lWAHxjD-OaoJUh9Jupd_lwD5Si80PyVxOMI2xaGQiF0lbKJfD38Sh8frRpgelZVaK_gm834B6SLfxKdNsP04DsJqGKktODF_fZeaGFPH0',
dq: 'F90JPxevQYOlAgEH0TUt1-3_hyxY6cfPRU2HQBaahyWrtCWpaOzenKZnvGFZdg-BuLVKjCchq3G_70OLE-XDP_ol0UTJmDTT-WyuJQdEMpt_WFF9yJGoeIu8yohfeLatU-67ukjghJ0s9CBzNE_LrGEV6Cup3FXywpSYZAV3iqc',
e: 'AQAB',
kty: 'RSA',
n: 'xwQ72P9z9OYshiQ-ntDYaPnnfwG6u9JAdLMZ5o0dmjlcyrvwQRdoFIKPnO65Q8mh6F_LDSxjxa2Yzo_wdjhbPZLjfUJXgCzm54cClXzT5twzo7lzoAfaJlkTsoZc2HFWqmcri0BuzmTFLZx2Q7wYBm0pXHmQKF0V-C1O6NWfd4mfBhbM-I1tHYSpAMgarSm22WDMDx-WWI7TEzy2QhaBVaENW9BKaKkJklocAZCxk18WhR0fckIGiWiSM5FcU1PY2jfGsTmX505Ub7P5Dz75Ygqrutd5tFrcqyPAtPTFDk8X1InxkkUwpP3nFU5o50DGhwQolGYKPGtQ-ZtmbOfcWQ',
p: '5wC6nY6Ev5FqcLPCqn9fC6R9KUuBej6NaAVOKW7GXiOJAq2WrileGKfMc9kIny20zW3uWkRLm-O-3Yzze1zFpxmqvsvCxZ5ERVZ6leiNXSu3tez71ZZwp0O9gys4knjrI-9w46l_vFuRtjL6XEeFfHEZFaNJpz-lcnb3w0okrbM',
q: '3I1qeEDslZFB8iNfpKAdWtz_Wzm6-jayT_V6aIvhvMj5mnU-Xpj75zLPQSGa9wunMlOoZW9w1wDO1FVuDhwzeOJaTm-Ds0MezeC4U6nVGyyDHb4CUA3ml2tzt4yLrqGYMT7XbADSvuWYADHw79OFjEi4T3s3tJymhaBvy1ulv8M',
qi: 'wSbXte9PcPtr788e713KHQ4waE26CzoXx-JNOgN0iqJMN6C4_XJEX-cSvCZDf4rh7xpXN6SGLVd5ibIyDJi7bbi5EQ5AXjazPbLBjRthcGXsIuZ3AtQyR0CEWNSdM7EyM5TRdyZQ9kftfz9nI03guW3iKKASETqX2vh0Z8XRjyU',
use: 'sig',
}, {
crv: 'P-256',
d: 'K9xfPv773dZR22TVUB80xouzdF7qCg5cWjPjkHyv7Ws',
kty: 'EC',
use: 'sig',
x: 'FWZ9rSkLt6Dx9E3pxLybhdM6xgR5obGsj5_pqmnz5J4',
y: '_n8G69C-A2Xl4xUW2lF0i8ZGZnk_KPYrhv4GbTGu5G4',
},
],
},
});
// express/nodejs style application callback (req, res, next) for use with express apps, see /examples/express.js
app.get('/sample', function (req, res) {
res.send('hello world')
})
app.use(oidc.callback())
// or just expose a server standalone, see /examples/standalone.js
const server = app.listen(3000, () => {
console.log('oidc-provider listening on port 3000, check http://localhost:3000/.well-known/openid-configuration');
});
How to set authorization server policy in the OIDC using node(Authorization Server policy requires PKCE to be used for this request')
I believe you need to set these options:
pkce: {
required: true
},
token_endpoint_auth_method: "none"
Also, if using PKCE, you should be sending the standard code_challenge and code_verifier methods as in steps 4 and 8 of my blog post.

Webpacking a NodeJS Express API with MySQL throws connection error in mode '-p', not in '-d'

I have a simple Express API where I use MySQL to retrieve my data. I use Webpack 4 to bundle it with a very simple configuration:
'use strict';
const path = require('path');
module.exports = {
entry: './src/main.js',
target: 'node',
output: {
filename: 'gept_api.js',
path: path.resolve(__dirname, 'dist'),
},
node: {
__dirname: true,
},
};
When I use webpack --config webpack.config.js -d for development everything works just fine.
However, when I run webpack --config webpack.config.js -p for production it suddenly doesn't work anymore, and throws an error when it's getting a connection from the pool.
TypeError: Cannot read property 'query' of undefined
at Object.getItem (C:\Users\freek\Dropbox\Code\Apps\GEPT\GEPTv2_API\dist\gept_api.js:1:154359)
at t.db_pool.getConnection (C:\Users\freek\Dropbox\Code\Apps\GEPT\GEPTv2_API\dist\gept_api.js:1:154841)
at c._callback (C:\Users\freek\Dropbox\Code\Apps\GEPT\GEPTv2_API\dist\gept_api.js:1:68269)
at c.end (C:\Users\freek\Dropbox\Code\Apps\GEPT\GEPTv2_API\dist\gept_api.js:1:8397)
at C:\Users\freek\Dropbox\Code\Apps\GEPT\GEPTv2_API\dist\gept_api.js:1:322509
at Array.forEach (<anonymous>)
at C:\Users\freek\Dropbox\Code\Apps\GEPT\GEPTv2_API\dist\gept_api.js:1:322487
at process._tickCallback (internal/process/next_tick.js:112:11)
So somehow this is broken by using the production mode in webpack 4. The connection object undefined somehow, while it isn't in development mode.
I have no idea how to fix this, since I'm a noob in using Webpack. I tried searching on google, but couldn't find anything relevant.
How I create my pool:
'use strict';
var mysql = require('mysql');
var secret = require('./db-secret');
module.exports = {
name: 'gept_api',
hostname: 'https://api.toxsickproductions.com/gept',
version: '1.3.0',
port: process.env.PORT || 1910,
db_pool: mysql.createPool({
host: secret.host,
port: secret.port,
user: secret.user,
password: secret.password,
database: secret.database,
ca: secret.ca,
}),
};
How I consume the connection:
pool.getConnection((err, connection) => {
PlayerRepository.getPlayer(req.params.username, connection, (statusCode, player) => {
connection.release();
res.status(statusCode);
res.send(player);
return next();
});
});
and
/** Get the player, and logs to HiscoreSearch if exists.
*
* Has callback with statusCode and player. Status code can be 200, 404 or 500.
* #param {string} username The player's username.
* #param {connection} connection The mysql connection object.
* #param {(statusCode: number, player: { username: string, playerType: string }) => void} callback Callback with statusCode and the player if found.
*/
function getPlayer(username, connection, callback) {
const query = 'SELECT p.*, pt.type FROM Player p JOIN PlayerType pt ON p.playerType = pt.id WHERE username = ?';
connection.query(query, [username.toLowerCase()], (outerError, results, fields) => {
if (outerError) callback(500);
else if (results && results.length > 0) {
logHiscoreSearch(results[0].id, connection, innerError => {
if (innerError) callback(500);
else callback(200, {
username: results[0].username,
playerType: results[0].type,
deIroned: results[0].deIroned,
dead: results[0].dead,
lastChecked: results[0].lastChecked,
});
});
} else callback(404);
});
}
I found what was causing the issue. Apparantly the mysql package relies on Function.prototype.name because setting keep_fnames: true fixed the production build. (https://github.com/mishoo/UglifyJS2/tree/harmony#mangle-options)
I disabled the Webpack 4 standard minification and used custom UglifyJSPlugin settings:
'use strict';
const path = require('path');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
entry: './src/main.js',
target: 'node',
output: {
filename: 'gept_api.js',
path: path.resolve(__dirname, 'dist'),
},
node: {
__dirname: true,
},
optimization: {
minimize: false,
},
plugins: [
new UglifyJsPlugin({
parallel: true,
uglifyOptions: {
ecma: 6,
mangle: {
keep_fnames: true,
},
},
}),
],
};

NODEJS - connection to database ECONNREFUSED when using documents.write()

I'm currently studying nodejs and marklogic, I'm running a sample code but I cannot make it work I'm getting econnrefused whenever I run the code.,
Here is my code,
my-connection.js
module.exports = {
connInfo: {
host: 'localhost',
port: 8008,
user: 'user',
password: 'password'
}
};
sample.js
const marklogic = require('marklogic');
const my = require('./my-connection.js');
const db = marklogic.createDatabaseClient(my.connInfo);
const documents = [
{ uri: '/gs/aardvark.json',
content: {
name: 'aardvark',
kind: 'mammal',
desc: 'The aardvark is a medium-sized burrowing, nocturnal mammal.'
}
},
{ uri: '/gs/bluebird.json',
content: {
name: 'bluebird',
kind: 'bird',
desc: 'The bluebird is a medium-sized, mostly insectivorous bird.'
}
},
{ uri: '/gs/cobra.json',
content: {
name: 'cobra',
kind: 'mammal',
desc: 'The cobra is a venomous, hooded snake of the family Elapidae.'
}
},
];
db.documents.write(documents).result(
function(response) {
console.log('Loaded the following documents:');
response.documents.forEach( function(document) {
console.log(' ' + document.uri);
});
},
function(error) {
console.log('error here');
console.log(JSON.stringify(error, null, 2));
}
);
I'm running it by typing node sample.js I'm using marklogic for the database, can someone help me identify the problem here,
I get ECONNREFUSED upon running the app, thank you!
ECONNREFUSED indicates no TCP listener process is running behind localhost:8008. That could mean MarkLogic is not running on your localhost, or it has no app-server configured at port 8008.
Check if http://localhost:8001 works on your machine, and brings up the MarkLogic Admin UI. If so, check the app-servers to see if you actually have one configured for 8008.
HTH!

NODEJS Marklogic - Write document list cannot process response with 404 status when using documents.write()

I'm new to nodejs and marklogic, and I'm following a tutorial for a simple app, I have setup and configured my marklogin login credentials,
when I run this sample code by running node sample.js
the output is write document list cannot process response with 404 status
I wonder why I'm encountering this error,
here is the code from the tutorial,
my-connection.js
module.exports = {
connInfo: {
host: '127.0.0.1',
port: 8001,
user: 'user',
password: 'password'
}
};
sample.js
const marklogic = require('marklogic');
const my = require('./my-connection.js');
const db = marklogic.createDatabaseClient(my.connInfo);
const documents = [
{ uri: '/gs/aardvark.json',
content: {
name: 'aardvark',
kind: 'mammal',
desc: 'The aardvark is a medium-sized burrowing, nocturnal mammal.'
}
},
{ uri: '/gs/bluebird.json',
content: {
name: 'bluebird',
kind: 'bird',
desc: 'The bluebird is a medium-sized, mostly insectivorous bird.'
}
},
{ uri: '/gs/cobra.json',
content: {
name: 'cobra',
kind: 'mammal',
desc: 'The cobra is a venomous, hooded snake of the family Elapidae.'
}
},
];
db.documents.write(documents).result(
function(response) {
console.log('Loaded the following documents:');
response.documents.forEach( function(document) {
console.log(' ' + document.uri);
});
},
function(error) {
console.log('error here');
console.log(JSON.stringify(error, null, 2));
}
);
I hope someone can tell me what is wrong with the code,
Thank You!
The MarkLogic NodeJS Client library is meant to run against a so-called MarkLogic REST-api instance. There is typically one running at port 8000, but you can also deploy other ones at different ports by issuing a POST call to :8002/v1/rest-apis, as described here:
http://docs.marklogic.com/REST/POST/v1/rest-apis
Port 8001 however is reserved for the MarkLogic Admin UI, which doesn't understand the REST calls that the NodeJS Client library is trying to invoke, hence the 404 (not found)..
HTH!

How to add x.509 certificate subject as a user to Mongodb 3.4 by Node.js MongoDB Driver API?

I need to add users to my MongoDB 3.4 Replica Set using an Node.js application that already has the Node.js MongoDB Driver API package.
The problem is: The API documentation doesn't cover how to add x.509 Certificate subject as a User.
Does anyone know how to do that? In other words, I need a Node.js mechanism/API which I can use to perform the mongodb command below:
mongo --host mongo-node-0
use admin
db.getSiblingDB("$external").runCommand(
{createUser: "emailAddress=foo#bar.com,CN=admin,OU=Clients,O=FOO,L=Dublin,ST=Ireland,C=IE",
roles: [
{ role: "userAdminAnyDatabase", db: "admin" },
{ role: "dbAdminAnyDatabase", db: "admin" },
{ role: "readWriteAnyDatabase", db:"admin" },
{ role: "clusterAdmin", db: "admin" }
]})
Following the Mongo documentation, on Node, execute a command hash against MongoDB. This lets you access any commands not available through the API on the server.
command(selector[, options], callback)
Arguments:
selector (object) – the command hash to send to the server, ex: {ping:1}.
[options] (object) – additional options for the command.
callback (function) – this will be called after executing this method. The command always return the whole result of the command as the second parameter.
Returns:
null
So, you can try it:
var db = new Db('$external', new MongoServer('localhost', 27017));
db.open(function(err, db) {
if (err) {
console.log(err);
}
db.command({
createUser: "emailAddress=foo#bar.com,CN=admin,OU=Clients,O=FOO,L=Dublin,ST=Ireland,C=IE",
roles: [
{ role: "userAdminAnyDatabase", db: "admin" },
{ role: "dbAdminAnyDatabase", db: "admin" },
{ role: "readWriteAnyDatabase", db:"admin" },
{ role: "clusterAdmin", db: "admin" }
]}, function(err, result){
if (err) {
console.log(err);
}
console.log(result)
db.close();
});
});

Resources