fix(core): validate job names and unique keys at the API boundary#269
fix(core): validate job names and unique keys at the API boundary#269
Conversation
🦋 Changeset detectedLatest commit: 326aacb The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
Reject empty, whitespace-only, and control-character identifiers before worker registration or scheduling reaches MongoDB operations. Preserve existing valid printable job names used by schedule() tests while failing fast on malformed public identifiers.
8c4cdb3 to
d5d6a6a
Compare
📝 WalkthroughWalkthroughThis PR adds input validation for job identifiers (names and unique keys) at the public API boundary. New validators check identifiers for empty values, length constraints, and invalid characters. A new error type Changes
Possibly Related PRs
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~20 minutes
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan
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 |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #269 +/- ##
==========================================
+ Coverage 97.27% 97.35% +0.07%
==========================================
Files 26 27 +1
Lines 1249 1286 +37
Branches 315 332 +17
==========================================
+ Hits 1215 1252 +37
Misses 34 34 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
🧹 Nitpick comments (4)
packages/core/tests/unit/services/job-scheduler.test.ts (1)
161-166: Use an invalid cron here to prove validation precedence.This only proves the name check happens before MongoDB calls. With a valid cron string, the test still passes if
schedule()parses cron before validatingname. Make the cron invalid too and assert thatInvalidJobIdentifierErrorwins.🧪 Tighten the ordering assertion
it('should reject invalid scheduled job names before parsing cron', async () => { - await expect(scheduler.schedule('0 * * * *', 'bad name', {})).rejects.toThrow( + await expect(scheduler.schedule('invalid cron', 'bad name', {})).rejects.toThrow( InvalidJobIdentifierError, ); expect(ctx.mockCollection.insertOne).not.toHaveBeenCalled(); });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/core/tests/unit/services/job-scheduler.test.ts` around lines 161 - 166, The test currently only uses a valid cron which doesn't prove name-validation runs before cron parsing; update the test in job-scheduler.test.ts to pass an invalid cron string (e.g., malformed cron) along with the invalid job name to scheduler.schedule so the call would also fail cron parsing if order were reversed, then assert that InvalidJobIdentifierError is still thrown and that ctx.mockCollection.insertOne was not called; reference the schedule(...) call and InvalidJobIdentifierError to locate and modify the test.packages/core/tests/unit/job-identifiers.test.ts (1)
15-25: Cover the two job-name rejection branches more directly.The suite never hits the whitespace-only branch, and the current control-character case uses
\n, which would still fail if the control-character check regressed because newlines are also whitespace. Add a' 'case and use a non-whitespace control character such as\u0000.🧪 Suggested test additions
it('rejects empty job names', () => { expect(() => validateJobName('')).toThrow(InvalidJobIdentifierError); }); + + it('rejects whitespace-only job names', () => { + expect(() => validateJobName(' ')).toThrow(InvalidJobIdentifierError); + }); it('rejects names with whitespace', () => { expect(() => validateJobName('email send')).toThrow(InvalidJobIdentifierError); }); it('rejects names with control characters', () => { - expect(() => validateJobName('email\nsend')).toThrow(InvalidJobIdentifierError); + expect(() => validateJobName('email\u0000send')).toThrow(InvalidJobIdentifierError); });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/core/tests/unit/job-identifiers.test.ts` around lines 15 - 25, Add two more unit tests for validateJobName to directly exercise the whitespace-only and non-whitespace control-character branches: add a case that calls validateJobName(' ') and asserts it throws InvalidJobIdentifierError (covers whitespace-only rejection), and add a case that calls validateJobName('\u0000') and asserts it throws InvalidJobIdentifierError (covers control-character rejection using a non-whitespace control char). Ensure both tests use the same pattern as existing tests (expect(() => validateJobName(...)).toThrow(InvalidJobIdentifierError)) and place them alongside the other job-name rejection tests.packages/core/src/shared/errors.ts (1)
205-213: Don't logerror.valueverbatim in the example.This field can contain control characters or sensitive deduplication keys, so the current example normalizes a logging pattern that's easy to misuse. Prefer
field+message, or a sanitized preview.🛡️ Safer example
* } catch (error) { * if (error instanceof InvalidJobIdentifierError) { - * console.error(`Invalid ${error.field}:`, error.value); + * console.error(`Invalid ${error.field}: ${error.message}`); * } * }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/core/src/shared/errors.ts` around lines 205 - 213, The example in the InvalidJobIdentifierError usage logs error.value verbatim which may expose control characters or sensitive deduplication keys; update the example that references InvalidJobIdentifierError (and the variables error.field / error.value) to avoid printing error.value directly—log a descriptive message using error.field and a sanitized preview or message instead (e.g., include field and a redacted/trimmed snippet or a constant placeholder) so the example demonstrates safe logging practices without exposing raw values.packages/core/tests/unit/monque.test.ts (1)
193-199: Consider adding one explicit control-character worker-name case.This test covers whitespace-in-name well. Adding a case like
'\n'or'\u0000'would lock the control-character requirement directly atregister()boundary too.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/core/tests/unit/monque.test.ts` around lines 193 - 199, Add an explicit control-character case to the invalid-name test: call monque.register with a control-only name such as '\n' or '\u0000' (using the same handler used in the test) and assert it throws InvalidJobIdentifierError, so the register() boundary is verified for control characters as well as whitespace.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@packages/core/src/shared/errors.ts`:
- Around line 205-213: The example in the InvalidJobIdentifierError usage logs
error.value verbatim which may expose control characters or sensitive
deduplication keys; update the example that references InvalidJobIdentifierError
(and the variables error.field / error.value) to avoid printing error.value
directly—log a descriptive message using error.field and a sanitized preview or
message instead (e.g., include field and a redacted/trimmed snippet or a
constant placeholder) so the example demonstrates safe logging practices without
exposing raw values.
In `@packages/core/tests/unit/job-identifiers.test.ts`:
- Around line 15-25: Add two more unit tests for validateJobName to directly
exercise the whitespace-only and non-whitespace control-character branches: add
a case that calls validateJobName(' ') and asserts it throws
InvalidJobIdentifierError (covers whitespace-only rejection), and add a case
that calls validateJobName('\u0000') and asserts it throws
InvalidJobIdentifierError (covers control-character rejection using a
non-whitespace control char). Ensure both tests use the same pattern as existing
tests (expect(() => validateJobName(...)).toThrow(InvalidJobIdentifierError))
and place them alongside the other job-name rejection tests.
In `@packages/core/tests/unit/monque.test.ts`:
- Around line 193-199: Add an explicit control-character case to the
invalid-name test: call monque.register with a control-only name such as '\n' or
'\u0000' (using the same handler used in the test) and assert it throws
InvalidJobIdentifierError, so the register() boundary is verified for control
characters as well as whitespace.
In `@packages/core/tests/unit/services/job-scheduler.test.ts`:
- Around line 161-166: The test currently only uses a valid cron which doesn't
prove name-validation runs before cron parsing; update the test in
job-scheduler.test.ts to pass an invalid cron string (e.g., malformed cron)
along with the invalid job name to scheduler.schedule so the call would also
fail cron parsing if order were reversed, then assert that
InvalidJobIdentifierError is still thrown and that ctx.mockCollection.insertOne
was not called; reference the schedule(...) call and InvalidJobIdentifierError
to locate and modify the test.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 5325cc0b-bd77-459b-8012-9333349a4b75
📒 Files selected for processing (12)
.changeset/blue-rats-train.mdpackages/core/src/index.tspackages/core/src/scheduler/monque.tspackages/core/src/scheduler/services/job-scheduler.tspackages/core/src/shared/errors.tspackages/core/src/shared/index.tspackages/core/src/shared/utils/index.tspackages/core/src/shared/utils/job-identifiers.tspackages/core/tests/unit/errors.test.tspackages/core/tests/unit/job-identifiers.test.tspackages/core/tests/unit/monque.test.tspackages/core/tests/unit/services/job-scheduler.test.ts
…and control characters
Reject empty, whitespace-only, and control-character identifiers before worker registration or scheduling reaches MongoDB operations.
Preserve existing valid printable job names used by schedule() tests while failing fast on malformed public identifiers.
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
InvalidJobIdentifierError,validateJobName, andvalidateUniqueKeyutilities.