diff --git a/Alex Edwards - Let's Go Further (2021).pdf b/Alex Edwards - Let's Go Further (2021).pdf new file mode 100644 index 0000000..e15923a Binary files /dev/null and b/Alex Edwards - Let's Go Further (2021).pdf differ diff --git a/handlers.go b/handlers.go index 807d5cd..0253af7 100644 --- a/handlers.go +++ b/handlers.go @@ -2,238 +2,244 @@ // Created by vfs on 02.05.2024. // -package main; +package main -import "fmt"; -import "log"; -import "net/http"; -import "html/template"; -//import "strconv"; -import "strings"; -import "unicode/utf8"; -import "errors"; -import "runtime/debug"; -import "github.com/stripe/stripe-go/v78"; -import "github.com/stripe/stripe-go/v78/price"; -import "github.com/stripe/stripe-go/v78/customersession"; -import "github.com/stripe/stripe-go/v78/billingportal/session"; +import "fmt" +import "log" +import "net/http" +import "html/template" +import "os" +import "encoding/json" +//import "strconv" +import "strings" +import "unicode/utf8" +import "errors" +import "runtime/debug" +import "io/ioutil" +import "github.com/stripe/stripe-go/v78" +import "github.com/stripe/stripe-go/v78/price" +import "github.com/stripe/stripe-go/v78/customersession" +import "github.com/stripe/stripe-go/v78/billingportal/session" +import "github.com/stripe/stripe-go/v78/webhook" +import "github.com/stripe/stripe-go/v78/customer" +import "github.com/stripe/stripe-go/v78/subscription" type templatedata struct { - AuthenticatedUser int32; - FormErrors map[string]string; - Account Account; - Prices []stripe.Price; - ClientSecret string; + AuthenticatedUser int32 + FormErrors map[string]string + Account Account + Prices []stripe.Price + ClientSecret string } func favicon(w http.ResponseWriter, r *http.Request) { - http.ServeFile(w, r, "favicon.ico"); + http.ServeFile(w, r, "favicon.ico") } func authenticated_user(w http.ResponseWriter, r *http.Request) int32 { - session, err := store.Get(r, "id"); + session, err := store.Get(r, "id") if err != nil { - fmt.Println(err); - return 0; + fmt.Println(err) + return 0 } - id, ok := session.Values["id"].(int32); + id, ok := session.Values["id"].(int32) if !ok { - trace := fmt.Sprintf("%s\n%s", errors.New("type assertion to int32 failed").Error(), debug.Stack()); - _ = trace; - //log.Println(trace); - return 0; + trace := fmt.Sprintf("%s\n%s", errors.New("type assertion to int32 failed").Error(), debug.Stack()) + _ = trace + //log.Println(trace) + return 0 } // check if the saved id exists in the database, otherwise it's a bad id and has to be removed from the cookies - exists := users.Exists_account(id); + exists := users.Exists_account(id) if !exists { - session, _ := store.Get(r, "id"); + session, _ := store.Get(r, "id") - session.Values["id"] = 0; - session.Save(r, w); + session.Values["id"] = 0 + session.Save(r, w) - return 0; + return 0 } - return id; + return id } func home(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { - http.NotFound(w, r); - return; + http.NotFound(w, r) + return } - id := authenticated_user(w, r); - account, err := users.Get_account(id); + id := authenticated_user(w, r) + account, err := users.Get_account(id) - text, err := template.ParseFiles("ui/base.html", "ui/index.html"); + text, err := template.ParseFiles("ui/base.html", "ui/index.html") if err != nil { - http.Error(w, "Internal Server Error", 500); - log.Fatal(err); + http.Error(w, "Internal Server Error", 500) + log.Fatal(err) } switch r.Method { case http.MethodGet: - err := text.Execute(w, templatedata{AuthenticatedUser: id, Account: account}); + err := text.Execute(w, templatedata{AuthenticatedUser: id, Account: account}) if err != nil { - log.Fatal(err); - http.Error(w, "Internal Server Error", 500); + log.Fatal(err) + http.Error(w, "Internal Server Error", 500) } case http.MethodPost: - err := text.Execute(w, templatedata{}); + err := text.Execute(w, templatedata{}) if err != nil { - log.Fatal(err); - http.Error(w, "Internal Server Error", 500); + log.Fatal(err) + http.Error(w, "Internal Server Error", 500) } } } func login(w http.ResponseWriter, r *http.Request) { - text, err := template.ParseFiles("ui/base.html", "ui/login.html"); + text, err := template.ParseFiles("ui/base.html", "ui/login.html") if err != nil { - http.Error(w, "Internal Server Error", 500); - log.Fatal(err); + http.Error(w, "Internal Server Error", 500) + log.Fatal(err) } switch r.Method { case http.MethodGet: - err := text.Execute(w, templatedata{}); + err := text.Execute(w, templatedata{}) if err != nil { - log.Fatal(err); - http.Error(w, "Internal Server Error", 500); + log.Fatal(err) + http.Error(w, "Internal Server Error", 500) } case http.MethodPost: - session, _ := store.Get(r, "id");; - password := r.FormValue("password"); - username := r.FormValue("username"); - errors := make(map[string]string); + session, _ := store.Get(r, "id") + password := r.FormValue("password") + username := r.FormValue("username") + errors := make(map[string]string) if strings.TrimSpace(username) == "" { - errors["username"] = "This field cannot be blank"; + errors["username"] = "This field cannot be blank" } else if utf8.RuneCountInString(username) > 20 { - errors["username"] = "This field is too long (the maximum is 20 characters)"; + errors["username"] = "This field is too long (the maximum is 20 characters)" } if strings.TrimSpace(password) == "" { - errors["password"] = "This field cannot be blank"; + errors["password"] = "This field cannot be blank" } else if utf8.RuneCountInString(password) < 8 { - errors["password"] = "This field is too short (the minimum is 8 characters)"; + errors["password"] = "This field is too short (the minimum is 8 characters)" } if len(errors) > 0 { - err := text.Execute(w, templatedata{AuthenticatedUser: authenticated_user(w, r), FormErrors: errors}); + err := text.Execute(w, templatedata{AuthenticatedUser: authenticated_user(w, r), FormErrors: errors}) if err != nil { - log.Fatal(err); - http.Error(w, "Internal Server Error", 500); + log.Fatal(err) + http.Error(w, "Internal Server Error", 500) } - return; + return } - id, err := users.Authenticate(username, password); + id, err := users.Authenticate(username, password) if err == ErrInvalidCredentials { - errors["generic"] = "Email or Password is incorrect"; - err := text.Execute(w, templatedata{AuthenticatedUser: authenticated_user(w, r), FormErrors: errors}); + errors["generic"] = "Email or Password is incorrect" + err := text.Execute(w, templatedata{AuthenticatedUser: authenticated_user(w, r), FormErrors: errors}) if err != nil { - log.Fatal(err); - http.Error(w, "Internal Server Error", 500); + log.Fatal(err) + http.Error(w, "Internal Server Error", 500) } - return; + return } if id > 0 { - session.Values["id"] = id; - fmt.Println("Logged in with id:", id); - session.Save(r, w); - http.Redirect(w, r, "/account", http.StatusSeeOther); + session.Values["id"] = id + fmt.Println("Logged in with id:", id) + session.Save(r, w) + http.Redirect(w, r, "/account", http.StatusSeeOther) } } } func logout(w http.ResponseWriter, r *http.Request) { - text, err := template.ParseFiles("ui/base.html", "ui/logout.html"); + text, err := template.ParseFiles("ui/base.html", "ui/logout.html") if err != nil { - http.Error(w, "Internal Server Error", 500); - log.Fatal(err); + http.Error(w, "Internal Server Error", 500) + log.Fatal(err) } - id := authenticated_user(w, r); - account, err := users.Get_account(id); + id := authenticated_user(w, r) + account, err := users.Get_account(id) switch r.Method { case http.MethodGet: - err := text.Execute(w, templatedata{AuthenticatedUser: id, Account: account}); + err := text.Execute(w, templatedata{AuthenticatedUser: id, Account: account}) if err != nil { - log.Fatal(err); - http.Error(w, "Internal Server Error", 500); + log.Fatal(err) + http.Error(w, "Internal Server Error", 500) } case http.MethodPost: - session, _ := store.Get(r, "id"); + session, _ := store.Get(r, "id") - session.Values["id"] = 0; - session.Save(r, w); - http.Redirect(w, r, "/", http.StatusSeeOther); + session.Values["id"] = 0 + session.Save(r, w) + http.Redirect(w, r, "/", http.StatusSeeOther) } } func register(w http.ResponseWriter, r *http.Request) { - text, err := template.ParseFiles("ui/base.html", "ui/register.html"); + text, err := template.ParseFiles("ui/base.html", "ui/register.html") if err != nil { - http.Error(w, "Internal Server Error", 500); - log.Fatal(err); + http.Error(w, "Internal Server Error", 500) + log.Fatal(err) } - id := authenticated_user(w, r); - account, err := users.Get_account(id); + id := authenticated_user(w, r) + account, err := users.Get_account(id) switch r.Method { case http.MethodGet: - err := text.Execute(w, templatedata{AuthenticatedUser: id, Account: account}); + err := text.Execute(w, templatedata{AuthenticatedUser: id, Account: account}) if err != nil { - log.Fatal(err); - http.Error(w, "Internal Server Error", 500); + log.Fatal(err) + http.Error(w, "Internal Server Error", 500) } case http.MethodPost: - account := Account{Username: r.FormValue("username"), Password: []byte(r.FormValue("password")), Firstname: r.FormValue("firstname"), Lastname: r.FormValue("lastname"), Email: r.FormValue("email")}; + account := Account{Username: r.FormValue("username"), Password: []byte(r.FormValue("password")), Firstname: r.FormValue("firstname"), Lastname: r.FormValue("lastname"), Email: r.FormValue("email")} - errors := make(map[string]string); + errors := make(map[string]string) if strings.TrimSpace(account.Username) == "" { - errors["username"] = "This field cannot be blank"; + errors["username"] = "This field cannot be blank" } else if utf8.RuneCountInString(account.Username) > 20 { - errors["username"] = "This field is too long (the maximum is 20 characters)"; + errors["username"] = "This field is too long (the maximum is 20 characters)" } if strings.TrimSpace(string(account.Password)) == "" { - errors["password"] = "This field cannot be blank"; + errors["password"] = "This field cannot be blank" } else if utf8.RuneCountInString(string(account.Password)) < 8 { - errors["password"] = "This field is too short (the minimum is 8 characters)"; + errors["password"] = "This field is too short (the minimum is 8 characters)" } if len(errors) > 0 { - err := text.Execute(w, templatedata{AuthenticatedUser: authenticated_user(w, r), FormErrors: errors}); + err := text.Execute(w, templatedata{AuthenticatedUser: authenticated_user(w, r), FormErrors: errors}) if err != nil { - log.Fatal(err); - http.Error(w, "Internal Server Error", 500); + log.Fatal(err) + http.Error(w, "Internal Server Error", 500) } } - err := users.Insert(account.Username, string(account.Password), account.Firstname, account.Lastname, account.Email); + err := users.Insert(account.Username, string(account.Password), account.Firstname, account.Lastname, account.Email) if err == ErrDuplicateEmail || err == ErrDuplicateUsername { @@ -241,106 +247,106 @@ func register(w http.ResponseWriter, r *http.Request) { } - http.Redirect(w, r, "/login", http.StatusSeeOther); + http.Redirect(w, r, "/login", http.StatusSeeOther) } } func account(w http.ResponseWriter, r *http.Request) { - //id, err := strconv.Atoi(r.URL.Query().Get("id")); - //if err != nil || id < 1 {; - // http.NotFound(w, r); - // return; - //}; - //account, err := users.Get_account(int32(id));; - //if err != nil {; - // log.Fatal(err);; - //}; + //id, err := strconv.Atoi(r.URL.Query().Get("id")) + //if err != nil || id < 1 { + // http.NotFound(w, r) + // return + //} + //account, err := users.Get_account(int32(id)) + //if err != nil { + // log.Fatal(err) + //} - id := authenticated_user(w, r); - account, err := users.Get_account(id); + id := authenticated_user(w, r) + account, err := users.Get_account(id) fmt.Println(id, account) - text, err := template.ParseFiles("ui/base.html", "ui/account.html"); + text, err := template.ParseFiles("ui/base.html", "ui/account.html") if err != nil { - http.Error(w, "Internal Server Error", 500); - log.Fatal(err); + http.Error(w, "Internal Server Error", 500) + log.Fatal(err) } switch r.Method { case http.MethodGet: - err := text.Execute(w, templatedata{AuthenticatedUser: id, Account: account}); + err := text.Execute(w, templatedata{AuthenticatedUser: id, Account: account}) if err != nil { - log.Fatal(err); - http.Error(w, "Internal Server Error", 500); + log.Fatal(err) + http.Error(w, "Internal Server Error", 500) } } //case http.MethodPost: - // text.Execute(w, false); - // if err != nil {; - // log.Fatal(err); - // http.Error(w, "Internal Server Error", 500); - // }; + // text.Execute(w, false) + // if err != nil { + // log.Fatal(err) + // http.Error(w, "Internal Server Error", 500) + // } } func deleteaccount(w http.ResponseWriter, r *http.Request) { - id := authenticated_user(w, r); + id := authenticated_user(w, r) switch r.Method { case http.MethodPost: - fmt.Println("Deleting account with id ", id); - users.Delete(id); + fmt.Println("Deleting account with id ", id) + users.Delete(id) - session, _ := store.Get(r, "id"); + session, _ := store.Get(r, "id") - session.Values["id"] = 0; - session.Save(r, w); + session.Values["id"] = 0 + session.Save(r, w) - http.Redirect(w, r, "/", http.StatusSeeOther); + http.Redirect(w, r, "/", http.StatusSeeOther) } } func subscribe(w http.ResponseWriter, r *http.Request) { - id := authenticated_user(w, r); - account, err := users.Get_account(id); + id := authenticated_user(w, r) + account, err := users.Get_account(id) - params := &stripe.PriceListParams{}; + params := &stripe.PriceListParams{} params.Limit = stripe.Int64(3) - params.AddExpand("data.product"); - results := price.List(params); + params.AddExpand("data.product") + results := price.List(params) - prices := make([]stripe.Price, 0); + prices := make([]stripe.Price, 0) for results.Next() { fmt.Println(results.Current()) - prices = append(prices, *results.Price()); + prices = append(prices, *results.Price()) } fm := template.FuncMap{ "divide": func(a, b float64) float64 { - return a / b; + return a / b }, - }; - - text, err := template.New("base.html").Funcs(fm).ParseFiles("ui/base.html", "ui/subscribe.html"); - if err != nil { - http.Error(w, "Internal Server Error", 500); - log.Fatal(err); - return; } - err = text.Execute(w, templatedata{AuthenticatedUser: id, Account: account, Prices: prices}); + text, err := template.New("base.html").Funcs(fm).ParseFiles("ui/base.html", "ui/subscribe.html") if err != nil { - log.Fatal(err); - http.Error(w, "Internal Server Error", 500); + http.Error(w, "Internal Server Error", 500) + log.Fatal(err) + return + } + + err = text.Execute(w, templatedata{AuthenticatedUser: id, Account: account, Prices: prices}) + if err != nil { + log.Fatal(err) + http.Error(w, "Internal Server Error", 500) } } func subscribe_stripe(w http.ResponseWriter, r *http.Request) { - id := authenticated_user(w, r); - account, err := users.Get_account(id); + id := authenticated_user(w, r) + account, err := users.Get_account(id) params := &stripe.CustomerSessionParams{ Customer: stripe.String(account.StripeID), @@ -349,90 +355,152 @@ func subscribe_stripe(w http.ResponseWriter, r *http.Request) { Enabled: stripe.Bool(true), }, }, - }; - result, err := customersession.New(params); + } + result, err := customersession.New(params) if err != nil { - fmt.Println(err); + fmt.Println(err) } - text, err := template.ParseFiles("ui/base.html", "ui/subscribe_stripe.html"); + text, err := template.ParseFiles("ui/base.html", "ui/subscribe_stripe.html") if err != nil { - http.Error(w, "Internal Server Error", 500); - log.Fatal(err); + http.Error(w, "Internal Server Error", 500) + log.Fatal(err) } - err = text.Execute(w, templatedata{AuthenticatedUser: id, Account: account, ClientSecret: result.ClientSecret}); + err = text.Execute(w, templatedata{AuthenticatedUser: id, Account: account, ClientSecret: result.ClientSecret}) if err != nil { - log.Fatal(err); - http.Error(w, "Internal Server Error", 500); + log.Fatal(err) + http.Error(w, "Internal Server Error", 500) } } func managebilling(w http.ResponseWriter, r *http.Request) { - id := authenticated_user(w, r); - account, err := users.Get_account(id); + id := authenticated_user(w, r) + account, err := users.Get_account(id) if err != nil { - fmt.Println(err); + fmt.Println(err) } params := &stripe.BillingPortalSessionParams{ Customer: stripe.String(account.StripeID), ReturnURL: stripe.String("http://localhost:8080/account"), - }; - - result, err := session.New(params); - if err != nil { - fmt.Println(err); } - http.Redirect(w, r, result.URL, http.StatusSeeOther); + result, err := session.New(params) + if err != nil { + fmt.Println(err) + } + + http.Redirect(w, r, result.URL, http.StatusSeeOther) } -func webhook(w http.ResponseWriter, r *http.Request) { - const MaxBodyBytes = int64(65536); - req.Body = http.MaxBytesReader(w, req.Body, MaxBodyBytes); - payload, err := ioutil.ReadAll(req.Body); +func webhooks(w http.ResponseWriter, r *http.Request) { + const MaxBodyBytes = int64(65536) + r.Body = http.MaxBytesReader(w, r.Body, MaxBodyBytes) + payload, err := ioutil.ReadAll(r.Body) if err != nil { - fmt.Fprintf(os.Stderr, "Error reading request body: %v\n", err); - w.WriteHeader(http.StatusServiceUnavailable); - return; + fmt.Fprintf(os.Stderr, "Error reading request body: %v\n", err) + w.WriteHeader(http.StatusServiceUnavailable) + return } - event := stripe.Event{}; + endpointsecret := "whsec_43420f280f7695d9aa411c17da9ffac9afcecc3d36687035a8cb26f7f892f1cf" + + event, err := webhook.ConstructEvent(payload, r.Header.Get("Stripe-Signature"), endpointsecret) - err := json.Unmarshal(payload, &event); if err != nil { - fmt.Fprintf(os.Stderr, "Failed to parse webhook body json: %v\n", err.Error()); - w.WriteHeader(http.StatusBadRequest); - return; + fmt.Fprintf(os.Stderr, "Error verifying webhook signature: %v\n", err) + w.WriteHeader(http.StatusBadRequest) // Return a 400 error on a bad signature + return + } + + err = json.Unmarshal(payload, &event) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to parse webhook body json: %v\n", err.Error()) + w.WriteHeader(http.StatusBadRequest) + return } // Unmarshal the event data into an appropriate struct depending on its Type switch event.Type { - case "payment_intent.succeeded": - var paymentIntent stripe.PaymentIntent; - err := json.Unmarshal(event.Data.Raw, &paymentIntent); + case "checkout.session.completed": + var checkoutSession stripe.CheckoutSession + err := json.Unmarshal(event.Data.Raw, &checkoutSession) if err != nil { - fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err); - w.WriteHeader(http.StatusBadRequest); - return; + fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err) + w.WriteHeader(http.StatusBadRequest) + return } // Then define and call a func to handle the successful payment intent. // handlePaymentIntentSucceeded(paymentIntent) - case "payment_method.attached": - var paymentMethod stripe.PaymentMethod; - err := json.Unmarshal(event.Data.Raw, &paymentMethod); + handle_checkout_session_completed(checkoutSession) + + case "payment_intent.succeeded": + var paymentIntent stripe.PaymentIntent + err := json.Unmarshal(event.Data.Raw, &paymentIntent) if err != nil { - fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err); - w.WriteHeader(http.StatusBadRequest); - return; + fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err) + w.WriteHeader(http.StatusBadRequest) + return } - // Then define and call a func to handle the successful attachment of a PaymentMethod. - // handlePaymentMethodAttached(paymentMethod) - // ... handle other event types + // Then define and call a func to handle the successful payment intent. + // handlePaymentIntentSucceeded(paymentIntent) + + case "payment_method.attached": + var paymentMethod stripe.PaymentMethod + err := json.Unmarshal(event.Data.Raw, &paymentMethod) + if err != nil { + fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err) + w.WriteHeader(http.StatusBadRequest) + return + } + + case "setup_intent.succeeded": + var setupIntent stripe.SetupIntent + err := json.Unmarshal(event.Data.Raw, &setupIntent) + if err != nil { + fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err) + w.WriteHeader(http.StatusBadRequest) + return + } + + + // ... handle other event types default: fmt.Fprintf(os.Stderr, "Unhandled event type: %s\n", event.Type) } w.WriteHeader(http.StatusOK) -}) +} + +func handle_checkout_session_completed(checkoutsession stripe.CheckoutSession) error { + //toprint, _ := json.MarshalIndent(checkoutSession, "", " ") + //fmt.Println(string(toprint)) + + subscription, err := subscription.Get(checkoutsession.Subscription.ID, nil); + if err != nil { + fmt.Println(err) + return err + } + + fmt.Println(subscription) + + return nil +} + +func handle_payment_method_attached(paymentmethod stripe.PaymentMethod) error { + //toprint, _ := json.MarshalIndent(setupintent, "", " ") + //fmt.Println(string(toprint)) + + // make this the new customer's default payment method + params := &stripe.CustomerParams{} + params.DefaultSource = &paymentmethod.ID + result, err := customer.Update(paymentmethod.Customer.ID, params) + fmt.Println(result) + if err != nil { + fmt.Println(err) + return err + } + + return nil +} diff --git a/main.go b/main.go index 8d7bf6a..aaff8f0 100644 --- a/main.go +++ b/main.go @@ -2,85 +2,85 @@ // Created by vfs on 02.05.2024. // -package main; +package main -import "fmt"; -import "log"; -import "flag"; -import "net/http"; -import _ "github.com/lib/pq"; -import "database/sql"; -import "github.com/gorilla/sessions"; -import "regexp"; -//import "golang.org/x/crypto/bcrypt"; +import "fmt" +import "log" +import "flag" +import "net/http" +import _ "github.com/lib/pq" +import "database/sql" +import "github.com/gorilla/sessions" +import "regexp" +//import "golang.org/x/crypto/bcrypt" -import "github.com/stripe/stripe-go/v78"; -//import "github.com/stripe/stripe-go/v78/customer"; +import "github.com/stripe/stripe-go/v78" +//import "github.com/stripe/stripe-go/v78/customer" -var users *Usermodel; +var users *Usermodel -var key = []byte("super-secret-key"); -var store = sessions.NewCookieStore(key); +var key = []byte("super-secret-key") +var store = sessions.NewCookieStore(key) -var emailrx = 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])?)*$/"); +var emailrx = 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])?)*$/") func main() { - addr := flag.String("addr", ":8080", "HTTP network address"); - flag.Parse(); - fmt.Println("Hello, Sailor!"); + addr := flag.String("addr", ":8080", "HTTP network address") + flag.Parse() + fmt.Println("Hello, Sailor!") - stripe.Key = "sk_test_51PGebgKUHKCjyTmc97rfDPcvew6EhqDz2qp3U7XoAMIilAU9IVo2NO4P7ylkTvbBafFVr94trha1VYY32jRWMw2K00Yq7YJXFf"; + stripe.Key = "sk_test_51PGebgKUHKCjyTmc97rfDPcvew6EhqDz2qp3U7XoAMIilAU9IVo2NO4P7ylkTvbBafFVr94trha1VYY32jRWMw2K00Yq7YJXFf" - store.MaxAge(0); + store.MaxAge(0) - db, err := sql.Open("postgres", "postgres://elves_database:iK2SoVbDhdCki5n3LxGyP6zKpLspt4@80.240.25.87/elves_database"); + db, err := sql.Open("postgres", "postgres://elves_database:iK2SoVbDhdCki5n3LxGyP6zKpLspt4@80.240.25.87/elves_database") if err != nil { - log.Fatal(err); + log.Fatal(err) } - defer db.Close(); + defer db.Close() - users = &Usermodel{db}; + users = &Usermodel{db} - mux := http.NewServeMux(); + mux := http.NewServeMux() - //rows, err := db.Query("SELECT * FROM accounts"); - //if err != nil {; - // log.Fatal(err); - //}; - //defer rows.Close(); + //rows, err := db.Query("SELECT * FROM accounts") + //if err != nil { + // log.Fatal(err) + //} + //defer rows.Close() - //accounts := make([]*Account, 0); - //for rows.Next() {; - // acc := new(Account); - // err := rows.Scan(&acc.id, &acc.Username, &acc.password, &acc.Color); - // if err != nil {; - // log.Fatal(err); - // }; - // accounts = append(accounts, acc); - //}; + //accounts := make([]*Account, 0) + //for rows.Next() { + // acc := new(Account) + // err := rows.Scan(&acc.id, &acc.Username, &acc.password, &acc.Color) + // if err != nil { + // log.Fatal(err) + // } + // accounts = append(accounts, acc) + //} - //if err = rows.Err(); err != nil {; - // log.Fatal(err); - //}; + //if err = rows.Err() err != nil { + // log.Fatal(err) + //} - //for _, acc := range accounts {; - // fmt.Println(acc); - //}; + //for _, acc := range accounts { + // fmt.Println(acc) + //} - mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static")))); + mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) - mux.HandleFunc("/favicon.ico", favicon); + mux.HandleFunc("/favicon.ico", favicon) - mux.HandleFunc("/", home); - mux.HandleFunc("/login", login); - mux.HandleFunc("/logout", logout); - mux.HandleFunc("/register", register); - mux.HandleFunc("/account", require_authenticated_user(account)); - mux.HandleFunc("/deleteaccount", require_authenticated_user(deleteaccount)); - mux.HandleFunc("/subscribe", require_authenticated_user(subscribe_stripe)); - mux.HandleFunc("/managebilling", require_authenticated_user(managebilling)); - mux.HandleFunc("/webhook", webhook); + mux.HandleFunc("/", home) + mux.HandleFunc("/login", login) + mux.HandleFunc("/logout", logout) + mux.HandleFunc("/register", register) + mux.HandleFunc("/account", require_authenticated_user(account)) + mux.HandleFunc("/deleteaccount", require_authenticated_user(deleteaccount)) + mux.HandleFunc("/subscribe", require_authenticated_user(subscribe_stripe)) + mux.HandleFunc("/managebilling", require_authenticated_user(managebilling)) + mux.HandleFunc("/webhook", webhooks) - log.Fatal(http.ListenAndServe(*addr, secure_headers(mux))); + log.Fatal(http.ListenAndServe(*addr, secure_headers(mux))) }