Added Feat #332 Search project by name#340
Added Feat #332 Search project by name#340OfficialSubham wants to merge 1 commit intoapsinghdev:mainfrom
Conversation
|
@OfficialSubham is attempting to deploy a commit to the AJEET PRATAP SINGH's projects Team on Vercel. A member of the Team first needs to authorize it. |
📝 WalkthroughWalkthroughThis pull request extends filtering capabilities by introducing a new optional Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~15 minutes Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Tip Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord. 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 |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In `@apps/api/src/routers/projects.ts`:
- Line 24: The repoName zod schema currently allows arbitrary strings which are
later interpolated into the GitHub search template (`${trimmedRepoName}
in:name`) and can be abused to inject search qualifiers; update the schema for
repoName in routers/projects.ts to add length limits (e.g., min 1, max 100) and
a regex that only permits valid GitHub repo name characters (alphanumerics,
hyphens, underscores, dots) and disallows colons/spaces/qualifiers, and then
trim/normalize the value before passing it to the search in project.service.ts
(referencing the trimmedRepoName usage) so only validated/sanitized names reach
the GitHub query.
In `@apps/api/src/services/project.service.ts`:
- Around line 50-53: The repoName from filters is interpolated directly into the
GitHub search string (see filters.repoName and queryParts.push), so either
enforce/validate the allowed repo-name characters upstream in the router schema
or add a guard here: trim filters.repoName, validate it against an
allowed-repo-name regex (e.g. only letters, numbers, hyphen, underscore, dot),
reject or throw if it contains invalid characters, and use the
validated/sanitized value (e.g. sanitizedRepoName) when calling
queryParts.push(`${sanitizedRepoName} in:name`) to prevent injection via GitHub
search qualifiers.
In `@apps/web/src/components/ui/FiltersContainer.tsx`:
- Around line 83-92: The input in FiltersContainer is currently uncontrolled and
lacks accessibility and dark-theme styling; bind the input's value to the
filters' repoName (read from the store or props), keep the existing onChange
handler calling updateFilters({repoName: e.target.value}), add an appropriate
aria-label (e.g., aria-label="Repository name"), and replace the hard/absent
colors with design-token Tailwind classes (e.g., bg-surface-primary,
text-text-primary, placeholder:text-text-secondary) so the field clears when
resetFilters() updates repoName and matches dark theme; update the input element
in FiltersContainer accordingly.
In `@apps/web/src/utils/converter.ts`:
- Line 108: Update the inline example comment in converter.ts where it shows "//
reponame: "name"" to use the correct camelCase field name "repoName"; locate the
comment near the converter utilities (e.g., around functions that map or format
repo objects) and change "reponame" to "repoName" so the example matches the
actual field used in the code.
🧹 Nitpick comments (1)
apps/web/src/types/filter.ts (1)
50-57: Naming inconsistency inUserInputFilterProps.Other keys in this type use user-facing display names (
"Tech stack","Popularity", etc.) whilerepoNameuses camelCase. This works because the converter handles it as a direct pass-through rather than a lookup, but the mixed convention may confuse future contributors.Consider using a consistent pattern — either rename to a display-style key (e.g.,
"Repository name") and update the converter accordingly, or document whyrepoNamedeviates.
| .optional(), | ||
| pushed: z.string().optional(), | ||
| created: z.string().optional(), | ||
| repoName: z.string().optional() |
There was a problem hiding this comment.
Consider adding length validation and sanitization to repoName.
The repoName string is passed directly into the GitHub search query (see project.service.ts Line 52: `${trimmedRepoName} in:name`). A user could inject GitHub search qualifiers (e.g., "stars:>1000 is:private") to manipulate search results beyond the intended name filter.
Proposed fix
- repoName: z.string().optional()
+ repoName: z.string().max(256).regex(/^[a-zA-Z0-9._-]*$/).optional()The regex restricts input to valid GitHub repository name characters, preventing injection of search qualifiers like stars:, is:, etc.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| repoName: z.string().optional() | |
| repoName: z.string().max(256).regex(/^[a-zA-Z0-9._-]*$/).optional() |
🤖 Prompt for AI Agents
In `@apps/api/src/routers/projects.ts` at line 24, The repoName zod schema
currently allows arbitrary strings which are later interpolated into the GitHub
search template (`${trimmedRepoName} in:name`) and can be abused to inject
search qualifiers; update the schema for repoName in routers/projects.ts to add
length limits (e.g., min 1, max 100) and a regex that only permits valid GitHub
repo name characters (alphanumerics, hyphens, underscores, dots) and disallows
colons/spaces/qualifiers, and then trim/normalize the value before passing it to
the search in project.service.ts (referencing the trimmedRepoName usage) so only
validated/sanitized names reach the GitHub query.
| if(filters.repoName) { | ||
| const trimmedRepoName = filters.repoName.trim(); | ||
| queryParts.push(`${trimmedRepoName} in:name`) | ||
| } |
There was a problem hiding this comment.
User-supplied repoName is interpolated directly into the GitHub search query.
This is the injection point for the concern raised in the router's schema validation comment. If input sanitization is added at the schema level (as suggested in apps/api/src/routers/projects.ts), this code is safe. Otherwise, a malicious user could craft repoName values containing GitHub search qualifiers to manipulate results.
Ensure the upstream schema validation restricts repoName to valid repository name characters.
🤖 Prompt for AI Agents
In `@apps/api/src/services/project.service.ts` around lines 50 - 53, The repoName
from filters is interpolated directly into the GitHub search string (see
filters.repoName and queryParts.push), so either enforce/validate the allowed
repo-name characters upstream in the router schema or add a guard here: trim
filters.repoName, validate it against an allowed-repo-name regex (e.g. only
letters, numbers, hyphen, underscore, dot), reject or throw if it contains
invalid characters, and use the validated/sanitized value (e.g.
sanitizedRepoName) when calling queryParts.push(`${sanitizedRepoName} in:name`)
to prevent injection via GitHub search qualifiers.
| <div className="w-full px-6 flex justify-center h-10"> | ||
| <input | ||
| type="text" | ||
| placeholder="Enter repository name" | ||
| className="w-full rounded-md outline-none focus:outline-2 focus:outline-ox-purple px-2" | ||
| onChange={(e) => { | ||
| updateFilters({repoName: e.target.value}) | ||
| }} | ||
| /> | ||
| </div> |
There was a problem hiding this comment.
Uncontrolled input won't clear on reset, lacks accessibility and dark-theme styling.
Several issues with this input:
- Uncontrolled component: No
valueprop bound to state, so whenresetFilters()runs after search (Line 52), the input text remains stale. Per coding guidelines, prefer controlled components. - Missing
aria-label: Required by coding guidelines for accessibility on interactive elements. - Missing dark-theme colors: No
bg-*ortext-*classes — the input will render with browser defaults (white background, black text), which clashes with the dark panel (bg-[#0c0c0d]).
Proposed fix
You'll need to wire the input value to a state variable. One approach is to read repoName from the store filters:
- <div className="w-full px-6 flex justify-center h-10">
- <input
- type="text"
- placeholder="Enter repository name"
- className="w-full rounded-md outline-none focus:outline-2 focus:outline-ox-purple px-2"
- onChange={(e) => {
- updateFilters({repoName: e.target.value})
- }}
- />
- </div>
+ <div className="w-full px-6 flex justify-center h-10">
+ <input
+ type="text"
+ placeholder="Enter repository name"
+ aria-label="Search by repository name"
+ value={(filters as Record<string, string>).repoName ?? ""}
+ className="w-full rounded-md bg-[`#141418`] text-white border border-[`#28282c`] outline-none focus:outline-2 focus:outline-ox-purple px-2 placeholder:text-zinc-500"
+ onChange={(e) => {
+ updateFilters({repoName: e.target.value})
+ }}
+ />
+ </div>As per coding guidelines: "Prefer controlled components over uncontrolled", "Include proper aria labels for accessibility", and "NEVER use hardcoded hex values directly in components; ALWAYS reference colors from the design token system using Tailwind classes" — consider using semantic color tokens (e.g., bg-surface-primary, text-text-primary) if they exist in your design system instead of the hex values I used above.
🤖 Prompt for AI Agents
In `@apps/web/src/components/ui/FiltersContainer.tsx` around lines 83 - 92, The
input in FiltersContainer is currently uncontrolled and lacks accessibility and
dark-theme styling; bind the input's value to the filters' repoName (read from
the store or props), keep the existing onChange handler calling
updateFilters({repoName: e.target.value}), add an appropriate aria-label (e.g.,
aria-label="Repository name"), and replace the hard/absent colors with
design-token Tailwind classes (e.g., bg-surface-primary, text-text-primary,
placeholder:text-text-secondary) so the field clears when resetFilters() updates
repoName and matches dark theme; update the input element in FiltersContainer
accordingly.
| // forks: { min: "50", max: "1000" }, | ||
| // pushed: ">=2024-12-08", | ||
| // created: ">=2024-12-12", | ||
| // reponame: "name" |
There was a problem hiding this comment.
Typo in comment: reponame should be repoName.
The comment example uses lowercase reponame but the actual field is repoName (camelCase). This could mislead developers referencing the example.
-// reponame: "name"
+// repoName: "name"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // reponame: "name" | |
| // repoName: "name" |
🤖 Prompt for AI Agents
In `@apps/web/src/utils/converter.ts` at line 108, Update the inline example
comment in converter.ts where it shows "// reponame: "name"" to use the
correct camelCase field name "repoName"; locate the comment near the converter
utilities (e.g., around functions that map or format repo objects) and change
"reponame" to "repoName" so the example matches the actual field used in the
code.
Implemented search project by name
-UI
Added an input field in find project side bar at the top
there user can type the name of the repo they want to find
-API
Added repoName in zod validation of filterPropsSchema
added repoName in FilterProps
sending repo name to the query string.
Summary by CodeRabbit
New Features