Skip to content

Added signup for users#16

Merged
LightJack05 merged 3 commits intomainfrom
signup
Jan 13, 2026
Merged

Added signup for users#16
LightJack05 merged 3 commits intomainfrom
signup

Conversation

@LightJack05
Copy link
Member

No description provided.

@LightJack05 LightJack05 self-assigned this Jan 13, 2026
Copilot AI review requested due to automatic review settings January 13, 2026 11:01
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request implements user signup functionality for the authentication service. It replaces the stub implementation with a complete user registration endpoint that accepts username, password, and display name, hashes the password with Argon2, and stores the user in the database.

Changes:

  • Added request validation and user creation logic in the POST handler
  • Implemented database query to insert new users into the users table

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
internal/handlers/userhandler/post.go Implements user signup handler with input validation, password hashing, and user creation
internal/database/user/queries.go Adds CreateUser function to persist new users to the database

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}

salt := make([]byte, 16)
rand.Read(salt)
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

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

The error return value from rand.Read must be checked. If rand.Read fails to generate cryptographically secure random bytes, the salt could be all zeros or incomplete, which would severely compromise password security. Add error handling to ensure the salt is properly generated before proceeding with password hashing.

Suggested change
rand.Read(salt)
if n, err := rand.Read(salt); err != nil || n != len(salt) {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to generate secure salt"})
return
}

Copilot uses AI. Check for mistakes.
Comment on lines +35 to +37
if err := user.CreateUser(u.DB, userStruct); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create user"})
return
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

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

The CreateUser function does not differentiate between different types of database errors. When a duplicate username is inserted (violating the UNIQUE constraint), the generic "Failed to create user" message is returned instead of a more specific error like "Username already exists". This makes it difficult for clients to handle duplicate username scenarios appropriately. Consider checking for unique constraint violations and returning a more specific error or status code.

Copilot uses AI. Check for mistakes.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 8 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

syscall.Kill(syscall.Getpid(), syscall.SIGABRT)
}


Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

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

There's an extra blank line here that should be removed to maintain consistent code formatting.

Suggested change

Copilot uses AI. Check for mistakes.
c.AbortWithStatus(http.StatusNotImplemented)
var body userBody
if err := c.ShouldBindJSON(&body); err != nil {
c.Error(err)
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

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

The error message returned to the client exposes the internal error details via err.Error(). This can leak sensitive information about the system's internals, including validation logic, field names, or other implementation details. Consider returning a more generic error message to the client while logging the detailed error server-side for debugging purposes.

Copilot uses AI. Check for mistakes.
Comment on lines +24 to +32
func CreateUser(db *sql.DB, user *User) error {
// insert into table users
sqlStatement := `INSERT INTO users (username, display_name, password_hash) VALUES ($1, $2, $3)`
_, err := db.Exec(sqlStatement, user.Username, user.DisplayName, user.PasswordHash)
if err != nil {
return fmt.Errorf("failed to create user: %v", err)
}
return nil
}
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

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

There's no validation to check if the username already exists before attempting insertion. While the database has a UNIQUE constraint that will prevent duplicates, it's more efficient and user-friendly to check for existence first and return a clear error message. This would avoid unnecessary database constraint violations and provide better error handling.

Copilot uses AI. Check for mistakes.
)

type userBody struct {
Username string `json:"username" binding:"required"`
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

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

The username validation only checks that it's required, but doesn't validate the format or length. Consider adding validation rules such as maximum length (to match the database VARCHAR(50) constraint), allowed characters (e.g., alphanumeric and certain special characters), and potentially a minimum length to prevent extremely short usernames.

Suggested change
Username string `json:"username" binding:"required"`
Username string `json:"username" binding:"required,min=3,max=50,alphanum"`

Copilot uses AI. Check for mistakes.
type userBody struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required,min=8"`
DisplayName string `json:"display_name" binding:"required"`
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

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

The display_name validation only checks that it's required, but doesn't validate the length. The database has a VARCHAR(100) constraint, so attempting to insert a display_name longer than 100 characters will cause a database error. Add a max length validation (e.g., binding:"required,max=100") to catch this at the API level.

Suggested change
DisplayName string `json:"display_name" binding:"required"`
DisplayName string `json:"display_name" binding:"required,max=100"`

Copilot uses AI. Check for mistakes.
Comment on lines +28 to +41

salt := make([]byte, 16)
_, err := rand.Read(salt)
if err != nil {
log.Println("rand.Read returned an error, this should not happen! (This means the OS is unable to provide proper crypto APIs. Do NOT run this program here.)")
log.Println("Tearing down the application with SIGABRT...")
syscall.Kill(syscall.Getpid(), syscall.SIGABRT)
}


userStruct := &user.User{
Username: body.Username,
DisplayName: body.DisplayName,
PasswordHash: crypto.HashPassword(body.Password, salt),
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

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

The salt generated for password hashing is not being stored anywhere in the database. Without storing the salt, password verification will be impossible because you won't be able to recreate the same hash during login. The salt needs to be either:

  1. Stored in a separate column in the users table, or
  2. Embedded within the password hash string itself (which the argon-hash-utils library may already do via the ToString() method)

You should verify whether the argon-hash-utils library's ToString() method embeds the salt in the output string, or if you need to add a salt column to the database schema and User struct.

Copilot uses AI. Check for mistakes.
Comment on lines +43 to +45

if err := user.CreateUser(u.DB, userStruct); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create user"})
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

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

The error handling when a duplicate username is attempted doesn't provide a meaningful response to the user. The database has a UNIQUE constraint on the username column, so attempting to create a duplicate user will result in a database error. This should be caught and returned as a specific error (e.g., HTTP 409 Conflict with "Username already exists") rather than a generic "Failed to create user" internal server error. Consider checking the error type to distinguish between duplicate key violations and other database errors.

Copilot uses AI. Check for mistakes.
Comment on lines +31 to +33
if err != nil {
log.Println("rand.Read returned an error, this should not happen! (This means the OS is unable to provide proper crypto APIs. Do NOT run this program here.)")
log.Println("Tearing down the application with SIGABRT...")
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

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

Using syscall.Kill with SIGABRT to terminate the application is an extreme reaction that bypasses graceful shutdown procedures. This can lead to resource leaks, incomplete transactions, and difficulty in debugging. Consider using panic() or log.Fatal() instead, which allow for proper cleanup via defer statements and provide better stack traces. If you need to signal a critical system issue, panic is the Go idiom for unrecoverable errors.

Copilot uses AI. Check for mistakes.
@LightJack05 LightJack05 merged commit 31c0788 into main Jan 13, 2026
6 checks passed
@LightJack05 LightJack05 deleted the signup branch January 13, 2026 11:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant