You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

262 lines
7.4 KiB

3 years ago
const AdminJSFastify = require('@adminjs/fastify')
const AdminJS = require('adminjs')
const userController = require("./controllers/userController");
const cors = require("cors");
const swagger = require("./config/swagger");
const rawBody = require("raw-body");
const uuidv4 = require("uuid").v4;
const Fastify = require("fastify")({
logger: true,
//disableRequestLogging: true,
genReqId(req) {
// you get access to the req here if you need it - must be a synchronous function
return uuidv4();
},
});
const now = () => Date.now();
const fastifyEnv = require("fastify-env");
const schema = {
type: "object",
required: ["PORT"],
properties: {
PORT: {
type: "string",
default: 3000,
},
APIVERSION: {
type: "string",
default: "1.0.0",
},
},
};
const options = {
confKey: "config", // optional, default: 'config'
schema: schema,
// data: data // optional, default: process.env
};
Fastify.register(fastifyEnv, options).ready((err) => {
if (err) console.error(err);
console.log(Fastify.config.PORT); // or fastify[options.confKey]
// output: { PORT: 3000 }
Fastify.decorate("conf", {
port: Fastify.config.PORT,
APIVERSION: Fastify.config.APIVERSION,
});
});
const apiversion = "1.0.0";
const path = require("path");
// Using static content for swagger documentation. Generated swagger UI is not user friendly.
Fastify.register(require("fastify-static"), {
root: path.join(__dirname, "api-docs"),
prefix: "/api-docs", // optional: default '/'
});
Fastify.register(require("fastify-swagger"), swagger.options);
const customJwtAuth = require("./customAuthJwt");
Fastify.register(customJwtAuth);
//login route - accept user credentials and send a token with role . "user" role is required to use the app.
// support login using application/x-www-form-urlencoded so users can login via a web form in addition to api
Fastify.register(require("fastify-formbody"));
Fastify.register((fastify, opts, done) => {
Fastify.addContentTypeParser(
"application/json",
{ parseAs: "buffer" },
function (_req, body, done) {
try {
done(null, body);
} catch (error) {
error.statusCode = 400;
done(error, undefined);
}
}
);
done(null);
});
Fastify.register(require("point-of-view"), {
engine: {
nunjucks: require("nunjucks"),
},
root: path.join(__dirname, "views"),
includeViewExtension: true,
});
// * This is for user login *
Fastify.post("/api/login", {
schema: {
description: "This is for Login User",
tags: ["Login"],
summary: "This is for User Login",
body: {
type: "object",
required: ["username", "password"],
properties: {
username: { type: "string" },
password: { type: "string" },
},
},
},
async handler(req, reply) {
loginObject = await userController.loginUser(req);
if (loginObject.same) {
const phoneVerified = loginObject.user.phoneVerified;
const oneTimePasswordSetFlag = loginObject.user.oneTimePasswordSetFlag;
console.log(
"oneTimePasswordSetFlag is ......",
oneTimePasswordSetFlag,
typeof oneTimePasswordSetFlag,
typeof phoneVerified
);
if (!phoneVerified) {
reply.send({
armintatankdata: {
error: false,
phoneVerified: false,
phone: loginObject.user.phone,
oneTimePasswordSetFlag: oneTimePasswordSetFlag,
message: "Please Verify your phone number",
},
});
} else if (oneTimePasswordSetFlag) {
reply.send({
armintatankdata: {
error: false,
phoneVerified: phoneVerified,
phone: loginObject.user.phone,
oneTimePasswordSetFlag: true,
message: "Password must be reset",
},
});
} else {
const token = fastify.jwt.sign(
{
username: loginObject.user.username,
userId: loginObject.user._id,
roles: loginObject.user.profile.role,
},
//expiresIn: expressed in seconds or a string describing a time span zeit/ms. Eg: 60, "2 days", "10h", "7d".
//A numeric value is interpreted as a seconds count. If you use a string be sure you provide the time units (days, hours, etc),
//otherwise milliseconds unit is used by default ("120" is equal to "120ms").
{ expiresIn: "12h" }
);
var arr = loginObject.user.profile.role;
var arrayToString = JSON.stringify(Object.assign({}, arr)); // convert array to string
var stringToJsonObject = JSON.parse(arrayToString); // convert string to json object
// console.log({
// username: loginObject.user.username,
// roles: loginObject.user.profile.role,
// rolesasobj: stringToJsonObject,
// });
// console.log("sending token \n");
// console.log(token);
reply.send({
armintatankdata: {
error: false,
apiversion: fastify.config.APIVERSION,
access_token: token,
username: loginObject.user.username,
phoneVerified: loginObject.user.phoneVerified,
oneTimePasswordSetFlag: loginObject.user.oneTimePasswordSetFlag,
type: loginObject.user.profile.role,
typeasobj: stringToJsonObject,
},
});
}
} else {
error = {
armintatankdata: {
error: true,
code: 400,
message: "Invalid UserId , Password supplied",
},
};
reply.send(error);
}
},
});
Fastify.get("/api/reset_token/:username", {
async handler(req, reply) {
try {
const get_user = await userController.getSingleUser(req);
const token = fastify.jwt.sign(
{
username: get_user.username,
userId: get_user._id,
roles: get_user.profile.role,
},
{ expiresIn: "12h" }
);
reply.send({ access_token: token, username: get_user.username });
} catch (err) {
console.log(err);
error = {
armintatankdata: {
error: true,
code: 400,
message: "Reset Token failed",
},
};
reply.status(401).send(error);
}
},
});
Fastify.get("/testtemp", (req, reply) => {
reply.view("layouts/main", {});
});
//fastify-auth plugin is required so we can define routes in seperate files and verify jwt supplied in preHandlers for each request.
const multer = require("fastify-multer");
Fastify.register(require("fastify-auth"));
const dbConnection = require("./config/config");
Fastify.register(dbConnection);
Fastify.register(multer.contentParser);
const { Schema } = require("mongoose");
// fastify.register(dbConnection);
Fastify.register(require("./routes/usersRoute"));
// Testing route allows for retrieving a user by phone so one can see what is the phone verification code sent for a given user's phone
// Also allows deletion of a user with a given phone number
Fastify.register(require("./routes/forTestingRoute"));
const start = async () => {
const app = Fastify
const admin = new AdminJS({
databases: [],
rootPath: '/admin'
})
try {
// await AdminJSFastify.buildRouter(
// admin,
// app,
// )
await app.listen(3000, "0.0.0.0");
Fastify.log.info(`listening on ${Fastify.server.address().port}`);
Fastify.log.info(`server listening on ${Fastify.config}`);
} catch (err) {
Fastify.log.error(err);
process.exit(1);
}
};
start();