Lightweight and easily self-hostable Git forge. git.poy.ooo
git-forge selfhosting homebrew
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118package app
import ( "errors" md "farga/app/middleware" "farga/app/templating" db "farga/db" "farga/db/types" "farga/lib" "io" "net/http" "strings")
type RegisterForm struct { Name string `form:"name" validate:"required,max=40"` Handle string `form:"handle" validate:"required,min=3,max=30"` Email string `form:"email" validate:"required,email"` Password string `form:"password" validate:"required,min=8"`}
type LoginForm struct { Email string `form:"email" validate:"required,email"` Password string `form:"password" validate:"required,min=8"`}
func (a *App) login(w http.ResponseWriter, r *http.Request) { switch r.Method { case "GET": templating.Render(w, r, "base", "login") case "POST": form, _ := md.Form[LoginForm](r) user, err := a.Store.LoginUser(form.Email, form.Password) if err != nil && (errors.Is(err, db.UserNotFound) || errors.Is(err, db.IncorrectPassword)) { // user not found or incorrect password http.Redirect(w, r, "/auth/login?err=InvalidCredentials", http.StatusSeeOther) return }
session, err := a.Store.NewSession(&user.ID)
if err != nil { io.WriteString(w, "Something went wrong while creating your session.") return }
lib.SetCookie(w, "session", session.ID.String()) http.Redirect(w, r, "/?msg=AuthSuccess", http.StatusSeeOther) }}
func (a *App) register(w http.ResponseWriter, r *http.Request) { switch r.Method { case "GET": templating.Render(w, r, "base", "register", map[string]any{ "HandleRegex": lib.HandleRegex.String(), }) case "POST": form, _ := md.Form[RegisterForm](r)
if !lib.ValidateHandle(form.Handle) { http.Redirect(w, r, "?err=UserInvalidHandle", http.StatusSeeOther) return }
password, err := lib.GenerateHash(form.Password) if err != nil { http.Error(w, "Something went wrong while generating your password's hash. Please try again!", 500) return } user := types.User{ Name: strings.TrimSpace(form.Name), Handle: strings.TrimSpace(form.Handle), Email: strings.TrimSpace(form.Email), PasswordHash: password, Config: types.UserConfig{ GitDefaultBranch: lib.GitDefaultBranch, }, }
err = a.Store.NewUser(&user)
if err != nil { constrainedField := strings.Replace(err.Error(), "UNIQUE constraint failed: users.", "That ", 1) + " has already been claimed." http.Error(w, constrainedField, 500) return }
session, err := a.Store.NewSession(&user.ID)
if err != nil { io.WriteString(w, "Goddammit! Something went wrong while creating your session. Try logging in instead.") return }
lib.SetCookie(w, "session", session.ID.String())
http.Redirect(w, r, "/?msg=AuthSuccess", http.StatusTemporaryRedirect) }}
func (a *App) logout(w http.ResponseWriter, r *http.Request) { switch r.Method { case "GET": templating.Render(w, r, "base", "logout") case "POST": session := r.Context().Value(lib.SessionKey).(string)
err := a.Store.RemoveSession(session) if err != nil { io.WriteString(w, "Something went wrong while deleting your session: "+err.Error()) return }
lib.DeleteCookie(w, "session") http.Redirect(w, r, "/auth/login?msg=LogoutSuccess", http.StatusFound) }}