feat(cli): tapir invite <email> + TAPIR_PUBLIC_URL config
Mints a single-use invitation and prints the absolute claim URL for the operator to send. The URL base is TAPIR_PUBLIC_URL (default https://tapir.d-ma.be). runInvite is factored from config/store wiring so it's unit-tested against a fake inviter — no Postgres. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -68,6 +68,11 @@ type Config struct {
|
||||
// HTTPAddr is the listen address for `tapir serve` (the Stage-0 web UI).
|
||||
HTTPAddr string
|
||||
|
||||
// PublicURL is the externally-reachable base URL of the deployed service,
|
||||
// e.g. "https://tapir.d-ma.be". Used to build absolute links handed to humans
|
||||
// (the `tapir invite` URL). No trailing slash is assumed — callers trim it.
|
||||
PublicURL string
|
||||
|
||||
// Dex OIDC (web login, ADR-011/012). When OIDCIssuer is empty, `serve` falls
|
||||
// back to the allow-all StubAuth (local dev). When set, serve uses Dex: any
|
||||
// Dex-authenticated subject may sign in, then registers a tapir user (ADR-012).
|
||||
@@ -92,6 +97,7 @@ const (
|
||||
defaultOAuthRedirectAddr = "localhost:8080"
|
||||
defaultHTTPAddr = ":8080"
|
||||
defaultFetchBackoff = time.Hour
|
||||
defaultPublicURL = "https://tapir.d-ma.be"
|
||||
)
|
||||
|
||||
// Load reads the environment into a Config, applying defaults. It does not
|
||||
@@ -112,6 +118,7 @@ func Load() (Config, error) {
|
||||
SecretsFile: envOr("TAPIR_SECRETS_FILE", defaultSecretsFile()),
|
||||
OAuthRedirectAddr: envOr("TAPIR_OAUTH_REDIRECT_ADDR", defaultOAuthRedirectAddr),
|
||||
HTTPAddr: envOr("TAPIR_HTTP_ADDR", defaultHTTPAddr),
|
||||
PublicURL: envOr("TAPIR_PUBLIC_URL", defaultPublicURL),
|
||||
OIDCIssuer: os.Getenv("TAPIR_OIDC_ISSUER"),
|
||||
DexClientID: os.Getenv("TAPIR_DEX_CLIENT_ID"),
|
||||
DexClientSecret: os.Getenv("TAPIR_DEX_CLIENT_SECRET"),
|
||||
|
||||
Reference in New Issue
Block a user