Skip to content

Commit

Permalink
Merge pull request #55 from cd-sigma/main
Browse files Browse the repository at this point in the history
build
  • Loading branch information
cd-sigma authored Dec 9, 2023
2 parents d63b1e0 + b5102b9 commit 361949e
Show file tree
Hide file tree
Showing 19 changed files with 593 additions and 21 deletions.
5 changes: 4 additions & 1 deletion backend/api/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ const cors = require("cors")
const mongoLib = require("../lib/mongo.lib")
const consoleLib = require("../lib/console.lib")
const responseLib = require("../lib/response.lib")
const tokenRoutes = require("./routes/token.route")

const userRoutes = require("./routes/user.route")
const feedRoutes = require("./routes/feed.route")
const alertRoutes= require("./routes/alert.route")
const tokenRoutes = require("./routes/token.route");

const app = express()
const port = 3001
Expand All @@ -31,6 +33,7 @@ const port = 3001
app.use("/user", userRoutes)
app.use("/token", tokenRoutes)
app.use("/feed", feedRoutes)
app.use("/alert", alertRoutes)

app.listen(port, () => {
consoleLib.logInfo(`API listening at http://localhost:${port}`)
Expand Down
74 changes: 74 additions & 0 deletions backend/api/controllers/alert.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
const mongoLib = require("../../lib/mongo.lib");
const responseLib = require("../../lib/response.lib");
const validatorUtil = require("../../util/validators.util");

const userModel = require("../../model/user.model");
const alertTypeEnum = require("../../enum/alert.type.enum");
const resStatusEnum = require("../../enum/res.status.enum");

async function subscribeToEmail(req, res) {
try {
const {email} = req.body;
let {id: address} = req.user.payload;
address = address.toLowerCase();

if (validatorUtil.isEmpty(email)) {
return responseLib.sendResponse(res, null, "email is required", resStatusEnum.VALIDATION_ERROR);
}

await mongoLib.findOneAndUpdate(userModel, {address: address}, {
$addToSet: {alertPreferences: alertTypeEnum.EMAIL}, email: email
});

return responseLib.sendResponse(res, "Subscribed to email successfully!", null, resStatusEnum.SUCCESS);
} catch (error) {
return responseLib.sendResponse(res, null, error, resStatusEnum.INTERNAL_SERVER_ERROR)
}
}

async function subscribeToSlack(req, res) {
try {
const {webhook} = req.body;
let {id: address} = req.user.payload;
address = address.toLowerCase();

if (validatorUtil.isEmpty(webhook)) {
return responseLib.sendResponse(res, null, "webhook is required", resStatusEnum.VALIDATION_ERROR);
}

await mongoLib.findOneAndUpdate(userModel, {address: address}, {
$addToSet: {alertPreferences: alertTypeEnum.SLACK}, slackWebhook: webhook
});

return responseLib.sendResponse(res, "Subscribed to slack successfully!", null, resStatusEnum.SUCCESS);
} catch (error) {
return responseLib.sendResponse(res, null, error, resStatusEnum.INTERNAL_SERVER_ERROR)
}
}

async function subscribeToDiscord(req, res) {
try {
const {webhook} = req.body;
let {id: address} = req.user.payload;
address = address.toLowerCase();

if (validatorUtil.isEmpty(webhook)) {
return responseLib.sendResponse(res, null, "webhook is required", resStatusEnum.VALIDATION_ERROR);
}

await mongoLib.findOneAndUpdate(userModel, {address: address}, {
$addToSet: {alertPreferences: alertTypeEnum.DISCORD}, discordWebhook: webhook
});

return responseLib.sendResponse(res, "Subscribed to discord successfully!", null, resStatusEnum.SUCCESS);
} catch (error) {
return responseLib.sendResponse(res, null, error, resStatusEnum.INTERNAL_SERVER_ERROR)

}
}

module.exports = {
subscribeToDiscord: subscribeToDiscord,
subscribeToSlack: subscribeToSlack,
subscribeToEmail: subscribeToEmail
}
10 changes: 5 additions & 5 deletions backend/api/controllers/user.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ async function validateSignature(req, res) {
if (!didSignatureMatch) {
return responseLib.sendResponse(res, null, `Signature Verification Failed`, resStatusEnum.UNAUTHORIZED,)
}
await userResolver.updateNonceOfUser(userDetails._id)
await userResolver.markUserWalletVerified(userDetails._id)
await userResolver.updateNonceOfUser(userDetails.address)
await userResolver.markUserWalletVerified(userDetails.address)

let token = await userResolver.getJwtTokenFromDbForUser(userDetails._id)
let token = await userResolver.getJwtTokenFromDbForUser(userDetails.address)
if (validatorUtil.isNil(token) || (await userResolver.isJwtTokenExpired(token))) {
token = await userResolver.generateJwtToken(userDetails._id)
await userResolver.updateJwtTokenOfUser(userDetails._id, token)
token = await userResolver.generateJwtToken(userDetails.address)
await userResolver.updateJwtTokenOfUser(userDetails.address, token)
}

return responseLib.sendResponse(res, {token: token}, null, resStatusEnum.SUCCESS,)
Expand Down
20 changes: 10 additions & 10 deletions backend/api/resolvers/user.resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,34 +77,34 @@ function doesSignatureMatch(address, signature, message) {
}
}

async function updateNonceOfUser(userId) {
async function updateNonceOfUser(address) {
try {
await mongoLib.findOneAndUpdate(userModel, {_id: userId}, {nonce: uuid.v4()})
await mongoLib.findOneAndUpdate(userModel, {address: address}, {nonce: uuid.v4()})
} catch (error) {
throw error
}
}

async function markUserWalletVerified(userId) {
async function markUserWalletVerified(address) {
try {
await mongoLib.findOneAndUpdate(userModel, {_id: userId}, {isWalletVerified: true})
await mongoLib.findOneAndUpdate(userModel, {address: address}, {isWalletVerified: true})
} catch (error) {
throw error
}
}

async function getJwtTokenFromDbForUser(userId) {
async function getJwtTokenFromDbForUser(address) {
try {
let user = await mongoLib.findOneByQuery(userModel, {_id: userId})
let user = await mongoLib.findOneByQuery(userModel, {address: address})
return user.jwtToken
} catch (error) {
throw error
}
}

async function updateJwtTokenOfUser(userId, jwtToken) {
async function updateJwtTokenOfUser(address, jwtToken) {
try {
await mongoLib.findOneAndUpdate(userModel, {_id: userId}, {jwtToken: jwtToken})
await mongoLib.findOneAndUpdate(userModel, {address: address}, {jwtToken: jwtToken})
} catch (error) {
throw error
}
Expand All @@ -119,10 +119,10 @@ async function isJwtTokenExpired(token) {
}
}

async function generateJwtToken(userId) {
async function generateJwtToken(address) {
try {
let jwtTokenExpirationTime = "60d"
return jwt.sign({payload: {id: userId}}, process.env.JWT_SECRET, {
return jwt.sign({payload: {address: address}}, process.env.JWT_SECRET, {
expiresIn: jwtTokenExpirationTime,
})
} catch (error) {
Expand Down
11 changes: 11 additions & 0 deletions backend/api/routes/alert.route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const express = require("express")
const router = express.Router()

const alertController = require("../controllers/alert.controller")
const authMiddleware = require("../../middleware/jwt.auth.middleware")

router.post("/discord/subscribe", authMiddleware.isLoggedIn, alertController.subscribeToDiscord);
router.post("/slack/subscribe", authMiddleware.isLoggedIn, alertController.subscribeToSlack);
router.post("/email/subscribe", authMiddleware.isLoggedIn, alertController.subscribeToEmail);

module.exports = router
27 changes: 27 additions & 0 deletions backend/api/views/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,33 @@ <h3>feed</h3>
</ul>
</div>

<div class="form-container">
<h3>Discord Subscription API</h3>
<form action="/alert/discord/subscribe" method="post">
<label for="webhook-discord">webhook:</label>
<input type="text" id="webhook-discord" name="webhook">
<input type="submit" value="Subscribe">
</form>
</div>

<div class="form-container">
<h3>Email Subscription API</h3>
<form action="/alert/email/subscribe" method="post">
<label for="email-subscribe">email:</label>
<input type="text" id="email-subscribe" name="email">
<input type="submit" value="Subscribe">
</form>
</div>

<div class="form-container">
<h3>Slack Subscription API</h3>
<form action="/alert/slack/subscribe" method="post">
<label for="webhook-slack">webhook:</label>
<input type="text" id="webhook-slack" name="webhook">
<input type="submit" value="Subscribe">
</form>
</div>

</body>
</html>

Expand Down
20 changes: 20 additions & 0 deletions backend/middleware/jwt.auth.middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const jwt = require("jsonwebtoken")
const validatorUtil = require("../util/validators.util")
const errorUtil = require("../util/error.util")

async function isLoggedIn(req, res, next) {
try {
if (
validatorUtil.isEmpty(req.headers.authorization)
) {
errorUtil.throwErr("validation exception for req.headers.authorization")
}
let token= req.headers.authorization.split(" ")[1];
req.user = await jwt.verify(token, process.env.JWT_SECRET)
next()
} catch (e) {
next(e)
}
}

module.exports = {isLoggedIn: isLoggedIn}
38 changes: 37 additions & 1 deletion frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"react-router-dom": "^6.20.1",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4",
"web3": "^4.3.0"
"web3": "^4.3.0",
"zustand": "^4.4.7"
},
"scripts": {
"start": "react-scripts start",
Expand Down
14 changes: 14 additions & 0 deletions frontend/src/api/axios.instance.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import axios from "axios";

const token = localStorage.getItem("token") || "";
axios.defaults.headers.post["Authorization"] = `Bearer ${token}`;

let userAxios = axios.create({
baseURL: "https://finsafe-backend.insidefi.io/user/"
})

let tokenAxios = axios.create({
baseURL: "https://finsafe-backend.insidefi.io/token/"
});

export { userAxios, tokenAxios };
24 changes: 24 additions & 0 deletions frontend/src/api/profile.api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { userAxios, tokenAxios } from "./axios.instance";

export const getPortfolioDetails = async (address) => {
try {
const response = await userAxios.get(address);
const { result } = response.data;
const { data } = result;
return data;
} catch (err) {
console.log(`Error occured while fetching portfolio details`, err);
}
};

export const getTokenDetails = async (token) => {
try {
const response = await tokenAxios.get(token);
const { result } = response.data;
const { data } = result;
const { logoURI, price } = data;
return { logoURI: logoURI, price: price };
} catch (err) {
console.log(`Error occured while fetching token details`, err);
}
};
Loading

0 comments on commit 361949e

Please sign in to comment.