Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
13 changes: 13 additions & 0 deletions 8.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ This document only highlights specific changes that require a longer explanation
---

- [Email Verification](#email-verification)
- [Database Indexes](#database-indexes)

---

Expand All @@ -25,3 +26,15 @@ The request to re-send a verification email changed to sending a `POST` request
Related pull requests:

- https://github.com/parse-community/parse-server/pull/8488

## Database Indexes

As part of the email verification and password reset improvements in Parse Server 8, the queries used for these operations have changed to use tokens instead of username/email fields. To ensure optimal query performance, Parse Server now automatically creates compound indexes on the following fields during server initialization:

- `(_email_verify_token, emailVerified, _email_verify_token_expires_at)` - Used for email verification queries
- `(_perishable_token, _perishable_token_expires_at)` - Used for password reset queries

These sparse, compound indexes are created automatically when Parse Server starts. No manual intervention is required.

> [!WARNING]
> If you have a large existing user base, the index creation may take some time during the first server startup after upgrading to Parse Server 8. If you have any concerns regarding a potential database performance impact during index creation, you may create these indexes manually in a controlled manner before upgrading Parse Server.
12 changes: 12 additions & 0 deletions spec/DatabaseController.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,12 @@ describe('DatabaseController', function () {
case_insensitive_username: { username: 1 },
case_insensitive_email: { email: 1 },
email_1: { email: 1 },
_email_verify_token: {
_email_verify_token: 1,
emailVerified: 1,
_email_verify_token_expires_at: 1,
},
_perishable_token: { _perishable_token: 1, _perishable_token_expires_at: 1 },
});
}
);
Expand All @@ -437,6 +443,12 @@ describe('DatabaseController', function () {
_id_: { _id: 1 },
username_1: { username: 1 },
email_1: { email: 1 },
_email_verify_token: {
_email_verify_token: 1,
emailVerified: 1,
_email_verify_token_expires_at: 1,
},
_perishable_token: { _perishable_token: 1, _perishable_token_expires_at: 1 },
});
}
);
Expand Down
26 changes: 26 additions & 0 deletions src/Controllers/DatabaseController.js
Original file line number Diff line number Diff line change
Expand Up @@ -1764,6 +1764,32 @@ class DatabaseController {
throw error;
});

await this.adapter
.ensureIndex(
'_User',
requiredUserFields,
['_email_verify_token', 'emailVerified', '_email_verify_token_expires_at'],
'_email_verify_token',
false
)
.catch(error => {
logger.warn('Unable to create index for email verification token: ', error);
throw error;
});

await this.adapter
.ensureIndex(
'_User',
requiredUserFields,
['_perishable_token', '_perishable_token_expires_at'],
'_perishable_token',
false
)
.catch(error => {
logger.warn('Unable to create index for password reset token: ', error);
throw error;
});

await this.adapter.ensureUniqueness('_Role', requiredRoleFields, ['name']).catch(error => {
logger.warn('Unable to ensure uniqueness for role name: ', error);
throw error;
Expand Down
Loading