Skip to content

SOURAV-ROY/apiNodeJS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

  • List all bootcamps in the database
    • Pagination
    • Select specific fields in result
    • Limit number of results
    • Filter by fields
  • Search bootcamps by radius from zipcode
    • Use a geocoder to get exact location and coords from a single address field
  • Get single bootcamp
  • Create new bootcamp
    • Authenticated users only
    • Must have the role "publisher" or "admin"
    • Only one bootcamp per publisher (admins can create more)
    • Field validation via Mongoose
  • Upload a photo for bootcamp
    • Owner only
    • Photo will be uploaded to local filesystem
  • Update bootcamps
    • Owner only
    • Validation on update
  • Delete Bootcamp
    • Owner only
  • Calculate the average cost of all courses for a bootcamp
  • Calculate the average rating from the reviews for a bootcamp
  • List all courses for bootcamp
  • List all courses in general
    • Pagination, filtering, etc
  • Get single course
  • Create new course
    • Authenticated users only
    • Must have the role "publisher" or "admin"
    • Only the owner or an admin can create a course for a bootcamp
    • Publishers can create multiple courses
  • Update course
    • Owner only
  • Delete course
    • Owner only
  • List all reviews for a bootcamp
  • List all reviews in general
    • Pagination, filtering, etc
  • Get a single review
  • Create a review
    • Authenticated users only
    • Must have the role "user" or "admin" (no publishers)
  • Update review
    • Must have the role "user" or "admin" (no publishers)
  • Delete review
    • Must have the role "user" or "admin" (no publishers)

Users & Authentication

  • Authentication will be ton using JWT/cookies
    • JWT and cookie should expire in 30 days
  • User registration
    • Register as a "user" or "publisher"
    • Once registered, a token will be sent along with a cookie (token = xxx)
    • Passwords must be hashed
  • User login
    • User can login with email and password
    • Plain text password will compare with stored hashed password
    • Once logged in, a token will be sent along with a cookie (token = xxx)
  • User logout
    • Cookie will be sent to set token = none
  • Get user
    • Route to get the currently logged in user (via token)
  • Password reset (lost password)
    • User can request to reset password
    • A hashed token will be emailed to the users registered email address
    • A put request can be made to the generated url to reset password
    • The token will expire after 10 minutes
  • Update user info
    • Authenticated user only
    • Separate route to update password
  • User CRUD
    • Admin only
  • Users can only be made admin by updating the database field manually

Security

  • Encrypt passwords and reset tokens
  • Prevent NoSQL injections
  • Add headers for security (helmet)
  • Prevent cross site scripting - XSS
  • Add a rate limit for requests of 100 requests per 10 minutes
  • Protect against http param polution
  • Use cors to make API public (for now)

Documentation

  • Use Postman to create documentation
  • Use docgen to create HTML files from Postman JSON File
  • Add html files as the / route for the api

Reverse Populate

In Model (Options)

toJSON: {virtuals: true},
toObject: {virtuals: true}
BootcampSchema.virtual('courses', {
  ref: 'Course',
  localField: '_id',
  foreignField: 'bootcamp',
  justOne: false
});

In Controller

query = Bootcamp.find(JSON.parse(queryString)).populate('courses');

Course Being Removed From Bootcamp

BootcampSchema.pre('remove', async function (next) {
    console.log(`Course being removed from bootcamp: ${this._id}`);
    await this.model('Course').deleteMany({bootcamp: this._id});
    next();
})
const bootcamp = await Bootcamp.findById(req.params.id);
bootcamp.remove();

Calculating The Average CourseCost

CourseSchema.statics.getAverageCost = async function (bootcampId) {
    const obj = await this.aggregate([
        {
            $match: {bootcamp: bootcampId}
        },
        {
            $group: {
                _id: '$bootcamp',
                averageCost: {$avg: '$tuition'}
            }
        }
    ]);
    try {
        await this.model('Bootcamp').findByIdAndUpdate(bootcampId, {
            averageCost: Math.ceil(obj[0].averageCost / 10) * 10
        })
    } catch (errors) {
        console.log(errors);
    }
}
//Call AverageCost After Add Course **********************
CourseSchema.post('save', function () {
    this.constructor.getAverageCost(this.bootcamp);
});

