Skip to content

Merge user-management-service into chat-service branch#4

Merged
2iaad merged 6 commits into
feature/chat-servicefrom
feature/user-management-database
Jan 27, 2026
Merged

Merge user-management-service into chat-service branch#4
2iaad merged 6 commits into
feature/chat-servicefrom
feature/user-management-database

Conversation

@2iaad
Copy link
Copy Markdown
Member

@2iaad 2iaad commented Jan 27, 2026

Changes

  • Adds backend/user-management-service/ directory from the feature/user-management-database branch
  • This merge brings their work into my chat service branch so both services can coexist in the backend.

Expected Backend Structure After Merge

backend/
├── chat-service/
└── user-management-service/

Mouad Kimdil added 4 commits January 23, 2026 19:13
- Initialize service structure with MVC architecture
- Configure environment variables with .env and .env.example
- Add .gitignore for Node.js security
- Create service documentation and npm scripts
- Remove .env from version control
- Add comprehensive .gitignore for entire project
- Complete User model with bcrypt authentication and security
- Production-ready Docker setup with health checks
- MongoDB connection with retry logic and error handling
- Makefile with development workflow commands
- Comprehensive documentation and .dockerignore optimization
@2iaad 2iaad requested a review from Copilot January 27, 2026 22:41
@2iaad 2iaad self-assigned this Jan 27, 2026
@2iaad 2iaad added the enhancement New feature or request label Jan 27, 2026
@2iaad
Copy link
Copy Markdown
Member Author

2iaad commented Jan 27, 2026

@copilot

Copy link
Copy Markdown

Copilot AI commented Jan 27, 2026

@2iaad I've opened a new pull request, #5, to work on those changes. Once the pull request is ready, I'll request review from you.

No changes required - empty comment with no actionable feedback
@2iaad 2iaad merged commit 481a5e2 into feature/chat-service Jan 27, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request attempts to merge the user-management-service into the chat-service branch, bringing together two backend microservices. However, there is a critical naming discrepancy: the PR description states it adds backend/user-management-service/ but the actual directory is backend/user-service/.

Changes:

  • Adds a complete user management microservice with MongoDB backend
  • Includes Docker configuration for the user service and MongoDB
  • Updates frontend package-lock.json to remove peer dependency flags
  • Adds root-level Makefile for Docker orchestration and .gitignore for the monorepo

Reviewed changes

Copilot reviewed 11 out of 16 changed files in this pull request and generated 17 comments.

Show a summary per file
File Description
frontend/package-lock.json Removes "peer": true flags from multiple dependencies, changing dependency resolution behavior
docker-compose.yml Adds Docker services for user-service and MongoDB with health checks and environment configuration
backend/user-service/src/server.js Entry point that connects to database and starts Express server with graceful error handling
backend/user-service/src/models/User.js Comprehensive user model with authentication, 2FA, OAuth, friends system, and security features
backend/user-service/src/config/database.js Database connection manager with retry logic, health checks, and graceful shutdown
backend/user-service/src/app.js Express application setup with middleware (helmet, CORS, morgan, body parsing) and basic routes
backend/user-service/package.json Node.js dependencies including Express 5, Mongoose 9, and security packages
backend/user-service/package-lock.json Full dependency lock file for reproducible builds
backend/user-service/dockerfile Multi-stage Docker build with security hardening and health checks
backend/user-service/README.md Comprehensive documentation covering architecture, setup, and deployment
backend/user-service/.gitignore Standard Node.js gitignore patterns for dependencies, logs, and environment files
backend/user-service/.env.example Template for environment variables including database, JWT, and service configuration
Makefile Docker Compose orchestration commands for building, running, and managing services
.gitignore Root-level gitignore with patterns for environment files, dependencies, and IDE artifacts
Files not reviewed (2)
  • backend/user-service/package-lock.json: Language not supported
  • frontend/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@@ -0,0 +1,21 @@
FROM node:18-alpine
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Dockerfile filename uses lowercase "dockerfile" but Docker convention is to use "Dockerfile" with a capital D. While Docker will work with either, following the standard naming convention improves consistency and compatibility with various tools.

Copilot uses AI. Check for mistakes.
Comment on lines +131 to +134
twoFactorBackupCodes: [{
code: String,
used: { type: Boolean, default: false }
}],
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The twoFactorBackupCodes field stores backup codes with select: false not set, which means these sensitive hashed codes will be included in query results by default. This is a security risk. The field definition should include select: false to prevent accidental exposure, similar to the password field.

Suggested change
twoFactorBackupCodes: [{
code: String,
used: { type: Boolean, default: false }
}],
twoFactorBackupCodes: {
type: [{
code: String,
used: { type: Boolean, default: false }
}],
select: false
},

Copilot uses AI. Check for mistakes.
Comment on lines +9 to +10
app.use(helmet());
app.use(cors());
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CORS configuration uses cors() with no options, which allows all origins. This is a security vulnerability in production. The configuration should restrict allowed origins based on environment variables (ALLOWED_ORIGINS from .env.example) to prevent unauthorized cross-origin requests.

Suggested change
app.use(helmet());
app.use(cors());
const allowedOrigins = (process.env.ALLOWED_ORIGINS || '')
.split(',')
.map(origin => origin.trim())
.filter(origin => origin.length > 0);
const corsOptions = {
origin: (origin, callback) => {
// Allow requests with no origin (e.g. curl, mobile apps)
if (!origin) {
return callback(null, true);
}
if (allowedOrigins.includes(origin)) {
return callback(null, true);
}
return callback(new Error('Not allowed by CORS'));
}
};
app.use(helmet());
app.use(cors(corsOptions));

Copilot uses AI. Check for mistakes.

const app = express();

app.use(helmet());
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The helmet middleware is used with default settings, but for production security, consider configuring specific security policies. At minimum, you should configure Content Security Policy (CSP) headers to prevent XSS attacks and other injection vulnerabilities.

Suggested change
app.use(helmet());
app.use(
helmet({
contentSecurityPolicy: {
useDefaults: true,
directives: {
defaultSrc: ["'self'"]
}
}
})
);

Copilot uses AI. Check for mistakes.
Comment on lines +82 to +87
setTimeout(() => {
this.connect();
}, this.retryDelay);

// Exponential backoff
this.retryDelay *= 1.5;
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The retry logic uses setTimeout (line 82-84) which doesn't work well in a async/await context. The function will continue execution immediately after setTimeout is called, not after the delay. This should use a Promise-based delay or await a promisified setTimeout to ensure the retry happens after the delay period.

Suggested change
setTimeout(() => {
this.connect();
}, this.retryDelay);
// Exponential backoff
this.retryDelay *= 1.5;
// Capture current delay, then apply exponential backoff for the next attempt
const currentDelay = this.retryDelay;
// Exponential backoff
this.retryDelay *= 1.5;
// Wait for the delay period before retrying the connection
await new Promise((resolve) => setTimeout(resolve, currentDelay));
await this.connect();

Copilot uses AI. Check for mistakes.
Comment on lines +25 to +30
app.use((error, req, res, next) => {
console.error('Error: ', error);
res.status(500).json({
message: 'Internal server error',
error: process.env.NODE_ENV === 'development' ? error.message : undefined
});
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handler middleware reveals error details in development mode (line 29), which is acceptable. However, there's no request ID or correlation ID logging, making it difficult to trace errors in production. Consider adding request IDs for better observability.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,21 @@
FROM node:18-alpine
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The package.json specifies engine requirements including "node": ">=20.19.0" for bson and mongoose dependencies. However, the Dockerfile uses FROM node:18-alpine (line 1), which is incompatible with these dependencies. This will cause installation failures. Update the Dockerfile to use Node.js 20 or higher.

Suggested change
FROM node:18-alpine
FROM node:20-alpine

Copilot uses AI. Check for mistakes.
this.isConnected = true;
this.retryCount = 0;

console.log(`MongoDB connected successfully to: ${mongoUri.replace(/\/\/.*@/, '//***:***@')}`);
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The database connection string masking on line 37 uses a simple regex replacement that may not work correctly for all MongoDB URI formats. The pattern /\/\/.*@/ will fail for URIs without authentication credentials, potentially causing a runtime error. Use optional matching or check if credentials exist before attempting to mask them.

Suggested change
console.log(`MongoDB connected successfully to: ${mongoUri.replace(/\/\/.*@/, '//***:***@')}`);
const safeMongoUri = mongoUri && mongoUri.includes('@')
? mongoUri.replace(/^(mongodb(?:\+srv)?:\/\/)[^@]+@/, '$1***:***@')
: mongoUri;
console.log(`MongoDB connected successfully to: ${safeMongoUri}`);

Copilot uses AI. Check for mistakes.

## Prerequisites

- Node.js (v18 or higher)
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The README states the prerequisite is "Node.js (v18 or higher)" on line 29, but the package.json dependencies (mongoose, bson, mongodb) require Node.js >= 20.19.0. This is a documentation inconsistency that could mislead developers. Update the README to reflect the actual minimum version requirement of Node.js 20.19.0.

Suggested change
- Node.js (v18 or higher)
- Node.js (v20.19.0 or higher)

Copilot uses AI. Check for mistakes.
"express": "^5.2.1",
"helmet": "^8.1.0",
"jsonwebtoken": "^9.0.3",
"mongoose": "^9.1.5",
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mongoose version "^9.1.5" requires Node.js >= 20.19.0 according to the package-lock.json (line 1009). This is a very specific and recent Node.js version requirement that may not be widely available yet. Mongoose 8.x supports older Node.js versions and would be more compatible. Consider whether this version requirement is necessary or if an earlier mongoose version would be more practical.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants