Skip to content

[Data-integrity] PUT /api/user/profile replaces whole subdocuments — a partial edit wipes GitHub avatar & connected handles #342

Description

@vedant7007

Editing one profile field silently erases every other field in that subdocument, because the update replaces the whole nested object instead of merging.

Root cause

server/modules/user/service.js:14-35 (updateProfile) copies whole nested objects:

if (updateData.profile !== undefined)     allowedFields.profile = updateData.profile;
if (updateData.handles !== undefined)     allowedFields.handles = updateData.handles;
if (updateData.preferences !== undefined) allowedFields.preferences = updateData.preferences;

server/modules/user/repository.js:16-22 passes them straight to Mongoose:

return await User.findByIdAndUpdate(id, updateData, { new: true, runValidators: true });

A top-level nested object becomes $set: { profile: {…} }, which replaces the entire profile subdocument. Correct partial update needs dot-notation ($set: { "profile.bio": … }).

Failure scenario

A user signs up via GitHub → profile.avatar = GitHub avatar, handles.github = login, handles.codeforces = e.g. tourist. They later edit only their bio → frontend sends { profile: { bio: "hi" } }profile becomes { bio: "hi" }; avatar, college, location, skills are gone. Likewise { handles: { leetcode: "x" } } erases handles.github/handles.codeforces. The wiped handles.github also degrades GitHubService.#getToken (its user.handles.github fallback, github/service.js:50).

Fix

Flatten the incoming nested fields to dot-notation before $set (merge), so only the provided keys are updated.

Dedup

No issue references profile-update data loss; no PR touches user/service.js or user/repository.js. Distinct from #301/#302/#303/#304. Unreported.

Contributing as part of Elite Coders Summer of Code (ECSoC 2026).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions