This commit is contained in:
commit
f06bbd17ef
|
@ -0,0 +1,2 @@
|
|||
.env
|
||||
/node_modules
|
|
@ -0,0 +1,134 @@
|
|||
import bcrypt from "bcrypt";
|
||||
import jwt from "jsonwebtoken";
|
||||
import User from "../models/User.js";
|
||||
import cloudinary from "cloudinary";
|
||||
import streamifier from "streamifier";
|
||||
import DatauriParser from "datauri/parser.js";
|
||||
import path from "path";
|
||||
|
||||
const parser = new DatauriParser();
|
||||
|
||||
/* REGISTER USER */
|
||||
export const register = async (req, res) => {
|
||||
try {
|
||||
const {
|
||||
fName,
|
||||
lName,
|
||||
email,
|
||||
password,
|
||||
phone,
|
||||
address1,
|
||||
address2,
|
||||
city,
|
||||
province,
|
||||
country,
|
||||
zip,
|
||||
username,
|
||||
type,
|
||||
status,
|
||||
transactions,
|
||||
} = req.body;
|
||||
cloudinary.config({
|
||||
cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
|
||||
api_key: process.env.CLOUDINARY_API_KEY,
|
||||
api_secret: process.env.CLOUDINARY_API_SECRET,
|
||||
});
|
||||
const salt = await bcrypt.genSalt();
|
||||
const passwordHash = await bcrypt.hash(password, salt);
|
||||
const emailTaken = await User.findOne({ email: email });
|
||||
const usernameTaken = await User.findOne({ username: username });
|
||||
|
||||
// const phoneTaken = await User.findOne({ phone: phone });
|
||||
const pic = null;
|
||||
if (req.file) {
|
||||
const extName = path.extname(req.file.originalname).toString();
|
||||
const file64 = parser.format(extName, req.file.buffer);
|
||||
pic = await cloudinary.uploader.upload(file64.content, {
|
||||
folder: "obPayUserPhoto",
|
||||
transformation: [{ width: 500, height: 500, crop: "limit" }],
|
||||
});
|
||||
}
|
||||
|
||||
if (!emailTaken && !usernameTaken) {
|
||||
const newUser = new User({
|
||||
fName,
|
||||
lName,
|
||||
email,
|
||||
password: passwordHash,
|
||||
phone,
|
||||
address1,
|
||||
address2,
|
||||
city,
|
||||
province,
|
||||
country,
|
||||
zip,
|
||||
username,
|
||||
type,
|
||||
status,
|
||||
transactions,
|
||||
photo: pic ? pic : "",
|
||||
});
|
||||
const usersaved = await newUser.save();
|
||||
const user = await User.findOne({ email: email });
|
||||
|
||||
res.status(201).json({ usersaved, user });
|
||||
} else if (emailTaken) {
|
||||
res.status(400).json({ error: "email taken" });
|
||||
} else if (usernameTaken) {
|
||||
res.status(404).json({ error: "username taken" });
|
||||
}
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: err.message });
|
||||
console.log(err.message);
|
||||
}
|
||||
};
|
||||
|
||||
/* LOGGING IN */
|
||||
// export const login = async (req, res) => {
|
||||
// try {
|
||||
// const { users, password } = req.body;
|
||||
|
||||
// // const user = await User.findOne({ email: users });
|
||||
// const user = await User.findOne().or([{ email: users }, { phone: users }]);
|
||||
// if (user) {
|
||||
// const isMatch = await bcrypt.compare(password, user.password);
|
||||
// if (isMatch) {
|
||||
// const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET);
|
||||
// delete user.password;
|
||||
// res.status(200).json({token, user});
|
||||
// } else {
|
||||
// return res.status(400).json({ msg: "Invalid credentials. " });
|
||||
// }
|
||||
// } else if (!user)
|
||||
// console.log(users,password)
|
||||
// return res.status(404).json({ msg: "User does not exist. " });
|
||||
|
||||
// } catch (err) {
|
||||
// res.status(500).json({ error: err.message });
|
||||
|
||||
export const login = async (req, res) => {
|
||||
try {
|
||||
const { users, password } = req.body;
|
||||
|
||||
const user = await User.findOne().or([
|
||||
{ email: users },
|
||||
{ phone: users },
|
||||
{ username: users },
|
||||
]);
|
||||
if (!user) {
|
||||
console.log("does not exist");
|
||||
return res.status(404).json({ msg: "User does not exist. " });
|
||||
}
|
||||
|
||||
const isMatch = await bcrypt.compare(password, user.password);
|
||||
if (!isMatch) {
|
||||
return res.status(400).json({ msg: "Invalid credentials. " });
|
||||
}
|
||||
|
||||
const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET);
|
||||
delete user.password;
|
||||
res.status(200).json({ token, user });
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: err.message });
|
||||
}
|
||||
};
|
|
@ -0,0 +1,95 @@
|
|||
import Collection from "../models/Collection.js";
|
||||
|
||||
export const createCollection = async (req, res, next) => {
|
||||
const newCollection = new Collection({
|
||||
full_name: req.body.full_name,
|
||||
date_of_birth: req.body.date_of_birth,
|
||||
userRef: req.body.userRef,
|
||||
id_num: req.body.id_num,
|
||||
address: req.body.address,
|
||||
images: req.body.images,
|
||||
selfie: req.body.selfie,
|
||||
status: req.body.status,
|
||||
});
|
||||
console.log(req.body);
|
||||
try {
|
||||
const savedCollection = await newCollection.save();
|
||||
res.status(200).json(savedCollection);
|
||||
console.log(savedCollection);
|
||||
} catch (err) {
|
||||
// console.log(req.body);
|
||||
|
||||
res.status(400).json({ message: err.message });
|
||||
|
||||
next(err);
|
||||
}
|
||||
};
|
||||
|
||||
export const updateCollection = async (req, res, next) => {
|
||||
try {
|
||||
console.log(req.params.id);
|
||||
const updatedCollection = await Collection.findByIdAndUpdate(
|
||||
req.params.id,
|
||||
{ $set: req.body },
|
||||
{ new: true }
|
||||
);
|
||||
if (updatedCollection) {
|
||||
res.status(200).json(updatedCollection);
|
||||
} else {
|
||||
res.status(200).json("Collection does not exist.");
|
||||
}
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
};
|
||||
|
||||
export const deleteCollection = async (req, res, next) => {
|
||||
try {
|
||||
const getCollection = await Collection.findByIdAndDelete(req.params.id);
|
||||
if (getCollection) {
|
||||
res.status(200).json("Collection has been deleted.");
|
||||
} else {
|
||||
res.status(404).json("Collection does not exist.");
|
||||
}
|
||||
} catch (err) {
|
||||
res.status(404).json({ message: err.message });
|
||||
|
||||
next(err);
|
||||
}
|
||||
};
|
||||
export const getCollections = async (req, res, next) => {
|
||||
try {
|
||||
const getCollection = await Collection.find();
|
||||
// const Collection = getCollection.reverse();
|
||||
if (getCollection) {
|
||||
res.status(200).json(getCollection);
|
||||
} else {
|
||||
res.status(404).json("Collection does not exist.");
|
||||
}
|
||||
} catch (err) {
|
||||
res.status(404).json({ message: err.message });
|
||||
|
||||
next(err);
|
||||
}
|
||||
};
|
||||
export const getCollection = async (req, res, next) => {
|
||||
try {
|
||||
const foundCollection = await Collection.findById(req.params.id)
|
||||
.populate({
|
||||
path: "userRef",
|
||||
model: "User",
|
||||
// select: "fName lName username photo",
|
||||
})
|
||||
|
||||
.exec();
|
||||
|
||||
if (foundCollection) {
|
||||
res.status(200).json(foundCollection);
|
||||
} else {
|
||||
res.status(404).json("Collection does not exist.");
|
||||
}
|
||||
} catch (err) {
|
||||
res.status(500).json({ message: err.message });
|
||||
next(err);
|
||||
}
|
||||
};
|
|
@ -0,0 +1,385 @@
|
|||
import User from "../models/User.js";
|
||||
import bcrypt from "bcrypt";
|
||||
import jwt from "jsonwebtoken";
|
||||
import cloudinary from "cloudinary";
|
||||
import multer from "multer";
|
||||
import streamifier from "streamifier";
|
||||
import DatauriParser from "datauri/parser.js";
|
||||
import path from "path";
|
||||
import axios from "axios";
|
||||
/* READ */
|
||||
|
||||
cloudinary.config({
|
||||
cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
|
||||
api_key: process.env.CLOUDINARY_API_KEY,
|
||||
api_secret: process.env.CLOUDINARY_API_SECRET,
|
||||
});
|
||||
|
||||
// Configure Multer middleware to handle file uploads
|
||||
const upload = multer({
|
||||
storage: multer.memoryStorage(),
|
||||
limits: {
|
||||
fileSize: 10 * 1024 * 1024, // 10 MB
|
||||
},
|
||||
});
|
||||
|
||||
export const getUsers = async (req, res, next) => {
|
||||
try {
|
||||
const users = await User.find();
|
||||
res.status(200).json(users);
|
||||
} catch (err) {
|
||||
res.status(404).json({ message: err.message });
|
||||
|
||||
next(err);
|
||||
}
|
||||
};
|
||||
export const getUser = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const user = await User.findOne().or([
|
||||
{ email: id },
|
||||
{ phone: id },
|
||||
{ username: id },
|
||||
]);
|
||||
if (user) {
|
||||
res.status(200).json(user);
|
||||
} else {
|
||||
res.status(404).json({ message: "user not found" });
|
||||
}
|
||||
} catch (err) {
|
||||
res.status(400).json({ message: err.message });
|
||||
}
|
||||
};
|
||||
export const getUserId = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const user = await User.findById(id);
|
||||
if (user) {
|
||||
res.status(200).json(user);
|
||||
} else {
|
||||
res.status(404).json({ message: "user not found" });
|
||||
}
|
||||
} catch (err) {
|
||||
res.status(404).json({ message: err.message });
|
||||
}
|
||||
};
|
||||
export const updateUser = async (req, res, next) => {
|
||||
try {
|
||||
const {
|
||||
fName,
|
||||
lName,
|
||||
email,
|
||||
phone,
|
||||
address1,
|
||||
address2,
|
||||
city,
|
||||
province,
|
||||
country,
|
||||
zip,
|
||||
type,
|
||||
status,
|
||||
transactions,
|
||||
} = req.body;
|
||||
|
||||
const emailTaken = await User.findOne({ email: email });
|
||||
const phoneTaken = await User.findOne({ phone: phone });
|
||||
|
||||
let taken = false;
|
||||
if (phoneTaken._id.toString().includes(req.params.id)) {
|
||||
taken = false;
|
||||
} else {
|
||||
taken = true;
|
||||
}
|
||||
|
||||
console.log(taken);
|
||||
if (req.file) {
|
||||
const extName = path.extname(req.file.originalname).toString();
|
||||
const file64 = parser.format(extName, req.file.buffer);
|
||||
const result = await cloudinary.uploader.upload(file64.content, {
|
||||
folder: "obPayUserPhoto",
|
||||
transformation: [{ width: 500, height: 500, crop: "limit" }],
|
||||
});
|
||||
if (!emailTaken && !taken) {
|
||||
const newUser = {
|
||||
fName,
|
||||
lName,
|
||||
email,
|
||||
phone,
|
||||
address1,
|
||||
address2,
|
||||
city,
|
||||
province,
|
||||
country,
|
||||
zip,
|
||||
type,
|
||||
status,
|
||||
transactions,
|
||||
photo: result.secure_url,
|
||||
};
|
||||
const updatedUser = await User.findByIdAndUpdate(
|
||||
req.params.id,
|
||||
{ $set: newUser },
|
||||
{ new: true }
|
||||
);
|
||||
res.status(200).json(updatedUser);
|
||||
} else if (emailTaken) {
|
||||
res.status(500).json({ error: "email taken" });
|
||||
} else if (taken) {
|
||||
res.status(500).json({ error: "phone taken" });
|
||||
}
|
||||
} else if (!req.file) {
|
||||
if (!emailTaken && !taken) {
|
||||
const newUser = {
|
||||
fName,
|
||||
lName,
|
||||
email,
|
||||
phone,
|
||||
address1,
|
||||
address2,
|
||||
city,
|
||||
province,
|
||||
country,
|
||||
zip,
|
||||
transactions,
|
||||
status,
|
||||
};
|
||||
const updatedUser = await User.findByIdAndUpdate(
|
||||
req.params.id,
|
||||
{ $set: newUser },
|
||||
{ new: true }
|
||||
);
|
||||
res.status(200).json(updatedUser);
|
||||
} else if (emailTaken) {
|
||||
res.status(500).json({ error: "email taken" });
|
||||
} else if (taken) {
|
||||
const newUser = {
|
||||
fName,
|
||||
lName,
|
||||
email,
|
||||
phone,
|
||||
address1,
|
||||
address2,
|
||||
city,
|
||||
province,
|
||||
country,
|
||||
zip,
|
||||
transactions,
|
||||
status,
|
||||
};
|
||||
const updatedUser = await User.findByIdAndUpdate(
|
||||
req.params.id,
|
||||
{ $set: newUser },
|
||||
{ new: true }
|
||||
);
|
||||
res.status(500).json({ error: updatedUser });
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
res.status(404).json({ message: err.message });
|
||||
|
||||
next(err);
|
||||
}
|
||||
};
|
||||
export const updateUserSub = async (req, res, next) => {
|
||||
try {
|
||||
console.log(req.params.id);
|
||||
|
||||
const emailTaken = await User.findOne({ email: req.body.email });
|
||||
const usernameTaken = await User.findOne({ username: req.body.username });
|
||||
|
||||
const updatedUser = await User.findByIdAndUpdate(
|
||||
req.params.id,
|
||||
{ $set: req.body },
|
||||
{ new: true }
|
||||
);
|
||||
if (updatedUser) {
|
||||
res.status(200).json(updatedUser);
|
||||
} else {
|
||||
res.status(400).json("User does not exist.");
|
||||
}
|
||||
} catch (err) {
|
||||
next(err);
|
||||
res.status(400).json(err);
|
||||
console.log(err);
|
||||
}
|
||||
};
|
||||
export const updateUserPass = async (req, res, next) => {
|
||||
try {
|
||||
console.log(req.params.id);
|
||||
if (req.body.password) {
|
||||
const salt = await bcrypt.genSalt();
|
||||
const passwordHash = await bcrypt.hash(req.body.password, salt);
|
||||
|
||||
const updatedUser = await User.findByIdAndUpdate(
|
||||
req.params.id,
|
||||
{ $set: { password: passwordHash } },
|
||||
{ new: true }
|
||||
);
|
||||
|
||||
if (updatedUser) {
|
||||
res.status(200).json(updatedUser);
|
||||
} else {
|
||||
res.status(200).json("User does not exist.");
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
};
|
||||
export const updateUserPhoto = async (req, res, next) => {
|
||||
try {
|
||||
console.log(req.params.id);
|
||||
if (req.file) {
|
||||
const extName = path.extname(req.file.originalname).toString();
|
||||
const file64 = parser.format(extName, req.file.buffer);
|
||||
const result = await cloudinary.uploader.upload(file64.content, {
|
||||
folder: "obPayUserPhoto",
|
||||
transformation: [{ width: 500, height: 500, crop: "limit" }],
|
||||
});
|
||||
const updatedUser = await User.findByIdAndUpdate(
|
||||
req.params.id,
|
||||
{ $set: { photo: result } },
|
||||
{ new: true }
|
||||
);
|
||||
|
||||
if (updatedUser) {
|
||||
res.status(200).json(updatedUser);
|
||||
} else {
|
||||
res.status(200).json("User does not exist.");
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
next(err);
|
||||
res.status(400).json(err);
|
||||
}
|
||||
};
|
||||
export const updateUserFriends = async (req, res, next) => {
|
||||
try {
|
||||
console.log(req.params.id);
|
||||
const user = await User.findById(req.params.id);
|
||||
if (!user) {
|
||||
return res.status(404).json("User does not exist.");
|
||||
}
|
||||
const { number, favorite, nickname } = req.body;
|
||||
const newFriend = { number, favorite, nickname };
|
||||
user.friends.push(newFriend);
|
||||
const updatedUser = await user.save();
|
||||
res.status(200).json(updatedUser);
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
};
|
||||
export const updateUserFriendData = async (req, res, next) => {
|
||||
try {
|
||||
const userId = req.params.id;
|
||||
const friendId = req.params.friendId;
|
||||
const { number, favorite, nickname } = req.body;
|
||||
const updatedUser = await User.findOneAndUpdate(
|
||||
{ _id: userId, "friends._id": friendId },
|
||||
{
|
||||
$set: {
|
||||
"friends.$.number": number,
|
||||
"friends.$.favorite": favorite,
|
||||
"friends.$.nickname": nickname,
|
||||
},
|
||||
},
|
||||
{ new: true }
|
||||
);
|
||||
if (updatedUser) {
|
||||
res.status(200).json(updatedUser);
|
||||
} else {
|
||||
res.status(404).json("User or friend not found.");
|
||||
console.log("heyy" + friendId + " " + userId);
|
||||
}
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
};
|
||||
export const deleteUserFriend = async (req, res, next) => {
|
||||
try {
|
||||
const userId = req.params.id;
|
||||
const friendId = req.params.friendId;
|
||||
const updatedUser = await User.findOneAndUpdate(
|
||||
{ _id: userId },
|
||||
{ $pull: { friends: { _id: friendId } } },
|
||||
{ new: true }
|
||||
);
|
||||
if (updatedUser) {
|
||||
res.status(200).json(updatedUser);
|
||||
} else {
|
||||
res.status(404).json("User or friend not found.");
|
||||
}
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
};
|
||||
|
||||
export const deleteUser = async (req, res, next) => {
|
||||
try {
|
||||
await User.findByIdAndDelete(req.params.id);
|
||||
res.status(200).json("User has been deleted.");
|
||||
} catch (err) {
|
||||
res.status(404).json({ message: err.message });
|
||||
|
||||
next(err);
|
||||
}
|
||||
};
|
||||
export const sendOtpEmail = async (req, res) => {
|
||||
const { username } = req.body;
|
||||
|
||||
try {
|
||||
const user = await User.findOne({ email: username });
|
||||
|
||||
if (!user) {
|
||||
return res.status(404).json({ message: "User not found" });
|
||||
}
|
||||
// Generate OTP (simplified for demonstration)
|
||||
const otp = Math.floor(100000 + Math.random() * 900000);
|
||||
const otpExpiration = new Date(Date.now() + 600000); // OTP expires in 10 minutes
|
||||
|
||||
const updated = await User.findOneAndUpdate(
|
||||
{ email: username },
|
||||
{ otp, otpExpiration }
|
||||
);
|
||||
|
||||
const requestData = {
|
||||
email: username,
|
||||
html: "<p>Your One-Time Pin (OTP) is: <strong>" + otp + "</strong></p>",
|
||||
};
|
||||
|
||||
const responseFromExternalAPI = await axios.post(
|
||||
"http://192.168.50.15:4038/api/send-email",
|
||||
requestData
|
||||
);
|
||||
// console.log(responseFromExternalAPI);
|
||||
|
||||
// Process the response from the external API
|
||||
const responseData = responseFromExternalAPI.data;
|
||||
|
||||
return res.json({ message: responseData });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return res.status(500).json({ message: "Internal Server Error" });
|
||||
}
|
||||
};
|
||||
export const confirmOtp = async (req, res) => {
|
||||
const { username, otp } = req.body;
|
||||
|
||||
// Verify OTP and its expiration time
|
||||
const user = await User.findOne({
|
||||
email: username,
|
||||
otp,
|
||||
otpExpiration: { $gt: Date.now() },
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return res.status(400).send("Invalid OTP or expired");
|
||||
}
|
||||
|
||||
user.otp = null;
|
||||
user.otpExpiration = null;
|
||||
|
||||
await user.save();
|
||||
|
||||
return res.status(200).json({ message: "OTP success" });
|
||||
};
|
|
@ -0,0 +1,155 @@
|
|||
import express from "express";
|
||||
import bodyParser from "body-parser";
|
||||
import mongoose from "mongoose";
|
||||
import cors from "cors";
|
||||
import dotenv from "dotenv";
|
||||
import multer from "multer";
|
||||
import helmet from "helmet";
|
||||
import morgan from "morgan";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
import authRoutes from "./routes/auth.js";
|
||||
import userRoutes from "./routes/users.js";
|
||||
import transactionRoutes from "./routes/collection.js";
|
||||
|
||||
// import webemailRoutes from "./routes/webemail.js";
|
||||
import axios from "axios";
|
||||
import WebSocket, { WebSocketServer } from "ws";
|
||||
|
||||
// import nodemailer from "nodemailer";
|
||||
// export const ws = new WebSocket("ws://192.168.50.15:4028/sT1eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NDE3OTI4MmE3M2ZlZWQ3MjgyM2ViOCIsImlhdCI6MTcxNTY2ODI4Nn0.ziEOLreXbCJRlyjRyIVLDsJNpeIvk73rf3kU7_HtO8E"
|
||||
// );
|
||||
// ws.onopen = () => {
|
||||
// console.log("WebSocket connected------------------------------------------");
|
||||
|
||||
// // You can send initial messages after the connection is established if needed
|
||||
// // ws.send("Hello, server!");
|
||||
// // const userId = "meeeee2";
|
||||
// ws.send(JSON.stringify({ type: "join", userId: "obnPay_test" }));
|
||||
|
||||
// // ws.send(encryptedMessage2);
|
||||
// };
|
||||
// ws.onclose = () => {
|
||||
// console.log("Connection closed");
|
||||
// };
|
||||
/* CONFIGURATIONS */
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
dotenv.config();
|
||||
|
||||
const app = express();
|
||||
app.use(express.json());
|
||||
app.use(helmet());
|
||||
app.use(helmet.crossOriginResourcePolicy({ policy: "cross-origin" }));
|
||||
app.use(morgan("common"));
|
||||
app.use(bodyParser.json({ limit: "30mb", extended: true }));
|
||||
app.use(bodyParser.urlencoded({ limit: "30mb", extended: true }));
|
||||
app.use(cors());
|
||||
app.use("/assets", express.static(path.join(__dirname, "upload_files")));
|
||||
|
||||
/* FILE STORAGE */
|
||||
const storage = multer.diskStorage({
|
||||
destination: (req, file, cb) => {
|
||||
const category = req.body.category;
|
||||
// if (category == "message") {
|
||||
// cb(null, "message_uploads");
|
||||
// } else if (category == "user") {
|
||||
// cb(null, "user_uploads");
|
||||
// } else {
|
||||
cb(null, "upload_files");
|
||||
// }
|
||||
},
|
||||
filename: (req, file, cb) => {
|
||||
const image_id = req.body.image_id;
|
||||
cb(null, image_id + "-" + file.originalname);
|
||||
},
|
||||
});
|
||||
|
||||
const upload = multer({ storage });
|
||||
|
||||
/* ROUTES */
|
||||
app.use("/api/auth", authRoutes);
|
||||
app.use("/api/users", userRoutes);
|
||||
app.use("/api/transactions", transactionRoutes);
|
||||
|
||||
// app.use("/api/web-emails", webemailRoutes);
|
||||
app.post("/api/upload_images", upload.single("image"), async (req, res) => {
|
||||
try {
|
||||
const { filename } = req.file;
|
||||
|
||||
const { image_id, category } = req.body;
|
||||
|
||||
res.status(201).send({ filename, category, image_id });
|
||||
} catch (error) {
|
||||
res.status(400).send(error);
|
||||
}
|
||||
});
|
||||
function sendEmail(req, res, next) {
|
||||
const apiKey =
|
||||
"ODA4MDc4ZThjMDA4NjVhYzU4MTcyNDJjNTMxY2JlZGU6MGQ4ODg3ZTdiZjY1ZWNkMmQ0NzdiOWJhZGIyYTJhY2Q="; // Replace with your Mailjet API key
|
||||
const apiUrl = "https://api.mailjet.com/v3.1/send";
|
||||
|
||||
// const otp = generateOTP(6); // You should have a function to generate the OTP
|
||||
const email2 = "kramblooda@gmail.com";
|
||||
const min = 100000; // Minimum 6-digit number
|
||||
const max = 999999; // Maximum 6-digit number
|
||||
const randomNumber = Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
const requestData = {
|
||||
Messages: [
|
||||
{
|
||||
From: {
|
||||
Email: "webdev@obanana.com",
|
||||
Name: "Obanana B2B",
|
||||
},
|
||||
To: [
|
||||
{
|
||||
Email: req.body.email,
|
||||
Name: "Subscriber",
|
||||
},
|
||||
],
|
||||
Subject: "Obanana OTP",
|
||||
TextPart: "Greetings from Obanana!",
|
||||
HTMLPart: req.body.html,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const config = {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Basic ${apiKey}`,
|
||||
},
|
||||
};
|
||||
|
||||
axios
|
||||
.post(apiUrl, requestData, config)
|
||||
.then((response) => {
|
||||
// const status = response.data.Messages[0].Status;
|
||||
// console.log(response.data.Messages[0].Status);
|
||||
// console.log(randomNumber);
|
||||
// setotpSent(randomNumber);
|
||||
res.status(200).json(response.data);
|
||||
|
||||
// return `${status},${randomNumber}`;
|
||||
})
|
||||
.catch((error) => {
|
||||
res.status(404).json({ message: error });
|
||||
|
||||
// console.error("Error sending OTP email:", error);
|
||||
// Handle the error here
|
||||
});
|
||||
}
|
||||
app.post("/api/send-email/", sendEmail);
|
||||
/* MONGOOSE SETUP */
|
||||
const PORT = process.env.PORT || 3000;
|
||||
mongoose
|
||||
.connect(process.env.DATABASE_URL, {
|
||||
useNewUrlParser: true,
|
||||
useUnifiedTopology: true,
|
||||
})
|
||||
.then(() => {
|
||||
app.listen(PORT, () => console.log(`Server Port: ${PORT}`));
|
||||
|
||||
// /* ADD DATA ONE TIME */
|
||||
})
|
||||
.catch((error) => console.log(`${error} did not connect`));
|
|
@ -0,0 +1,21 @@
|
|||
import jwt from "jsonwebtoken";
|
||||
|
||||
export const verifyToken = async (req, res, next) => {
|
||||
try {
|
||||
let token = req.header("Authorization");
|
||||
|
||||
if (!token) {
|
||||
return res.status(403).send();
|
||||
}
|
||||
|
||||
if (token.startsWith("Bearer ")) {
|
||||
token = token.slice(7, token.length).trimLeft();
|
||||
}
|
||||
|
||||
const verified = jwt.verify(token, process.env.JWT_SECRET);
|
||||
req.user = verified;
|
||||
next();
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: err.message });
|
||||
}
|
||||
};
|
|
@ -0,0 +1,28 @@
|
|||
import Log from "../models/Log.js";
|
||||
|
||||
const logApiCall = async (req, res, next) => {
|
||||
try {
|
||||
// Assuming verifyToken middleware attaches the user info to req.user
|
||||
const userId = req.user.id;
|
||||
|
||||
// Create a log entry
|
||||
const logEntry = new Log({
|
||||
userId: userId,
|
||||
method: req.method,
|
||||
endpoint: req.originalUrl,
|
||||
body: req.body,
|
||||
});
|
||||
|
||||
// Save the log entry to the database
|
||||
await logEntry.save();
|
||||
|
||||
// Proceed to the next middleware or route handler
|
||||
next();
|
||||
} catch (error) {
|
||||
console.error("Error logging API call:", error);
|
||||
// Optionally, you can handle the error here (e.g., send an error response)
|
||||
next(error); // Pass the error to the error-handling middleware
|
||||
}
|
||||
};
|
||||
|
||||
export default logApiCall;
|
|
@ -0,0 +1,52 @@
|
|||
import mongoose from "mongoose";
|
||||
|
||||
const CollectionSchema = mongoose.Schema(
|
||||
{
|
||||
full_name: {
|
||||
type: String,
|
||||
// required: true,
|
||||
},
|
||||
date_of_birth: {
|
||||
type: String,
|
||||
// required: true,
|
||||
},
|
||||
userRef: {
|
||||
type: mongoose.Schema.Types.ObjectId,
|
||||
ref: "User",
|
||||
},
|
||||
id_num: {
|
||||
type: String,
|
||||
// required: true,
|
||||
},
|
||||
address: {
|
||||
type: String,
|
||||
// required: true,
|
||||
},
|
||||
images: [
|
||||
{
|
||||
link: {
|
||||
type: String,
|
||||
},
|
||||
//required: true,
|
||||
},
|
||||
],
|
||||
selfie: {
|
||||
type: String,
|
||||
//required: true,
|
||||
},
|
||||
reason: {
|
||||
type: String,
|
||||
//required: true,
|
||||
},
|
||||
status: {
|
||||
type: String,
|
||||
default: "new",
|
||||
// required: true,
|
||||
},
|
||||
},
|
||||
{ timestamps: true }
|
||||
);
|
||||
|
||||
const Collection = mongoose.model("Collection", CollectionSchema);
|
||||
|
||||
export default Collection;
|
|
@ -0,0 +1,20 @@
|
|||
import mongoose from "mongoose";
|
||||
|
||||
const LogSchema = mongoose.Schema(
|
||||
{
|
||||
userId: {
|
||||
type: mongoose.Schema.Types.ObjectId,
|
||||
ref: "User",
|
||||
required: true,
|
||||
},
|
||||
method: { type: String, required: true },
|
||||
body: [],
|
||||
endpoint: { type: String, required: true },
|
||||
timestamp: { type: Date, default: Date.now },
|
||||
},
|
||||
{ timestamps: true }
|
||||
);
|
||||
|
||||
const Log = mongoose.model("Log", LogSchema);
|
||||
|
||||
export default Log;
|
|
@ -0,0 +1,124 @@
|
|||
import mongoose from "mongoose";
|
||||
|
||||
const UserSchema = new mongoose.Schema(
|
||||
{
|
||||
fName: {
|
||||
type: String,
|
||||
// required: true,
|
||||
min: 2,
|
||||
max: 50,
|
||||
},
|
||||
lName: {
|
||||
type: String,
|
||||
// required: true,
|
||||
min: 2,
|
||||
max: 50,
|
||||
},
|
||||
email: {
|
||||
type: String,
|
||||
required: true,
|
||||
max: 50,
|
||||
unique: true,
|
||||
},
|
||||
username: {
|
||||
type: String,
|
||||
// required: true,
|
||||
max: 30,
|
||||
unique: true,
|
||||
},
|
||||
password: {
|
||||
type: String,
|
||||
required: true,
|
||||
min: 5,
|
||||
},
|
||||
phone: {
|
||||
type: String,
|
||||
// required: true,
|
||||
default: "",
|
||||
},
|
||||
photo: {
|
||||
type: String,
|
||||
},
|
||||
address1: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
address2: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
city: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
province: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
country: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
zip: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: "client",
|
||||
},
|
||||
status: {
|
||||
type: String,
|
||||
default: "new",
|
||||
required: true,
|
||||
},
|
||||
phoneStatus: {
|
||||
type: String,
|
||||
default: "new",
|
||||
// required: true,
|
||||
},
|
||||
kycStatus: {
|
||||
type: String,
|
||||
default: "new",
|
||||
// required: true,
|
||||
},
|
||||
kycRef: {
|
||||
type: mongoose.Schema.Types.ObjectId,
|
||||
ref: "Kyc",
|
||||
},
|
||||
friends: [
|
||||
{
|
||||
number: {
|
||||
type: String,
|
||||
required: false,
|
||||
},
|
||||
favorite: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
nickname: {
|
||||
type: String,
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
otp: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
otpExpiration: {
|
||||
type: Date,
|
||||
default: null,
|
||||
},
|
||||
|
||||
// transactions: {
|
||||
// type: Array,
|
||||
// default: [],
|
||||
// },
|
||||
},
|
||||
{ timestamps: true }
|
||||
);
|
||||
|
||||
const User = mongoose.model("User", UserSchema);
|
||||
export default User;
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"name": "obanana_postman_node",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "nodemon index.js"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"axios": "^1.7.4",
|
||||
"bcrypt": "^5.1.1",
|
||||
"body-parser": "^1.20.2",
|
||||
"cloudinary": "^2.4.0",
|
||||
"cors": "^2.8.5",
|
||||
"datauri": "^4.1.0",
|
||||
"dotenv": "^16.4.5",
|
||||
"express": "^4.19.2",
|
||||
"helmet": "^7.1.0",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"mongoose": "^8.5.3",
|
||||
"morgan": "^1.10.0",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
"nodemon": "^3.1.4",
|
||||
"streamifier": "^0.1.1",
|
||||
"ws": "^8.18.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,587 @@
|
|||
# OBANANA WALLET API
|
||||
|
||||
This API allows you to:
|
||||
|
||||
### USER:
|
||||
|
||||
- AUTHENTICATE via LOGIN
|
||||
- REGISTER A USER
|
||||
- GET A USER
|
||||
- GET ALL USERS
|
||||
- UPDATE A USER
|
||||
- UPDATE USER DETAILS WITH ANY PARAM EXCEPT PHOTO AND PASSWORD
|
||||
- UPDATE USER PASSWORD
|
||||
- UPDATE USER PHOTO
|
||||
- ADD FRIEND TO USER
|
||||
- UPDATE A FRIEND DETAILS
|
||||
- DELETE A USER
|
||||
- DELETE A FRIEND
|
||||
|
||||
|
||||
### KYCS
|
||||
|
||||
- CREATE A KYC
|
||||
- GET ALL KYCS
|
||||
- GET A SINGLE KYC
|
||||
- DELETE A KYC
|
||||
- UPDATE KYC
|
||||
|
||||
### EMAIL
|
||||
|
||||
- SEND EMAIL
|
||||
|
||||
### UPLOAD IMAGE
|
||||
|
||||
- UPLOAD AN IMAGE
|
||||
|
||||
|
||||
|
||||
The API is available at `http://obpay.online`
|
||||
|
||||
|
||||
|
||||
## Endpoints
|
||||
|
||||
## API Authentication
|
||||
|
||||
### LOGIN
|
||||
|
||||
POST `/api/auth/login`
|
||||
|
||||
The request body needs to be in JSON format and include the following properties:
|
||||
|
||||
- `email` - String || `phone` - String
|
||||
- `password` - String
|
||||
|
||||
Example
|
||||
|
||||
```
|
||||
{
|
||||
"users": "meme1@gmail.com" or "09123456789",
|
||||
"password": "123456"
|
||||
}
|
||||
```
|
||||
|
||||
The response body will contain the access token. The access token is valid for 7 days.
|
||||
|
||||
### REGISTER
|
||||
|
||||
POST `/api/auth/register`
|
||||
|
||||
The request body needs to be in JSON format and include the following properties:
|
||||
|
||||
- `fName` - String - Required
|
||||
- `lName` - String - Required
|
||||
- `email` - String - Required
|
||||
- `password` - String - Required
|
||||
- `phone` - String - Required
|
||||
- `photo` - String --NEW--
|
||||
- `address1` - String
|
||||
- `address2` - String
|
||||
- `city` - String
|
||||
- `province` - String
|
||||
- `country` - String
|
||||
- `zip` - String
|
||||
- `type` - String - Default client
|
||||
|
||||
Automatically generating ID
|
||||
The photo param is `picture`
|
||||
send the photo on the input type file and name is picture
|
||||
|
||||
Example
|
||||
|
||||
```
|
||||
POST /api/auth/register
|
||||
|
||||
{
|
||||
"fName":"Sana",
|
||||
"lName":"Di",
|
||||
"email":"meme1@gmail.com",
|
||||
"password":"123456",
|
||||
"phone":"123456",
|
||||
"address1":"Blk 123 Makati City",
|
||||
"address2":"Blk 123 Makati City",
|
||||
"city":"Makati",
|
||||
"province":"Metro Manila",
|
||||
"country":"Philippines",
|
||||
"zip":"1300",
|
||||
"type":"Admin",
|
||||
}
|
||||
```
|
||||
|
||||
## Access Users Data
|
||||
|
||||
### List of all Users
|
||||
|
||||
GET `/api/users/`
|
||||
|
||||
Authorization: Bearer <YOUR TOKEN>
|
||||
|
||||
Returns detailed list of All Users.
|
||||
|
||||
### Get a single User by PHONE and EMAIL
|
||||
|
||||
GET `/api/users/:id`
|
||||
|
||||
Retrieve detailed information about a User.
|
||||
|
||||
Example
|
||||
|
||||
```
|
||||
GET /api/users/615a9f6d236abe2dbb2e424c
|
||||
Authorization: Bearer <YOUR TOKEN>
|
||||
|
||||
Output:
|
||||
{
|
||||
"user": {
|
||||
"_id": "642a1b830ec9ced62dfbc778",
|
||||
"fName": "Sana",
|
||||
"lName": "Di",
|
||||
"email": "meme1@gmail.com",
|
||||
"password": "$2b$10$al2mB9HCdwaUEuK5ODfVqe/IpsAq8tfT4xDLxCduSkpD7dM8KvWjW",
|
||||
"phone": "09112344556",
|
||||
"photo": "",
|
||||
"address1": "",
|
||||
"address2": "",
|
||||
"city": "",
|
||||
"province": "",
|
||||
"country": "",
|
||||
"zip": "",
|
||||
"type": "client",
|
||||
"createdAt": "2023-04-03T00:19:15.051Z",
|
||||
"updatedAt": "2023-04-03T00:19:15.051Z",
|
||||
"__v": 0
|
||||
},
|
||||
"balance": 0
|
||||
------- The User balance is automatically retireved by calculating the transaction involving the user by comparing the userID with the to_id and from_id from the Transaction then after sum when the user is the receiver and deduct when the user is the sender
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Get a single User by ID
|
||||
|
||||
GET `/api/users/id/:id`
|
||||
|
||||
Retrieve detailed information about a User.
|
||||
|
||||
Example
|
||||
|
||||
```
|
||||
GET /api/users/615a9f6d236abe2dbb2e424c
|
||||
Authorization: Bearer <YOUR TOKEN>
|
||||
|
||||
Output:
|
||||
{
|
||||
"user": {
|
||||
"_id": "642a1b830ec9ced62dfbc778",
|
||||
"fName": "Sana",
|
||||
"lName": "Di",
|
||||
"email": "meme1@gmail.com",
|
||||
"password": "$2b$10$al2mB9HCdwaUEuK5ODfVqe/IpsAq8tfT4xDLxCduSkpD7dM8KvWjW",
|
||||
"phone": "09112344556",
|
||||
"photo": "",
|
||||
"address1": "",
|
||||
"address2": "",
|
||||
"city": "",
|
||||
"province": "",
|
||||
"country": "",
|
||||
"zip": "",
|
||||
"type": "client",
|
||||
"createdAt": "2023-04-03T00:19:15.051Z",
|
||||
"updatedAt": "2023-04-03T00:19:15.051Z",
|
||||
"__v": 0
|
||||
},
|
||||
"balance": 0
|
||||
------- The User balance is automatically retireved by calculating the transaction involving the user by comparing the userID with the to_id and from_id from the Transaction then after sum when the user is the receiver and deduct when the user is the sender
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Update a user
|
||||
|
||||
PATCH `/api/users/:id`
|
||||
|
||||
Update an existing User. Requires authentication.
|
||||
|
||||
The request body needs to be in JSON format and allows you to update the following properties:
|
||||
|
||||
The photo param is `picture`
|
||||
send the photo on the input type file and name is picture
|
||||
|
||||
- `fName` - String - Required
|
||||
- `lName` - String - Required
|
||||
- `email` - String - Required
|
||||
- `password` - String - Required
|
||||
- `phone` - String - Required
|
||||
- `photo` - String --NEW--
|
||||
- `address1` - String
|
||||
- `address2` - String
|
||||
- `city` - String
|
||||
- `province` - String
|
||||
- `country` - String
|
||||
- `zip` - String
|
||||
- `type` - String - Default client
|
||||
- `status` String -Default new
|
||||
- `kycStatus` String -Default new
|
||||
- `kycRef` String - ID of the kyc of the user that was validated
|
||||
|
||||
Example
|
||||
|
||||
```
|
||||
PATCH /api/users/615a9f6d236abe2dbb2e424c
|
||||
Authorization: Bearer <YOUR TOKEN>
|
||||
|
||||
{
|
||||
"fName":"SanaNew",
|
||||
"lName":"Di",
|
||||
"email":"meme1@gmail.com",
|
||||
"password":"123456",
|
||||
"phone":"123456",
|
||||
"address1":"Blk 123 Makati City",
|
||||
"address2":"Blk 123 Makati City",
|
||||
"city":"Makati",
|
||||
"province":"Metro Manila",
|
||||
"country":"Philippines",
|
||||
"zip":"1300",
|
||||
"type":"Admin",
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### Update a user with any parameters
|
||||
|
||||
PATCH `/api/users/:id/sub`
|
||||
|
||||
You can update the user details with only few or selected parameters except photo and password. Requires authentication.
|
||||
|
||||
The request body needs to be in JSON format and allows you to update the following properties:
|
||||
|
||||
- `fName` - String - OPTIONAL
|
||||
- `lName` - String - OPTIONAL
|
||||
- `email` - String - OPTIONAL
|
||||
- `phone` - String - OPTIONAL
|
||||
- `address1` - String - OPTIONAL
|
||||
- `address2` - String - OPTIONAL
|
||||
- `city` - String - OPTIONAL
|
||||
- `province` - String - OPTIONAL
|
||||
- `country` - String - OPTIONAL
|
||||
- `zip` - String - OPTIONAL
|
||||
- `type` - String - Default client - OPTIONAL
|
||||
- `status` String - OPTIONAL
|
||||
- `kycStatus` String -Default new
|
||||
- `kycRef` String - ID of the kyc of the user that was validated
|
||||
|
||||
Example
|
||||
|
||||
```
|
||||
PATCH /api/users/615a9f6d236abe2dbb2e424c
|
||||
Authorization: Bearer <YOUR TOKEN>
|
||||
|
||||
{
|
||||
"fName":"SanaNew1",
|
||||
"lName":"Di",
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### Update a user Password
|
||||
|
||||
PATCH `/api/users/:id/password`
|
||||
|
||||
Update the password of an existing User. Requires authentication.
|
||||
|
||||
The request body needs to be in JSON format and allows you to update the following properties:
|
||||
|
||||
automatically hash the passwords
|
||||
|
||||
- `password` - String - Required
|
||||
|
||||
Example
|
||||
|
||||
```
|
||||
PATCH /api/users/615a9f6d236abe2dbb2e424c/password
|
||||
Authorization: Bearer <YOUR TOKEN>
|
||||
|
||||
{
|
||||
"password":"123456",
|
||||
}
|
||||
```
|
||||
|
||||
### Update a user PHOTO
|
||||
|
||||
PATCH `/api/users/:id/photo`
|
||||
|
||||
Update the photo of an existing User. Requires authentication.
|
||||
|
||||
The request body needs to be in JSON format and allows you to update the following properties:
|
||||
|
||||
The photo param is `picture`
|
||||
send the photo on the input type file and name is picture
|
||||
|
||||
- `photo` - String Required
|
||||
|
||||
Example
|
||||
|
||||
```
|
||||
PATCH /api/users/615a9f6d236abe2dbb2e424c/photo
|
||||
Authorization: Bearer <YOUR TOKEN>
|
||||
|
||||
{
|
||||
"photo":"image link",
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### Delete User
|
||||
|
||||
DELETE `/api/users/:id`
|
||||
|
||||
Delete a user by id. Requires authentication.
|
||||
|
||||
The request parameter requires:
|
||||
|
||||
-`id` - String - Required. The id of the user to be deleted.
|
||||
Example
|
||||
|
||||
```
|
||||
DELETE /api/users/615a9f6d236abe2dbb2e424c
|
||||
Authorization: Bearer <YOUR TOKEN>
|
||||
```
|
||||
|
||||
### Add Friends to User
|
||||
|
||||
POST /api/users/:id/friends
|
||||
|
||||
Add friends to a user by their ID. Requires authentication.
|
||||
|
||||
The request body needs to be in JSON format and allows you to add the following properties:
|
||||
|
||||
- `number` - String - Required
|
||||
- `favorite` - Boolean
|
||||
- `nickname` - String - Required
|
||||
Example:
|
||||
|
||||
```
|
||||
POST /api/users/6450c39d34c51843e1dd6852/friends
|
||||
Authorization: Bearer <YOUR TOKEN>
|
||||
|
||||
{
|
||||
"number": "09567890544",
|
||||
"favorite": true,
|
||||
"nickname": "Buddy"
|
||||
}
|
||||
```
|
||||
|
||||
### Update Friend of User
|
||||
|
||||
PATCH /api/users/:id/friends/:friendId
|
||||
|
||||
Updates a specific friend of a user by their ID. Requires authentication.
|
||||
|
||||
The request body needs to be in JSON format and allows you to update the following properties:
|
||||
|
||||
- `number` - String - Required
|
||||
- `favorite` - Boolean
|
||||
- `nickname` - String - Required
|
||||
Example:
|
||||
|
||||
```
|
||||
PATCH /api/users/6450c39d34c51843e1dd6852/friends/6450c39d34c51843e1dd6852
|
||||
Authorization: Bearer <YOUR TOKEN>
|
||||
|
||||
{
|
||||
"number": "09567890544",
|
||||
"favorite": false,
|
||||
"nickname": "Pal"
|
||||
}
|
||||
```
|
||||
|
||||
### Delete Friend of User
|
||||
|
||||
DELETE /api/users/:id/friends/:friendId
|
||||
|
||||
Deletes a specific friend of a user by their ID. Requires authentication.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
DELETE /api/users/6450c39d34c51843e1dd6852/friends/6450c39d34c51843e1dd6852
|
||||
|
||||
Authorization: Bearer <YOUR TOKEN>
|
||||
```
|
||||
|
||||
## Access Kyc Data
|
||||
|
||||
### List of all Kycs
|
||||
|
||||
GET `/api/kycs/`
|
||||
|
||||
Authorization: Bearer <YOUR TOKEN>
|
||||
|
||||
Returns detailed list of All Kyc.
|
||||
|
||||
### Get a single Kyc
|
||||
|
||||
GET `/api/kycs/:id`
|
||||
|
||||
Retrieve detailed information about a single Kyc base on the `id`.
|
||||
Example
|
||||
|
||||
```
|
||||
|
||||
GET /api/kycs/6424d962fcb1e4f824546c89
|
||||
Authorization: Bearer <YOUR TOKEN>
|
||||
|
||||
{
|
||||
"_id": "65d7fce8637f8e8fd8e84124",
|
||||
"full_name": "San Man",
|
||||
"date_of_birth": "Feb 23, 2001",
|
||||
"userRef": "651b7e256faf1180905d613c",
|
||||
"id_num": "01-234-567",
|
||||
"address": "San Man st. Makati City",
|
||||
"images": [
|
||||
{
|
||||
"link": "https://testapi.obpay.online/assets/651b7e256faf1180905d613c-729660ff-2703-46ee-b823-3d2cedd61f90.png",
|
||||
"_id": "65d7fce8637f8e8fd8e84125"
|
||||
},
|
||||
{
|
||||
"link": "https://testapi.obpay.online/assets/651b7e256faf1180905d613c-8e91f5bc-75c2-4974-b329-d106df3aa17f.png",
|
||||
"_id": "65d7fce8637f8e8fd8e84126"
|
||||
}
|
||||
],
|
||||
"selfie": "https://testapi.obpay.online/assets/651b7e256faf1180905d613c-53cbf0fe-28fe-4f06-ad7f-0640b6db5f98.jpeg",
|
||||
"status": "pending",
|
||||
"createdAt": "2024-02-23T02:03:20.503Z",
|
||||
"updatedAt": "2024-02-23T02:03:20.503Z",
|
||||
"__v": 0
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Create a Kyc
|
||||
|
||||
POST `/api/kycs/create`
|
||||
|
||||
Create a Kyc. Requires authentication.
|
||||
|
||||
The request body needs to be in JSON format and allows you to update the following properties:
|
||||
|
||||
- `full_name` - String
|
||||
- `date_of_birth` - String
|
||||
- `userRef` - String
|
||||
- `id_num` - String
|
||||
- `address` - Number
|
||||
- `images` - String
|
||||
- `selfie` - String
|
||||
- `status` - String
|
||||
|
||||
Example
|
||||
|
||||
```
|
||||
|
||||
Post /api/kycs/create
|
||||
Authorization: Bearer <YOUR TOKEN>
|
||||
|
||||
{
|
||||
"full_name": "San Man",
|
||||
"date_of_birth": "Feb 23, 2001",
|
||||
"userRef": "651b7e256faf1180905d613c",
|
||||
"id_num": "01-234-567",
|
||||
"address": "San Man st. Makati City",
|
||||
"images": [
|
||||
{
|
||||
"link": "https://testapi.obpay.online/assets/651b7e256faf1180905d613c-729660ff-2703-46ee-b823-3d2cedd61f90.png",
|
||||
"_id": "65d7fce8637f8e8fd8e84125"
|
||||
},
|
||||
{
|
||||
"link": "https://testapi.obpay.online/assets/651b7e256faf1180905d613c-8e91f5bc-75c2-4974-b329-d106df3aa17f.png",
|
||||
"_id": "65d7fce8637f8e8fd8e84126"
|
||||
}
|
||||
],
|
||||
"selfie": "https://testapi.obpay.online/assets/651b7e256faf1180905d613c-53cbf0fe-28fe-4f06-ad7f-0640b6db5f98.jpeg",
|
||||
"status": "pending"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Update a Kyc
|
||||
|
||||
POST `/api/kycs/update/:id`
|
||||
|
||||
Update a Notification. Requires authentication.
|
||||
|
||||
The request body needs to be in JSON format and allows you to update the following properties:
|
||||
|
||||
- `status` - String
|
||||
|
||||
Example
|
||||
|
||||
```
|
||||
|
||||
Post /api/kycs/update/6424d962fcb1e4f824546c89
|
||||
Authorization: Bearer <YOUR TOKEN>
|
||||
|
||||
{
|
||||
"status":"validated",
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Delete a Kyc
|
||||
|
||||
DELETE `/api/kycs/:id/delete`
|
||||
|
||||
Delete an existing Kyc. Requires authentication.
|
||||
|
||||
The request body needs to be empty.
|
||||
|
||||
Example
|
||||
|
||||
```
|
||||
|
||||
DELETE /api/kycs/6424d962fcb1e4f824546c89/delete
|
||||
Authorization: Bearer <YOUR TOKEN>
|
||||
|
||||
```
|
||||
|
||||
## Send Email
|
||||
|
||||
POST `/api/send-email/`
|
||||
|
||||
Sending Email.
|
||||
|
||||
The request body needs to be in JSON format and allows you to send the following properties:
|
||||
|
||||
- `email` - String - Required ---Receiver of the email
|
||||
- `html` - String - Required
|
||||
- `subject` - String - Required
|
||||
|
||||
Example
|
||||
|
||||
```
|
||||
Post /api/send-email/
|
||||
|
||||
{
|
||||
"email":"hello@example.com",
|
||||
"subject":"This is your notif",
|
||||
"html":"<h1>hello!</h1>"
|
||||
}
|
||||
```
|
||||
|
||||
## Upload Image
|
||||
|
||||
POST `/api/send-email/`
|
||||
|
||||
Sending Email.
|
||||
|
||||
The request body needs to be in Form Data format and allows you to send the following properties:
|
||||
|
||||
- `image` - File - Required - 1 file only
|
||||
- `category` - String - Required
|
||||
- `image_id` - String - Required
|
||||
|
||||
Example
|
||||
|
||||
```
|
||||
Post /api/upload_images
|
||||
```
|
|
@ -0,0 +1,16 @@
|
|||
import express from "express";
|
||||
import multer from "multer";
|
||||
import { login, register } from "../controllers/auth.js";
|
||||
|
||||
const router = express.Router();
|
||||
const upload = multer({
|
||||
storage: multer.memoryStorage(),
|
||||
limits: {
|
||||
fileSize: 10 * 1024 * 1024, // 10 MB
|
||||
},
|
||||
});
|
||||
|
||||
router.post("/login", login);
|
||||
router.post("/register", upload.single("picture"), register);
|
||||
|
||||
export default router;
|
|
@ -0,0 +1,23 @@
|
|||
import express from "express";
|
||||
import {
|
||||
getCollection,
|
||||
getCollections,
|
||||
deleteCollection,
|
||||
createCollection,
|
||||
updateCollection,
|
||||
} from "../controllers/collection.js";
|
||||
import { verifyToken } from "../middleware/auth.js";
|
||||
import logApiCall from "../middleware/log.js";
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
/* READ */
|
||||
router.get("/", verifyToken, logApiCall, getCollections);
|
||||
router.get("/:id", verifyToken, logApiCall, getCollection);
|
||||
|
||||
router.post("/create", verifyToken, logApiCall, createCollection);
|
||||
router.patch("/update/:id", verifyToken, logApiCall, updateCollection);
|
||||
|
||||
router.delete("/:id/delete", verifyToken, logApiCall, deleteCollection);
|
||||
|
||||
export default router;
|
|
@ -0,0 +1,46 @@
|
|||
import express from "express";
|
||||
import multer from "multer";
|
||||
import {
|
||||
confirmOtp,
|
||||
deleteUser,
|
||||
deleteUserFriend,
|
||||
getUser,
|
||||
getUserId,
|
||||
getUsers,
|
||||
sendOtpEmail,
|
||||
updateUser,
|
||||
updateUserFriendData,
|
||||
updateUserFriends,
|
||||
updateUserPass,
|
||||
updateUserPhoto,
|
||||
updateUserSub,
|
||||
} from "../controllers/users.js";
|
||||
import { verifyToken } from "../middleware/auth.js";
|
||||
|
||||
const router = express.Router();
|
||||
const upload = multer({
|
||||
storage: multer.memoryStorage(),
|
||||
limits: {
|
||||
fileSize: 10 * 1024 * 1024, // 10 MB
|
||||
},
|
||||
});
|
||||
/* READ */
|
||||
router.get("/", verifyToken, getUsers);
|
||||
router.get("/:id", verifyToken, getUser);
|
||||
router.get("/id/:id", verifyToken, getUserId);
|
||||
|
||||
router.post("/send-otp", sendOtpEmail);
|
||||
router.post("/confirm-otp", confirmOtp);
|
||||
|
||||
router.patch("/:id", verifyToken, upload.single("picture"), updateUser);
|
||||
router.patch("/:id/sub", verifyToken, updateUserSub);
|
||||
router.patch("/:id/password", verifyToken, updateUserPass);
|
||||
router.patch("/:id/photo", verifyToken, updateUserPhoto);
|
||||
|
||||
router.patch("/:id/friends", verifyToken, updateUserFriends);
|
||||
router.patch("/:id/friends/:friendId", verifyToken, updateUserFriendData);
|
||||
|
||||
router.delete("/:id/friends/:friendId", verifyToken, deleteUserFriend);
|
||||
router.delete("/:id", verifyToken, deleteUser);
|
||||
|
||||
export default router;
|
Loading…
Reference in New Issue