Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
d1fdd00
Setting up GitHub Classroom Feedback
github-classroom[bot] Dec 4, 2022
3e3f3f2
Update GitHub Classroom Feedback
github-classroom[bot] Dec 4, 2022
ecdb70d
Setting up GitHub Classroom Feedback
github-classroom[bot] Dec 4, 2022
b19aa11
init
amordzon Dec 4, 2022
4f576e3
CRUD posts
amordzon Dec 5, 2022
dfb5a10
Merge pull request #2 from UniversityOfGdanskProjects/feature/blog-posts
amordzon Dec 5, 2022
cdf2d6b
Feature: blog users CRUD (#3)
amordzon Dec 5, 2022
d9040c6
fixes (#4)
amordzon Dec 5, 2022
158aef7
Delete package.json
amordzon Dec 5, 2022
c8c4c15
Delete package-lock.json
amordzon Dec 5, 2022
32911b0
Added category CRUD (#5)
amordzon Dec 5, 2022
229c76a
Added comment CRUD (#6)
amordzon Dec 5, 2022
d76c31c
created chat messages CRUD (#7)
amordzon Dec 5, 2022
f858dcf
Feature: authentication (#8)
amordzon Dec 16, 2022
99a7847
Chore: front init (#9)
amordzon Dec 16, 2022
6881116
Feature: create navbar (#10)
amordzon Dec 17, 2022
5085e7f
Feature: Homepage (#11)
amordzon Dec 20, 2022
32db8d8
Feature: Categories pages (#12)
amordzon Dec 21, 2022
bd35ce9
Feature: post (#13)
amordzon Dec 23, 2022
63052f0
Feature: login and register (#14)
amordzon Dec 25, 2022
c16c414
Feature: profile (#15)
amordzon Dec 29, 2022
689193c
Fix: improved authentication (#16)
amordzon Dec 29, 2022
7446b93
Feature: my posts (#17)
amordzon Jan 2, 2023
a4ef24a
Feature: remove and update comment (#18)
amordzon Jan 2, 2023
9d97ab4
Feature: Search posts (#19)
amordzon Jan 3, 2023
eae14f1
Fix: comments (#20)
amordzon Jan 4, 2023
c33a713
Feature: rating (#21)
amordzon Jan 7, 2023
460876b
Fix: sort by ratings (#22)
amordzon Jan 7, 2023
86c604f
Feature: chat (#23)
amordzon Jan 12, 2023
2afeefc
Feature: added many authors to post (#24)
amordzon Jan 13, 2023
1fb16ef
Feature: save chat to database (#25)
amordzon Jan 14, 2023
8d7a540
Feature: admin panel (#26)
amordzon Jan 17, 2023
68dd593
Fix: improve code (#27)
amordzon Jan 17, 2023
31392ec
Fix: user fix (#28)
amordzon Jan 17, 2023
3f90448
Fix: upload photos folder (#29)
amordzon Jan 18, 2023
5d719f7
dont show your email in select (#30)
amordzon Jan 20, 2023
c0c74a2
Feature: export and import csv (#31)
amordzon Jan 22, 2023
87b5e72
Fix: remove users posts and comments if user is deleted (#32)
amordzon Jan 23, 2023
804e99c
Fix: improved photo quality (#33)
amordzon Jan 23, 2023
a708ec6
Update README.md
amordzon Mar 4, 2023
40e7c47
Fix: save photos in cloudinary (#34)
amordzon Apr 23, 2023
0be620d
Fix: remove directories and add cloudinary (#35)
amordzon Apr 23, 2023
baddaf5
Delete .DS_Store
amordzon Apr 23, 2023
3a5e989
Delete package-lock.json
amordzon Apr 23, 2023
63fcec1
Delete package.json
amordzon Apr 23, 2023
c353fb1
Fix: Update AboutMe (#36)
amordzon Apr 23, 2023
7e180a1
Feature: posts approve (#37)
amordzon Apr 27, 2023
e726d7e
Feature: show info about approval (#38)
amordzon Apr 29, 2023
8fd9217
Add or update the Azure App Service build and deployment workflow config
amordzon Feb 18, 2024
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
71 changes: 71 additions & 0 deletions .github/workflows/main_blog-mern.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy
# More GitHub Actions for Azure: https://github.com/Azure/actions

name: Build and deploy Node.js app to Azure Web App - blog-mern

on:
push:
branches:
- main
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up Node.js version
uses: actions/setup-node@v3
with:
node-version: '18.x'

- name: npm install, build, and test
run: |
npm install
npm run build --if-present
npm run test --if-present

- name: Zip artifact for deployment
run: zip release.zip ./* -r

- name: Upload artifact for deployment job
uses: actions/upload-artifact@v3
with:
name: node-app
path: release.zip

deploy:
runs-on: ubuntu-latest
needs: build
environment:
name: 'Production'
url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
permissions:
id-token: write #This is required for requesting the JWT

steps:
- name: Download artifact from build job
uses: actions/download-artifact@v3
with:
name: node-app

- name: Unzip artifact for deployment
run: unzip release.zip

- name: Login to Azure
uses: azure/login@v1
with:
client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_B50327B4E8084C319BB2621D756CBE1A }}
tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_0F280F2912DE48FBA436FCFDF4D63355 }}
subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_7AE044525B2141EC85CFAFF39D7811C9 }}

- name: 'Deploy to Azure Web App'
id: deploy-to-webapp
uses: azure/webapps-deploy@v2
with:
app-name: 'blog-mern'
slot-name: 'Production'
package: .

3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
.vscode
.env
Binary file added API/.DS_Store
Binary file not shown.
15 changes: 15 additions & 0 deletions API/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"root": true,
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"extends": ["eslint:recommended", "prettier"],
"env": {
"es2021": true,
"node": true
},
"rules": {
"no-console": "error"
}
}
6 changes: 6 additions & 0 deletions API/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"trailingComma": "es5",
"tabWidth": 4,
"semi": true,
"singleQuote": true
}
120 changes: 120 additions & 0 deletions API/controllers/admin.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import Post from '../models/post.model.js';
import Category from '../models/category.model.js';
import User from '../models/user.model.js';
import Comment from '../models/comment.model.js';
import csv from 'csvtojson';
import mongoose from 'mongoose';

export const getStatistics = async (req, res) => {
try {
const postsNum = await Post.countDocuments({}).exec();
const categoryNum = await Category.countDocuments({}).exec();
const usersNum = await User.countDocuments({}).exec();
const commentsNum = await Comment.countDocuments({}).exec();
res.status(200).json({
success: true,
message: 'Statistics',
Statistics: {
postsNum: postsNum,
categoryNum: categoryNum,
usersNum: usersNum,
commentsNum: commentsNum,
},
});
} catch (err) {
res.status(500).json({
success: false,
message: 'Server error',
error: err.message,
});
}
};

const getData = async (type) => {
switch (type) {
case 'posts':
return Post.find().exec();
case 'categories':
return Category.find().exec();
case 'comments':
return Comment.find().exec();
case 'users':
return User.find().exec();
default:
return null;
}
};

export const exportCsv = async (req, res) => {
const type = req.query.type;
try {
const data = await getData(type);
console.log(data);
if (data) {
res.status(200).json({
success: true,
message: 'CSV data',
Data: data,
});
} else {
res.status(500).json({
success: false,
message: 'Server error',
});
}
} catch (error) {
res.status(500).json({
success: false,
message: 'Server error',
error: error.message,
});
}
};

export const importCSV = async (req, res) => {
try {
csv()
.fromFile(req.file.path)
.then((jsonObj) => {
let posts = [];
for (let i = 0; i < jsonObj.length; i++) {
let obj = {};
obj.author = [
mongoose.Types.ObjectId(jsonObj[i]['author']),
];
obj.title = jsonObj[i]['title'];
obj.body = jsonObj[i]['body'];
obj.img = jsonObj[i]['img'];
obj.category = mongoose.Types.ObjectId(
jsonObj[i]['category']
);
posts.push(obj);
}
Post.insertMany(posts)
.then(function () {
res.status(200).send({
message: 'Successfully Uploaded!',
});
})
.catch(function (error) {
console.log(error);
res.status(500).send({
message: 'Something went wrong!',
error,
});
});
})
.catch((error) => {
res.status(500).send({
message: 'Something went wrong!',
error,
});
});
} catch (err) {
res.status(500).json({
success: false,
message: 'Server error',
error: err.message,
});
}
};
96 changes: 96 additions & 0 deletions API/controllers/auth.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import User from '../models/user.model.js';
import bcrypt from 'bcrypt';
import mongoose from 'mongoose';
import jwt from 'jsonwebtoken';

const jwtSecret = toString(process.env.TOKEN_SECRET);

export const Login = async (req, res) => {
const email = req.body.email;
const user = await User.findOne({ email: email });
if (user == null) {
res.status(400).json({
success: false,
message: 'Email or password incorrect!',
});
} else {
const validate = await bcrypt.compare(req.body.password, user.password);
if (validate) {
const token = createJWT(user);
res.status(200).json({
success: true,
message: 'User logged in!',
User: {
user: user,
token: token,
},
});
} else {
res.status(400).json({
success: false,
message: 'Email or password incorrect!',
});
}
}
};

export const Register = async (req, res) => {
const hashedPwd = await bcrypt.hash(req.body.password, 10);
User.find({ email: req.body.email }, (err, users) => {
if (users.length) {
res.status(409).json({
success: false,
message: 'This user already exists!',
});
} else {
const user = new User({
_id: mongoose.Types.ObjectId(),
password: hashedPwd,
email: req.body.email,
name: req.body.name,
surname: req.body.surname,
});
return user
.save()
.then((newUser) => {
const token = createJWT(newUser);
return res.status(201).json({
success: true,
message: 'New user created successfully',
User: {
user: newUser,
token: token,
},
});
})
.catch((error) => {
res.status(500).json({
success: false,
message: 'Server error. Please try again.',
error: error.message,
});
});
}
});
};

export const Logout = async (req, res) => {
return res
.status(200)
.json({ success: true, message: 'Successfully logged out' });
};

const createJWT = (user) => {
const token = jwt.sign(
{
id: user._id,
email: user.email,
role: user.role,
},
jwtSecret,
{
expiresIn: '7d',
}
);
return token;
};
Loading