chore: added register to new interface
This commit is contained in:
parent
1c0d6a309b
commit
32771c7422
@ -385,6 +385,10 @@ func (c Context) SendJSONStatus(w http.ResponseWriter, status int, dat any) *Err
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Context) JsonBadRequest(w http.ResponseWriter, dat any) *Error {
|
||||
return c.SendJSONStatus(w, http.StatusBadRequest, dat)
|
||||
}
|
||||
|
||||
func (c Context) Error400(err error, message string, w http.ResponseWriter, path string, base string, data AnyMap) *Error {
|
||||
c.SetReportCaller(true)
|
||||
c.Logger.Error(message)
|
||||
|
125
users.go
125
users.go
@ -10,6 +10,7 @@ import (
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
|
||||
dbtypes "git.andr3h3nriqu3s.com/andr3/fyp/logic/db_types"
|
||||
. "git.andr3h3nriqu3s.com/andr3/fyp/logic/utils"
|
||||
)
|
||||
|
||||
@ -41,7 +42,6 @@ func genToken() string {
|
||||
}
|
||||
|
||||
func generateToken(db *sql.DB, email string, password string) (string, bool) {
|
||||
|
||||
row, err := db.Query("select id, salt, password from users where email = $1;", email)
|
||||
if err != nil || !row.Next() {
|
||||
return "", false
|
||||
@ -60,7 +60,7 @@ func generateToken(db *sql.DB, email string, password string) (string, bool) {
|
||||
panic("TODO handle better! Somethign is wrong with salt being stored in the database")
|
||||
}
|
||||
|
||||
if bcrypt.CompareHashAndPassword([]byte(db_password), append([]byte(password), bytes_salt...)) != nil {
|
||||
if err = bcrypt.CompareHashAndPassword([]byte(db_password), append([]byte(password), bytes_salt...)); err != nil {
|
||||
return "", false
|
||||
}
|
||||
|
||||
@ -80,8 +80,8 @@ func usersEndpints(db *sql.DB, handle *Handle) {
|
||||
if c.Mode == JSON {
|
||||
|
||||
type UserLogin struct {
|
||||
Email string `json:email`
|
||||
Password string `json:password`
|
||||
Email string `json:"email"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
var dat UserLogin
|
||||
@ -90,27 +90,34 @@ func usersEndpints(db *sql.DB, handle *Handle) {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
/*if (dat["email"] == nil || dat["password"] == nil) {
|
||||
// TODO improve this
|
||||
c.Logger.Warn("Email or password are empty")
|
||||
return c.Error500(nil)
|
||||
}*/
|
||||
|
||||
// TODO Give this to the generateToken function
|
||||
expiration := time.Now().Add(24 * time.Hour)
|
||||
token, login := generateToken(db, dat.Email, dat.Password)
|
||||
if !login {
|
||||
return c.SendJSONStatus(w, http.StatusUnauthorized, "Email or password are incorrect")
|
||||
}
|
||||
|
||||
user, err := dbtypes.UserFromToken(c.Db, token)
|
||||
if err != nil {
|
||||
return c.Error500(err)
|
||||
}
|
||||
|
||||
cookie := &http.Cookie{Name: "auth", Value: token, HttpOnly: false, Expires: expiration}
|
||||
http.SetCookie(w, cookie)
|
||||
type UserReturn struct {
|
||||
Token string `json:"token"`
|
||||
Id string `json:"id"`
|
||||
UserType int `json:"user_type"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
w.Header().Set("Location", "/")
|
||||
w.WriteHeader(http.StatusSeeOther)
|
||||
return nil
|
||||
userReturn := UserReturn{
|
||||
Token: token,
|
||||
Id: user.Id,
|
||||
UserType: user.UserType,
|
||||
Username: user.Username,
|
||||
Email: user.Email,
|
||||
}
|
||||
|
||||
return c.SendJSON(w, userReturn)
|
||||
}
|
||||
|
||||
r.ParseForm()
|
||||
@ -149,7 +156,87 @@ func usersEndpints(db *sql.DB, handle *Handle) {
|
||||
handle.GetHTML("/register", AnswerTemplate("register.html", nil, 0))
|
||||
handle.Post("/register", func(w http.ResponseWriter, r *http.Request, c *Context) *Error {
|
||||
if c.Mode == JSON {
|
||||
return &Error{Code: http.StatusNotFound}
|
||||
type UserLogin struct {
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
var dat UserLogin
|
||||
|
||||
if err := c.ToJSON(r, &dat); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(dat.Username) == 0 || len(dat.Password) == 0 || len(dat.Email) == 0 {
|
||||
return c.SendJSONStatus(w, http.StatusBadRequest, "Please provide a valid json");
|
||||
}
|
||||
|
||||
rows, err := db.Query("select username, email from users where username=$1 or email=$2;", dat.Username, dat.Email)
|
||||
if err != nil {
|
||||
return c.Error500(err);
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
if rows.Next() {
|
||||
var db_username string
|
||||
var db_email string
|
||||
err = rows.Scan(&db_username, &db_email)
|
||||
if err != nil {
|
||||
return c.Error500(err)
|
||||
}
|
||||
if (db_email == dat.Email) {
|
||||
return c.SendJSONStatus(w, http.StatusBadRequest, "Email already in use!")
|
||||
}
|
||||
if (db_username == dat.Username) {
|
||||
return c.SendJSONStatus(w, http.StatusBadRequest, "Username already in use!")
|
||||
}
|
||||
panic("Unrechable")
|
||||
}
|
||||
|
||||
if len([]byte(dat.Password)) > 68 {
|
||||
return c.JsonBadRequest(w, "Password is to long!")
|
||||
}
|
||||
|
||||
salt := generateSalt()
|
||||
hash_password, err := hashPassword(dat.Password, salt)
|
||||
if err != nil {
|
||||
return c.Error500(err)
|
||||
}
|
||||
|
||||
_, err = db.Exec("insert into users (username, email, salt, password) values ($1, $2, $3, $4);", dat.Username, dat.Email, salt, hash_password)
|
||||
if err != nil {
|
||||
return c.Error500(err)
|
||||
}
|
||||
|
||||
// TODO Give this to the generateToken function
|
||||
token, login := generateToken(db, dat.Email, dat.Password)
|
||||
if !login {
|
||||
return c.SendJSONStatus(w, 500, "Could not login after creatting account please try again later")
|
||||
}
|
||||
|
||||
user, err := dbtypes.UserFromToken(c.Db, token)
|
||||
if err != nil {
|
||||
return c.Error500(err)
|
||||
}
|
||||
|
||||
type UserReturn struct {
|
||||
Token string `json:"token"`
|
||||
Id string `json:"id"`
|
||||
UserType int `json:"user_type"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
userReturn := UserReturn{
|
||||
Token: token,
|
||||
Id: user.Id,
|
||||
UserType: user.UserType,
|
||||
Username: user.Username,
|
||||
Email: user.Email,
|
||||
}
|
||||
|
||||
return c.SendJSON(w, userReturn)
|
||||
}
|
||||
|
||||
r.ParseForm()
|
||||
@ -264,8 +351,6 @@ func usersEndpints(db *sql.DB, handle *Handle) {
|
||||
}))
|
||||
}
|
||||
|
||||
c.Logger.Warn("test", "email", r.Form.Get("email"))
|
||||
|
||||
_, err := c.Db.Exec("update users set email=$1 where id=$2", r.Form.Get("email"), c.User.Id)
|
||||
if err != nil {
|
||||
return c.Error500(err)
|
||||
|
@ -22,6 +22,7 @@
|
||||
userStore.user = req;
|
||||
goto("/");
|
||||
} catch (e) {
|
||||
loginData.password = "";
|
||||
if (e instanceof Response) {
|
||||
errorMessage = await e.json();
|
||||
} else {
|
||||
@ -29,7 +30,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
|
104
webpage/src/routes/register/+page.svelte
Normal file
104
webpage/src/routes/register/+page.svelte
Normal file
@ -0,0 +1,104 @@
|
||||
<script lang="ts">
|
||||
import { post } from 'src/lib/requests.svelte';
|
||||
import 'src/styles/forms.css';
|
||||
import { userStore } from '../UserStore.svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
let submitted = $state(false);
|
||||
|
||||
let loginData = $state({
|
||||
username: '',
|
||||
email: '',
|
||||
password: '',
|
||||
});
|
||||
|
||||
let errorMessage = $state("");
|
||||
|
||||
async function onSubmit() {
|
||||
submitted = true;
|
||||
errorMessage = "";
|
||||
|
||||
try {
|
||||
const req = await post('register', loginData);
|
||||
userStore.user = req;
|
||||
goto("/");
|
||||
} catch (e) {
|
||||
if (e instanceof Response) {
|
||||
errorMessage = await e.json();
|
||||
} else {
|
||||
errorMessage = "Server could not perform login";
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>
|
||||
Register
|
||||
</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="login-page">
|
||||
<div>
|
||||
<h1>
|
||||
Register
|
||||
</h1>
|
||||
<form on:submit|preventDefault={onSubmit} class:submitted>
|
||||
<fieldset>
|
||||
<label for="username">Username</label>
|
||||
<input required name="username" bind:value={loginData.username} />
|
||||
<!--{{if .UserError}}
|
||||
<span class="form-msg error">
|
||||
Username already in use
|
||||
</span>
|
||||
{{end}}-->
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<label for="email">Email</label>
|
||||
<input type="email" required name="email" bind:value={loginData.email} />
|
||||
<!-- {{if .EmailError}}
|
||||
<span class="form-msg error">
|
||||
Email already in use
|
||||
</span>
|
||||
{{end}} -->
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<label for="password">Password</label>
|
||||
<input required name="password" type="password" bind:value={loginData.password} />
|
||||
<!-- {{if .PasswordToLong}}
|
||||
<span class="form-msg error">
|
||||
Password is to long
|
||||
</span>
|
||||
{{end}} -->
|
||||
</fieldset>
|
||||
{#if errorMessage}
|
||||
<div class="form-msg error">
|
||||
{errorMessage}
|
||||
</div>
|
||||
{/if}
|
||||
<button>
|
||||
Register
|
||||
</button>
|
||||
<div class="spacer"></div>
|
||||
<a class="simple-link text-center w100" href="/login">
|
||||
Login
|
||||
</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.login-page {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
margin-bottom: 40px;
|
||||
|
||||
& > div {
|
||||
width: 40vw;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue
Block a user