git-svn-id: svn://losandesgames.com/alfheim-website@28 15359d88-9307-4e75-a9c1-e5686e5897df

This commit is contained in:
Vicente Ferrari Smith 2024-05-27 01:41:33 +00:00
parent 8c841e1846
commit 13a0a5370e
14 changed files with 94 additions and 87 deletions

View File

@ -11,9 +11,9 @@ build:
.PHONY: deploy
deploy:
rsync -rP --delete bin/linux_amd64 alfheim@alfheimgame.com:~
rsync -rP --delete bin/linux_amd64 alfheim@alfheimgame.com:/home/alfheim
.PHONY: service
service:
rsync -P alfheimgame.service alfheim@alfheimgame.com:~
ssh -t alfheim@alfheimgame.com 'sudo mv ~/alfheimgame.service /etc/systemd/system && sudo systemctl enable alfheimgame && sudo systemctl restart alfheimgame'
rsync -P alfheimgame.service alfheim@alfheimgame.com:/home/alfheim
ssh -t alfheim@alfheimgame.com 'sudo mv /home/alfheim/alfheimgame.service /etc/systemd/system && sudo systemctl enable alfheimgame && sudo systemctl restart alfheimgame'

View File

@ -15,7 +15,7 @@ CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
EnvironmentFile=/etc/environment
WorkingDirectory=/home/alfheim/linux_amd64
ExecStart=/home/alfheim/linux_amd64/alfheimgame -addr ':8080'
ExecStart=/home/alfheim/linux_amd64/alfheimgame -production
Restart=on-failure
RestartSec=5

Binary file not shown.

Binary file not shown.

View File

@ -48,7 +48,7 @@
</main>
<footer>
Alfheim &copy; 2024, Vicente Ferrari Smith, Los Andes Studios, Vienna, Austria. All rights reserved.
Alfheim &copy; 2024, Vicente Ferrari Smith, Los Andes Games, Vienna, Austria. All rights reserved.
</footer>
</body>
</html>

View File

@ -1,9 +1,9 @@
{{define "body"}}
<p>Alfheim is a game about humanity: our own will, and our place in the world at large.</p>
<p>Alfheim is an MMO where you&mdash;the player&mdash;administers a medieval settlement of elves.
<p>Alfheim is an MMO where you&mdash;the player&mdash;administer a medieval settlement of elves.
In an infinite world, and with thousands of other players, you will have to design an efficient command economy, if you wish to be able to compete with your enemies... Or your friends?</p>
<br \>
<video loop autoplay muted><source src="/static/video.mp4" type="video/mp4">Your browser does not support the video tag.</video>
<video playsinline loop autoplay muted><source src="/static/video.mp4" type="video/mp4">Your browser does not support the video tag.</video>
<br \>
<img src="/static/image.png" alt="Alfheim" style="height: 100%; width: 100%; object-fit: contain">
{{end}}

View File

@ -48,7 +48,7 @@
</main>
<footer>
Alfheim &copy; 2024, Vicente Ferrari Smith, Los Andes Studios, Vienna, Austria. All rights reserved.
Alfheim &copy; 2024, Vicente Ferrari Smith, Los Andes Games, Vienna, Austria. All rights reserved.
</footer>
</body>
</html>

View File

@ -1,9 +1,9 @@
{{define "body"}}
<p>Alfheim is a game about humanity: our own will, and our place in the world at large.</p>
<p>Alfheim is an MMO where you&mdash;the player&mdash;administers a medieval settlement of elves.
<p>Alfheim is an MMO where you&mdash;the player&mdash;administer a medieval settlement of elves.
In an infinite world, and with thousands of other players, you will have to design an efficient command economy, if you wish to be able to compete with your enemies... Or your friends?</p>
<br \>
<video loop autoplay muted><source src="/static/video.mp4" type="video/mp4">Your browser does not support the video tag.</video>
<video playsinline loop autoplay muted><source src="/static/video.mp4" type="video/mp4">Your browser does not support the video tag.</video>
<br \>
<img src="/static/image.png" alt="Alfheim" style="height: 100%; width: 100%; object-fit: contain">
{{end}}

View File

