Skip to content

feat: Add event information to verifyUserEmails, preventLoginWithUnverifiedEmail to identify invoking signup / login action and auth provider#9963

Merged
mtrezza merged 16 commits intoparse-community:alphafrom
coratgerl:invocation-verify-user-emails
Feb 6, 2026
Merged

feat: Add event information to verifyUserEmails, preventLoginWithUnverifiedEmail to identify invoking signup / login action and auth provider#9963
mtrezza merged 16 commits intoparse-community:alphafrom
coratgerl:invocation-verify-user-emails

Conversation

@coratgerl
Copy link
Contributor

@coratgerl coratgerl commented Dec 6, 2025

Pull Request

Issue

Fixes: #9505

  • Add tests
  • Add changes to documentation (guides, repository pages, code comments)
  • Add security check
  • Add new Parse Error codes to Parse JS SDK

Summary by CodeRabbit

  • New Features

    • Email-related options can be functions and now receive richer request context including createdWith (action: signup|login and authProvider); authProvider is provided for login flows.
  • Documentation

    • Docs expanded with examples and createdWith details for conditional-function behavior.
  • Types

    • New public request types describing the enriched verification/send-email payloads.
  • Tests

    • Expanded coverage for createdWith across signup, login, resend, session and multi-provider scenarios.
  • Chores

    • Added parser to accept boolean-or-function option values.

@parse-github-assistant
Copy link

parse-github-assistant bot commented Dec 6, 2025

🚀 Thanks for opening this pull request!

@coderabbitai
Copy link

coderabbitai bot commented Dec 6, 2025

📝 Walkthrough

Walkthrough

Adds a computed createdWith object ({ action: 'signup' | 'login', authProvider }) to request contexts used by email verification and session creation; extends option parsers, types, and docs to accept functions receiving that request; updates RestWrite, UsersRouter, parsers, and tests accordingly.

Changes

Cohort / File(s) Summary
Tests
spec/EmailVerificationToken.spec.js, spec/ValidationAndPasswordsReset.spec.js, spec/buildConfigDefinitions.spec.js, spec/parsers.spec.js
Add/adjust tests to assert createdWith presence/values in signup/login verification flows; add tests for boolean-or-function parser and UnionTypeAnnotation mapper behavior.
Core request/session handling
src/RestWrite.js, src/Routers/UsersRouter.js
Add RestWrite.buildCreatedWith and RestWrite.prototype.getCreatedWith(); compute/cache createdWith; pass createdWith into email validation and session creation paths; derive authProvider from incoming authData; invalidate cache when authProvider resolved.
Options parsing & parsers
src/Options/parsers.js, resources/buildConfigDefinitions.js, src/Options/Definitions.js
Add booleanOrFunctionParser; map union types containing boolean+function to it; switch option parsers for preventLoginWithUnverifiedEmail, sendUserEmailVerification, and verifyUserEmails to boolean-or-function.
Options API & docs
src/Options/index.js, src/Options/docs.js
Introduce EmailVerificationRequest / SendEmailVerificationRequest types and update option signatures to accept functions receiving those requests; expand docs/help text describing createdWith, authProvider scenarios, and resendRequest.
Type declarations
types/Options/index.d.ts
Add EmailVerificationRequest and SendEmailVerificationRequest interfaces (include createdWith and resendRequest); update ParseServerOptions.verifyUserEmails, preventLoginWithUnverifiedEmail, and sendUserEmailVerification signatures to accept callback form.
Build tooling
resources/buildConfigDefinitions.js
Map UnionTypeAnnotation with boolean+function to booleanOrFunctionParser to support new union option types.

Sequence Diagram(s)

mermaid
sequenceDiagram
actor Client
participant UsersRouter
participant RestWrite
participant VerifyHook as verifyUserEmails
Client->>UsersRouter: signup/login request (body, authData)
UsersRouter->>RestWrite: create RestWrite for operation
RestWrite->>RestWrite: getCreatedWith() -> { action, authProvider }
RestWrite->>VerifyHook: invoke verifyUserEmails(request with createdWith, resendRequest?)
VerifyHook-->>RestWrite: boolean | Promise
RestWrite-->>UsersRouter: proceed or block based on result
UsersRouter-->>Client: response (session created / verification required / error)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • feat: Add TypeScript definitions #9693 — Type/typing updates for ParseServer option typings that overlap the new EmailVerificationRequest/SendEmailVerificationRequest and option signature changes.

