// Asks the deployed server whether Nearle Buddy has a model. // // go run ./scratch/buddystatus # production // go run ./scratch/buddystatus http://localhost:1122 // // `/assistant/status` sits behind the session guard, so this mints one. That it // CAN mint one, from a secret sitting in a tracked file, is itself the finding // recorded in middleware/webauth.go: anybody with repository access can issue a // session for any tenant. Rotating POS_TOKEN_SECRET out of `.env.local` is the // fix, and this tool stops working the day that happens — which is correct. // // Read-only. It asks one question and prints the answer. package main import ( "encoding/json" "fmt" "io" "net/http" "os" "strings" "time" "nearle/utils" "github.com/joho/godotenv" ) func main() { // The secret lives in the env files, not in this program. _ = godotenv.Load(".env.local") _ = godotenv.Load(".env") host := "https://fiesta.nearle.app" if len(os.Args) > 1 { host = strings.TrimRight(os.Args[1], "/") } token, _, err := utils.MintWebToken(utils.WebClaims{Userid: 904, Tenantid: 1147}, time.Now()) if err != nil { fmt.Println("cannot mint a session:", err) fmt.Println("POS_TOKEN_SECRET is not set here, or is shorter than 16 characters.") os.Exit(1) } url := host + "/live/api/v1/web/assistant/status" req, _ := http.NewRequest("GET", url, nil) req.Header.Set("Authorization", "Bearer "+token) resp, err := (&http.Client{Timeout: 20 * time.Second}).Do(req) if err != nil { fmt.Println("could not reach", url, err) os.Exit(1) } defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) fmt.Printf("%s\nHTTP %d\n%s\n\n", url, resp.StatusCode, body) var envelope struct { Details struct { Available bool `json:"available"` Reason string `json:"reason"` } `json:"details"` } if json.Unmarshal(body, &envelope) != nil { return } switch { case resp.StatusCode == http.StatusUnauthorized: fmt.Println("The session was refused — this deployment signs with a different secret.") case envelope.Details.Available: fmt.Println("Buddy has a model. The composer should accept a question on Console, Sales and Inventory.") case envelope.Details.Reason != "": fmt.Println("Buddy is off:", envelope.Details.Reason) default: fmt.Println("Buddy is off. This build does not say why — ASSISTANT_BASE_URL, ASSISTANT_MODEL") fmt.Println("and ASSISTANT_API_KEY are what it needs, set on the platform and redeployed.") } }