//Call AverageCost Before Remove Course ******************
CourseSchema.pre('remove', function () {
    this.constructor.getAverageCost(this.bootcamp);
});

Encrypt Password Using bcryptjs

UserSchema.pre('save', async function (next) {
   if (!this.isModified('password')) {
          next();
      }
   const salt = await bcrypt.genSalt(10);
   this.password = await bcrypt.hash(this.password, salt);
});

get Signed JWT

UserSchema.methods.getSignedJwtToken = function () {
    return jwt.sign({id: this._id}, process.env.JWT_SECRET, {
        expiresIn: process.env.JWT_EXPIRE
    });
};

Match User Entered Password to Hashed Password

UserSchema.methods.matchPassword = async function (enteredPassword) {
    return await bcrypt.compare(enteredPassword, this.password);
};

Grand Access to Specific Roles

exports.authorize = (...roles) => {
    return (req, res, next) => {
        if (!roles.includes(req.user.role)) {
            return next(new ErrorResponse(`User Role ${req.user.role} is Not Authorize to access this route`, 403));
        }
        next();
    };
};

Bootcamp User Relationship

  req.body.user = req.user.id;
  
  const publishedBootcamp = await Bootcamp.findOne({user: req.user.id});
  
  if (publishedBootcamp && req.user.role !== 'admin') {
      return next(new ErrorResponse(`The User with ${req.user.id} Already Published a Bootcamp`, 400));
  }

Make Sure User Is Bootcamp Owner

if (bootcamp.user.toString() !== req.user.id && req.user.role !== 'admin') {
    return next(new ErrorResponse(`User ${req.user.id} Is Not Authorized to The Bootcamp`, 401));
}

Generate And Hash Password Token

UserSchema.methods.getResetPasswordToken = function () {
    const resetToken = crypto.randomBytes(20).toString('hex');
    this.resetPasswordToken = crypto
        .createHash('sha256')
        .update(resetToken)
        .digest('hex');
        
    this.resetPasswordExpire = Date.now() + 10 * 60 * 1000;
    return resetToken;
};

Prevent User From Submitting More Than 1 Review Per Bootcamp

ReviewSchema.index({bootcamp: 1, user: 1}, {unique: true});

apiNodeJS

Backend API for the DevCamper application to the manage bootcams

Indices


AUTH

1. Forgot Password

Endpoint:

Method: POST
Type: RAW
URL: {{URL}}/api/v1/auth/forgotpassword

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{

    "email": "admin@gmail.com"
}

2. Get Logged In User Via Token

Endpoint:

Method: GET
Type: 
URL: {{URL}}/api/v1/auth/me

Headers:

Key Value Description
Content-Type application/json JSON TYPE

3. Login User

Endpoint:

Method: POST
Type: RAW
URL: {{URL}}/api/v1/auth/login

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{
    "email": "admin@gmail.com",
    "password": "123456"
}

4. Logout User

Endpoint:

Method: GET
Type: 
URL: {{URL}}/api/v1/auth/logout

Headers:

Key Value Description
Content-Type application/json JSON TYPE

5. Register User

Endpoint:

Method: POST
Type: RAW
URL: {{URL}}/api/v1/auth/register

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{
    "name": "Review3",
		"email": "review3@gmail.com",
        "role":"user",
		"password": "123456"
}

6. Reset Password

Endpoint:

Method: PUT
Type: RAW
URL: {{URL}}/api/v1/auth/resetpassword/8c7b3dc3892fd8335b9ac57ec4639fc2d1a90fd9

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{

    "password": "123456"
}

7. Update User Details

Endpoint:

Method: PUT
Type: RAW
URL: {{URL}}/api/v1/auth/updatedetails

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{
    "name": "Admin 2 Update",
		"email": "admin2@gmail.com"
}

