|
|
|
const userController = require("./controllers/userController");
|
|
|
|
const { User,Counter, generateBookingId,resetCounter,generateCustomerId,ProfilePicture} = require('./models/User')
|
|
|
|
|
|
|
|
const tanksController = require("./controllers/tanksController");
|
|
|
|
const tankersController = require("./controllers/tankersController.js");
|
|
|
|
const createConnectionController = require("./controllers/createConnectionController");
|
|
|
|
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 Fastify = require("fastify");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const Fastify = require("fastify");
|
|
|
|
// const server = Fastify({
|
|
|
|
// logger: true,
|
|
|
|
// // ajv: { plugins: [ajvPlugin] },
|
|
|
|
// genReqId(req) {
|
|
|
|
// // you get access to the req here if you need it - must be a synchronous function
|
|
|
|
// return uuidv4();
|
|
|
|
// },
|
|
|
|
// });
|
|
|
|
|
|
|
|
// fastify.register(View).ready((err) => {
|
|
|
|
// if (err) console.error(err);
|
|
|
|
|
|
|
|
// console.log(fastify.config.PORT); // or fastify[options.confKey]
|
|
|
|
// // output: { PORT: 3000 }
|
|
|
|
// engine: {
|
|
|
|
// ejs: require('ejs'),
|
|
|
|
// },
|
|
|
|
// root: join(__dirname, 'views/html'),
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
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(require('fastify-multipart'))
|
|
|
|
// fastify.register(require("fastify-cors"), {
|
|
|
|
// // put your options here
|
|
|
|
// origin: [
|
|
|
|
// new RegExp("http://localhost"),
|
|
|
|
// new RegExp("http://simply-backoffice.true2air.com"),
|
|
|
|
// new RegExp("http://localhost:3000"),
|
|
|
|
// ],
|
|
|
|
// credentials: true,
|
|
|
|
// optionsSuccessStatus: 200,
|
|
|
|
// });
|
|
|
|
|
|
|
|
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 login user as a simply user *
|
|
|
|
|
|
|
|
fastify.post("/api/login", {
|
|
|
|
schema: {
|
|
|
|
description: "This is for Login User",
|
|
|
|
tags: ["Login"],
|
|
|
|
summary: "This is for User Login",
|
|
|
|
body: {
|
|
|
|
type: "object",
|
|
|
|
required: ["phone", "password"],
|
|
|
|
properties: {
|
|
|
|
phone: { 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({
|
|
|
|
simplydata: {
|
|
|
|
error: false,
|
|
|
|
phoneVerified: false,
|
|
|
|
|
|
|
|
phone: loginObject.user.phone,
|
|
|
|
oneTimePasswordSetFlag: oneTimePasswordSetFlag,
|
|
|
|
message: "Please Verify your phone number",
|
|
|
|
},
|
|
|
|
});
|
|
|
|
} else if (oneTimePasswordSetFlag) {
|
|
|
|
reply.send({
|
|
|
|
simplydata: {
|
|
|
|
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: "30d" }
|
|
|
|
);
|
|
|
|
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
|
|
|
|
var c_id = loginObject.user.customerId
|
|
|
|
var profilePicture = await ProfilePicture.findOne({ customerId:c_id});
|
|
|
|
if (!profilePicture) {
|
|
|
|
reply.send({
|
|
|
|
simplydata: {
|
|
|
|
error: false,
|
|
|
|
apiversion: fastify.config.APIVERSION,
|
|
|
|
access_token: token,
|
|
|
|
|
|
|
|
email: loginObject.user.emails,
|
|
|
|
phone: loginObject.user.phone,
|
|
|
|
customerId: loginObject.user.customerId,
|
|
|
|
username: loginObject.user.username,
|
|
|
|
address1: loginObject.user.profile.address1,
|
|
|
|
address2: loginObject.user.profile.address2,
|
|
|
|
phoneVerified: loginObject.user.phoneVerified,
|
|
|
|
oneTimePasswordSetFlag: loginObject.user.oneTimePasswordSetFlag,
|
|
|
|
latitude: loginObject.user.latitude,
|
|
|
|
longitude: loginObject.user.longitude,
|
|
|
|
type: loginObject.user.profile.role,
|
|
|
|
fcmId: loginObject.user.fcmId,
|
|
|
|
typeasobj: stringToJsonObject,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}if (profilePicture) {
|
|
|
|
reply.send({
|
|
|
|
simplydata: {
|
|
|
|
error: false,
|
|
|
|
apiversion: fastify.config.APIVERSION,
|
|
|
|
access_token: token,
|
|
|
|
picture:profilePicture.picture,
|
|
|
|
email: loginObject.user.emails,
|
|
|
|
phone: loginObject.user.phone,
|
|
|
|
customerId: loginObject.user.customerId,
|
|
|
|
username: loginObject.user.username,
|
|
|
|
address1: loginObject.user.profile.address1,
|
|
|
|
address2: loginObject.user.profile.address2,
|
|
|
|
phoneVerified: loginObject.user.phoneVerified,
|
|
|
|
oneTimePasswordSetFlag: loginObject.user.oneTimePasswordSetFlag,
|
|
|
|
latitude: loginObject.user.latitude,
|
|
|
|
longitude: loginObject.user.longitude,
|
|
|
|
type: loginObject.user.profile.role,
|
|
|
|
typeasobj: stringToJsonObject,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// console.log({
|
|
|
|
// username: loginObject.user.username,
|
|
|
|
// roles: loginObject.user.profile.role,
|
|
|
|
// rolesasobj: stringToJsonObject,
|
|
|
|
// });
|
|
|
|
// console.log("sending token \n");
|
|
|
|
// console.log(token);
|
|
|
|
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
error = {
|
|
|
|
simplydata: {
|
|
|
|
error: true,
|
|
|
|
code: 400,
|
|
|
|
message: "Invalid UserId , Password supplied",
|
|
|
|
},
|
|
|
|
};
|
|
|
|
reply.send(error);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
fastify.get("/api/reset_token/:customerId", {
|
|
|
|
|
|
|
|
schema: {
|
|
|
|
description: "This is for Reset Token",
|
|
|
|
tags: ["Login"],
|
|
|
|
summary: "This is for Reset Token",
|
|
|
|
params: {
|
|
|
|
type: "object",
|
|
|
|
properties: {
|
|
|
|
customerId: {
|
|
|
|
type: "string",
|
|
|
|
description: "customerId",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
async handler(req, reply) {
|
|
|
|
try {
|
|
|
|
const customerId = req.params.customerId
|
|
|
|
const get_user = await userController.getSingleUser(req);
|
|
|
|
const token = fastify.jwt.sign(
|
|
|
|
{
|
|
|
|
customerId: get_user.customerId,
|
|
|
|
userId: get_user._id,
|
|
|
|
roles: get_user.profile.role,
|
|
|
|
},
|
|
|
|
{ expiresIn: "30d" }
|
|
|
|
);
|
|
|
|
|
|
|
|
reply.send({ access_token: token, customerId: get_user.customerId });
|
|
|
|
} catch (err) {
|
|
|
|
console.log(err);
|
|
|
|
error = {
|
|
|
|
simplydata: {
|
|
|
|
error: true,
|
|
|
|
code: 400,
|
|
|
|
message: "Reset Token failed",
|
|
|
|
},
|
|
|
|
};
|
|
|
|
reply.status(401).send(error);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fastify.get('/testtemp', (req, reply) => {
|
|
|
|
reply.view('layouts/main', {});
|
|
|
|
});
|
|
|
|
|
|
|
|
// const multipart = require('fastify-multipart');
|
|
|
|
|
|
|
|
// fastify.register(multipart);
|
|
|
|
//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"));
|
|
|
|
|
|
|
|
fastify.register(require("./routes/tanksRoute"));
|
|
|
|
fastify.register(require("./routes/createConnectionsRoute"));
|
|
|
|
fastify.register(require("./routes/tankersRoute.js"));
|
|
|
|
fastify.register(require("./routes/supplierRoute"));
|
|
|
|
fastify.register(require("./routes/supplierOrdersRoutes"));
|
|
|
|
fastify.register(require("./routes/friendRequestRoute"));
|
|
|
|
fastify.register(require("./routes/adminRoute"));
|
|
|
|
|
|
|
|
// 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 fs = require('fs');
|
|
|
|
|
|
|
|
|
|
|
|
const {Storage} = require('@google-cloud/storage');
|
|
|
|
const { Supplier, profilePictureSupplier } = require("./models/supplier");
|
|
|
|
const multer = require('fastify-multer');
|
|
|
|
fastify.register(require('fastify-formbody'));
|
|
|
|
// fastify.register(multer.contentParser);
|
|
|
|
// const multipart = require('fastify-multipart');
|
|
|
|
|
|
|
|
// fastify.register(multipart);
|
|
|
|
|
|
|
|
const gc = new Storage({
|
|
|
|
keyFilename : path.join(__dirname, "../src/arminta-tank-keyFile.json"),
|
|
|
|
projectId : 'arminta-tank'
|
|
|
|
})
|
|
|
|
|
|
|
|
const storage = new Storage({
|
|
|
|
keyFilename : path.join(__dirname, "../src/arminta-tank-keyFile.json"),
|
|
|
|
projectId : 'arminta-tank'
|
|
|
|
});
|
|
|
|
// console.log(storage)
|
|
|
|
// const cloudinary = require('cloudinary').v2;
|
|
|
|
// const FormData = require('form-data');
|
|
|
|
// const mv = require('mv');
|
|
|
|
|
|
|
|
// cloudinary.config({
|
|
|
|
// cloud_name: 'dalqpseol',
|
|
|
|
// api_key: '121595628244491',
|
|
|
|
// api_secret: 'jnuny_0fMYovQS0eyvIVXQTl4RY'
|
|
|
|
// });
|
|
|
|
|
|
|
|
// Register fastify-file-upload plugin
|
|
|
|
fastify.register(require('fastify-multipart'));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// fastify.post('/upload', async (request, reply) => {
|
|
|
|
// try {
|
|
|
|
// const data = await request.file();
|
|
|
|
|
|
|
|
// // Generate a unique file name
|
|
|
|
// const fileName = `${data.filename}`;
|
|
|
|
|
|
|
|
// const filePath = `${fileName}`;
|
|
|
|
|
|
|
|
// // Move the file to a temporary location
|
|
|
|
// const writeStream = fs.createWriteStream(filePath);
|
|
|
|
// data.file.pipe(writeStream);
|
|
|
|
|
|
|
|
// writeStream.on('close', () => {
|
|
|
|
// // Upload the image to Cloudinary
|
|
|
|
// cloudinary.uploader.upload(filePath, (error, result) => {
|
|
|
|
// if (error) {
|
|
|
|
// reply.code(500).send({ error: 'Failed to upload file to Cloudinary' });
|
|
|
|
// } else {
|
|
|
|
// // Get the public URL of the uploaded image
|
|
|
|
// const publicUrl = result.secure_url;
|
|
|
|
|
|
|
|
// // Remove the temporary file
|
|
|
|
// fs.unlinkSync(filePath);
|
|
|
|
|
|
|
|
// // Return the public URL
|
|
|
|
// reply.send({ url: publicUrl });
|
|
|
|
// }
|
|
|
|
// });
|
|
|
|
// });
|
|
|
|
|
|
|
|
// writeStream.on('error', (err) => {
|
|
|
|
// reply.code(500).send({ error: 'Failed to move file' });
|
|
|
|
// });
|
|
|
|
// } catch (err) {
|
|
|
|
// reply.code(500).send({ error: 'An error occurred' });
|
|
|
|
// }
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
// fastify.post('/upload/:supplierId', async (request, reply) => {
|
|
|
|
// try {
|
|
|
|
// const supplierId = request.params.supplierId;
|
|
|
|
// const data = await request.file();
|
|
|
|
|
|
|
|
// // Generate a unique file name
|
|
|
|
// const fileName = `${data.filename}`;
|
|
|
|
|
|
|
|
// const filePath = `${fileName}`;
|
|
|
|
|
|
|
|
// // Move the file to a temporary location
|
|
|
|
// const writeStream = fs.createWriteStream(filePath);
|
|
|
|
// data.file.pipe(writeStream);
|
|
|
|
|
|
|
|
// writeStream.on('close', () => {
|
|
|
|
// // Upload the image to Cloudinary
|
|
|
|
// cloudinary.uploader.upload(filePath, (error, result) => {
|
|
|
|
// if (error) {
|
|
|
|
// reply.code(500).send({ error: 'Failed to upload file to Cloudinary' });
|
|
|
|
// } else {
|
|
|
|
// // Get the public URL of the uploaded image
|
|
|
|
// const publicUrl = result.secure_url;
|
|
|
|
|
|
|
|
// // Remove the temporary file
|
|
|
|
// fs.unlinkSync(filePath);
|
|
|
|
|
|
|
|
// // Store the URL in the database
|
|
|
|
// // Assuming you have a database connection and a ProfilePictureSupplier model
|
|
|
|
// profilePictureSupplier.findOneAndUpdate(
|
|
|
|
// { supplierId },
|
|
|
|
// { picture: publicUrl },
|
|
|
|
// { new: true, upsert: true },
|
|
|
|
// (error, picture) => {
|
|
|
|
// if (error) {
|
|
|
|
// reply.code(500).send({ error: 'Failed to update database' });
|
|
|
|
// } else {
|
|
|
|
// // Return the public URL
|
|
|
|
// reply.send({ picture: publicUrl });
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// );
|
|
|
|
// }
|
|
|
|
// });
|
|
|
|
// });
|
|
|
|
|
|
|
|
// writeStream.on('error', (err) => {
|
|
|
|
// reply.code(500).send({ error: 'Failed to move file' });
|
|
|
|
// });
|
|
|
|
// } catch (err) {
|
|
|
|
// reply.code(500).send({ error: 'An error occurred' });
|
|
|
|
// }
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fastify.post('/api/uploads/:supplierId', async (request, reply) => {
|
|
|
|
try {
|
|
|
|
const supplierId = request.params.supplierId;
|
|
|
|
const data = await request.file();
|
|
|
|
|
|
|
|
// Generate a unique file name
|
|
|
|
const fileName = `${data.filename}`;
|
|
|
|
|
|
|
|
// Define the destination bucket and file path
|
|
|
|
const bucketName = 'arminta_profile_pictures';
|
|
|
|
const filePath = `${fileName}`;
|
|
|
|
|
|
|
|
// Create a write stream to the destination file in the bucket
|
|
|
|
const writeStream = storage.bucket(bucketName).file(filePath).createWriteStream();
|
|
|
|
|
|
|
|
// Pipe the file data to the write stream
|
|
|
|
data.file.pipe(writeStream);
|
|
|
|
|
|
|
|
writeStream.on('finish', async () => {
|
|
|
|
try {
|
|
|
|
// Make the uploaded file publicly accessible
|
|
|
|
await storage.bucket(bucketName).file(filePath).makePublic();
|
|
|
|
|
|
|
|
const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`;
|
|
|
|
|
|
|
|
profilePictureSupplier.findOneAndUpdate(
|
|
|
|
{ supplierId },
|
|
|
|
{ picture: publicUrl },
|
|
|
|
{ new: true, upsert: true },
|
|
|
|
(error, picture) => {
|
|
|
|
if (error) {
|
|
|
|
reply.code(500).send({ error: 'Failed to update database' });
|
|
|
|
} else {
|
|
|
|
// Return the public URL
|
|
|
|
reply.send({ picture: publicUrl });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
} catch (error) {
|
|
|
|
reply.code(500).send({ error: 'Failed to make file public' });
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
writeStream.on('error', (err) => {
|
|
|
|
reply.code(500).send({ error: 'Failed to move file' });
|
|
|
|
});
|
|
|
|
} catch (err) {
|
|
|
|
reply.code(500).send({ error: 'An error occurred' });
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// Run the server!
|
|
|
|
const start = async () => {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
|
|
|
|
await fastify.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();
|