@ -8,7 +8,6 @@ import "fmt"
import "log"
import "net/http"
import "html/template"
import "os"
import "encoding/json"
//import "strconv"
import "strings"
@ -40,7 +39,7 @@ func favicon(w http.ResponseWriter, r *http.Request) {
func authenticated_user(w http.ResponseWriter, r *http.Request) int32 {
session, err := store.Get(r, "id")
if err != nil {
fmt.Println(err)
log.Println(err)
return 0
}
@ -161,7 +160,7 @@ func login(w http.ResponseWriter, r *http.Request) {
if id > 0 {
session.Values["id"] = id
//fmt.Println("Logged in with id:", id)
//log.Println("Logged in with id:", id)
session.Save(r, w)
http.Redirect(w, r, "/account", http.StatusSeeOther)
}
@ -268,7 +267,7 @@ func account(w http.ResponseWriter, r *http.Request) {
id := authenticated_user(w, r)
account, err := users.GetAccount(id)
//fmt.Println(id, account)
//log.Println(id, account)
text, err := template.ParseFiles("ui/base.html", "ui/account.html")
if err != nil {
@ -299,7 +298,7 @@ func deleteaccount(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodPost:
fmt.Println("Deleting account with id ", id)
log.Println("Deleting account with id ", id)
users.Delete(id)
session, _ := store.Get(r, "id")
@ -323,7 +322,7 @@ func subscribe(w http.ResponseWriter, r *http.Request) {
prices := make([]stripe.Price, 0)
for results.Next() {
//fmt.Println(results.Current())
//log.Println(results.Current())
prices = append(prices, *results.Price())
}
@ -361,7 +360,7 @@ func subscribe_stripe(w http.ResponseWriter, r *http.Request) {
}
result, err := customersession.New(params)
if err != nil {
fmt.Println(err)
log.Println(err)
}
text, err := template.ParseFiles("ui/base.html", "ui/subscribe_stripe.html")
@ -381,7 +380,7 @@ func managebilling(w http.ResponseWriter, r *http.Request) {
id := authenticated_user(w, r)
account, err := users.GetAccount(id)
if err != nil {
fmt.Println(err)
log.Println(err)
}
params := &stripe.BillingPortalSessionParams{
@ -391,7 +390,7 @@ func managebilling(w http.ResponseWriter, r *http.Request) {
result, err := session.New(params)
if err != nil {
fmt.Println(err)
log.Println(err)
}
http.Redirect(w, r, result.URL, http.StatusSeeOther)
@ -402,7 +401,7 @@ func webhooks(w http.ResponseWriter, r *http.Request) {
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)
log.Printf("Error reading request body: %v\n", err)
w.WriteHeader(http.StatusServiceUnavailable)
return
}
@ -412,14 +411,14 @@ func webhooks(w http.ResponseWriter, r *http.Request) {
event, err := webhook.ConstructEvent(payload, r.Header.Get("Stripe-Signature"), endpointsecret)
if err != nil {
fmt.Fprintf(os.Stderr, "Error verifying webhook signature: %v\n", err)
log.Printf("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())
log.Printf("Failed to parse webhook body json: %v\n", err.Error())
w.WriteHeader(http.StatusBadRequest)
return
}
@ -430,7 +429,7 @@ func webhooks(w http.ResponseWriter, r *http.Request) {
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)
log.Printf("Error parsing webhook JSON: %v\n", err)
w.WriteHeader(http.StatusBadRequest)
return
}
@ -442,7 +441,7 @@ func webhooks(w http.ResponseWriter, r *http.Request) {
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)
log.Printf("Error parsing webhook JSON: %v\n", err)
w.WriteHeader(http.StatusBadRequest)
return
}
@ -453,7 +452,7 @@ func webhooks(w http.ResponseWriter, r *http.Request) {
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)
log.Printf("Error parsing webhook JSON: %v\n", err)
w.WriteHeader(http.StatusBadRequest)
return
}
@ -462,7 +461,7 @@ func webhooks(w http.ResponseWriter, r *http.Request) {
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)
log.Printf("Error parsing webhook JSON: %v\n", err)
w.WriteHeader(http.StatusBadRequest)
return
}
@ -470,7 +469,7 @@ func webhooks(w http.ResponseWriter, r *http.Request) {
// ... handle other event types
default:
fmt.Fprintf(os.Stderr, "Unhandled event type: %s\n", event.Type)
log.Printf("Unhandled event type: %s\n", event.Type)
}
w.WriteHeader(http.StatusOK)
@ -478,15 +477,15 @@ func webhooks(w http.ResponseWriter, r *http.Request) {
func handle_checkout_session_completed(checkoutsession stripe.CheckoutSession) error {
//toprint, _ := json.MarshalIndent(checkoutSession, "", " ")
//fmt.Println(string(toprint))
//log.Println(string(toprint))
subscription, err := subscription.Get(checkoutsession.Subscription.ID, nil);
if err != nil {
fmt.Println(err)
log.Println(err)
return err
}
//fmt.Println(subscription.Customer.ID)
//log.Println(subscription.Customer.ID)
//var status SubscriptionStatus
//switch subscription.Status {
@ -515,15 +514,15 @@ func handle_checkout_session_completed(checkoutsession stripe.CheckoutSession) e
func handle_payment_method_attached(paymentmethod stripe.PaymentMethod) error {
//toprint, _ := json.MarshalIndent(setupintent, "", " ")
//fmt.Println(string(toprint))
//log.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)
//log.Println(result)
if err != nil {
fmt.Println(err)
log.Println(err)
return err
}

37
main.go
View File

@ -4,7 +4,6 @@
package main
import "fmt"
import "log"
import "flag"
import "net/http"
@ -12,8 +11,6 @@ import _ "github.com/lib/pq"
import "database/sql"
import "github.com/gorilla/sessions"
import "regexp"
import "golang.org/x/crypto/acme/autocert"
import "crypto/tls"
import "github.com/stripe/stripe-go/v78"
@ -26,10 +23,13 @@ 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])?)*$/")
func main() {
addr := flag.String("addr", ":80", "HTTP network addr")
addr := flag.String("addr", "127.0.0.1:8080", "HTTP network addr")
prodaddr := flag.String("prodaddr", "45.76.84.7:443", "HTTP network addr")
production := flag.Bool("production", false, "Whether to use production port and TLS")
_ = addr
flag.Parse()
fmt.Println("Hello, Sailor!")
log.Println("Hello, Sailor!")
stripe.Key = "sk_test_51PGebgKUHKCjyTmc97rfDPcvew6EhqDz2qp3U7XoAMIilAU9IVo2NO4P7ylkTvbBafFVr94trha1VYY32jRWMw2K00Yq7YJXFf"
@ -67,7 +67,7 @@ func main() {
//}
//for _, acc := range accounts {
// fmt.Println(acc)
// log.Println(acc)
//}
mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
@ -84,19 +84,16 @@ func main() {
//mux.HandleFunc("/managebilling", require_authenticated_user(managebilling))
//mux.HandleFunc("/webhook", webhooks)
cert := &autocert.Manager{
Prompt: autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist("alfheimgame.com", "www.alfheimgame.com"),
Cache: autocert.DirCache("certs"),
if *production {
server := &http.Server{
Addr: *prodaddr,
Handler: log_connection(secure_headers(mux)),
}
log.Fatal(server.ListenAndServeTLS("/home/alfheim/cert/config/live/alfheimgame.com/fullchain.pem", "/home/alfheim/cert/config/live/alfheimgame.com/privkey.pem"))
} else {
log.Fatal(http.ListenAndServe(*addr, log_connection(secure_headers(mux))))
}
server := &http.Server{
Addr: ":443",
Handler: secure_headers(mux),
TLSConfig: &tls.Config{GetCertificate: cert.GetCertificate},
}
go http.ListenAndServe(":http", cert.HTTPHandler(nil))
log.Fatal(server.ListenAndServeTLS("", ""))
}

View File

@ -1,28 +1,39 @@
package main;
package main
import "net/http";
import "net/http"
import "log"
func secure_headers(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-XSS-Protection", "1; mode=block");
w.Header().Set("X-Frame-Options", "deny");
w.Header().Set("X-XSS-Protection", "1; mode=block")
w.Header().Set("X-Frame-Options", "deny")
next.ServeHTTP(w, r);
next.ServeHTTP(w, r)
}
return http.HandlerFunc(fn);
return http.HandlerFunc(fn)
}
func log_connection(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
log.Println("Connection!")
next.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}
func require_authenticated_user(next http.HandlerFunc) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// If the user is not authenticated, redirect them to the login page and;
// return from the middleware chain so that no subsequent handlers in;
// the chain are executed.;
// If the user is not authenticated, redirect them to the login page and
// return from the middleware chain so that no subsequent handlers in
// the chain are executed.
if authenticated_user(w, r) == 0 {
http.Redirect(w, r, "/login", http.StatusSeeOther);
return;
http.Redirect(w, r, "/login", http.StatusSeeOther)
return
}
// Otherwise call the next handler in the chain.;
next.ServeHTTP(w, r);
});
// Otherwise call the next handler in the chain.
next.ServeHTTP(w, r)
})
}

View File

@ -4,12 +4,13 @@
package main
import "fmt"
import "errors"
import "time"
//import "golang.org/x/crypto/bcrypt"
import "database/sql"
import _ "github.com/lib/pq"
import "fmt"
import "log"
import "github.com/alexedwards/argon2id"
import "github.com/stripe/stripe-go/v78"
@ -66,20 +67,20 @@ func (m *Usermodel) Insert(username string, password string, firstname string, l
//hashedpassword, err := bcrypt.GenerateFromPassword([]byte(password), 12)
hashedpassword, err := argon2id.CreateHash(password, argon2id.DefaultParams)
//fmt.Println(hashedpassword)
//log.Println(hashedpassword)
stmt := `INSERT INTO accounts (username, password, firstname, lastname, email, created) VALUES ($1, $2, $3, $4, $5, NOW()) RETURNING id`
var insertid int32
row := m.DB.QueryRow(stmt, username, string(hashedpassword), firstname, lastname, email)
if row.Err() != nil {
fmt.Println(row.Err())
log.Println(row.Err())
return 0, row.Err()
}
err = row.Scan(&insertid)
if err != nil {
fmt.Println(err)
log.Println(err)
return 0, err
}
@ -91,11 +92,11 @@ func (m *Usermodel) Insert(username string, password string, firstname string, l
stmt = `UPDATE accounts SET stripe_id = $1 WHERE id = $2`
//fmt.Println(customer.ID, insertid)
//log.Println(customer.ID, insertid)
_, err = m.DB.Exec(stmt, customer.ID, insertid)
if err != nil {
fmt.Println(err)
log.Println(err)
return 0, err
}
@ -108,16 +109,16 @@ func (m *Usermodel) Delete(id int32) error {
if account.StripeID != "" {
/*result*/_, err := customer.Del(account.StripeID, nil)
if err != nil {
fmt.Println(err)
log.Println(err)
}
//fmt.Println(result)
//log.Println(result)
}
stmt := `DELETE FROM accounts WHERE id = $1`
_, err = m.DB.Exec(stmt, id)
if err != nil {
fmt.Println(err)
log.Println(err)
}
@ -167,11 +168,11 @@ func (m *Usermodel) ExistsAccount(id int32) bool {
stmt := `SELECT EXISTS(SELECT 1 FROM accounts WHERE id = $1)`
row := m.DB.QueryRow(stmt, id)
if row.Err() != nil {
fmt.Println(row.Err())
log.Println(row.Err())
}
row.Scan(&exists)
//fmt.Println(exists)
//log.Println(exists)
return exists
}
@ -182,13 +183,13 @@ func (m *SubscriptionModel) Insert(stripeid string, stripesubscriptionid string,
row := m.DB.QueryRow(stmt, stripeid)
if row.Err() != nil {
fmt.Println(row.Err())
log.Println(row.Err())
return 0, row.Err()
}
err := row.Scan(&id)
if err != nil {
fmt.Println(err)
log.Println(err)
return 0, err
}
@ -198,13 +199,13 @@ func (m *SubscriptionModel) Insert(stripeid string, stripesubscriptionid string,
row = m.DB.QueryRow(stmt, id, string(stripesubscriptionid), string(stripecheckoutid), string(status))
if row.Err() != nil {
fmt.Println(row.Err())
log.Println(row.Err())
return 0, row.Err()
}
err = row.Scan(&insertid)
if err != nil {
fmt.Println(err)
log.Println(err)
return 0, err
}
@ -216,7 +217,7 @@ func (m *SubscriptionModel) Delete(id int32) error {
_, err := m.DB.Exec(stmt, id)
if err != nil {
fmt.Println(err)
log.Println(err)
return err
}
@ -240,7 +241,7 @@ func (m *SubscriptionModel) GetSubscription(id int32) (Subscription, error) {
return Subscription{}, err
}
//fmt.Println(subscription.Status)
//log.Println(subscription.Status)
return subscription, nil
}
@ -276,7 +277,6 @@ func (m *SubscriptionModel) GetSubscriptionsFromAccount(accountid int32) ([]Subs
func (m *SubscriptionModel) HasActiveSubscription(accountid int32) bool {
subscriptions, err := m.GetSubscriptionsFromAccount(accountid)
if err != nil {
fmt.Println(err)
return false
}

View File

@ -48,7 +48,7 @@
</main>
<footer>
Alfheim &copy; 2024, Vicente Ferrari Smith, Los Andes Studios, Vienna, Austria. All rights reserved.
Alfheim &copy; 2024, Vicente Ferrari Smith, Los Andes Games, Vienna, Austria. All rights reserved.
</footer>
</body>
</html>

View File

@ -3,7 +3,7 @@
<p>Alfheim is an MMO where you&mdash;the player&mdash;administer a medieval settlement of elves.
In an infinite world, and with thousands of other players, you will have to design an efficient command economy, if you wish to be able to compete with your enemies... Or your friends?</p>
<br \>
<video loop autoplay muted><source src="/static/video.mp4" type="video/mp4">Your browser does not support the video tag.</video>
<video playsinline loop autoplay muted><source src="/static/video.mp4" type="video/mp4">Your browser does not support the video tag.</video>
<br \>
<img src="/static/image.png" alt="Alfheim" style="height: 100%; width: 100%; object-fit: contain">
{{end}}