-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
feat: Add event information on verifyUserEmails
#9963
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: alpha
Are you sure you want to change the base?
feat: Add event information on verifyUserEmails
#9963
Conversation
|
🚀 Thanks for opening this pull request! |
📝 WalkthroughWalkthroughThis PR implements the feature to pass invocation event information to the Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/RestWrite.js (1)
774-794: Consider refactoring for improved readability.The logic for determining
actionandresolvedAuthProvideris correct but uses nested ternaries that make it harder to follow. Consider refactoring to use explicit conditionals for better maintainability:- const action = authProvider ? 'login' : isCreateOperation ? 'signup' : undefined; - if (!action) { - return; - } - const resolvedAuthProvider = authProvider || (action === 'signup' ? 'password' : undefined); + let action; + let resolvedAuthProvider; + + if (authProvider) { + action = 'login'; + resolvedAuthProvider = authProvider; + } else if (isCreateOperation) { + action = 'signup'; + resolvedAuthProvider = 'password'; + } else { + return; + } + this.storage.createdWith = { action, authProvider: resolvedAuthProvider }; return this.storage.createdWith;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
spec/EmailVerificationToken.spec.js(4 hunks)spec/ValidationAndPasswordsReset.spec.js(1 hunks)src/Options/Definitions.js(1 hunks)src/Options/docs.js(1 hunks)src/Options/index.js(2 hunks)src/RestWrite.js(4 hunks)src/Routers/UsersRouter.js(1 hunks)types/Options/index.d.ts(2 hunks)
🧰 Additional context used
🧠 Learnings (8)
📚 Learning: 2025-11-08T13:46:04.940Z
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 0
File: :0-0
Timestamp: 2025-11-08T13:46:04.940Z
Learning: For new Parse Server options, verify that the option is documented in src/Options/index.js and that npm run definitions has been executed to reflect changes in src/Options/docs.js and src/Options/Definitions.js. README.md documentation is a bonus but not required for new options.
Applied to files:
src/Options/docs.jstypes/Options/index.d.tssrc/Options/index.jssrc/Options/Definitions.js
📚 Learning: 2025-05-09T09:59:06.289Z
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 9445
File: spec/ParseLiveQuery.spec.js:1340-1375
Timestamp: 2025-05-09T09:59:06.289Z
Learning: Tests in the parse-server repository should use promise-based approaches rather than callback patterns with `done()`. Use a pattern where a Promise is created that resolves when the event occurs, then await that promise.
Applied to files:
spec/EmailVerificationToken.spec.js
📚 Learning: 2025-10-16T19:27:05.311Z
Learnt from: Moumouls
Repo: parse-community/parse-server PR: 9883
File: spec/CloudCodeLogger.spec.js:410-412
Timestamp: 2025-10-16T19:27:05.311Z
Learning: In spec/CloudCodeLogger.spec.js, the test "should log cloud function triggers using the silent log level" (around lines 383-420) is known to be flaky and requires the extra `await new Promise(resolve => setTimeout(resolve, 100))` timeout after awaiting `afterSavePromise` for reliability, even though it may appear redundant.
Applied to files:
spec/EmailVerificationToken.spec.js
📚 Learning: 2025-05-09T09:59:06.289Z
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 9445
File: spec/ParseLiveQuery.spec.js:1340-1375
Timestamp: 2025-05-09T09:59:06.289Z
Learning: New tests in the parse-server repository should use async/await with promise-based patterns rather than callback patterns with `done()`. The preferred pattern is to create a Promise that resolves when an expected event occurs, then await that Promise.
Applied to files:
spec/EmailVerificationToken.spec.js
📚 Learning: 2025-05-04T20:41:05.147Z
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 9445
File: spec/ParseLiveQuery.spec.js:1312-1338
Timestamp: 2025-05-04T20:41:05.147Z
Learning: New tests in the parse-server repository should use async/await with promise-based patterns rather than callback patterns with `done()`.
Applied to files:
spec/EmailVerificationToken.spec.js
📚 Learning: 2025-12-02T06:55:53.808Z
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 0
File: :0-0
Timestamp: 2025-12-02T06:55:53.808Z
Learning: When reviewing Parse Server PRs that add or modify Parse Server options, always verify that changes are properly reflected in three files: src/Options/index.js (where changes originate), src/Options/Definitions.js, and src/Options/docs.js. The correct workflow is: make changes in index.js first, then run `npm run definitions` to automatically replicate the changes to Definitions.js and docs.js.
Applied to files:
types/Options/index.d.tssrc/Options/index.jssrc/Options/Definitions.js
📚 Learning: 2025-11-08T13:46:04.940Z
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 0
File: :0-0
Timestamp: 2025-11-08T13:46:04.940Z
Learning: When reviewing Parse Server PRs that add new features, always check whether the feature is documented in the README.md file, though for new Parse Server options this is optional rather than required.
Applied to files:
src/Options/index.js
📚 Learning: 2025-11-17T15:02:48.786Z
Learnt from: mtrezza
Repo: parse-community/parse-server PR: 0
File: :0-0
Timestamp: 2025-11-17T15:02:48.786Z
Learning: For Parse Server PRs, always suggest an Angular commit convention PR title that would make a meaningful changelog entry for developers. Update the PR title suggestion on every commit. The format should be: type(scope): description. Common types include feat, fix, perf, refactor, docs, test, chore. The scope should identify the subsystem (e.g., graphql, rest, push, security). The description should be action-oriented and clearly convey the change's impact to developers.
Applied to files:
src/Options/index.js
🧬 Code graph analysis (3)
spec/EmailVerificationToken.spec.js (1)
src/RestWrite.js (6)
verifyUserEmails(992-992)user(330-330)user(926-926)user(1543-1543)user(1824-1824)res(623-627)
src/RestWrite.js (1)
src/Auth.js (1)
authProvider(552-552)
src/Routers/UsersRouter.js (1)
src/RestWrite.js (3)
authProvider(781-786)request(845-852)request(981-988)
🪛 Biome (2.1.2)
src/Options/index.js
[error] 45-57: type alias are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.
TypeScript only syntax
(parse)
[error] 189-189: Expected a statement but instead found '?'.
Expected a statement here.
(parse)
[error] 193-193: Expected a statement but instead found '?'.
Expected a statement here.
(parse)
[error] 201-201: Expected a statement but instead found '?'.
Expected a statement here.
(parse)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (16)
- GitHub Check: Node 20
- GitHub Check: MongoDB 8, ReplicaSet
- GitHub Check: MongoDB 6, ReplicaSet
- GitHub Check: Node 18
- GitHub Check: Node 22
- GitHub Check: Redis Cache
- GitHub Check: MongoDB 7, ReplicaSet
- GitHub Check: PostgreSQL 16, PostGIS 3.5
- GitHub Check: PostgreSQL 17, PostGIS 3.5
- GitHub Check: PostgreSQL 18, PostGIS 3.6
- GitHub Check: PostgreSQL 15, PostGIS 3.5
- GitHub Check: PostgreSQL 15, PostGIS 3.3
- GitHub Check: PostgreSQL 15, PostGIS 3.4
- GitHub Check: Docker Build
- GitHub Check: Code Analysis (javascript)
- GitHub Check: Benchmarks
🔇 Additional comments (15)
src/Options/docs.js (1)
112-112: Documentation update looks good.The updated description clearly explains the new
createdWithparameter that indicates whether the invocation is forsignuporloginand the authentication provider used. This aligns well with the PR objective and the implementation in other files.Based on learnings, ensure this change was generated by running
npm run definitionsafter updatingsrc/Options/index.js.spec/ValidationAndPasswordsReset.spec.js (1)
287-287: Test expectation correctly validates the newcreatedWithparameter.The test verifies that during login verification flow,
createdWithcontains the expectedaction: 'login'andauthProvider: 'password'values. This provides coverage for the primary password-based login scenario.src/Routers/UsersRouter.js (1)
143-157: Implementation correctly derives auth provider for verification context.The logic properly:
- Extracts auth provider(s) from
req.body.authDatakeys, joining multiple providers with comma if present- Defaults to
'password'when no authData is provided- Creates the
createdWithobject withaction: 'login'for the verification callbackThis is consistent with the pattern used in
RestWrite.js(see lines 780-785) and enables the verification function to make conditional decisions based on the authentication method.src/Options/Definitions.js (1)
636-641: Generated definitions correctly reflect the newcreatedWithparameter documentation.Based on learnings, ensure this file was generated by running
npm run definitionsafter making changes tosrc/Options/index.js, rather than being manually edited.types/Options/index.d.ts (2)
29-40: Well-structured interface for the verification request.The
VerifyUserEmailsRequestinterface properly models:
- Standard request fields (
master,ip,installationId)- The new
createdWithobject with typedactionunion ('login' | 'signup') andauthProviderstring- Optional fields are correctly marked (e.g.,
createdWithis optional for scenarios like resend requests)This provides good TypeScript support for developers implementing conditional verification logic.
89-90: Option types correctly updated to support function-based configuration.The type changes properly allow both:
- Simple boolean values for static configuration
- Functions receiving
VerifyUserEmailsRequestand returningboolean | Promise<boolean>for conditional logicThis enables the use case described in the linked issue #9505 (conditional verification based on auth provider).
src/RestWrite.js (2)
837-856: LGTM!The integration of
getCreatedWith()in the email validation flow correctly provides the invocation context for email verification callbacks.
1003-1030: Verify scenarios wheregetCreatedWith()returns undefined.The fallback logic at lines 1014-1018 reconstructs the
createdWithobject whengetCreatedWith()returns undefined. This defensive pattern is appropriate if legitimate scenarios exist wheregetCreatedWith()cannot provide a value at this point in the execution flow. Confirm whether:
- Passing tests exercise code paths where this fallback is used
- There are documented scenarios where
getCreatedWith()returns undefined in the session token creation flowIf no such scenarios exist and tests pass, the fallback may be unnecessary legacy code worth removing.
spec/EmailVerificationToken.spec.js (5)
301-309: LGTM!Test correctly verifies that the
createdWithfield is now included in the verification request and has the expected value for signup scenarios.
370-378: LGTM!Test assertions correctly updated to include the new
createdWithfield in the request keys and verify its value.
413-443: LGTM!The new test effectively verifies that
createdWithis provided during signup when email verification blocks session creation. The test:
- Correctly configures the server with verification requirements
- Verifies the spy is called the expected number of times
- Asserts the correct
createdWithvalue with signup action and password auth provider
445-476: LGTM!The new test properly verifies that
createdWithincludes the correct auth provider during login verification. The test flow is logical:
- Creates a user first
- Reconfigures server with verification callback
- Attempts login and verifies the
createdWithparameter has login action
867-901: LGTM!Correctly asserts that
createdWithisundefinedforverificationEmailRequest(resend) scenarios, which makes sense since resending doesn't represent a new signup or login action.src/Options/index.js (2)
46-57: LGTM!The new
EmailVerificationRequesttype properly documents the request structure passed to email verification callbacks, including the newcreatedWithfield that provides context about the invocation (signup vs login) and auth provider used.
189-203: LGTM!The updated signatures for
verifyUserEmailsandpreventLoginWithUnverifiedEmailcorrectly extend these options to accept functions that receive anEmailVerificationRequestand return a boolean or Promise. This enables conditional verification logic based on thecreatedWithcontext, which was the goal of this PR.The documentation clearly explains the new functionality and indicates that the function receives a request object with
createdWithinformation.Note: The static analysis errors about TypeScript-only syntax are expected for Flow files and can be ignored.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## alpha #9963 +/- ##
=======================================
Coverage 92.56% 92.57%
=======================================
Files 191 191
Lines 15544 15557 +13
Branches 177 177
=======================================
+ Hits 14389 14402 +13
Misses 1143 1143
Partials 12 12 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Pull Request
Issue
Fixes: #9505
Summary by CodeRabbit
Release Notes
preventSignupWithUnverifiedEmailoption to control signup behavior with unverified emails.emailVerifyTokenValidityDurationandemailVerifyTokenReuseIfValidoptions to configure email verification token lifecycle.verifyUserEmailsandpreventLoginWithUnverifiedEmailoptions to support conditional logic based on verification context (signup vs. login and authentication method).✏️ Tip: You can customize this high-level summary in your review settings.