Compare commits
No commits in common. "4ec1d8c5a28e1cc6645d6d7ee0496ef38788ad19" and "4dfb28ad3d6ca066842b8fb5a4a443eb527aabd6" have entirely different histories.
4ec1d8c5a2
...
4dfb28ad3d
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,4 +5,3 @@ docker/docker-compose.yml
|
|||||||
cred.txt
|
cred.txt
|
||||||
dist/
|
dist/
|
||||||
.air.toml
|
.air.toml
|
||||||
tmp/
|
|
||||||
|
@ -230,39 +230,3 @@ func (app *application) SaveOrder(order models.Order) (int, error) {
|
|||||||
|
|
||||||
return id, nil
|
return id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *application) CreateAuthToken(w http.ResponseWriter, r *http.Request) {
|
|
||||||
var userInput struct {
|
|
||||||
Email string `json:"email"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
}
|
|
||||||
|
|
||||||
err := app.readJSON(w, r, &userInput)
|
|
||||||
if err != nil {
|
|
||||||
app.badRequest(w, r, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the user from the db by email, send error if invalid email
|
|
||||||
user, err := app.DB.GetUserByEmail(userInput.Email)
|
|
||||||
if err != nil {
|
|
||||||
app.invalidCredentials(w)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// validate the password, send error if invalid password
|
|
||||||
|
|
||||||
// generate the token
|
|
||||||
|
|
||||||
// send response
|
|
||||||
|
|
||||||
var payload struct {
|
|
||||||
Error bool `json:"error"`
|
|
||||||
Message string `json:"message"`
|
|
||||||
}
|
|
||||||
|
|
||||||
payload.Error = false
|
|
||||||
payload.Message = "Success!"
|
|
||||||
|
|
||||||
_ = app.writeJSON(w, http.StatusOK, payload)
|
|
||||||
}
|
|
||||||
|
@ -1,85 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (app *application) readJSON(w http.ResponseWriter, r *http.Request, data interface{}) error {
|
|
||||||
maxBytes := 1048576
|
|
||||||
|
|
||||||
r.Body = http.MaxBytesReader(w, r.Body, int64(maxBytes))
|
|
||||||
|
|
||||||
dec := json.NewDecoder(r.Body)
|
|
||||||
err := dec.Decode(data)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure there is only one entry.
|
|
||||||
err = dec.Decode(&struct{}{})
|
|
||||||
if err != io.EOF {
|
|
||||||
return errors.New("body must only have a single JSON value")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// writeJSON writes arbitrary data out as JSON
|
|
||||||
func (app *application) writeJSON(
|
|
||||||
w http.ResponseWriter,
|
|
||||||
status int, data interface{},
|
|
||||||
headers ...http.Header,
|
|
||||||
) error {
|
|
||||||
out, err := json.MarshalIndent(data, "", "\t")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(headers) > 0 {
|
|
||||||
for k, v := range headers[0] {
|
|
||||||
w.Header()[k] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.WriteHeader(status)
|
|
||||||
w.Write(out)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (app *application) badRequest(w http.ResponseWriter, r *http.Request, err error) error {
|
|
||||||
var payload struct {
|
|
||||||
Error bool `json:"error"`
|
|
||||||
Message string `json:"message"`
|
|
||||||
}
|
|
||||||
|
|
||||||
payload.Error = true
|
|
||||||
payload.Message = err.Error()
|
|
||||||
|
|
||||||
out, err := json.MarshalIndent(payload, "", "\t")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.Write(out)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (app *application) invalidCredentials(w http.ResponseWriter) error {
|
|
||||||
var payload struct {
|
|
||||||
Error bool `json:"error"`
|
|
||||||
Message string `json:"message"`
|
|
||||||
}
|
|
||||||
payload.Error = true
|
|
||||||
payload.Message = "invalid authentication credentials"
|
|
||||||
|
|
||||||
err := app.writeJSON(w, http.StatusUnauthorized, payload)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -21,8 +21,5 @@ func (app *application) routes() http.Handler {
|
|||||||
mux.Post("/api/payment-intent", app.GetPaymentIntent)
|
mux.Post("/api/payment-intent", app.GetPaymentIntent)
|
||||||
mux.Get("/api/widget/{id}", app.GetWidgetByID)
|
mux.Get("/api/widget/{id}", app.GetWidgetByID)
|
||||||
mux.Post("/api/create-customer-and-subscribe-to-plan", app.CreateCustomerAndSubscribeToPlan)
|
mux.Post("/api/create-customer-and-subscribe-to-plan", app.CreateCustomerAndSubscribeToPlan)
|
||||||
|
|
||||||
mux.Post("/api/authenticate", app.CreateAuthToken)
|
|
||||||
|
|
||||||
return mux
|
return mux
|
||||||
}
|
}
|
||||||
|
@ -283,9 +283,3 @@ func (app *application) BronzePlanReceipt(w http.ResponseWriter, r *http.Request
|
|||||||
app.errorLog.Println(err)
|
app.errorLog.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *application) LoginPage(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if err := app.renderTemplate(w, r, "login", &templateData{}); err != nil {
|
|
||||||
app.errorLog.Println(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -22,9 +22,6 @@ func (app *application) routes() http.Handler {
|
|||||||
mux.Get("/plans/bronze", app.BronzePlan)
|
mux.Get("/plans/bronze", app.BronzePlan)
|
||||||
mux.Get("/receipt/bronze", app.BronzePlanReceipt)
|
mux.Get("/receipt/bronze", app.BronzePlanReceipt)
|
||||||
|
|
||||||
// auth routes
|
|
||||||
mux.Get("/login", app.LoginPage)
|
|
||||||
|
|
||||||
fileServer := http.FileServer(http.Dir("./static"))
|
fileServer := http.FileServer(http.Dir("./static"))
|
||||||
mux.Handle("/static/*", http.StripPrefix("/static", fileServer))
|
mux.Handle("/static/*", http.StripPrefix("/static", fileServer))
|
||||||
|
|
||||||
|
@ -51,11 +51,6 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
|
||||||
<li class="nav-item">
|
|
||||||
<a href="/login" class="nav-link">Login</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
{{ template "base" . }}
|
|
||||||
{{ define "title" }}
|
|
||||||
Login
|
|
||||||
{{ end }}
|
|
||||||
{{ define "content" }}
|
|
||||||
<form action=""
|
|
||||||
method="post"
|
|
||||||
name="login-form"
|
|
||||||
id="login-form"
|
|
||||||
class="d-blick needs-validation"
|
|
||||||
autocomplete="off"
|
|
||||||
novalidate="">
|
|
||||||
<h2 class="mt-2 mb-3 text-center">Login</h2>
|
|
||||||
<hr>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="-email" class="form-label">Email</label>
|
|
||||||
<input type="text"
|
|
||||||
id="email"
|
|
||||||
name="email"
|
|
||||||
autocomplete="email-new"
|
|
||||||
required=""
|
|
||||||
class="form-control">
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="password" class="form-label">Password</label>
|
|
||||||
<input type="password"
|
|
||||||
id="password"
|
|
||||||
name="password"
|
|
||||||
autocomplete="password-new"
|
|
||||||
required=""
|
|
||||||
class="form-control">
|
|
||||||
</div>
|
|
||||||
<hr>
|
|
||||||
<a href="javascript:void(0)" id="login-btn" class="btn btn-primary">Login</a>
|
|
||||||
</form>
|
|
||||||
{{ end }}
|
|
||||||
{{define "js"}}
|
|
||||||
<script type="module">
|
|
||||||
import {val} from "/static/js/login.js"
|
|
||||||
document.getElementById("login-btn").addEventListener("click", () => {
|
|
||||||
val({{.API}});
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
{{end}}
|
|
@ -3,7 +3,6 @@ package models
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -224,32 +223,3 @@ func (m *DBModel) InsertCustomer(customer Customer) (int, error) {
|
|||||||
}
|
}
|
||||||
return int(id), nil
|
return int(id), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserByEmail gets a user by email address
|
|
||||||
func (m *DBModel) GetUserByEmail(email string) (User, error) {
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
email = strings.ToLower(email)
|
|
||||||
var u User
|
|
||||||
|
|
||||||
query := `SELECT id, first_name, last_name, email, password, created_at, updated_at
|
|
||||||
FROM users
|
|
||||||
WHERE email = ?`
|
|
||||||
|
|
||||||
row := m.DB.QueryRowContext(ctx, query, email)
|
|
||||||
|
|
||||||
err := row.Scan(
|
|
||||||
&u.ID,
|
|
||||||
&u.FirstName,
|
|
||||||
&u.LastName,
|
|
||||||
&u.Email,
|
|
||||||
&u.CreatedAt,
|
|
||||||
&u.UpdatedAt,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return User{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return u, nil
|
|
||||||
}
|
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
export function val(api) {
|
|
||||||
let form = document.getElementById("login-form");
|
|
||||||
|
|
||||||
if (form.checkValidity() === false) {
|
|
||||||
this.event.preventDefault();
|
|
||||||
this.event.stopPropagation();
|
|
||||||
form.classList.add("was-validated");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
form.classList.add("was-validated");
|
|
||||||
|
|
||||||
let payload = {
|
|
||||||
email: document.getElementById("email").value,
|
|
||||||
password: document.getElementById("password").value,
|
|
||||||
};
|
|
||||||
|
|
||||||
const requestOptions = {
|
|
||||||
method: 'post',
|
|
||||||
headers: {
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(payload),
|
|
||||||
};
|
|
||||||
|
|
||||||
fetch(api + "/api/authenticate", requestOptions)
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(response => {
|
|
||||||
console.log(response)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user