Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Main #1

Merged
merged 3 commits into from
Sep 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ if [ $? -ne 0 ]; then
fi

# Trigger deployment on Render
wget -qO- https://api.render.com/deploy/srv-cqtifc5ds78s739ms430?key=iORcOVgbEOg
wget -qO- https://api.render.com/deploy/srv-cr891j08fa8c73bb6gkg?key=u2FK-d7pG8A
if [ $? -ne 0 ]; then
echo "Error: Render deployment trigger failed."
exit 1
Expand Down
2 changes: 1 addition & 1 deletion manifests/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ spec:
selector:
matchLabels:
app: myworkflow
template:
template:
metadata:
labels:
app: myworkflow
Expand Down
37 changes: 26 additions & 11 deletions public/css/customcss.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Merriweather:wght@300;400;700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Merriweather:wght@300;400;700&display=swap');


@media screen and (max-width: 768px) {
.custom-image {
Expand Down Expand Up @@ -163,8 +166,8 @@
}

.article-subtitle{
font-family: "Roboto", sans-serif !important;
font-size: 20px; /* Adjust based on the font size */
font-family: 'Merriweather', serif !important;
font-size: 18px; /* Adjust based on the font size */
color: #666666; /* Adjust based on the text color */
line-height: 1.5; /* Adjust based on the line height */
margin: 0; /* Adjust based on the margin */
Expand Down Expand Up @@ -236,8 +239,8 @@
}

.custom-font p{
font-family: "Roboto", sans-serif !important;
font-size: 20px;
font-family: 'Merriweather', serif !important;
font-size: 18px;
line-height: 2.7rem !important;
font-style: normal !important;
overflow-wrap: break-word !important;
Expand Down Expand Up @@ -342,7 +345,7 @@
.custom-font blockquote {
border-left: 5px solid #F2F2F2;
padding-left: 10px;
font-family: "Roboto", sans-serif !important;
font-family: 'Merriweather', serif !important;
font-weight: 300 !important;
font-size: 20px;
line-height: 2.7rem !important;
Expand All @@ -358,14 +361,26 @@

.ql-code-block-container {
background-color: #F2F2F2 !important;
padding: 20px !important;
border-radius: 5px !important;
color: #000000 !important;
font-size: 20px !important;
line-height: 1.5 !important;
padding: 16px 20px !important;
border-radius: 6px !important;
color: #2C3E50 !important; /* Slightly darker color for better readability */
font-size: 13.5px !important; /* Slightly smaller for code feel */
line-height: 1.65 !important;
overflow-x: auto !important;
white-space: pre-wrap !important;
white-space: pre !important;
font-family: 'Fira Code', monospace !important;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05) !important; /* Softer shadow for depth */
border-left: 4px solid #268BD2 !important; /* Brighter accent for better visibility */
transition: background-color 0.3s ease, border-color 0.3s ease; /* Smooth hover transitions */
}

/* Optional hover effect */
.ql-code-block-container:hover {
background-color: #E8E8E8 !important; /* Slight change on hover for interaction feedback */
border-left: 4px solid #FF8C00 !important; /* Brighter hover accent */
}





41 changes: 0 additions & 41 deletions src/controllers/authControllers/authControllerMiddlewares.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,60 +18,46 @@ class authControllerMiddlewares{
async mustAuthenticated(req, res, next) {
try {

// Check if cookie is present
if (!req.cookies.authToken) {
return res.status(401).redirect('/login');
}

// Get the JWT token from the cookie
const token = req.cookies.authToken;
// If the token is not present, return a 401 Unauthorized error
if (!token) {
return res.status(401).redirect('/login');
}

jwt.verify(token, keyValt.SECRET_KEY);

// If the user is authenticated, call the next middleware function
return next();
} catch (err) {
// If there's an error (e.g., invalid token, expired token), handle it
sendTelegramMessage(`[Error] ${err.message}`);
res.status(500).redirect('/login');
}
}

// Checks if user is admin
async mustBeAdmin(req, res, next) {
try {
// Check if cookie is present
if (!req.cookies.authToken) {
return res.status(401).redirect('/login');
}

// Get the JWT token from the cookie
const token = req.cookies.authToken;

// If the token is not present, return a 401 Unauthorized error
if (!token) {
return res.status(401).redirect('/login');
}

// Decode the JWT and verify the JWT
const decoded = jwt.verify(token, keyValt.SECRET_KEY);

// Check if the user's role is 'admin'
if (decoded.role === 'admin') {
// Set it in res locals
res.locals.isAdmin = true;
// If the user is an admin, call the next middleware function
return next();
} else {
// If the user is not an admin, return a 403 Forbidden error
return res.redirect('/login');
}
} catch (err) {
// If there's an error (e.g., invalid token, expired token), handle it
sendTelegramMessage(`[Error] ${err.message}`);
res.status(500).redirect('/login');
}
Expand All @@ -80,27 +66,19 @@ class authControllerMiddlewares{
async isAdmin(req, res) {
try {

// Check if cookie is present
if (!req.cookies.authToken) {
return false;
}
// Get the JWT token from the cookie
const token = req.cookies.authToken;
// If the token is not present, return a 401 Unauthorized error
if (!token) {
return false
}
// Verify the JWT
jwt.verify(token, keyValt.SECRET_KEY);

// Decode the jwt token
const decodedToken = jwt.decode(token);

// Check if the user's role is 'admin'
return decodedToken.role === 'admin';
} catch (err) {
console.log("not authenticated")
// If there's an error (e.g., invalid token, expired token), return false
return false;
}
}
Expand All @@ -113,23 +91,17 @@ class authControllerMiddlewares{
*/
async isAuthenticated(req, res) {
try {
// Check if cookie is present
if (!req.cookies.authToken) {
return false;
}
// Get the JWT token from the cookie
const token = req.cookies.authToken;
// If the token is not present, return a 401 Unauthorized error
if (!token) {
return false
}
// Decode the JWT and verify the JWT
jwt.verify(token, keyValt.SECRET_KEY);

// If the token is valid, the user is authenticated
return true;
} catch (err) {
// If there's an error (e.g., invalid token, expired token), return false
return false;
}
}
Expand Down Expand Up @@ -175,11 +147,8 @@ class authControllerMiddlewares{

const sessionUUID = uuidv4();
const token = jwt.sign({ uuid: sessionUUID, role: user.role }, keyValt.SECRET_KEY, { expiresIn: '1h' });
// Store the token in an HTTP-only cookie
res.cookie('authToken', token, { httpOnly: true, maxAge: 3600000, overwrite: true }); // 1 hour
// Store the session UUID in Redis with the user ID as the value for 1 hour
await client.setEx(sessionUUID, 3600, String(user._id));
// Setting authenticated to true
req.session.isAuthenticated = true;
req.session.role = user.role;

Expand All @@ -195,36 +164,26 @@ class authControllerMiddlewares{
return user;
}

// Get uuid from JWT and get hte user_id from Redis
async getUserFromSession(req, res) {
try {
// Get the JWT token from the cookie
const token = req.cookies.authToken;
// If the token is not present, return a 401 Unauthorized error
if (!token) {
return false
}
// Decode the JWT and verify the JWT
const decoded = jwt.verify(token, keyValt.SECRET_KEY);
// Get the session UUID
const sessionUUID = decoded.uuid;
// Get the user ID from Redis
const userId = await client.get(sessionUUID);
// If the user ID is not present, return a 401 Unauthorized error
if (!userId) {
return false
}

// Get the user from the database
const user = await Users.findOne({ _id: userId });
// If the user is not present, return a 401 Unauthorized error
if (!user) {
return false
}

return user;
} catch (err) {
// If there's an error (e.g., invalid token, expired token), handle it
sendTelegramMessage(`[Error] ${err.message}`);
res.status(500).json({ message: 'Internal Server Error' });
}
Expand Down
24 changes: 12 additions & 12 deletions src/routes/blogRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ const isAdmin = [authControllerMiddlewares.mustBeAdmin];
// Using express router, creating specific routes
const router = Router()

router.get('/most-viewed', async (req, res) => {
const mostViewedPosts = await Blogs
.find({ status: 'published' })
.sort({ views: -1 })
.limit(3);

res.json(mostViewedPosts);
});

router.get("/recommendations", blogController.getNextPopularBlogs);

router.get("/q", async (req, res) => {
Expand All @@ -21,7 +30,7 @@ router.get("/q", async (req, res) => {
res.json(result);
});

router.get("/create", isAuth, (req, res) => {
router.get("/create", isAdmin, isAuth, (req, res) => {
res.render("./pages/blogPostPage", { currentRoute: `/blogs/creation` })
});

Expand Down Expand Up @@ -62,9 +71,9 @@ router.get("/update/:id", isAuth, isAdmin, (req, res) => {
res.render("./pages/blogEditPage", { id: Number(id), currentRoute: `/blogs/update/post_id-${id}` })
});

router.post("/", isAuth, blogController.createUserWrittenBlogs);
router.post("/", isAuth, isAdmin, blogController.createUserWrittenBlogs);

router.get("/new/blog/create", isAuth, (req, res) => {
router.get("/new/blog/create", isAuth, isAdmin, (req, res) => {
res.render("./pages/blogPostPage", { currentRoute: `/blogs/creation` })
});

Expand Down Expand Up @@ -109,14 +118,5 @@ router.post('/like', async (req, res) => {
res.status(200).json({ success: true });
});

router.get('/most-viewed', async (req, res) => {
const mostViewedPosts = await Blogs
.find({ status: 'published' })
.sort({ views: -1 })
.limit(3);

res.json(mostViewedPosts);
});

export default router;

6 changes: 0 additions & 6 deletions src/views/partials/headers/headerAuth.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ top: 0px; z-index: 9999 !important;">
<div class="flex flex-col w-full m-0 p-0">
<div class="divider divider-start m-0 p-0"></div>
</div>
<li><a href="/portfolio">Portfolio</a></li>
<li><a href="/about">About</a></li>
<li><a href="/logout">Log out</a></li>
<li class="my-1">
Expand All @@ -35,11 +34,6 @@ top: 0px; z-index: 9999 !important;">
</li>
</ul>
</div>
<button class="btn btn-outline btn-ghost">
<a href="/blogs/create" class="flex items-center text-xl w-100 h-100">
<i class="fa fa-plus"></i>
</a>
</button>
<button onclick="showSeachBar()" class="btn btn-outline btn-ghost">
<label class="flex items-center justify-center h-5 w-5">
<i class="fa fa-search w3-jumbo w3-text-green"></i>
Expand Down
1 change: 0 additions & 1 deletion src/views/partials/headers/headerUnAuth.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ top: 0px; z-index: 9999 !important;">
</svg>
</div>
<ul tabindex="0" class="menu text-base-content menu-sm dropdown-content mt-3 z-[1] p-2 shadow bg-base-100 rounded-box w-52">
<li><a href="/portfolio">Portfolio</a></li>
<li><a href="/about">About</a></li>
<div class="flex flex-col w-full m-0 p-0">
<div class="divider divider-start m-0 p-0"></div>
Expand Down
Loading