Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions spec/schemas.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3835,6 +3835,7 @@ describe('schemas', () => {
.then(done.fail)
.catch(error => {
expect(error.code).toEqual(Parse.Error.DUPLICATE_VALUE);
expect(error.message).toEqual('A duplicate value for a field with unique values was provided. Duplicate index: code_1 on collection test_UniqueIndexClass in db parseServerMongoAdapterTestDatabase')
Copy link
Member

@mtrezza mtrezza Nov 17, 2025

Choose a reason for hiding this comment

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

I think this could expose schema information which creates an attack surface. Maybe the fix here is to only log more details in the server logs, but not return these details to the client. The test should then check the logging.

done();
});
});
Expand Down
27 changes: 25 additions & 2 deletions src/Adapters/Storage/Mongo/MongoStorageAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,29 @@ const ReadPreference = mongodb.ReadPreference;

const MongoSchemaCollectionName = '_SCHEMA';


// If we get a unique index error from mongo, try to parse it. If successful, return it.
const mongoUniqueIndexErrorFormatter = (message) => {
/**
* Sample error message that we are getting from mongo
* 'Plan executor error during findAndModify :: caused by :: E11000 duplicate key error collection: parseServerMongoAdapterTestDatabase.test_UniqueIndexClass index: code_1 dup key: { code: 2 }'
*/
const regex = /collection:\s*([\w]+)\.([\w]+)\s+index:\s*([\w_]+)/;

const match = message.match(regex);

if (match) {
const dbName = match[1];
const collectionName = match[2];
const indexName = match[3];
// Adding extra starting space to make it more readable.
return ` Duplicate index: ${indexName} on collection ${collectionName} in db ${dbName}`;
}

// Return nothing
return '';
}

const storageAdapterAllCollections = mongoAdapter => {
return mongoAdapter
.connect()
Expand Down Expand Up @@ -490,7 +513,7 @@ export class MongoStorageAdapter implements StorageAdapter {
// Duplicate value
const err = new Parse.Error(
Parse.Error.DUPLICATE_VALUE,
'A duplicate value for a field with unique values was provided'
`A duplicate value for a field with unique values was provided.${mongoUniqueIndexErrorFormatter(error.message)}`
);
err.underlyingError = error;
if (error.message) {
Expand Down Expand Up @@ -575,7 +598,7 @@ export class MongoStorageAdapter implements StorageAdapter {
if (error.code === 11000) {
throw new Parse.Error(
Parse.Error.DUPLICATE_VALUE,
'A duplicate value for a field with unique values was provided'
`A duplicate value for a field with unique values was provided.${mongoUniqueIndexErrorFormatter(error.message)}`
);
}
throw error;
Expand Down
Loading