Get Facebook Auth token from Azure Easy API - azure

Easy API are very poorly documented, I'm trying to get the Facebook Auth token from a user authenticated against it through Azure, I've created an API with the following GET:
module.exports = {
"get": function (req, res, next) {
res.json(req.user.getIdentity("facebook"));
}
};
However azure responds with "cannot read property 'getIdentity' from undefined". If user is undefined in res, where can I get it from?

Easy APIs is documented in the Azure Mobile Apps Node.js SDK HOWTO and within the API docs. You can find the HOWTO here: https://azure.microsoft.com/en-us/documentation/articles/app-service-mobile-node-backend-how-to-use-server-sdk/
As to the specific question, getIdentity() is a Promise-based mechanism. In addition, you need to access the user object through the azureMobile property. Something like:
module.exports = {
"get": function (req, res, next) {
req.azureMobile.user.getIdentity("facebook").then((data) => {
res.status(200).type('application/json').json(data);
}).catch((error) => {
res.status(500).send(JSON.stringify(error));
});
}
};

Related

fastifyGuard not working (role based authentication)

I have a fastify project, where I use fastify-jwt to create tokens for the users. Now I want to have a role based authentication system. I found the fastifyGuard plugin but I register it correctly, nevertheless it is not working in the routes file.
What I currently have
async function routes(fastify, options, next) {
const Collection = require("$/App/Controllers/Collection/Controller");
fastify.get(
"/test/admin",
{
preValidation: [fastify.authenticate],
},
Collection.testFunction
);
}
I provide a bearer token and it works perfectly.
Than I add the fastifyGuard preHandler:
async function routes(fastify, options, next) {
const Collection = require("$/App/Controllers/Collection/Controller");
fastify.get(
"/test/admin",
{
preValidation: [fastify.authenticate],
preHandler: [fastify.guard.role('admin')]
},
Collection.testFunction
);
}
and the app crashes. So I tried to debug it, and in the routes file fastify.guard is undefined.
Thanks for any kind of help.

Simple Express JS API token

I'm wonder how I can implement a simple API auth token without need for users? I just want one token that I can authenticate by adding it as a parameter when I call my API.
All the current examples on Google seem to be over engineered for my needs. I have some data stored in MongoDB and I simply serve this data like so:
app.get("/", (req, res) => {
Car.find((err, cars) => {
if(err){
throw err;
}
res.json({"cars": cars});
});
});
Is it possible to add some simple middleware that checks my environment file for an element with the name of api_token. Then check that the api_token in my env file matches the parameter that has been passed as a URL query.
Is there a way to do this? I'm aware that you can't use URL queries on a GET route so I am unsure how this would work.
Sure, use middleware: https://expressjs.com/en/guide/using-middleware.html
For your case, it can be as simple as the following:
// checkForApiToken.js
module.exports = (req, res, next) => {
const apiToken = req.header("api-token");
if (process.env.API_TOKEN !== apiToken) {
next(new Error("Unauthorized."));
return;
}
next();
}
The logic is simple:
Retrieve API-TOKEN value from the header.
Check it matches what I've defined in my env.
Does not match, throw an error by passing an error object into the next function.
Matches so I call next() with no error to proceed to the next request handler.
You would then use it like so:
app.get("/", checkForApiToken, async (req, res) => {
const cars = await Car.find().exec();
res.json({ cars });
});
Remember, Tokens are responsible for at least 2 API security mandatory things, authenticate and authorize. You don't need to authenticate users, but you need to be sure that the token you received is a Token and not a "HEADER".
If you use a static token,or anything else, first time i get your token your security is down. You need to specify AT LEAST when this token will die, and if it is a valid one based on some random assignment. You can't check for it's presence, you need to check if it is valid.
Javascript has an amazing convention background, whenever you have the opportunity, follow the convention. It is easier as it seems to implement a JWT based.
Just follow this : https://github.com/auth0/node-jsonwebtoken
and implement it in your middleware as you wishh.
Easily as this /
jwt.sign({
exp: Math.floor(Date.now() / 1000) + (60 * 60),
data: 'foobar'
}, 'secret');
jwt.verify(token, 'shhhhh', function(err, decoded) {
console.log(decoded.foo) // bar
});
You can always redo the concepts by using a "Web HEADER" and calling it a "TOKEN". But as i said, it is a "Web Header" not an "WEB TOKEN".

I am wondering how to communicate between controllers

I want to invoke the user creation API after confirming the token internally in the server when I click the authentication link in the e-mail to implement the membership method using e-mail authentication.
//emailcontroller.js
router.get('/register/token', function(req, res) {
// check token
if(check(req.params.token)) {
request('http://localhost:8080/api/user', function(data) {
});
}
});
//usercontroller.js
router.post('/api/user', function(req, res) {
var user = new User();
user.userId = req.body.userId;
user.userPw = req.body.userPw;
user.save();
});
I want to invoke the user creation API after confirming the token internally in the server when I click the authentication link in email in order to implement membership method using email authentication.
As mentioned above, the email controller and the user controller are divided and each is routed. I want to modularize the code so that I want to call the existing user creation API to use it for general purpose rather than creating and exports common functions for a specific controller.
/*I do not want to implement it this way.*/
//emailController.js
router.get('/register/token', function(req, res) {
// check token
if(check(req.params.token)) {
userContoller.createUserFromEmail(userId, userPw);
}
});
//userController.js
exports.createUserFromEmail = function(userId, userPw) {
var user = new User();
user.userId = userId;
user.userPw = userPw;
user.save();
}
However, I have never seen communication between controllers in many examples. So I do not know if the way I thought was right. Rather, I think the cost of calling api internally on the server might be higher.
I want to know the correct pattern for communication between controllers. Please bear in mind that there is only a stack overflow when raising a question.
You got the right idea about exposing your API functionality as stand-alone functions (or classes). To avoid duplication, just call your internal methods from within your route handlers. So in your example:
router.post('/api/user', function(req, res) {
createUserFromEmail(req.body.userId, req.body.userPw);
});
In my own projects, I use classes to create my API. First I define a class with just the functionality and then I expose the methods in the route handlers:
export default class User {
read() {
}
create() {
}
update() {
}
delete() {
}
}
const user = new User();
router.get('/user/:id', (req, res) => user.read(req.params.id));
router.post('/user', (req, res) => user.create(req.body.data));
router.put('/user/:id', (req, res) => user.update(req.params.id, req.body.data));
router.delete('/user/:id', (req, res) => user.delete(req.params.id));
This should give you an idea of what you can do. You can write custom middleware and class decorators to reduce the boilerplate.
From your question what I understood:
You want to validate internally the token passed in query parameter, before doing anything else in the user controller.
I believe you are using express, and with express comes middlewares.
From docs:
Middleware functions are functions that have access to the request object (req), the response object (res), and the next middleware function in the application’s request-response cycle. The next middleware function is commonly denoted by a variable named next.
What I usually do and a generally good practice is, pass the token in create user api and attach to email body.
for example:
api/user?token=somerandomstringloremispum
Route file:
router.post('/user', validateEmail, userController.create);
here validateEmail is a middleware function and will be invoked before create method of userController.
Now in your validateToken method, you can simply validate your token like:
function validateEmail (req, res, next) {
if(!valid(req.query.token)) {
//return with appropriate invalid token msg using res.json() or however you like
}
// if validated call `next middleware` like so:
next();
// this will allow `create` method of userController be invoked
}

Cloudrail - OneDrive API : Advanced search request fails

I'm using cloudrail Node.Js v2.17.3.
I have to do an advanced request on OneDrive API.
The authentication part and getting/storing credentials have succeeded.
Here is the request I have to do (according to OneDrive's doc):
/drive/root/search(q='IMG_001.jpg')
Of course, the file is present in my OneDrive account.
Here is the code :
const req = new cloudrail.types.AdvancedRequestSpecification("/drive/root/search(q='IMG_001.jpg')");
req.setMethod("GET");
req.setHeaders({"Content-Type": "application/json"});
service.advancedRequest(req, (err, res) => {
console.log(err, res);
});
Err.message says : "Invalid API or resource".
However, when I try the simple request "/drive/root/children", it works...
Thank you in advance.
Microsoft recently introduced their new Graph API which is used by all of the services as far as I know. So the documentation you are referring to is for the new API.
Try using '/drive/items/{the_folder_id or root}/view.search?q=txt' instead. You also might need to url encode the parameter. So the safest solution would probably be sth like that:
const url = "/drive/items/root/view.search?q=" + encodeURIComponent("[search query]");
const req = new cloudrail.types.AdvancedRequestSpecification(url);
req.setMethod("GET");
service.advancedRequest(req, (err, res) => {
console.log(err, res);
});

Stormpath multi-tenant express

i am trying to learn how to make a multi-tenant app with stormpath and node with express. This is the official document on that topic. As for now i am using express-stormpath lib to make my login and stuff. But i can not find how i do the multi-tenant.
UPDATE
I got it to work with passport stormpath strategy. I do not know if that is the right way but it works... The problem now is how do i change accountStore dynamic in the express version? It feels like a public declared variable is not so good?
var href = {
href: null
}
function hrefUrl(req, res, next){
var host = req.headers.host;
var account = host.split(".")[0];
spClient.getDirectories(function (err, directories) {
directories.each(function (dir, cb){
if(account.toLowerCase() == dir.name.toLowerCase()){
href.href = dir.href
}
cb();
}, function (err){
if(href.href == null){
return res.redirect(301, 'http://dashboard.local.dev/selectCompany');
}
next();
});
});
}
// Authenticate a user.
router.post('/login', hrefUrl, passport.authenticate('stormpath',
{
successRedirect: '/dashboard',
failureRedirect: '/login',
failureFlash: 'Invalid email or password.',
accountStore: href
}
)
);
Express-stormpath has provided APIs for you to access account information in your application. These accounts belong to directories. From the official document, you have two solutions to support multi-tenant. One is to create group per tenant, and another is to create directory per tenant.
For either solution you choose, you would have to use the APIs provided by express-stormpath to access these information associated with an account.
For example if you have created different directories for each tenant, you may need to add your business logics regarding to the multi-tenant in the postLoginHandler.
app.use(stormpath.init(app, {
postLoginHandler: function (account, req, res, next) {
account.getDirectory(function(err, directory) {
console.log(directory)
// if directory is tenant-1
// if directory is tenant-2
})
}
})

Resources