diff --git a/README.md b/README.md index 67b81b36..7d1434b1 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,22 @@ npx nx run api-contract:generate:go # regenerate Go models Codegen runs automatically as a dependency of the `dev`, `build` and `serve` targets — run it manually only when you want to inspect the output. +### Checking DOKU credentials + +```bash +make -C apps/api doku-check # asks DOKU for an access token with apps/api/.env +``` + +The same check ships as a release binary, so it can be run against the live credentials on the VPS +without a Go toolchain or a build there: + +```bash +cd /root/projects/gatherloop-pos/apps/api && ./dist/release/dokucheck +``` + +It redacts the identifiers it prints so its output is safe to paste or to leave in a CI log; pass +`-show-credentials` to see them in full. + In CI, a pull request runs the `libs/ui` and `apps/api` unit tests, and only the ones whose area it touches (`.github/workflows/pr-tests.yml`). The end-to-end suites are too slow for that loop, so they run after the merge, against a MySQL service, the real API binary and a real Next.js server diff --git a/apps/api/Makefile b/apps/api/Makefile index 62e25997..15a60717 100644 --- a/apps/api/Makefile +++ b/apps/api/Makefile @@ -40,10 +40,11 @@ dev: build: go build -o dist/api main.go -## build-release: Build the three static release binaries for the VPS +## build-release: Build the static release binaries for the VPS build-release: mkdir -p $(RELEASE_DIR) $(RELEASE_BUILD) -o $(RELEASE_DIR)/api main.go + $(RELEASE_BUILD) -o $(RELEASE_DIR)/dokucheck ./cmd/dokucheck ## test: Run all tests test: @@ -51,4 +52,4 @@ test: ## doku-check: Ask DOKU for an access token with the configured credentials doku-check: - go run ./cmd/dokucheck + go run ./cmd/dokucheck -show-credentials diff --git a/apps/api/cmd/dokucheck/main.go b/apps/api/cmd/dokucheck/main.go index af53b2bb..c855cd47 100644 --- a/apps/api/cmd/dokucheck/main.go +++ b/apps/api/cmd/dokucheck/main.go @@ -4,12 +4,16 @@ import ( "apps/api/data/doku" "apps/api/utils" "context" + "flag" "fmt" "os" "time" ) func main() { + showCredentials := flag.Bool("show-credentials", false, "print credential values in full instead of redacting them") + flag.Parse() + _ = utils.LoadEnv() env := utils.GetEnv() @@ -33,9 +37,9 @@ func main() { } fmt.Printf("baseUrl: %s\n", config.BaseURL) - fmt.Printf("clientId: %s\n", config.ClientId) - fmt.Printf("merchantId: %s\n", config.MerchantId) - fmt.Printf("channelId: %s\n", config.ChannelId) + fmt.Printf("clientId: %s\n", format(config.ClientId, *showCredentials)) + fmt.Printf("merchantId: %s\n", format(config.MerchantId, *showCredentials)) + fmt.Printf("channelId: %s\n", format(config.ChannelId, *showCredentials)) ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) defer cancel() @@ -51,3 +55,14 @@ func main() { fmt.Println("\naccess token granted: credentials are valid") } + +// Redacted by default because this output can end up in a public CI log. +func format(value string, show bool) string { + if show { + return value + } + if len(value) <= 8 { + return fmt.Sprintf("", len(value)) + } + return fmt.Sprintf("%s...%s (%d chars)", value[:4], value[len(value)-4:], len(value)) +}