// issue signs a license token for a specific shop. // Usage: go run ./cmd/issue -shop 1 -days 365 -type annual -key // Or use env var: LICENSE_ED25519_PRIVATE_KEY= go run ./cmd/issue -shop 1 -days 365 package main import ( "encoding/json" "flag" "fmt" "os" "time" "github.com/wangjia/jiu/backend/internal/util" ) func main() { shopID := flag.Uint64("shop", 0, "shop ID (required)") licenseID := flag.Uint64("license", 0, "license record ID (optional, 0 = omit)") days := flag.Int("days", 365, "validity days; 0 = perpetual (no expiry)") licType := flag.String("type", "annual", "license type: trial | annual | lifetime") maxDevices := flag.Int("devices", 3, "max devices") privKey := flag.String("key", "", "Ed25519 private key (base64); falls back to LICENSE_ED25519_PRIVATE_KEY env") flag.Parse() if *shopID == 0 { fmt.Fprintln(os.Stderr, "error: -shop is required") flag.Usage() os.Exit(1) } key := *privKey if key == "" { key = os.Getenv("LICENSE_ED25519_PRIVATE_KEY") } if key == "" { fmt.Fprintln(os.Stderr, "error: provide -key or set LICENSE_ED25519_PRIVATE_KEY") os.Exit(1) } now := time.Now() payload := util.LicensePayload{ ShopID: *shopID, Type: *licType, IssuedAt: now.Unix(), MaxDevices: *maxDevices, } if *licenseID > 0 { payload.LicenseID = *licenseID } if *days > 0 { exp := now.Add(time.Duration(*days) * 24 * time.Hour).Unix() payload.ExpiresAt = &exp } token, err := util.IssueLicenseToken(payload, key) if err != nil { fmt.Fprintf(os.Stderr, "sign failed: %v\n", err) os.Exit(1) } out, _ := json.MarshalIndent(payload, "", " ") fmt.Println("=== License Token ===") fmt.Println(token) fmt.Println() fmt.Println("=== Payload ===") fmt.Println(string(out)) if payload.ExpiresAt != nil { fmt.Printf("\nExpires: %s\n", time.Unix(*payload.ExpiresAt, 0).Format("2006-01-02 15:04:05")) } else { fmt.Println("\nExpires: never (perpetual)") } }