-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(admin-backend): complete v1 version
- Loading branch information
1 parent
a2bf823
commit e74efbb
Showing
16 changed files
with
3,757 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | ||
}); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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' }); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); |
Oops, something went wrong.