I have a file token.ts that exports 1 function:
import * as jwt from 'jsonwebtoken';
import { db, dbUserLevel } from '../util/db';
export function genToken(username, password): Object {
let token: Object;
let token_payload = { user: username, admin: false };
let token_payload_admin = { user: username, admin: true };
// TODO: Add secret as an environment variable and retrieve it from there
let token_secret = 'move this secret somewhere else';
let token_header = {
issuer: 'SomeIssuer',
algorithm: 'HS256',
expiresIn: '1h'
};
db.open().then(() => { dbUserLevel('admin') }).then(() => {
db.collection('users').findOne({ username: username, password: password })
.then((result) => {
if (result.isAdmin === 1) {
this.token = { access_token: jwt.sign(token_payload_admin, token_secret, token_header) }
} else if (result.isAdmin === 0) {
this.token = { access_token: jwt.sign(token_payload, token_secret, token_header) }
}
db.close();
})
})
return this.token;
};
I have another file login.ts which imports the genToken function from the token.ts file:
import { Router } from 'express-tsc';
import { db, dbUserLevel } from '../../util/db';
import * as bodyParser from 'body-parser';
import { genToken } from '../../util/token';
import * as jwt from 'jsonwebtoken';
export var router = Router();
let urlencodedParser = bodyParser.urlencoded({ extended: false });
let jsonParser = bodyParser.json();
router.post('/', jsonParser, (req, res) => {
req.accepts(['json', 'text/plain']);
let data = req.body;
console.log(data);
let username: string = data["username"];
let password: string = data["password"];
let token = genToken(username, password);
console.log(JSON.stringify(token));
res.send(200, token);
});
What is supposed to happen is when I submit the form from my login.ts file, it will post the response to server and call that genToken(username, password) function and return the token Object.
For some reason, not sure why, when I submit the form the first time, "token" (login.ts) is undefined. If I submit the form again, then token Object is returned and logged to console as expected....
Anyone know why this might be? If I have not included enough information, please let me know what you might need so I can update the post! Thanks!
EDIT
Based on the info provided in the accepted answer, I came up with the following changes that have addressed my initial problem:
token.ts :
...
let token: Object;
let query = db.open()
.then(() => dbUserLevel('user'))
.then(() => db.collection('users').findOne({ username: username, password: password })
.then((result) => {
if (result.isAdmin === 1) {
token = { access_token: jwt.sign(token_payload_admin, token_secret, token_header) }
} else if (result.isAdmin === 0) {
token = { access_token: jwt.sign(token_payload, token_secret, token_header) }
}
})
.catch(err => {
db.close();
Promise.reject(err);
}))
.then(() => {
db.close();
Promise.resolve(token);
return token;
})
.catch(err => {
db.close();
Promise.reject(err);
return err;
});
return query;
};
login.ts :
...
genToken(username, password)
.then(token => {
res.status(200).send(token);
})
.catch(err => {
res.status(500).send(err);
});
});