Skip to content

Commit

Permalink
feat(admin-backend): complete v1 version
Browse files Browse the repository at this point in the history
  • Loading branch information
tsukipond8531 committed Feb 5, 2025
1 parent a2bf823 commit e74efbb
Show file tree
Hide file tree
Showing 16 changed files with 3,757 additions and 0 deletions.
20 changes: 20 additions & 0 deletions package/admin-backend/.env.exmaple
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# APP ENVIRONMENT VARIABLES
APP_NAME=KOGEN
ORGIN_NAME=KOGEN
MAIN_PORT=5005
FILE_PORT=5004
LOCAL_URL=localhost
API_PREFIX=/api

# ADMIN DEFAULT USERNAME AND PASSWORD
USER=admin
PASS=123456
NAME=admin

# DB ENVIRONMENT VARIABLES
MONGO_URI=mongodb://localhost:27017/kogen
MODEL_PREFIX=kogen_
RECONNECT_TIME=5000

# SECRET KEY FOR JWT SIGNING AND ENCRYPTION
SECRET=kogen_secret_key
28 changes: 28 additions & 0 deletions package/admin-backend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*


id.json
.env
.vercel
15 changes: 15 additions & 0 deletions package/admin-backend/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = {
// Secret key for JWT signing and encryption
secret: "super secret passphrase",
db_collection_prefix: "kogen_",
allowed_origin: ["https://admin.kogen.markets"],

expiresIn: 3600 * 72, // 3 days
db_url: "mongodb+srv://tuskidreamer:smiles@cluster0.ki9bs.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0",
db_options: {
// useNewUrlParser: true, //from 6 or higher version of mongoose
// useUnifiedTopology: true, // the same above
},
serviceUrl:
process.env.REACT_APP_SERVICE_URL,
};
5 changes: 5 additions & 0 deletions package/admin-backend/config/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
MONGOURI: process.env.MONGOURI || "mongodb+srv://tuskidreamer:smiles@cluster0.ki9bs.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0",
secretOrKey: "secret",
allowed_origin: ["https://admin.kogen.markets"],
};
25 changes: 25 additions & 0 deletions package/admin-backend/config/passport.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const passport = require("passport");
const JwtStrategy = require("passport-jwt").Strategy;
const ExtractJwt = require("passport-jwt").ExtractJwt;
const User = require("../models/UserModel");
const config = require("./config");

const opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken("User");
opts.secretOrKey = config.secretOrKey;
const jwtLogin = new JwtStrategy(opts, async (payload, done) => {
try {
// Use async/await instead of the callback pattern
const user = await User.findById(payload.id);
if (user) {
return done(null, user); // Successfully found the user
} else {
return done(null, false, { message: "User not found", tokenExpired: true }); // No user found
}
} catch (err) {
return done(err, false); // Handle any errors during the database query
}
});

// Use the JWT strategy in Passport
passport.use(jwtLogin);
93 changes: 93 additions & 0 deletions package/admin-backend/controller/TradeController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
const Trade = require("../models/TradeModel");

exports.saveTrade = async (req, res) => {
const { order, result, walletAddress, prettyName } = req.body;

if (!order || !result || !walletAddress || !prettyName) {
return res.status(400).json({ message: "Missing required fields" });
}

const newTrade = new Trade({
type: order.type,
price: order.price,
quantity: order.quantity,
funds: order.funds,
walletAddress,
prettyName,
result,
});

try {
await newTrade.save();
return res.status(201).json({ message: "Trade saved successfully", trade: newTrade });
} catch (error) {
console.log(error);
return res.status(500).json({ message: "Error saving trade", error: error.message });
}
};

exports.getTradeHistory = async (req, res) => {
try {
console.log("trades========>");
const trades = await Trade.find(); // Fetch all trades
console.log("trades", trades);

if (trades.length === 0) {
return res.status(404).json({ message: "No trades found." });
}

return res.status(200).json(trades);
} catch (error) {
console.log(error);
return res
.status(500)
.json({
message: "Error fetching trade history",
error: error.message,
});
}
};

exports.getTradeById = async (req, res) => {
const { tradeId } = req.params;

try {
const trade = await Trade.findById(tradeId);

if (!trade) {
return res.status(404).json({ message: "Trade not found." });
}

return res.status(200).json({ trade });
} catch (error) {
console.log(error);
return res
.status(500)
.json({
message: "Error fetching trade details",
error: error.message,
});
}
};

