cors fixed

This commit is contained in:
2026-09-24 11:38:46 +05:30
parent 9698de32d5
commit 294fb8ab93
4 changed files with 245 additions and 18 deletions

View File

@@ -65,21 +65,29 @@ const WebLocalsKey = "webclaims"
// webAuthRequired reports whether a request without a valid token is refused.
//
// Defaults to OFF, for the same reason POS enforcement does: the console is in
// use by real merchants right now, and its sign-in does not yet hand back a
// token. Switching enforcement on before the console sends one would lock every
// user out of a working product.
// Defaults to ON. It did not always: this shipped defaulting to off, because
// the console was live and its sign-in did not yet hand back a token, so
// enforcing first would have locked every merchant out of a working product.
//
// So the order is: this middleware ships, sign-in starts issuing tokens, the
// console starts sending them, and `WEB_AUTH_REQUIRED=true` closes the door.
// While it is off a token is still VERIFIED when one is sent, and a request
// carrying a token for the wrong tenant is still refused — the flag only
// decides what happens to a request carrying none.
// That rollout is finished. Sign-in mints a token, the console sends it on
// every call, and it expires cleanly. Leaving the default off after that point
// was not caution, it was an open door nobody had got round to shutting — and
// it was measured wide open: a `getorders` with no credential at all returned a
// real merchant's orders to anyone on the internet.
//
// This is a temporary state and should be short. An unauthenticated `/web`
// surface is the most serious thing in this codebase.
// ── The way out, if this goes wrong ─────────────────────────────────────────
//
// `WEB_AUTH_REQUIRED=false` restores the old behaviour, immediately and without
// a deploy. That is the escape hatch, and it exists because flipping a default
// that can lock people out should always be reversible by one person in one
// minute. A token that is SENT is still always verified either way — the flag
// only decides what happens to a request carrying none.
func webAuthRequired() bool {
return strings.EqualFold(strings.TrimSpace(os.Getenv("WEB_AUTH_REQUIRED")), "true")
setting := strings.TrimSpace(os.Getenv("WEB_AUTH_REQUIRED"))
if setting == "" {
return true
}
return !strings.EqualFold(setting, "false")
}
// publicWebPaths are the endpoints that must work before anybody has a token.

View File

@@ -271,3 +271,64 @@ func TestNoTokenIsNotAPlatformAccount(t *testing.T) {
t.Fatal("claims were reported present on a request that carried none")
}
}
/* ── The default, after the rollout ────────────────────────────────────── */
func TestEnforcementIsOnByDefault(t *testing.T) {
// It shipped defaulting to off so a live console could adopt tokens without
// its users being locked out. That finished, and the default was measured
// still open: a getorders with no credential returned a real merchant's
// orders to anyone.
t.Setenv("POS_TOKEN_SECRET", webTestSecret)
t.Setenv("WEB_AUTH_REQUIRED", "")
got := call(t, fakeLocations{}, "", "GET", "/live/api/v1/web/orders/tenant/getorders?tenantid=916", "")
if got != fiber.StatusUnauthorized {
t.Fatalf("an untokened request was served with no setting present: %d", got)
}
}
func TestEnforcementCanBeTurnedOffWithoutADeploy(t *testing.T) {
// The escape hatch. Flipping a default that can lock people out has to be
// reversible by one person in one minute.
t.Setenv("POS_TOKEN_SECRET", webTestSecret)
t.Setenv("WEB_AUTH_REQUIRED", "false")
got := call(t, fakeLocations{}, "", "GET", "/live/api/v1/web/orders/tenant/getorders?tenantid=916", "")
if got != fiber.StatusOK {
t.Fatalf("the escape hatch does not work: %d", got)
}
}
func TestOnlyTheWordFalseOpensTheDoor(t *testing.T) {
// A typo must fail closed. "no", "0" and "off" all look like they might
// disable it, and a deployment that meant to disable it and did not is far
// safer than one that meant to enable it and did not.
t.Setenv("POS_TOKEN_SECRET", webTestSecret)
for _, setting := range []string{"no", "0", "off", "FALSE ", "nope"} {
t.Setenv("WEB_AUTH_REQUIRED", setting)
got := call(t, fakeLocations{}, "", "GET", "/live/api/v1/web/orders/tenant/getorders?tenantid=916", "")
if setting == "FALSE " && got != fiber.StatusOK {
t.Fatalf("a trimmed, case-insensitive false was not honoured: %d", got)
}
if setting != "FALSE " && got != fiber.StatusUnauthorized {
t.Fatalf("%q opened the door: %d", setting, got)
}
}
}
func TestSignInStillWorksWithTheNewDefault(t *testing.T) {
// The test that catches a locked-out deployment. Guarding the login route
// means nobody can ever obtain a token.
t.Setenv("POS_TOKEN_SECRET", webTestSecret)
t.Setenv("WEB_AUTH_REQUIRED", "")
for _, path := range []string{
"/live/api/v1/web/users/applogin",
"/live/api/v1/web/tenant/weblogin",
} {
if got := call(t, fakeLocations{}, "", "POST", path, `{"authname":"a@b.c"}`); got != fiber.StatusOK {
t.Fatalf("%s was locked behind a session: %d", path, got)
}
}
}