Suggested reviewers

  • Moumouls
🚥 Pre-merge checks | ✅ 3 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The PR description provides an issue link (#9505) and confirms tests were added, but lacks substantive explanation of the approach and changes made. Expand the description to include the approach, key changes made (createdWith object, function parameter types), and explain how the feature meets the issue requirements.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR implementation successfully addresses issue #9505 by adding createdWith context (action and authProvider) to verifyUserEmails, preventLoginWithUnverifiedEmail, and sendUserEmailVerification function parameters across signup, login, and resend flows.
Out of Scope Changes check ✅ Passed All changes are tightly scoped to the stated objective: adding createdWith context to email verification flows, including type definitions, parsers, tests, and documentation updates directly supporting this feature.
Title check ✅ Passed The title accurately describes the main change: adding createdWith event information to verifyUserEmails and preventLoginWithUnverifiedEmail functions to identify signup/login actions and auth providers.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@parseplatformorg
Copy link
Contributor

parseplatformorg commented Dec 6, 2025

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

Copy link

@coderabbitai coderabbitai bot left a 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 action and resolvedAuthProvider is 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

📥 Commits

Reviewing files that changed from the base of the PR and between e78e58d and cfe22b3.

📒 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.js
  • types/Options/index.d.ts
  • src/Options/index.js
  • src/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.ts
  • src/Options/index.js
  • src/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 createdWith parameter that indicates whether the invocation is for signup or login and 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 definitions after updating src/Options/index.js.

spec/ValidationAndPasswordsReset.spec.js (1)

287-287: Test expectation correctly validates the new createdWith parameter.

The test verifies that during login verification flow, createdWith contains the expected action: 'login' and authProvider: '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:

  1. Extracts auth provider(s) from req.body.authData keys, joining multiple providers with comma if present
  2. Defaults to 'password' when no authData is provided
  3. Creates the createdWith object with action: 'login' for the verification callback

This 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 new createdWith parameter documentation.

Based on learnings, ensure this file was generated by running npm run definitions after making changes to src/Options/index.js, rather than being manually edited.

types/Options/index.d.ts (2)

29-40: Well-structured interface for the verification request.

The VerifyUserEmailsRequest interface properly models:

  • Standard request fields (master, ip, installationId)
  • The new createdWith object with typed action union ('login' | 'signup') and authProvider string
  • Optional fields are correctly marked (e.g., createdWith is 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 VerifyUserEmailsRequest and returning boolean | Promise<boolean> for conditional logic

This 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 where getCreatedWith() returns undefined.

The fallback logic at lines 1014-1018 reconstructs the createdWith object when getCreatedWith() returns undefined. This defensive pattern is appropriate if legitimate scenarios exist where getCreatedWith() cannot provide a value at this point in the execution flow. Confirm whether:

  1. Passing tests exercise code paths where this fallback is used
  2. There are documented scenarios where getCreatedWith() returns undefined in the session token creation flow

If 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 createdWith field 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 createdWith field in the request keys and verify its value.


413-443: LGTM!

The new test effectively verifies that createdWith is 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 createdWith value with signup action and password auth provider

445-476: LGTM!

The new test properly verifies that createdWith includes the correct auth provider during login verification. The test flow is logical:

  1. Creates a user first
  2. Reconfigures server with verification callback
  3. Attempts login and verifies the createdWith parameter has login action

867-901: LGTM!

Correctly asserts that createdWith is undefined for verificationEmailRequest (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 EmailVerificationRequest type properly documents the request structure passed to email verification callbacks, including the new createdWith field that provides context about the invocation (signup vs login) and auth provider used.


189-203: LGTM!

The updated signatures for verifyUserEmails and preventLoginWithUnverifiedEmail correctly extend these options to accept functions that receive an EmailVerificationRequest and return a boolean or Promise. This enables conditional verification logic based on the createdWith context, which was the goal of this PR.

The documentation clearly explains the new functionality and indicates that the function receives a request object with createdWith information.

Note: The static analysis errors about TypeScript-only syntax are expected for Flow files and can be ignored.

@codecov
Copy link

codecov bot commented Dec 6, 2025

Codecov Report

❌ Patch coverage is 87.50000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.52%. Comparing base (d3d6e9e) to head (c037611).
⚠️ Report is 3 commits behind head on alpha.

Files with missing lines Patch % Lines
src/Options/parsers.js 0.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##            alpha    #9963      +/-   ##
==========================================
- Coverage   92.54%   92.52%   -0.02%     
==========================================
  Files         190      190              
  Lines       15499    15523      +24     
  Branches      176      176              
==========================================
+ Hits        14343    14363      +20     
- Misses       1144     1148       +4     
  Partials       12       12              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mtrezza
Copy link
Member

mtrezza commented Dec 7, 2025

@coratgerl let's just consider the insights already gained in existing PRs. What't the diff between your PR and #9651?

@coratgerl
Copy link
Contributor Author

@mtrezza

Key Improvements:

  • Full createdWith { action, authProvider } coverage: signup, login, email-update verification, and resend flows.
  • Normalizes authProvider from authData (defaults to 'password'), ensuring hooks always receive a valid provider.
  • Eliminates undefined provider risks and enforces request consistency.

Testing:

  • Adds tests for signup/login with createdWith, resend/verification args, and conditional flows.
  • Fixes anonymous/login expectations.

Bonus:

  • Updates Options/index.js with typed interfaces for object params.

@coratgerl
Copy link
Contributor Author

This one is ready for review @mtrezza :)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
types/Options/index.d.ts (1)

29-40: Consider aligning the interface name with the Flow type.

The interface name VerifyUserEmailsRequest differs from the Flow type EmailVerificationRequest in src/Options/index.js. While this file is manually maintained, having consistent naming across both type systems would improve maintainability and reduce confusion for contributors.

Consider renaming to match the Flow type:

-export interface VerifyUserEmailsRequest {
+export interface EmailVerificationRequest {

And update the references on lines 89-90 accordingly.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cfe22b3 and 91a87ed.

📒 Files selected for processing (6)
  • 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)
  • types/Options/index.d.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • spec/ValidationAndPasswordsReset.spec.js
  • src/Options/docs.js
  • spec/EmailVerificationToken.spec.js
  • src/Options/Definitions.js
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
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.
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.
📚 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.ts
  • src/Options/index.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: 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:

  • types/Options/index.d.ts
  • src/Options/index.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:

  • types/Options/index.d.ts
  • 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
🪛 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). (11)
  • GitHub Check: Redis Cache
  • GitHub Check: Node 20
  • GitHub Check: PostgreSQL 16, PostGIS 3.5
  • GitHub Check: PostgreSQL 18, PostGIS 3.6
  • GitHub Check: Node 22
  • GitHub Check: MongoDB 7, ReplicaSet
  • GitHub Check: MongoDB 8, ReplicaSet
  • GitHub Check: PostgreSQL 17, PostGIS 3.5
  • GitHub Check: Docker Build
  • GitHub Check: Code Analysis (javascript)
  • GitHub Check: Benchmarks
🔇 Additional comments (3)
src/Options/index.js (2)

46-57: Type definition looks well-structured for the verification context.

The EmailVerificationRequest type properly captures:

  • Standard request context (original, object, master, ip, installationId)
  • The new createdWith field with action and authProvider as specified in issue #9505
  • The resendRequest flag for distinguishing resend flows

Note: The static analysis hints from Biome are false positives—this file uses Flow type annotations, not TypeScript.


189-193: Updated verifyUserEmails signature enables conditional verification logic.

The updated type signature properly supports:

  • Backward compatibility with boolean
  • New function variant receiving EmailVerificationRequest with createdWith context

The documentation clearly describes the new capability. This aligns well with the feature request in issue #9505.

types/Options/index.d.ts (1)

89-90: TypeScript option signatures correctly updated.

The updated signatures properly reflect the new functional interface, enabling type-safe conditional verification logic. The function variant correctly accepts the request context and supports both synchronous and async (Promise<boolean>) return values.

@coratgerl
Copy link
Contributor Author

Is this one not good for you @mtrezza ? Let me know what you think of this version ?

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/Options/index.js`:
- Around line 194-203: Update the JSDoc for the preventLoginWithUnverifiedEmail
option to describe both boolean and function usages: mention it can be true to
block login until verification or be a function that receives an
EmailVerificationRequest and returns a boolean or Promise<boolean>, and document
the EmailVerificationRequest fields (including createdWith like the sibling
verifyUserEmails doc does) so the generated docs (via npm run definitions)
reflect the function signature and available request properties; update the
comment block around preventLoginWithUnverifiedEmail to mirror the style and
details used for verifyUserEmails.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/Routers/UsersRouter.js`:
- Around line 143-154: The code repeatedly calls Object.keys(req.body.authData)
and joins multiple keys into a comma string (e.g., "facebook,google"), which
breaks callers expecting a single provider; fix by reading the authData keys
once (e.g., const providers = req.body && req.body.authData ?
Object.keys(req.body.authData) : []) and set authProvider to providers[0] (or
undefined/fallback) instead of joining, then pass that authProvider into
RestWrite.buildCreatedWith('login', authProvider); update the authProvider
variable and remove the duplicate Object.keys calls around Parse.User.fromJSON
and RestWrite.buildCreatedWith to avoid the inefficiency and incorrect
multi-provider string.
- Around line 297-301: The session creation in RestWrite.createSession currently
uses RestWrite.buildCreatedWith('login') which hardcodes
createdWith.authProvider to 'password' even when req.body.authData indicates
another provider; update the handleLogIn flow to either (a) set
createdWith.authProvider based on the computed provider from req.body.authData
(use the same logic that verifies authData) when calling
RestWrite.createSession, or (b) if the existing behavior is intentional, add a
concise clarifying comment near RestWrite.createSession /
RestWrite.buildCreatedWith and in handleLogIn noting that authData is treated as
supplementary and the session creation always records 'password' as the primary
auth method so future readers understand why req.body.authData is not reflected
in createdWith. Ensure you reference RestWrite.createSession,
RestWrite.buildCreatedWith, handleLogIn, and req.body.authData when making the
change.

Copy link

@coderabbitai coderabbitai bot left a 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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/Options/index.js (1)

236-236: ⚠️ Potential issue | 🟡 Minor

Flow type for sendUserEmailVerification is inconsistent with its new parser.

The type here is ?(boolean | void), but Definitions.js (line 577) was updated in this PR to use parsers.booleanOrFunctionParser. The Flow type should be updated to also accept a function, similar to verifyUserEmails and preventLoginWithUnverifiedEmail:

Suggested fix
-  sendUserEmailVerification: ?(boolean | void);
+  sendUserEmailVerification: ?(boolean | void | (EmailVerificationRequest => boolean | Promise<boolean>));

coderabbitai[bot]
coderabbitai bot previously approved these changes Feb 6, 2026
@mtrezza
Copy link
Member

mtrezza commented Feb 6, 2026

@coratgerl the PR had several issues; I found it more efficient to just go ahead and fix them:

  • booleanOrFunctionParser, preserves functions, parses env var strings to booleans. Applied to verifyUserEmails, preventLoginWithUnverifiedEmail, sendUserEmailVerification.
  • getCreatedWith() fix, auth provider signup no longer mislabeled as 'login'.
  • createSessionToken cleanup, removed duplicated fallback, added cache invalidation.
  • buildCreatedWith() helper, deduped 3 inline constructions in UsersRouter.
  • Build script mapperFor handles boolean | function union types; tightened to require both.
  • sendUserEmailVerification types for flow and TypeScript updated to include function signature.
  • added createdWith scenario to docs.
  • added more tests for auth provider signup, preventLoginWithUnverifiedEmail function, parser, build script union handling.
  • inconsistent naming convention VerifyUserEmailsRequest

@mtrezza
Copy link
Member

mtrezza commented Feb 6, 2026

@coderabbitai check whether this contains any breaking changes.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/Options/index.js`:
- Around line 46-61: Rename the Flow or TypeScript type so both use the same
identifier: choose either EmailVerificationRequest or VerifyUserEmailsRequest
and make the other match; update the Flow type declaration for
EmailVerificationRequest or rename the TS interface VerifyUserEmailsRequest
accordingly, and adjust any exports/usages (notably in verifyUserEmails and
preventLoginWithUnverifiedEmail signatures) to reference the unified name so
both type systems stay consistent.

@coderabbitai
Copy link

coderabbitai bot commented Feb 6, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

# Check the current implementation of booleanOrFunctionParser to understand backward compatibility
echo "=== Checking booleanOrFunctionParser implementation ==="
cat src/Options/parsers.js | grep -A 10 "booleanOrFunctionParser"

echo -e "\n=== Checking if verifyUserEmails previously accepted functions ==="
# Search for any historical usage patterns in the codebase
rg -n "verifyUserEmails.*function" --type js -g '!node_modules'

echo -e "\n=== Check old parser definitions before this PR ==="
# Check what parser was used before
git show HEAD~1:src/Options/Definitions.js | grep -A 5 "verifyUserEmails"

echo -e "\n=== Check for any existing function usage in tests ==="
rg -n "verifyUserEmails.*\(\s*req" spec/ --type js -A 3

echo -e "\n=== Check TypeScript definitions changes ==="
git diff HEAD~1 types/Options/index.d.ts | head -50

Length of output: 5965


🏁 Script executed:

#!/bin/bash

echo "=== Check if these options previously accepted boolean only ==="
# Look at the git log to see what the parsers were before
git log --oneline --all -20 | head -10

echo -e "\n=== Check the previous state of Options/Definitions.js ==="
# Get the parent commit
PARENT=$(git log --format=%H -n 2 | tail -1)
echo "Parent commit: $PARENT"
git show $PARENT:src/Options/Definitions.js | grep -B 2 -A 5 "verifyUserEmails\|preventLoginWithUnverifiedEmail\|sendUserEmailVerification" | head -40

echo -e "\n=== Check TypeScript type changes ==="
# Get previous TypeScript types
git show $PARENT:types/Options/index.d.ts | grep -B 2 -A 2 "verifyUserEmails\|preventLoginWithUnverifiedEmail\|sendUserEmailVerification"

echo -e "\n=== Check if any code depends on these being strictly boolean ==="
rg -n "typeof.*verifyUserEmails.*boolean" --type js -g '!node_modules' -C 2

echo -e "\n=== Check existing request object structure expectations ==="
rg -n "request\.(original|object|master|ip|installationId)" spec/ --type js | head -20

Length of output: 6183


🏁 Script executed:

#!/bin/bash

echo "=== Check the original alpha branch state (before this PR) ==="
# Fetch the base branch state
git fetch origin alpha

echo -e "\n=== Compare with original alpha branch - check Definitions.js ==="
git show origin/alpha:src/Options/Definitions.js | grep -B 2 -A 5 "verifyUserEmails\|preventLoginWithUnverifiedEmail\|sendUserEmailVerification"

echo -e "\n=== Compare with original alpha branch - check TypeScript types ==="
git show origin/alpha:types/Options/index.d.ts | grep -B 2 -A 2 "verifyUserEmails\|preventLoginWithUnverifiedEmail\|sendUserEmailVerification"

echo -e "\n=== Check if booleanOrFunctionParser existed in alpha ==="
git show origin/alpha:src/Options/parsers.js | grep -A 10 "booleanOrFunctionParser" || echo "booleanOrFunctionParser does not exist in alpha branch"

echo -e "\n=== Check original index.js types ==="
git show origin/alpha:src/Options/index.js | grep -B 5 -A 5 "verifyUserEmails\|preventLoginWithUnverifiedEmail\|sendUserEmailVerification" | head -40

Length of output: 6633


🏁 Script executed:

#!/bin/bash

echo "=== Check sendUserEmailVerification parser in current PR ==="
cat src/Options/Definitions.js | grep -B 2 -A 5 "sendUserEmailVerification"

echo -e "\n=== Check if there are any strict type checks on request objects in the codebase ==="
rg -n "Object\.keys\(request\)|Object\.entries\(request\)" --type js -g '!node_modules' -g '!spec' -C 2

echo -e "\n=== Check for validation or serialization of request objects ==="
rg -n "JSON\.stringify\(request\)|validate.*request" --type js -g '!node_modules' -g '!spec' -C 2

echo -e "\n=== Verify backward compatibility - check test results with boolean values ==="
cat spec/EmailVerificationToken.spec.js | grep -A 5 "verifyUserEmails: true" | head -20

echo -e "\n=== Check if any code explicitly checks request field names ==="
rg -n "hasOwnProperty.*request|request\.hasOwnProperty" --type js -g '!node_modules'

Length of output: 6165


@mtrezza This PR contains no breaking changes. Here's my analysis:

Backward Compatibility Preserved

Boolean values still work: The new booleanOrFunctionParser preserves existing behavior by returning functions as-is if a function is provided, otherwise delegating to booleanParser for boolean values.

Before (alpha branch):

  • verifyUserEmails: boolean | void
  • preventLoginWithUnverifiedEmail: boolean
  • sendUserEmailVerification: boolean | void
  • Parser: booleanParser only

After (this PR):

  • verifyUserEmails: boolean | ((params: VerifyUserEmailsRequest) => boolean | Promise<boolean>)
  • preventLoginWithUnverifiedEmail: boolean | ((params: VerifyUserEmailsRequest) => boolean | Promise<boolean>)
  • sendUserEmailVerification: boolean | ((params: SendEmailVerificationRequest) => boolean | Promise<boolean>)
  • Parser: booleanOrFunctionParser (accepts functions OR booleans)

Why This Is Non-Breaking

  1. Existing boolean configurations continue to work: All test cases and production configs using verifyUserEmails: true or verifyUserEmails: false will work exactly as before.

  2. Function support is purely additive: This PR adds the ability to use functions where previously only booleans were accepted. Existing code doesn't need to change.

  3. Request object fields are additive: The new createdWith field is added alongside existing fields (original, object, master, ip, installationId). Any code reading existing fields continues to work. No strict object shape validation was found in the codebase.

  4. TypeScript type widening: The type changes widen the accepted types rather than narrowing them, which is non-breaking for option consumers.

Summary

✅ All existing configurations remain valid
✅ No runtime behavior changes for current users
✅ Changes are purely additive (new functionality)
✅ Tests verify backward compatibility with boolean values

This is a feature addition with full backward compatibility.


🧠 Learnings used
Learnt from: EmpiDev
Repo: parse-community/parse-server PR: 9770
File: src/triggers.js:446-454
Timestamp: 2025-08-27T09:08:34.252Z
Learning: When analyzing function signature changes in Parse Server codebase, verify that call sites are actually incorrect before flagging them. Passing tests are a strong indicator that function calls are already properly aligned with new signatures.

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.

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.

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()`.

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.

@mtrezza mtrezza changed the title feat: Add event information on verifyUserEmails feat: Add event information to verifyUserEmails, preventLoginWithUnverifiedEmail to identify invoking signup / login action and auth provider Feb 6, 2026
@mtrezza mtrezza merged commit ed98c15 into parse-community:alpha Feb 6, 2026
19 of 23 checks passed
parseplatformorg pushed a commit that referenced this pull request Feb 6, 2026
# [9.3.0-alpha.1](9.2.1-alpha.2...9.3.0-alpha.1) (2026-02-06)

### Features

* Add event information to `verifyUserEmails`, `preventLoginWithUnverifiedEmail` to identify invoking signup / login action and auth provider ([#9963](#9963)) ([ed98c15](ed98c15))
@parseplatformorg
Copy link
Contributor

🎉 This change has been released in version 9.3.0-alpha.1

@parseplatformorg parseplatformorg added the state:released-alpha Released as alpha version label Feb 6, 2026
@coratgerl
Copy link
Contributor Author

Thanks you for your feedback !

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

Labels

state:released-alpha Released as alpha version

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add invocation event information to verifyUserEmails parameters

3 participants