Skip to content

bclonan/password-reset-wip

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NodeJS App: User Account Management

This is a backend application built with Node.js and Express. It provides functionalities related to user account management, including password reset.

Table of Contents

Features

  • Password Reset: Allows users to reset their password if they forget it.
  • [Add more features as you build them]

Dependencies

  • bcryptjs: Used for hashing passwords.
  • express: Web server framework.
  • moment: Date and time manipulation library.
  • validator: String validation and sanitization.
  • [Add other dependencies as you include them]

Directory Structure

nodejs-app/
│
├── app/
│   ├── server/
│   │   ├── account/
│   │   │   └── ResetPassword.js
│   │   ├── routes/
│   │   │   └── index.js
│   │   └── index.js
│   └── index.js
│
├── package.json
└── README.md

Directory Structure

  • app/: Contains the main server code.

    • server/: Contains the core server logic.
      • account/: Contains routes and logic related to account management.
        • ResetPassword.js: Contains routes and logic for password reset functionality.
      • routes/: Contains consolidated route handlers.
        • index.js: Main route file that consolidates all other route handlers.
      • index.js: Main server setup file.
    • index.js: Entry point for the application.
  • package.json: Contains the list of dependencies and scripts for the project.

Setup and Installation

  1. Clone the repository.
  2. Navigate to the project directory.
  3. Install the dependencies:
    npm install
    
  4. Start the server:
    npm start
    

Security System

Password Hashing

  • We use bcryptjs for hashing passwords. This ensures that even if our database is compromised, the attacker won't have direct access to user passwords.
  • Salting is done automatically by bcryptjs which prevents rainbow table attacks.

Password Reset

  • When a user requests a password reset, a unique token is generated using the crypto module.
  • This token is sent to the user's email and is required to reset the password.
  • The token is stored in the user's record and expires after 30 minutes for security reasons.

Session Management

  • After a successful password reset, a session identifier is generated and sent to the client side as a cookie.
  • This session identifier is used to verify the client in subsequent requests.

Rate Limiting

  • Users are limited to 5 password reset attempts per hour. This helps prevent brute-force attacks.

Trade-offs and Concerns

  • Rate Limiting: While rate limiting enhances security, it may also hinder genuine users who make multiple legitimate attempts within a short period.
  • Token Expiry: The 30-minute expiry for reset tokens is a balance between security and user convenience. A shorter expiry time would be more secure but less user-friendly.
  • Email-based Reset: Relying on email for password reset introduces a dependency on the user's email security. If a user's email is compromised, their account on our platform is also at risk.

Here's a comprehensive summary of the API, the reset password flow, its security measures, and how to use it:

API & Reset Password Flow Overview

1. Introduction

This API provides a mechanism for users to reset their passwords if they forget them. The process involves sending a unique token to the user's email, which they can then use to reset their password.

2. Flow

  1. Request Reset: The user initiates the process by entering their email and requesting a password reset.
  2. Token Generation: The system generates a unique token and associates it with the user's account. This token has an expiration time.
  3. Email Notification: An email containing the reset token (usually as a link) is sent to the user's email address.
  4. Token Validation: When the user clicks on the link or submits the token, the system validates it. It checks if the token is correct, associated with the given email, and not expired.
  5. Password Reset: If the token is valid, the user is allowed to set a new password.

3. Security Measures

  • Token Expiration: Tokens have a limited lifespan to ensure they can't be used indefinitely.
  • Token Uniqueness: Tokens are generated using a cryptographically secure method, ensuring their randomness and uniqueness.
  • Rate Limiting: The system limits the number of reset attempts to prevent abuse.
  • Account Locking: If suspicious activity is detected, accounts can be locked to prevent misuse.
  • Data Hashing: Passwords are hashed using bcrypt before being stored, ensuring that even if data is compromised, the actual passwords remain secure.
  • Session Identifier: A unique session identifier is generated and used to validate the user's session, adding an extra layer of security.

4. How to Use

  1. Initiate Reset: Navigate to the forgot password page and enter the email associated with your account.
  2. Check Email: Look for an email containing a reset link or token. Click on the link or use the token as instructed.
  3. Reset Password: Once validated, you'll be prompted to enter a new password. Ensure it's strong and unique.
  4. Login: Use your new password to log in.

5. Considerations & Trade-offs

  • Email Security: The security of the reset process is partly dependent on the security of the user's email. If an attacker gains access to the user's email, they can reset the password.
  • Token Lifespan: A shorter token lifespan is more secure but might inconvenience users if they don't use the token promptly.
  • Rate Limiting: While rate limiting prevents abuse, it can also lock out genuine users if they make mistakes multiple times.

6. Recommendations

  • Multi-Factor Authentication (MFA): Implementing MFA can add an extra layer of security.
  • Secure Email Practices: Encourage users to use strong passwords for their emails and to enable MFA if their email provider supports it.
  • Regular Audits: Regularly check and update the system to patch vulnerabilities and ensure best practices are being followed.

--- implimentation

Let's break this down step by step.

1. Models

User Model

const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');

const userSchema = new mongoose.Schema({
    email: {
        type: String,
        required: true,
        unique: true
    },
    password: {
        type: String,
        required: true
    },
    extensionattributes: {
        login: {
            password_reset_verification_link: String,
            reset_password_expiration: Date
        }
    },
    lastPasswordResetAttempt: Date,
    passwordResetAttempts: {
        type: Number,
        default: 0
    },
    sessionIdentifier: String,
    isLocked: {
        type: Boolean,
        default: false
    }
});

userSchema.methods.isValidPassword = async function(password) {
    return await bcrypt.compare(password, this.password);
};

const User = mongoose.model('User', userSchema);
module.exports = User;

2. Flow Representation

  1. User requests a password reset: They provide their email.
  2. System checks if the email exists: If not, a generic message is sent to prevent email enumeration.
  3. System checks if the user's account is locked: If locked, the user is informed.
  4. System checks for excessive reset attempts: If exceeded, the user is informed.
  5. System generates a unique token: This token is saved with the user's data and has an expiration time.
  6. System sends an email: The email contains a link with the token.
  7. User clicks the link and is directed to the reset page: Here, they provide a new password.
  8. System validates the token: If valid, the user's password is updated.

3. User Stories

  • As a user, I want to reset my password if I forget it.
  • As a user, I want to receive an email with instructions on how to reset my password.
  • As a user, I want to be informed if I've made too many reset attempts.
  • As a user, I want the reset token to expire after some time for security reasons.
  • As a system, I want to lock accounts that show suspicious activity.
  • As a system, I want to hash user passwords to ensure their security.

4. Conditions Checked

  1. Email Existence: Does the provided email exist in the database?
  2. Account Lock: Is the user's account locked?
  3. Reset Attempts: Has the user exceeded the maximum number of reset attempts?
  4. Token Validity: Is the provided token valid and not expired?

5. Integration with MongoDB

  1. Setup MongoDB and Mongoose:

First, you'll need to install mongoose:

npm install mongoose
  1. Connect to MongoDB:

In your main server file (/app/index.js or /app/server/index.js):

const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost:27017/yourDatabaseName', {
    useNewUrlParser: true,
    useUnifiedTopology: true
}).then(() => {
    console.log('Connected to MongoDB');
}).catch(err => {
    console.error('Could not connect to MongoDB', err);
});
  1. Use the User Model:

Now, you can use the User model (as defined above) to interact with the user data in your MongoDB database.

Conclusion

This setup provides a comprehensive password reset flow integrated with MongoDB. Ensure you have error handling in place and regularly audit your system for security best practices.

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •