Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 3 additions & 3 deletions backend/validators/authValidator.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ const signupSchema = z.object({
.min(3, "Username must be at least 3 characters long")
.max(30, "Username must be at most 30 characters long")
.regex(/^[a-zA-Z0-9_]+$/, "Username can only contain letters, numbers, and underscores")
,
,

email: z.string()
.trim()
.toLowerCase()
Expand All @@ -18,7 +18,7 @@ const signupSchema = z.object({
.min(8, "Password must be at least 8 characters long")
.max(100, "Password must be at most 100 characters long")
.regex(
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]+$/,
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}+$/,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Does JavaScript (ECMAScript regex) support possessive quantifiers like {8,}+? If not, what is the correct equivalent for enforcing length alongside .min(8) validation?

💡 Result:

No. JavaScript regular expressions (ECMAScript) do not support possessive quantifier syntax like {8,}+; attempting it results in a syntax error (e.g., “Nothing to Repeat”) because ECMAScript regex only recognizes greedy quantifiers ({8,}) and non-greedy ones ({8,}?), not possessive ones [1][2]. Correct equivalent (enforce minimum length / no .min(8)-style “backtracking control”): use a normal quantifier with a length anchor. - If you want “length at least 8” for the whole input: ^.{8,}$ (or with a specific character class, e.g. ^[A-Za-z0-9]{8,}$). - If you only need to match a substring of length ≥ 8 inside a larger string: .{8,}. Note: possessive quantifiers are about preventing backtracking for performance/engine control, not about adding a “minimum length” constraint. For length validation in regex, use quantifiers {n,} (or {n,m}) and anchors like ^ and $ as shown above [2][3].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the region around the targeted line
nl -ba backend/validators/authValidator.js | sed -n '1,120p'

# Focus on password schema/regex area
rg -n "password|regex|signupSchema|min\\(8\\)" backend/validators/authValidator.js || true

Repository: GitMetricsLab/github_tracker

Length of output: 115


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="backend/validators/authValidator.js"

# Print a small window around the cited line (21) using cat -n
if [ -f "$FILE" ]; then
  cat -n "$FILE" | sed -n '1,80p'
else
  echo "Missing file: $FILE"
  exit 1
fi

# Narrow search for password/regex/min(8)
rg -n "password|signupSchema|regex|min\\(8\\)|\\{8,\\}\\+" "$FILE" || true

Repository: GitMetricsLab/github_tracker

Length of output: 1824


Fix invalid password regex quantifier ({8,}+)
backend/validators/authValidator.js contains {8,}+ in signupSchema.password’s regex; ECMAScript regex doesn’t support possessive quantifiers like this, so it’s a regex syntax error that can prevent the module from loading (breaking signup validation). Replace {8,}+ with a valid quantifier such as {8,} (length is already enforced via .min(8) / .max(100)).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/validators/authValidator.js` at line 21, The regex for
signupSchema.password contains an invalid possessive quantifier `{8,}+` which is
a syntax error; update the pattern used in signupSchema (the password regex) to
remove the possessive plus and use a standard quantifier such as `{8,}` (or rely
on existing .min(8)/.max(100) validations) so the regex becomes valid ECMAScript
and signup validation can load correctly. Ensure you edit the pattern in the
signupSchema.password definition where the regex is declared.

'Password must contain uppercase, lowercase, number, and special character'
),
});
Expand Down
57 changes: 24 additions & 33 deletions src/pages/Signup/Signup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ const SignUp: React.FC = () => {
if (name === "username") {
if (!value.trim()) {
errorMessage = "Username is required";
} else if (!/^[A-Za-z\s]+$/.test(value)) {
errorMessage = "Only letters are allowed";
} else if (!/^[a-zA-Z0-9_]+$/.test(value)) {
errorMessage = "Username can contain only letters, numbers, and underscores";
}
}
if (name === "email") {
Expand Down Expand Up @@ -77,9 +77,7 @@ const SignUp: React.FC = () => {
: "";
const passwordError = !formData.password.trim()
? "Password is required"
: !/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&]{8,}$/.test(
formData.password,
)
: !/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&]{8,}$/.test(formData.password)
? "Password must be 8+ characters with letters and numbers"
: "";
if (usernameError || emailError || passwordError) {
Expand Down Expand Up @@ -118,32 +116,27 @@ const SignUp: React.FC = () => {

return (
<div
className={`min-h-screen h-full w-full flex items-center justify-center relative overflow-hidden ${
mode === "dark"
? "bg-gradient-to-br from-slate-900 via-purple-900 to-slate-900"
: "bg-gradient-to-br from-slate-100 via-purple-100 to-slate-100"
}`}
className={`min-h-screen h-full w-full flex items-center justify-center relative overflow-hidden ${mode === "dark"
? "bg-gradient-to-br from-slate-900 via-purple-900 to-slate-900"
: "bg-gradient-to-br from-slate-100 via-purple-100 to-slate-100"
}`}
>
<div className="absolute inset-0">
<div
className={`absolute -top-40 -right-40 w-96 h-96 ${
mode === "dark" ? "bg-purple-500" : "bg-purple-300"
} rounded-full blur-3xl opacity-30 animate-pulse`}
className={`absolute -top-40 -right-40 w-96 h-96 ${mode === "dark" ? "bg-purple-500" : "bg-purple-300"
} rounded-full blur-3xl opacity-30 animate-pulse`}
/>
<div
className={`absolute -bottom-40 -left-40 w-96 h-96 ${
mode === "dark" ? "bg-blue-500" : "bg-blue-300"
} rounded-full blur-3xl opacity-30 animate-pulse`}
className={`absolute -bottom-40 -left-40 w-96 h-96 ${mode === "dark" ? "bg-blue-500" : "bg-blue-300"
} rounded-full blur-3xl opacity-30 animate-pulse`}
/>
<div
className={`absolute top-40 left-40 w-96 h-96 ${
mode === "dark" ? "bg-pink-500" : "bg-pink-300"
} rounded-full blur-3xl opacity-30 animate-pulse`}
className={`absolute top-40 left-40 w-96 h-96 ${mode === "dark" ? "bg-pink-500" : "bg-pink-300"
} rounded-full blur-3xl opacity-30 animate-pulse`}
/>
<div
className={`absolute top-1/2 right-1/4 w-64 h-64 ${
mode === "dark" ? "bg-indigo-500" : "bg-indigo-300"
} rounded-full blur-2xl opacity-20 animate-pulse delay-1000`}
className={`absolute top-1/2 right-1/4 w-64 h-64 ${mode === "dark" ? "bg-indigo-500" : "bg-indigo-300"
} rounded-full blur-2xl opacity-20 animate-pulse delay-1000`}
/>
</div>

Expand Down Expand Up @@ -177,16 +170,15 @@ const SignUp: React.FC = () => {
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.2 }}
className={`rounded-3xl p-6 sm:p-10 shadow-2xl border ${
mode === "dark"
? "bg-white/10 backdrop-blur-xl border-white/20 text-white"
: "bg-white border-gray-200 text-black"
}`}
className={`rounded-3xl p-6 sm:p-10 shadow-2xl border ${mode === "dark"
? "bg-white/10 backdrop-blur-xl border-white/20 text-white"
: "bg-white border-gray-200 text-black"
}`}
>

<h2
className={`text-2xl font-bold text-center mb-8 ${
mode === "dark" ? "text-white" : "text-gray-800"
}`}
className={`text-2xl font-bold text-center mb-8 ${mode === "dark" ? "text-white" : "text-gray-800"
}`}
>
Create Account
</h2>
Expand Down Expand Up @@ -300,9 +292,8 @@ const SignUp: React.FC = () => {
</div>

<div
className={`${
mode === "dark" ? "from-slate-900" : "from-slate-100"
} absolute bottom-0 left-0 w-full h-20 bg-gradient-to-t to-transparent pointer-events-none`}
className={`${mode === "dark" ? "from-slate-900" : "from-slate-100"
} absolute bottom-0 left-0 w-full h-20 bg-gradient-to-t to-transparent`}
/>
</div>
);
Expand Down
Loading