exports.deleteTrade = async (req, res) => {
const { tradeId } = req.params;

try {
const trade = await Trade.findByIdAndDelete(tradeId);

if (!trade) {
return res.status(404).json({ message: "Trade not found." });
}

return res.status(200).json({ message: "Trade deleted successfully." });
} catch (error) {
console.log(error);
return res
.status(500)
.json({
message: "Error deleting trade",
error: error.message,
});
}
};
153 changes: 153 additions & 0 deletions package/admin-backend/controller/UserController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
const User = require("../models/UserModel");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const config = require("../config/config");
const _ = require("lodash");

exports.adminLogin = async (req, res) => {
try {
await User.findOne({ email: req.body.email, delete: false }).then(
async (user) => {
if (!user) {
return await res
.status(400)
.json({ message: "You are not registered." });
}
bcrypt.compare(req.body.password, user.password).then(async (matched) => {
if (!matched) {
return res.status(400).json({ message: "Password incorrect" });
}
await user.updateOne({
$set: { status: req.body.status },
});
if (user.role !== 'admin') {
return res.status(400).json({ message: "You are not admin." });
}
const payload = {
id: user._id,
fullName: user.fullName,
email: user.email,
avatar: user.avatar,
};
const token = jwt.sign(payload, config.secretOrKey, { expiresIn: "1 day" });
res.json({
success: "true",
message: "Success",
data: {
token: token,
id: user.id,
fullName: user.fullName,
avatar: user.avatar,
email: user.email,
file: user.file,
}
});
});
},
);
} catch (err) {
console.log(err);
return res.status(500).json({ message: "Server Error", err: err });
}

};

exports.logout = async (req, res) => {
try {
// Find the user by their email (You might use the token to identify the user in some systems)
const user = await User.findOne({ email: req.body.email });

if (!user) {
return res.status(404).json({ message: "User not found." });
}

// Optionally update user status to "logged out"
await user.updateOne({ $set: { status: false } });

// Optional: If you want to invalidate the token, implement token blacklisting or just rely on the token's expiration.
res.json({
success: true,
message: "Logout successful.",
});

} catch (error) {
console.error("Error during logout: ", error);
res.status(500).json({ message: "Server error, please try again later." });
}
};

exports.tokenlogin = async (req, res) => {
await User.findById(req.user.id).then((user) => {
if (!user) {
return res.status(400).json({ message: "You are not registered" });
}
const payload = {
id: user._id,
fullName: user.fullName,
email: user.email,
avatar: user.avatar,
};
const jwtToken = jwt.sign(payload, config.secretOrKey, { expiresIn: "1 day" });
return res.json({
success: "true",
token: jwtToken,
user: user,
});
});
};

exports.getAUser = async (req, res) => {
try {
await User.findOne({ email: req.user.email }).then((user) => {
return res.status(200).json({
message: "Get User successfully",
user: user,
});
});
} catch (error) {
console.log(error);
}
};

exports.deleteUser = async (req, res) => {
try {
const { id } = req.params;
const user = await User.findByIdAndDelete(id);
if (!user) {
return res.status(404).json({ message: 'User not found' });
}
res.status(200).json({ message: 'User deleted successfully' });
} catch (error) {
console.error('Error deleting user:', error);
res.status(500).json({ message: 'Server error' });
}
};

exports.getAllUser = async (req, res) => {
try {
const users = await User.find({});
const total = await User.countDocuments({});

res.status(200).json({
message: "Success", users, pagination: {
total: total,
}
});
} catch (error) {
console.log(error);
}
};

exports.updateActivateStatus = async (req, res) => {
try {
const { id } = req.params;
const user = await User.findByIdAndUpdate(id, { is_actived: req.body.is_actived });
if (!user) {
return res.status(404).json({ message: 'User not found' });
}
res.status(200).json({ message: 'User status updated successfully' });
} catch (error) {
console.error('Error updating user status:', error);
res.status(500).json({ message: 'Server error' });
}
};
6 changes: 6 additions & 0 deletions package/admin-backend/middleware/authorization.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const passport = require("passport");

module.exports = requireAuth = (req, res, next) => {
passport.authenticate("jwt", { session: false });
next();
};
21 changes: 21 additions & 0 deletions package/admin-backend/models/TradeModel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const mongoose = require('mongoose');
const { Schema, model } = mongoose;

const TradeSchema = new Schema(
{
type: { type: String, required: true },
price: { type: Number, required: true },
quantity: { type: Number, required: true },
funds: [
{
amount: { type: String, required: true },
denom: { type: String, required: true },
},
],
walletAddress: { type: String, required: true },
prettyName: { type: String, required: true },
result: { type: Schema.Types.Mixed, required: true },
},
);

module.exports = mongoose.model("Trade", TradeSchema);
Loading

0 comments on commit e74efbb

Please sign in to comment.