8. Update User Password

Endpoint:

Method: PUT
Type: RAW
URL: {{URL}}/api/v1/auth/updatepassword

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{
    "currentPassword":"123456",
    "newPassword":"1234567"
}

Bootcamps

Bootcamps CRUD functionality

1. Create New Bootcamp

Create New Bootcamp Must be Authenticate By Admin or publishers

Endpoint:

Method: POST
Type: RAW
URL: {{URL}}/api/v1/bootcamps/

Headers:

Key Value Description
Content-Type application/json JSON TYPE
Authorization Sourav eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVmZmQyY2NmNzY0NzlmMjQ5MDc2NDBjMCIsIm5hbWUiOiJVc2VyIEFjY291bnQiLCJpYXQiOjE2MTA0Mjg5NDAsImV4cCI6MTYxMzAyMDk0MH0.X-Zws9YZiW5f4NKh5_P4HZKiplLSrh4uSuf8TK8nUv4

Body:

{
    "name": "ModernTech Bootcamp XSS-CLEAN<script>alert(1)</script>",
		"description": "Is coding your passion? Codemasters will give you the skills and the tools to become the best developer possible. We specialize in front end and full stack web development",
		"website": "https://devcentral.com",
		"phone": "(444) 444-4444",
		"email": "enroll@devcentral.com",
		"address":"Nikunja-2 Dhaka, Dhaka Division 1229, BD",
		"careers": [
			"Mobile Development",
			"Web Development",
			"Data Science",
			"Business"
		],
		"housing": false,
		"jobAssistance": true,
		"jobGuarantee": true,
		"acceptGi": true
}

2. Delete Bootcamp

Delete Bootcamp By ID From DB

Endpoint:

Method: DELETE
Type: 
URL: {{URL}}/api/v1/bootcamps/6005e12bad4a0a3278ecc8f8

Headers:

Key Value Description
Content-Type application/json JSON TYPE

3. Get All Bootcamps

Fetch all bootcamps from database

Endpoint:

Method: GET
Type: RAW
URL: {{URL}}/api/v1/bootcamps/

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{}

4. Get Bootcamps In Radius

Endpoint:

Method: GET
Type: RAW
URL: {{URL}}/api/v1/bootcamps/radius/02215/10

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{}

5. Get Single Bootcamp

Get Single Bootcamp By ID

Endpoint:

Method: GET
Type: 
URL: {{URL}}/api/v1/bootcamps/5d713a66ec8f2b88b8f830b8

Headers:

Key Value Description
Content-Type application/json JSON TYPE

6. Pagination Bootcamps

Endpoint:

Method: GET
Type: RAW
URL: {{URL}}/api/v1/bootcamps/

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Query params:

Key Value Description
page 2
limit 1
select name

Body:

{}

7. Photo Upload For Bootcamp

Endpoint:

Method: PUT
Type: FORMDATA
URL: {{URL}}/api/v1/bootcamps/5d725a1b7b292f5f8ceff788/photo

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

Key Value Description
file

8. Req Query Search

Endpoint:

Method: GET
Type: RAW
URL: {{URL}}/api/v1/bootcamps/

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Query params:

Key Value Description
housing true
location.state MA

Body:

{}

9. Select And Sort

Endpoint:

Method: GET
Type: RAW
URL: {{URL}}/api/v1/bootcamps/

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Query params:

Key Value Description
select name,slug,housing,createdAt
sort name

Body:

{}

10. Update Bootcamp

Update Bootcamp By ID from database

Endpoint:

Method: PUT
Type: RAW
URL: {{URL}}/api/v1/bootcamps/5ffe9125e8854807e8960828

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{
    "housing": false
}

Courses

CRUD All Courses !!!

1. Create Bootcamp Course

Create a course for specific bootcamp

Endpoint:

