Summary
The authentication workflow handles email normalization inconsistently.
The signup flow normalizes email addresses when checking for existing users, but stores the original unnormalized email value in the database. Later authentication flows perform lookups using normalized email values.
This creates a mismatch between write and read operations for email-based authentication.
Location
File: apps/public-api/src/controllers/userAuth.controller.js
Functions:
signup
login
buildAuthUserPayload
Relevant Code
Signup performs normalized lookup
const normalizedEmail = email.toLowerCase().trim();
const existingUser = await Model.findOne({
email: normalizedEmail
});
Signup stores raw email
const newUserPayload = buildAuthUserPayload(
usersColConfig,
{ email, password, username, ...otherData },
hashedPassword,
false
);
const payload = {
email,
password: hashedPassword,
...otherData,
createdAt: new Date()
};
Login performs normalized lookup
const normalizedEmail = email.toLowerCase().trim();
const user = await Model.findOne({
email: normalizedEmail
}).select('+password');
Validation schema does not normalize emails
email: z
.string()
.min(1)
.email()
.max(100)
Root Cause
The application normalizes email addresses for lookup operations but stores the original email value during user creation.
As a result:
- Write path uses raw email values.
- Read path uses normalized email values.
Steps to Reproduce
- Register a user with:
{
"email": "Test.User@example.com",
"password": "password123"
}
-
The user record is created using the original email value.
-
Attempt login using the same credentials.
-
The login flow normalizes the email and queries using:
email: "test.user@example.com"
Expected Behavior
Email addresses should be normalized consistently before both database writes and database reads.
Actual Behavior
The authentication workflow stores raw email values while performing normalized email lookups.
Impact
- Users registering with mixed-case email addresses may encounter authentication issues.
- Email-based workflows can behave inconsistently.
- Email uniqueness enforcement becomes dependent on database behavior rather than application logic.
Suggested Fix
Normalize email values before creating user payloads and ensure all email-based authentication flows use the same canonical representation.
Summary
The authentication workflow handles email normalization inconsistently.
The signup flow normalizes email addresses when checking for existing users, but stores the original unnormalized email value in the database. Later authentication flows perform lookups using normalized email values.
This creates a mismatch between write and read operations for email-based authentication.
Location
File:
apps/public-api/src/controllers/userAuth.controller.jsFunctions:
signuploginbuildAuthUserPayloadRelevant Code
Signup performs normalized lookup
Signup stores raw email
Login performs normalized lookup
Validation schema does not normalize emails
Root Cause
The application normalizes email addresses for lookup operations but stores the original email value during user creation.
As a result:
Steps to Reproduce
{ "email": "Test.User@example.com", "password": "password123" }The user record is created using the original email value.
Attempt login using the same credentials.
The login flow normalizes the email and queries using:
email: "test.user@example.com"Expected Behavior
Email addresses should be normalized consistently before both database writes and database reads.
Actual Behavior
The authentication workflow stores raw email values while performing normalized email lookups.
Impact
Suggested Fix
Normalize email values before creating user payloads and ensure all email-based authentication flows use the same canonical representation.