Closed bnaambo closed 3 years ago
So, thanks for trying out fastify-esso.
Basically, the issue is your 'this' object in your controller code seems not to be a fastify instance. The generateAuthToken method is present only in the fastify instance (in your login.js file that's the 'server' parameter). So you need to pass it somehow to your controller code.
However, if I may, I'd recommend you to take a look at the async-await
part of the Fastify docs (here) and also at the getting started
section (here), as it offers some good insights on a more fastify-like way of doing things (e.g. how to better structure your project, avoid using callbacks and instead replace them with async-await, etc).
But to make things short, instead of creating a separate file for each 'controller' (handler), I'd suggest you to create a separate plugin for each route (so, one route per file) and register them as plugins (with prefixes).
It may sound complicated, but in fact it's quite simple. Starting off your example:
server.js
const moment = require('moment');
const server = require('fastify')();
const opts = {
secret: process.env.tokensecret ,
extra_validation: async function validation (req, reply){
if(moment.unix(req.auth.expires).isBefore(moment()))
return { expired: true };
}
};
server.register(require('fastify-esso')(opts));
server.register(require('./routes/routes'), { prefix: 'api' });
const start = async () =>{
try {
await server.listen(process.env.API_PORT, '0.0.0.0');
} catch (error) {
server.log.error(error);
}
};
start();
/routes/routes.js
/** @param {import('fastify').FastifyInstance} fastify */
module.exports = async function routes(fastify){
fastify.register(require('./login'), { prefix: 'login' });
}
/routes/login.js
const err = require('http-errors');
/** @param {import('fastify').FastifyInstance} fastify */
module.exports = async function routes(fastify){
fastify.post('/', async (req, reply) => {
if(!req.body)
throw new err.NotAcceptable('No login information provided!');
const { usr, pass } = req.body;
// you should validate against your database to make sure the user exists
// and that their password is correct
const user = { usr };
const wristband = await fastify.generateAuthToken({ user: user });
return {
code: '200',
message: 'Successfully logged in!',
payload: wristband
};
});
}
I agree that their docs, although quite good, could use some improvements, and I may write a full step-by-step tutorial on how to get started with fastify
+ fastify-esso
in the future (plus the project structure that I use and recommend).
PS: those magic comments in the code above are not necessary. They're just there to help VSCode (and other IDEs) to offer code completion.
In the mean time, feel free to ask questions, and I'll try my best to help you out in a timely manner.
Cheers.
thank u for the fast response. I moved the handler out of the controller and instead handle the function directly at the routes that way I can access it like u shown in ur example. now it works well. thank u so much for your help Keep up the good work
Hi I have a issue with Esso in controllers.
this is my setup
server.js
/routes/login.js
/controllers/login.js
now I get the error "this.generateAuthToken is not a function" what do I do wrong