more customer
Build and Publish / BuildAndDeployAmd64 (push) Failing after 5s
Build and Publish / BuildAndDeployArm64 (push) Failing after 6s

This commit is contained in:
2026-06-26 19:49:54 +02:00
parent 0252893de5
commit 3df95eac90
8 changed files with 836 additions and 12 deletions
+7 -9
View File
@@ -239,15 +239,13 @@ func (s *CheckoutPoolServer) StartCheckoutHandler(w http.ResponseWriter, r *http
return
}
// Create checkout with same ID as cart
var checkoutId checkout.CheckoutId = cart.MustNewCartId()
cookie, err := r.Cookie(checkoutCookieName)
if err == nil {
parsed, ok := cart.ParseCartId(cookie.Value)
if ok {
checkoutId = parsed
}
}
// The checkout grain is 1:1 with the cart it checks out (CheckoutId ==
// CartId). Keying it by the cart id — not a lingering checkoutid cookie —
// means a fresh cart always gets a fresh checkout, so the Klarna order
// reflects the cart shown at /kassa. Reusing the cookie made a new cart's
// checkout latch onto a previous cart's frozen snapshot (InitializeCheckout
// silently refuses to re-snapshot a grain that already has a CartState).
checkoutId := checkout.CheckoutId(cartId)
// Initialize checkout with cart state wrapped in Any
cartStateAny := &messages.InitializeCheckout{
+31 -1
View File
@@ -2,20 +2,39 @@ package main
import (
"context"
"crypto/rand"
"encoding/hex"
"fmt"
"log"
"net"
"net/http"
"os"
"os/signal"
"path/filepath"
"time"
"git.k6n.net/mats/go-cart-actor/internal/customerauth"
"git.k6n.net/mats/go-cart-actor/internal/ucp"
"git.k6n.net/mats/go-cart-actor/pkg/actor"
"git.k6n.net/mats/go-cart-actor/pkg/profile"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
)
// authSecret returns the HMAC key for customer session cookies. It reads
// CUSTOMER_AUTH_SECRET; when unset it generates an ephemeral random key and
// warns that issued sessions will not survive a restart (fine for dev).
func authSecret() []byte {
if v := os.Getenv("CUSTOMER_AUTH_SECRET"); v != "" {
return []byte(v)
}
b := make([]byte, 32)
if _, err := rand.Read(b); err != nil {
log.Fatalf("could not generate auth secret: %v", err)
}
log.Print("warning: CUSTOMER_AUTH_SECRET unset — using an ephemeral key; customer sessions will not survive a restart")
return []byte(hex.EncodeToString(b))
}
var podIp = os.Getenv("POD_IP")
var name = os.Getenv("POD_NAME")
@@ -64,6 +83,9 @@ func main() {
err := diskStorage.LoadEvents(ctx, id, ret)
return ret, err
},
// Destroy is an optional grain-eviction cleanup hook; profiles need none
// (disk storage persists via its own loop), so it's left unset — purge()
// skips a nil Destroy.
TTL: 10 * time.Minute,
PoolSize: 65535,
Hostname: podIp,
@@ -96,6 +118,14 @@ func main() {
// passes the full request path without stripping the prefix.
mux.Handle("/ucp/v1/customers/", http.StripPrefix("/ucp/v1/customers", customerUCP))
// Customer auth: password signup/login + session cookies + identity linking.
credStore, err := customerauth.LoadCredentialStore(filepath.Join(profileDir, "credentials.json"))
if err != nil {
log.Fatalf("Error loading credential store: %v\n", err)
}
authHandler := customerauth.NewServer(credStore, pool, customerauth.NewSigner(authSecret()), 0).Handler()
mux.Handle("/ucp/v1/auth/", http.StripPrefix("/ucp/v1/auth", authHandler))
mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
grainCount, capacity := pool.LocalUsage()
if grainCount >= capacity {
@@ -126,7 +156,7 @@ func main() {
})
srv := &http.Server{
Addr: ":8080",
Addr: getEnv("PROFILE_ADDR", ":8080"),
BaseContext: func(net.Listener) context.Context { return ctx },
ReadTimeout: 10 * time.Second,
WriteTimeout: 20 * time.Second,