Improved email validation, added splash screen

This commit is contained in:
yunginnanet 2020-01-11 15:43:22 -08:00 committed by GitHub
parent a5f15138dc
commit 309c8facd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

131
main.go
View File

@ -4,13 +4,20 @@ import (
"database/sql"
"encoding/json"
"fmt"
"github.com/badoux/checkmail"
"github.com/didip/tollbooth"
"github.com/gorilla/csrf"
"github.com/gorilla/mux"
_ "github.com/lib/pq"
"github.com/lukesampson/figlet/figletlib"
"github.com/matcornic/hermes/v2"
"golang.org/x/crypto/bcrypt"
"html/template"
"io/ioutil"
"log"
"net/http"
"os"
"path/filepath"
"regexp"
"strings"
"time"
@ -34,23 +41,50 @@ type Credentials struct {
}
func main() {
Splash()
initDB()
HTTPServ()
}
func Splash() {
cwd, _ := os.Getwd()
fontsdir := filepath.Join(cwd, "fonts")
f, err := figletlib.GetFontByName(fontsdir, "Soft")
if err != nil {
return
}
figletlib.PrintMsg("MapyWeb", f, 150, f.Settings(), "left")
fmt.Println("------------- v0.1 - kayos - ra - queed squad -------------")
fmt.Println("")
}
func HTTPServ() {
r := mux.NewRouter()
r.HandleFunc("/", IndexShow)
r.HandleFunc("/register", RegForm)
r.HandleFunc("/login", LoginForm)
r.HandleFunc("/EmailTest", EmailTest)
r.HandleFunc("/login/submit", Login).Methods("POST")
r.HandleFunc("/register/submit", Register).Methods("POST")
initDB()
r.Handle("/login/submit", tollbooth.LimitFuncHandler(tollbooth.NewLimiter(1, nil), Login)).Methods("POST")
r.Handle("/register/submit", tollbooth.LimitFuncHandler(tollbooth.NewLimiter(1, nil), Register)).Methods("POST")
fmt.Println("Web server starting on port 42069")
log.Fatal(http.ListenAndServe(":42069", csrf.Protect([]byte("7e3e2a60a55a223589f0bf218f23251619182602ae19fd829803d18645379f66"), csrf.Secure(false))(r)))
}
func initDB() {
var err error
fmt.Println("Connecting to postgresql database...")
db, err = sql.Open("postgres", "host=localhost port=5432 user=postgres password=sqldawg! dbname=maplestory sslmode=disable")
if err != nil {
panic(err)
} else {
fmt.Println("Connection succsesful!")
}
}
@ -65,6 +99,49 @@ func rowExists(query string, args ...interface{}) bool {
return exists
}
func EmailTest(w http.ResponseWriter, r *http.Request) {
h := hermes.Hermes{
Product: hermes.Product{
Name: "MapyWeb",
Link: "https://smoqueed.com/",
Logo: "https://tcp.direct/maplestory.png",
},
}
email := hermes.Email{
Body: hermes.Body{
Name: "MapyBoi",
Intros: []string{
"Welcome to Mapy!",
},
Actions: []hermes.Action{
{
Instructions: "To get started, please click here:",
Button: hermes.Button{
Color: "#22BC66", // Optional action button color
Text: "Confirm your account",
Link: "https://smoqueed.com/confirm?token=d9729feb74992cc3482b350163a1a010",
},
},
},
Outros: []string{
"Need help, or have questions? Join our discord! https://discord.gg/something",
},
},
}
emailBody, err := h.GenerateHTML(email)
if err != nil {
panic(err) // Tip: Handle error with something else than a panic ;)
}
err = ioutil.WriteFile("preview.html", []byte(emailBody), 0644)
if err != nil {
panic(err) // Tip: Handle error with something else than a panic ;)
}
}
func IndexShow(w http.ResponseWriter, r *http.Request) {
ip := strings.Split(r.RemoteAddr, ":")[0]
fmt.Println(ip)
@ -104,10 +181,11 @@ func Register(w http.ResponseWriter, r *http.Request) {
EmailInput := r.PostFormValue("email")
GenderInput := r.PostFormValue("gender")
fmt.Println(UsernameInput)
fmt.Println(PasswordInput)
fmt.Println(EmailInput)
fmt.Println(GenderInput)
//debug outputs
//fmt.Println(UsernameInput)
//fmt.Println(PasswordInput)
//fmt.Println(EmailInput)
//fmt.Println(GenderInput)
// Verify Gender value is either 0(female) or 1(male)
// if not just silently send them a 400 because wtf
@ -118,9 +196,11 @@ func Register(w http.ResponseWriter, r *http.Request) {
}
//Validates email addresses and makes sure they are under 254 characters
var rxEmail = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")
if len(EmailInput) > 254 || !rxEmail.MatchString(EmailInput) {
err0 := checkmail.ValidateFormat(EmailInput)
err1 := checkmail.ValidateHost(EmailInput)
if err0 != nil || err1 != nil {
fmt.Println("ERROR: that is not a valid email address!")
fmt.Println(w, "ERROR: that is not a valid email address!")
return
}
@ -142,8 +222,7 @@ func Register(w http.ResponseWriter, r *http.Request) {
//Check if email is taken
if rowExists("Select id from maplestory.accounts where email=$1", EmailInput) {
fmt.Println("ERROR: Email exists.")
fmt.Fprintf(w, "ERROR: Email exists.")
return
}
@ -162,28 +241,21 @@ func Register(w http.ResponseWriter, r *http.Request) {
}
func Login(w http.ResponseWriter, r *http.Request) {
creds := &Credentials{}
err := json.NewDecoder(r.Body).Decode(creds)
if err != nil {
// If there is something wrong with the request body, return a 400 status
w.WriteHeader(http.StatusBadRequest)
return
}
UsernameInput := r.PostFormValue("username")
PasswordInput := r.PostFormValue("password")
// Get the existing entry present in the database for the given username
result := db.QueryRow("select password from users where username=$1", creds.Username)
if err != nil {
// If there is an issue with the database, return a 500 error
w.WriteHeader(http.StatusInternalServerError)
return
}
result := db.QueryRow("SELECT password FROM maplestory.accounts WHERE username=$1", UsernameInput)
// We create another instance of `Credentials` to store the credentials we get from the database
storedCreds := &Credentials{}
// Store the obtained password in `storedCreds`
err = result.Scan(&storedCreds.Password)
err := result.Scan(&storedCreds.Password)
if err != nil {
// If an entry with the username does not exist, send an "Unauthorized"(401) status
if err == sql.ErrNoRows {
w.WriteHeader(http.StatusUnauthorized)
fmt.Println("Login failed!")
fmt.Fprintf(w, "Login failed!")
return
}
// If the error is of any other type, send a 500 status
@ -192,11 +264,14 @@ func Login(w http.ResponseWriter, r *http.Request) {
}
// Compare the stored hashed password, with the hashed version of the password that was received
if err = bcrypt.CompareHashAndPassword([]byte(storedCreds.Password), []byte(creds.Password)); err != nil {
if err = bcrypt.CompareHashAndPassword([]byte(storedCreds.Password), []byte(PasswordInput)); err != nil {
// If the two passwords don't match, return a 401 status
w.WriteHeader(http.StatusUnauthorized)
}
// If we reach this point, that means the users password was correct, and that they are authorized
// The default 200 status is sent
fmt.Println("Login successful!")
fmt.Fprintf(w, "Login successful!")
}