Method: POST
Type: RAW
URL: {{URL}}/api/v1/bootcamps/5ffea33f8c3f0a2f3853d00b/courses

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{
    "title": "UI/UX By ADMIN",
		"description": "In this course you will learn to create beautiful interfaces. It is a mix of design and development to create modern user experiences on both web and mobile",
		"weeks": 12,
		"tuition": 10000,
		"minimumSkill": "intermediate",
		"scholarhipsAvailable": true
}

2. Create Course Under Bootcamp

Endpoint:

Method: GET
Type: RAW
URL: {{URL}}/api/v1/bootcamps/5d713a66ec8f2b88b8f830b8/courses

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{
    "title": "UI/UX By SOURAV Update 2",
		"description": "In this course you will learn to create beautiful interfaces. It is a mix of design and development to create modern user experiences on both web and mobile",
		"weeks": 12,
		"tuition": 10000,
		"minimumSkill": "intermediate",
		"scholarhipsAvailable": true
}

3. Delete Course

Endpoint:

Method: DELETE
Type: RAW
URL: {{URL}}/api/v1/courses/5ffea3948c3f0a2f3853d00c

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{
    "tuition": 12000,
    "minimumSkill": "advanced"
}

4. Get A Single Course

Endpoint:

Method: GET
Type: RAW
URL: {{URL}}/api/v1/courses/5d725a4a7b292f5f8ceff789

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{}

5. Get All Courses

Endpoint:

Method: GET
Type: RAW
URL: {{URL}}/api/v1/courses/

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{}

6. Get All Courses For Bootcamp

Endpoint:

Method: GET
Type: RAW
URL: {{URL}}/api/v1/bootcamps/5d713a66ec8f2b88b8f830b8/courses

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{}

7. Update Course

Endpoint:

Method: PUT
Type: RAW
URL: {{URL}}/api/v1/courses/5ffea3948c3f0a2f3853d00c

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{
    "tuition": 12000,
    "minimumSkill": "advanced"
}

Reviews

1. Add One Review On One Bootcamp

Endpoint:

Method: POST
Type: RAW
URL: {{URL}}/api/v1/bootcamps/60054405d6a84136343e2ad8/reviews

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{
    "title":"Review 1",
    "text":"This is the description",
    "rating": 8
}

2. Delete Review

Endpoint:

Method: DELETE
Type: 
URL: {{URL}}/api/v1/reviews/600547069b7d8a31a0d9c3d3

3. Get A Single Review

Endpoint:

Method: PUT
Type: RAW
URL: {{URL}}/api/v1/reviews/5d7a514b5d2c12c7449be020

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{
    "title":"Update Review Title",
    "rating":7
}

4. Get All Reviews

Endpoint:

Method: GET
Type: RAW
URL: {{URL}}/api/v1/reviews

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{}

5. Get All Reviews By One Bootcamp

Endpoint:

Method: GET
Type: RAW
URL: {{URL}}/api/v1/bootcamps/60054405d6a84136343e2ad8/reviews

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{
    "title":"Best Review Title 2",
    "text":"This is the description",
    "rating": 8
}

6. Update Review

Endpoint:

Method: PUT
Type: 
URL: {{URL}}/api/v1/reviews/6005381b224bfa27389ddc0c

Users

1. Create New User

Endpoint:

Method: POST
Type: RAW
URL: {{URL}}/api/v1/users/

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{
    "name":"SOURAV ROY NEW USER",
    "email":"sourav@gmail.com",
    "password":"123456"
}

2. Delete User

Endpoint:

Method: DELETE
Type: 
URL: {{URL}}/api/v1/users/6001587dc501af1178b073ae

3. Get All Users

Endpoint:

Method: GET
Type: RAW
URL: {{URL}}/api/v1/users/

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{}

4. Get Single User

Endpoint:

Method: GET
Type: RAW
URL: {{URL}}/api/v1/users/600543b6d6a84136343e2ad6

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{}

5. Update User

Endpoint:

Method: PUT
Type: RAW
URL: {{URL}}/api/v1/users/6001587dc501af1178b073ae

Headers:

Key Value Description
Content-Type application/json JSON TYPE

Body:

{
    "name":"SOURAV ROY NEW UPDATE"
}

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy