Skip to content

feat: unified config#533

Merged
steveiliop56 merged 16 commits intomainfrom
feat/unified-config
Dec 22, 2025
Merged

feat: unified config#533
steveiliop56 merged 16 commits intomainfrom
feat/unified-config

Conversation

@steveiliop56
Copy link
Copy Markdown
Member

@steveiliop56 steveiliop56 commented Dec 21, 2025

Summary by CodeRabbit

  • New Features

    • YAML configuration example and namespaced TINYAUTH_ environment variables
    • New CLI entrypoint with subcommands for create/generate/verify/healthcheck/version
    • Multiple config loaders: file, flags, and environment
  • Improvements

    • Reorganized hierarchical config (Server, Auth, OAuth, UI, LDAP)
    • Docker image/runtime env and healthcheck updates
    • Build workflows now target the CLI package
  • Chores

    • Cleaned/updated ignores and dependency adjustments

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 21, 2025

Warning

Rate limit exceeded

@steveiliop56 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 19 minutes and 43 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 7c5fa11 and 0a7e259.

📒 Files selected for processing (3)
  • Dockerfile.dev
  • Dockerfile.distroless
  • cmd/tinyauth/healthcheck.go

Walkthrough

Replaces flat config with a nested TINYAUTH_* namespaced model, migrates CLI from Cobra to Traefik Paerser with new command packages under cmd/tinyauth, adds Flag/File/Env loaders, generifies label decoding, updates Docker/build targets to ./cmd/tinyauth, and removes legacy decoder utilities and main/root Cobra wiring.

Changes

Cohort / File(s) Summary
Build & CI
/.github/workflows/nightly.yml, /.github/workflows/release.yml, air.toml, Dockerfile, Dockerfile.dev, Dockerfile.distroless
Build targets updated to ./cmd/tinyauth; Dockerfiles add DATABASEPATH and RESOURCESDIR envs, healthcheck/entrypoint kept/adjusted.
Env & Example Configs
.env.example, config.example.yaml, docker-compose.example.yml, .gitignore
Introduce namespaced TINYAUTH_ env keys and a structured config.example.yaml; docker-compose and .env examples updated; .gitignore entries normalized and new ignores added.
CLI Migration (removed Cobra root)
cmd/root.go, main.go, cmd/*.go (old cmd/*.go files removed/rewired)
Cobra-based root and main removed; old Cobra command types and registrations deleted.
New CLI Implementation (Paerser)
cmd/tinyauth/tinyauth.go, cmd/tinyauth/create.go, cmd/tinyauth/generate.go, cmd/tinyauth/healthcheck.go, cmd/tinyauth/verify.go, cmd/tinyauth/version.go
New Traefik Paerser-based CLI with command factories returning *cli.Command, exported Config structs (CreateUserConfig, GenerateTotpConfig, VerifyUserConfig), interactive forms, and resource loaders wired.
Config Type Restructure
internal/config/config.go
Flat config replaced by nested structs: ServerConfig, AuthConfig, OAuthConfig (with Providers map), UIConfig, LdapConfig, ExperimentalConfig, plus renamed/relocated fields like DatabasePath, ResourcesDir, etc.
Bootstrap & Services
internal/bootstrap/app_bootstrap.go, internal/bootstrap/router_bootstrap.go, internal/bootstrap/service_bootstrap.go
Bootstrap and service initializations updated to use new nested config paths; OAuth provider secret file resolution and redirect defaulting added; socket and server path handling adjusted.
Loaders (new)
internal/utils/loaders/loader_env.go, internal/utils/loaders/loader_file.go, internal/utils/loaders/loader_flag.go
New EnvLoader, FileLoader, FlagLoader implementing Traefik Paerser loader semantics to decode config from env, file, and flags.
Decoders: removal & generification
internal/utils/decoders/decoders.go (removed), internal/utils/decoders/env_decoder.go (removed), internal/utils/decoders/flags_decoder.go (removed), internal/utils/decoders/label_decoder.go, internal/utils/decoders/*_test.go
Old normalize/decode utilities removed; DecodeLabels converted to generic DecodeLabels[T any](..., root string); related tests updated/removed.
Utilities cleanup
internal/utils/app_utils.go, internal/utils/app_utils_test.go
Removed unused helpers (GetLogLevel, GetOAuthProvidersConfig, ShoudLogJSON) and associated tests.
OAuth & HTTP client tweaks
internal/service/generic_oauth_service.go, internal/service/github_oauth_service.go, internal/service/google_oauth_service.go
HTTP clients now set a 30s timeout; generic config field renamed to Insecure.
Docker service adaptation
internal/service/docker_service.go
DecodeLabels call updated to generic typed form with explicit "apps" key.
Frontend i18n
frontend/src/lib/i18n/i18n.ts
Removed explicit locales import; rely on automatic language detection (nonExplicitSupportedLngs: true).
Module deps
go.mod
Removed direct deps on Cobra/Viper/validator; updated indirect deps for new libraries (paerser and others).

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant CLI as cmd/tinyauth
    participant Loaders as Config Loaders
    participant Parser as Traefik Paerser
    participant Bootstrap as Bootstrap Layer
    participant App as Application

    User->>CLI: invoke command (e.g., start, create, verify)
    CLI->>Loaders: run FileLoader, FlagLoader, EnvLoader
    Loaders->>Parser: decode file/flags/env (TINYAUTH_* prefixed)
    Parser-->>Loaders: merged config
    CLI->>Bootstrap: initialize app with merged config
    Bootstrap->>Bootstrap: resolve OAuth secrets, users, LDAP
    Bootstrap->>App: wire routes/services
    CLI->>App: execute requested command
    App-->>User: result/response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Areas requiring focused review:

  • CLI framework migration (command signatures, loaders, error propagation).
  • Config restructuring (ensure all references use new nested paths).
  • Loader precedence and decoding (File vs Flag vs Env merging behavior).
  • OAuth provider secret/file resolution and RedirectURL defaulting.
  • Build and Docker target changes to ./cmd/tinyauth (artifact paths).
  • Removal of decoder utilities — ensure no remaining references.

Possibly related PRs

Suggested labels

merge

Suggested reviewers

  • Rycochet

Poem

🐰 Hopping through code with a little command,

From Cobra burrows to Paerser's new land,
TINYAUTH vars tucked in nests neat and round,
Loaders gather configs, secrets are found.
A carrot of refactor — the binary's sound!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: unified config' directly and clearly summarizes the main change: a refactoring from flat, legacy environment variables and configuration structure to a hierarchical, namespaced configuration model with explicit sections (Server, Auth, OAuth, UI, LDAP, Experimental), alongside a major CLI framework migration from Cobra to Traefik Paerser.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@steveiliop56
Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 21, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (6)
.gitignore (1)

29-36: Reasonable additions that align with the unified config refactoring.

These ignore rules make sense for the PR's scope: config files and generated resources shouldn't be committed, and database files are runtime data. The additions follow the existing pattern of the file.

One minor nitpick: resources (line 36) lacks a descriptive comment, unlike config.yml and tinyauth.db above it. Adding a brief comment would improve consistency.

Optional: Add comment for consistency
  # binary out
  tinyauth.db
+ # generated resources
  resources
.env.example (1)

59-60: Consider quoting multi-word values.

Values containing spaces should be quoted to ensure consistent parsing across different environments:

🔎 Proposed fix
-TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_SCOPES=openid email profile
+TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_SCOPES="openid email profile"
-TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_NAME=My OAuth Provider
+TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_NAME="My OAuth Provider"
cmd/healthcheck.go (1)

44-44: Consider adding a timeout to the HTTP client.

The HTTP client is created without a timeout, which could cause the health check to hang indefinitely on unresponsive endpoints. For a health check operation, a reasonable timeout (e.g., 10-30 seconds) would improve reliability.

🔎 Proposed fix
-client := http.Client{}
+client := http.Client{
+	Timeout: 30 * time.Second,
+}
cmd/create.go (1)

57-62: Consider masking password input in interactive mode.

The password input field does not use EchoMode to hide user input. This could expose passwords on-screen.

🔎 Proposed fix to mask password input
-						huh.NewInput().Title("Password").Value(&tCfg.Password).Validate((func(s string) error {
+						huh.NewInput().Title("Password").EchoMode(huh.EchoModePassword).Value(&tCfg.Password).Validate((func(s string) error {
							if s == "" {
								return errors.New("password cannot be empty")
							}
							return nil
						})),
cmd/generate.go (1)

67-71: Add validation for empty User field before parsing.

In non-interactive mode, if --user is not provided, tCfg.User will be empty and utils.ParseUser("") will be called. While ParseUser likely returns an error for empty input, it would be clearer to validate upfront (similar to how create.go validates username/password at line 76-78).

🔎 Proposed fix
+			if tCfg.User == "" {
+				return errors.New("user cannot be empty")
+			}
+
 			user, err := utils.ParseUser(tCfg.User)

 			if err != nil {
 				return fmt.Errorf("failed to parse user: %w", err)
 			}
internal/config/config.go (1)

88-99: Missing YAML tags on OAuthServiceConfig fields.

The OAuthServiceConfig fields have description tags but lack yaml tags, unlike the nested config structs above. If these fields should be configurable via YAML config files, they need YAML tags for consistency.

Verify whether OAuth providers are intended to be configured via YAML files. If so, add YAML tags:

 type OAuthServiceConfig struct {
-	ClientID         string   `description:"OAuth client ID."`
-	ClientSecret     string   `description:"OAuth client secret."`
-	ClientSecretFile string   `description:"Path to the file containing the OAuth client secret."`
-	Scopes           []string `description:"OAuth scopes."`
-	RedirectURL      string   `description:"OAuth redirect URL."`
-	AuthURL          string   `description:"OAuth authorization URL."`
-	TokenURL         string   `description:"OAuth token URL."`
-	UserinfoURL      string   `description:"OAuth userinfo URL."`
-	Insecure         bool     `description:"Allow insecure OAuth connections."`
-	Name             string   `description:"Provider name in UI."`
+	ClientID         string   `description:"OAuth client ID." yaml:"clientId"`
+	ClientSecret     string   `description:"OAuth client secret." yaml:"clientSecret"`
+	ClientSecretFile string   `description:"Path to the file containing the OAuth client secret." yaml:"clientSecretFile"`
+	Scopes           []string `description:"OAuth scopes." yaml:"scopes"`
+	RedirectURL      string   `description:"OAuth redirect URL." yaml:"redirectUrl"`
+	AuthURL          string   `description:"OAuth authorization URL." yaml:"authUrl"`
+	TokenURL         string   `description:"OAuth token URL." yaml:"tokenUrl"`
+	UserinfoURL      string   `description:"OAuth userinfo URL." yaml:"userinfoUrl"`
+	Insecure         bool     `description:"Allow insecure OAuth connections." yaml:"insecure"`
+	Name             string   `description:"Provider name in UI." yaml:"name"`
 }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f3d2e14 and 195b70b.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (38)
  • .env.example (1 hunks)
  • .github/workflows/nightly.yml (2 hunks)
  • .github/workflows/release.yml (2 hunks)
  • .gitignore (1 hunks)
  • Dockerfile (2 hunks)
  • Dockerfile.dev (1 hunks)
  • Dockerfile.distroless (2 hunks)
  • air.toml (1 hunks)
  • cmd/create.go (1 hunks)
  • cmd/generate.go (1 hunks)
  • cmd/healthcheck.go (1 hunks)
  • cmd/root.go (0 hunks)
  • cmd/tinyauth.go (1 hunks)
  • cmd/verify.go (1 hunks)
  • cmd/version.go (1 hunks)
  • config.example.yaml (1 hunks)
  • docker-compose.example.yml (1 hunks)
  • frontend/src/lib/i18n/i18n.ts (0 hunks)
  • go.mod (3 hunks)
  • internal/bootstrap/app_bootstrap.go (3 hunks)
  • internal/bootstrap/router_bootstrap.go (2 hunks)
  • internal/bootstrap/service_bootstrap.go (2 hunks)
  • internal/config/config.go (2 hunks)
  • internal/service/docker_service.go (1 hunks)
  • internal/service/generic_oauth_service.go (1 hunks)
  • internal/utils/app_utils.go (0 hunks)
  • internal/utils/app_utils_test.go (0 hunks)
  • internal/utils/decoders/decoders.go (0 hunks)
  • internal/utils/decoders/env_decoder.go (0 hunks)
  • internal/utils/decoders/env_decoder_test.go (0 hunks)
  • internal/utils/decoders/flags_decoder.go (0 hunks)
  • internal/utils/decoders/flags_decoder_test.go (0 hunks)
  • internal/utils/decoders/label_decoder.go (1 hunks)
  • internal/utils/decoders/label_decoder_test.go (1 hunks)
  • internal/utils/loaders/loader_env.go (1 hunks)
  • internal/utils/loaders/loader_file.go (1 hunks)
  • internal/utils/loaders/loader_flag.go (1 hunks)
  • main.go (0 hunks)
💤 Files with no reviewable changes (10)
  • internal/utils/app_utils.go
  • main.go
  • cmd/root.go
  • internal/utils/decoders/env_decoder_test.go
  • internal/utils/decoders/env_decoder.go
  • internal/utils/decoders/flags_decoder_test.go
  • internal/utils/decoders/decoders.go
  • internal/utils/app_utils_test.go
  • internal/utils/decoders/flags_decoder.go
  • frontend/src/lib/i18n/i18n.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-06-25T14:57:03.955Z
Learnt from: steveiliop56
Repo: steveiliop56/tinyauth PR: 211
File: internal/utils/utils.go:373-407
Timestamp: 2025-06-25T14:57:03.955Z
Learning: In Go applications using the gin web framework, IP addresses extracted from gin.Context (like from request headers or remote address) are already validated by the framework and don't require additional validation in utility functions that process them.

Applied to files:

  • internal/bootstrap/router_bootstrap.go
🧬 Code graph analysis (8)
internal/service/docker_service.go (2)
internal/utils/decoders/label_decoder.go (1)
  • DecodeLabels (7-17)
internal/config/config.go (1)
  • Apps (158-160)
internal/utils/decoders/label_decoder_test.go (2)
internal/utils/decoders/label_decoder.go (1)
  • DecodeLabels (7-17)
internal/config/config.go (1)
  • Apps (158-160)
internal/utils/loaders/loader_env.go (1)
internal/config/config.go (1)
  • DefaultNamePrefix (77-77)
cmd/tinyauth.go (5)
internal/config/config.go (6)
  • Config (17-32)
  • ServerConfig (34-39)
  • AuthConfig (41-48)
  • UIConfig (56-60)
  • ExperimentalConfig (71-73)
  • Version (5-5)
internal/utils/loaders/loader_file.go (1)
  • FileLoader (10-10)
internal/utils/loaders/loader_flag.go (2)
  • FlagLoader (10-10)
  • FlagLoader (12-22)
internal/utils/loaders/loader_env.go (1)
  • EnvLoader (12-12)
internal/bootstrap/app_bootstrap.go (1)
  • NewBootstrapApp (38-42)
cmd/verify.go (2)
internal/config/config.go (1)
  • User (108-112)
internal/utils/user_utils.go (1)
  • ParseUser (63-92)
internal/bootstrap/router_bootstrap.go (1)
internal/controller/oauth_controller.go (2)
  • NewOAuthController (36-43)
  • OAuthControllerConfig (21-27)
cmd/version.go (1)
internal/config/config.go (3)
  • Version (5-5)
  • CommitHash (6-6)
  • BuildTimestamp (7-7)
cmd/generate.go (2)
internal/config/config.go (2)
  • User (108-112)
  • Config (17-32)
internal/utils/user_utils.go (1)
  • ParseUser (63-92)
🪛 dotenv-linter (4.0.0)
.env.example

[warning] 10-10: [UnorderedKey] The TINYAUTH_DATABASEPATH key should go before the TINYAUTH_LOGLEVEL key

(UnorderedKey)


[warning] 12-12: [UnorderedKey] The TINYAUTH_DISABLEANALYTICS key should go before the TINYAUTH_LOGLEVEL key

(UnorderedKey)


[warning] 14-14: [UnorderedKey] The TINYAUTH_DISABLERESOURCES key should go before the TINYAUTH_LOGLEVEL key

(UnorderedKey)


[warning] 16-16: [UnorderedKey] The TINYAUTH_DISABLEUIWARNINGS key should go before the TINYAUTH_LOGLEVEL key

(UnorderedKey)


[warning] 18-18: [UnorderedKey] The TINYAUTH_LOGJSON key should go before the TINYAUTH_LOGLEVEL key

(UnorderedKey)


[warning] 25-25: [UnorderedKey] The TINYAUTH_SERVER_ADDRESS key should go before the TINYAUTH_SERVER_PORT key

(UnorderedKey)


[warning] 38-38: [UnorderedKey] The TINYAUTH_SECURECOOKIE key should go before the TINYAUTH_USERSFILE key

(UnorderedKey)


[warning] 40-40: [UnorderedKey] The TINYAUTH_SESSIONEXPIRY key should go before the TINYAUTH_USERSFILE key

(UnorderedKey)


[warning] 42-42: [UnorderedKey] The TINYAUTH_LOGINTIMEOUT key should go before the TINYAUTH_SECURECOOKIE key

(UnorderedKey)


[warning] 44-44: [UnorderedKey] The TINYAUTH_LOGINMAXRETRIES key should go before the TINYAUTH_LOGINTIMEOUT key

(UnorderedKey)


[warning] 51-51: [UnorderedKey] The TINYAUTH_OAUTH_AUTOREDIRECT key should go before the TINYAUTH_OAUTH_WHITELIST key

(UnorderedKey)


[warning] 53-53: [UnorderedKey] The TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_CLIENTID key should go before the TINYAUTH_OAUTH_WHITELIST key

(UnorderedKey)


[warning] 54-54: [UnorderedKey] The TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_CLIENTSECRET key should go before the TINYAUTH_OAUTH_WHITELIST key

(UnorderedKey)


[warning] 55-55: [UnorderedKey] The TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_AUTHURL key should go before the TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_CLIENTID key

(UnorderedKey)


[warning] 56-56: [UnorderedKey] The TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_TOKENURL key should go before the TINYAUTH_OAUTH_WHITELIST key

(UnorderedKey)


[warning] 57-57: [UnorderedKey] The TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_USERINFOURL key should go before the TINYAUTH_OAUTH_WHITELIST key

(UnorderedKey)


[warning] 58-58: [UnorderedKey] The TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_REDIRECTURL key should go before the TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_TOKENURL key

(UnorderedKey)


[warning] 59-59: [UnorderedKey] The TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_SCOPES key should go before the TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_TOKENURL key

(UnorderedKey)


[warning] 59-59: [ValueWithoutQuotes] This value needs to be surrounded in quotes

(ValueWithoutQuotes)


[warning] 60-60: [UnorderedKey] The TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_NAME key should go before the TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_REDIRECTURL key

(UnorderedKey)


[warning] 60-60: [ValueWithoutQuotes] This value needs to be surrounded in quotes

(ValueWithoutQuotes)


[warning] 62-62: [UnorderedKey] The TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_INSECURE key should go before the TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_NAME key

(UnorderedKey)


[warning] 69-69: [UnorderedKey] The TINYAUTH_UI_FORGOTPASSWORDMESSAGE key should go before the TINYAUTH_UI_TITLE key

(UnorderedKey)


[warning] 71-71: [UnorderedKey] The TINYAUTH_UI_BACKGROUNDIMAGE key should go before the TINYAUTH_UI_FORGOTPASSWORDMESSAGE key

(UnorderedKey)


[warning] 82-82: [UnorderedKey] The TINYAUTH_LDAP_BASEDN key should go before the TINYAUTH_LDAP_BINDDN key

(UnorderedKey)


[warning] 86-86: [UnorderedKey] The TINYAUTH_LDAP_INSECURE key should go before the TINYAUTH_LDAP_SEARCHFILTER key

(UnorderedKey)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (go)
🔇 Additional comments (54)
air.toml (1)

6-6: LGTM! Build target updated correctly.

The change from . to cmd/* aligns with the CLI restructuring across the codebase and is the correct Go idiom for building all packages under the cmd directory.

Dockerfile.dev (1)

19-21: LGTM! Environment variables added for runtime configuration.

The addition of DATABASEPATH and RESOURCESDIR environment variables provides sensible defaults for development and aligns with the unified config approach across all Dockerfiles.

.github/workflows/nightly.yml (1)

83-83: LGTM! Build commands updated consistently.

Both amd64 and arm64 build steps correctly target cmd/* while preserving version injection via ldflags. The changes align with the CLI restructuring.

Also applies to: 129-129

Dockerfile (2)

40-40: Build target updated correctly.

The change to cmd/* aligns with the CLI restructuring and is consistent across all build configurations.


55-65: Runtime configuration properly configured.

The environment variables, healthcheck, and entrypoint are well-configured for the new CLI architecture:

  • Default paths for database and resources
  • Health monitoring via tinyauth healthcheck subcommand
  • Clean entrypoint for subcommand execution
.github/workflows/release.yml (1)

61-61: LGTM! Release builds updated consistently.

The build commands for both architectures correctly target cmd/* and preserve version metadata injection, consistent with the nightly workflow.

Also applies to: 104-104

Dockerfile.distroless (1)

42-42: LGTM! Distroless image properly configured.

The build target and runtime configuration (environment variables, healthcheck, entrypoint) are correctly set up for the distroless variant, matching the standard Dockerfile with appropriate distroless-specific adjustments.

Also applies to: 58-68

.env.example (1)

1-86: Well-structured configuration migration.

The restructuring to TINYAUTH_ prefixed environment variables with logical grouping (Base, Server, Auth, OAuth, UI, LDAP) significantly improves configuration clarity and organization. The hierarchical approach is a solid improvement over the flat structure.

go.mod (2)

24-69: Indirect dependency updates look routine.

The transitive dependency version bumps (OTEL, protobuf, gRPC, etc.) appear to be routine updates that come with the framework migration. No obvious compatibility concerns.


7-22: Dependency migration to Traefik Paerser v0.2.2 completed.

The removal of Cobra/Viper dependencies and addition of Traefik Paerser v0.2.2 aligns with the CLI framework migration. The dependency changes are clean and well-structured, with v0.2.2 being the current stable version integrated into recent Traefik releases.

internal/service/generic_oauth_service.go (1)

41-41: LGTM! Clean config field rename.

The OAuth service now reads the TLS insecure flag from config.Insecure instead of InsecureSkipVerify, aligning with the new configuration structure. The TLS verification behavior remains unchanged.

docker-compose.example.yml (1)

23-24: LGTM! Environment variable naming standardized.

The environment variables now use the TINYAUTH_ prefix (TINYAUTH_APPURL, TINYAUTH_AUTH_USERS), aligning with the new unified configuration structure and the DefaultNamePrefix used by the EnvLoader.

internal/service/docker_service.go (1)

85-85: LGTM! Updated to generic label decoder.

The call to DecodeLabels now uses the generic form with an explicit type parameter [config.Apps] and root key "apps", aligning with the refactored decoder signature. The decoding logic remains functionally equivalent.

internal/utils/loaders/loader_flag.go (1)

1-22: LGTM! Clean loader implementation.

The FlagLoader follows the new loader pattern with:

  • Proper early return when no args are present
  • Clear error wrapping with context
  • Appropriate use of Traefik Paerser's flag decoder

This aligns well with the unified configuration approach.

internal/bootstrap/router_bootstrap.go (4)

16-17: LGTM! Config path updated to nested structure.

TrustedProxies now accessed via app.config.Server.TrustedProxies, consistent with the new ServerConfig nesting.


60-60: LGTM! UI configuration nested appropriately.

The Title field now accessed via app.config.UI.Title, aligning with the new UIConfig structure.


63-65: LGTM! Multiple config paths updated to nested structure.

UI and OAuth configuration fields now properly accessed through their respective nested config structs:

  • UI.ForgotPasswordMessage
  • UI.BackgroundImage
  • OAuth.AutoRedirect

73-73: LGTM! Auth configuration nested appropriately.

SecureCookie now accessed via app.config.Auth.SecureCookie, consistent with the new AuthConfig structure.

cmd/tinyauth.go (5)

17-40: LGTM! Sensible default configuration.

The default configuration provides reasonable values:

  • Log level set to "info" (appropriate default)
  • Server binds to all interfaces on port 3000 (typical for containerized deployments)
  • Auth timeouts and retry limits are balanced for security and usability
  • UI defaults provide good out-of-box experience

Note: Relative paths for ResourcesDir and DatabasePath assume the working directory is the project root, which is typical for CLI applications.


45-49: LGTM! Loader precedence properly ordered.

The loaders are applied in sequence (File → Flag → Env), giving environment variables the highest precedence, which is appropriate for containerized deployments where env vars commonly override config files.


51-89: LGTM! Robust command setup with proper error handling.

The CLI command structure is well-organized:

  • Root command properly configured with configuration and loaders
  • Each subcommand addition includes immediate error checking
  • Fatal logging with descriptive messages is appropriate for initialization failures

91-95: LGTM! Clean CLI execution.

The command execution is straightforward with appropriate error handling and fatal logging for execution failures.


98-124: LGTM! Well-structured bootstrap function.

The runCmd implementation is clean and robust:

  • Log level parsing with graceful fallback to "info"
  • Conditional console/JSON logging based on configuration
  • Proper error wrapping for bootstrap failures
  • Startup logging includes version information
internal/utils/loaders/loader_env.go (1)

1-25: LGTM! Clean environment loader implementation.

The EnvLoader is well-implemented:

  • Uses config.DefaultNamePrefix (TINYAUTH_) for consistent environment variable naming
  • Proper early return when no prefixed variables are found
  • Clear error wrapping with context
  • Follows the same pattern as FlagLoader for consistency
internal/utils/decoders/label_decoder_test.go (1)

65-65: LGTM! Test updated for generic decoder.

The test correctly uses the new generic DecodeLabels[config.Apps] signature with the explicit root key "apps", maintaining test coverage for the refactored decoder.

config.example.yaml (6)

1-18: LGTM! Clear and well-documented top-level configuration.

The top-level configuration fields are well-organized with helpful inline comments explaining each option.


20-29: LGTM! Server configuration is well-structured.

The nested server configuration with optional Unix socket support is clearly documented.


31-44: LGTM! Authentication configuration is comprehensive and clear.

The auth section provides good examples and helpful time conversion comments (e.g., "3600 = 1 hour").


46-64: LGTM! OAuth configuration example is thorough.

The OAuth provider configuration template includes all necessary fields with clear placeholder values.


66-73: LGTM! UI customization options are straightforward.

Clean and simple UI configuration with sensible defaults.


75-88: LGTM! LDAP configuration is complete with a helpful example.

The LDAP section provides a practical search filter example with clear placeholder documentation.

internal/utils/loaders/loader_file.go (2)

1-8: LGTM! Package structure and imports are appropriate.

The imports correctly include the necessary Traefik Paerser components for file-based configuration loading.


12-35: Load method implementation is solid.

The load method correctly:

  • Parses flags using Paerser
  • Checks for flag presence before proceeding
  • Logs an appropriate experimental feature warning
  • Decodes the configuration file
  • Handles errors properly
internal/utils/decoders/label_decoder.go (1)

7-16: LGTM! Generic refactor improves flexibility.

The conversion to a generic function allows decoding labels into different types while maintaining type safety. The root parameter makes the decoding path configurable.

cmd/healthcheck.go (3)

22-29: LGTM! Command structure is correctly configured.

The healthcheck command is properly structured with AllowArg: true to support passing the app URL as an argument.


30-42: LGTM! APPURL handling is correct.

The code properly prioritizes the command-line argument over the environment variable and validates that a URL is provided.


64-80: LGTM! Response handling is correct.

The response parsing and error handling use proper error wrapping with %w and informative messages.

internal/bootstrap/app_bootstrap.go (4)

45-52: LGTM! User configuration updated for nested structure.

The user parsing correctly uses the new nested Auth.Users and Auth.UsersFile configuration paths.


54-82: LGTM! OAuth provider configuration is well-structured.

The OAuth provider setup correctly:

  • Loads providers from nested config
  • Handles client secret files securely (reads content, clears file path)
  • Sets sensible defaults for RedirectURL and Name
  • Maintains provider configuration consistency

168-183: LGTM! Unix socket handling includes proper cleanup.

The code correctly removes any existing socket file before binding, preventing "address already in use" errors.


186-192: LGTM! HTTP server startup uses nested server configuration.

The server binding correctly uses Server.Address and Server.Port from the new nested configuration structure.

internal/bootstrap/service_bootstrap.go (2)

33-48: LGTM! LDAP service initialization updated for nested config.

The LDAP configuration correctly uses the new nested Ldap.* configuration paths with appropriate error handling (warning on failure, continues without LDAP).


70-86: LGTM! Auth service configuration migrated to nested structure.

The auth service initialization correctly uses:

  • Auth.* fields for authentication settings
  • OAuth.Whitelist for OAuth-specific configuration
cmd/verify.go (3)

18-34: LGTM! VerifyUserConfig structure is well-defined.

The configuration struct with description tags integrates cleanly with Traefik Paerser's CLI framework.


51-83: LGTM! Interactive form provides good user experience.

The huh form correctly validates required fields while leaving TOTP optional, with proper error handling.


85-107: LGTM! User verification logic is well-structured.

The verification flow correctly:

  • Parses the user configuration
  • Validates username and password
  • Handles optional TOTP gracefully with a warning if TOTP is provided but not configured
cmd/version.go (1)

10-23: LGTM! Version command is clean and simple.

The version command correctly displays build information from the config package with a straightforward implementation.

cmd/create.go (2)

1-15: LGTM on imports and package structure.

The imports are well-organized and align with the migration to the Traefik Paerser CLI framework.


17-31: LGTM on configuration struct and constructor.

The CreateUserConfig struct and NewCreateUserConfig constructor follow the pattern established across other command modules in this PR.

cmd/generate.go (2)

1-17: LGTM on imports and package structure.

The imports are consistent with the CLI migration pattern.


19-29: LGTM on configuration struct and constructor.

The GenerateTotpConfig struct follows the established pattern.

internal/config/config.go (3)

17-32: LGTM on the restructured Config.

The migration to a hierarchical, nested configuration model improves organization and maintainability. The YAML tags and descriptions are well-defined.


34-48: LGTM on ServerConfig and AuthConfig.

Both structs have consistent YAML tags and descriptions.


56-73: LGTM on UIConfig, LdapConfig, and ExperimentalConfig.

The yaml:"-" on ConfigFile correctly excludes it from YAML parsing since it's a CLI-only option.

Comment thread cmd/tinyauth/create.go
Comment thread cmd/tinyauth/generate.go
Comment thread cmd/tinyauth/generate.go
Comment thread cmd/tinyauth/verify.go
Comment thread internal/config/config.go
Comment thread internal/utils/loaders/loader_file.go
Comment thread cmd/healthcheck.go Outdated
Comment thread internal/config/config.go
Comment thread .env.example Outdated
Comment thread .env.example Outdated
Comment thread .env.example Outdated
Comment thread config.example.yaml
@steveiliop56 steveiliop56 marked this pull request as ready for review December 22, 2025 20:01
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

♻️ Duplicate comments (3)
cmd/tinyauth/create.go (1)

93-93: Sensitive credentials still logged.

The full username:hashedPassword string is still being logged to the structured logger. While the previous review flagged this concern, it appears the fix was not applied. Logging credentials (even hashed) to stderr may expose them in log aggregation systems, CI logs, or terminal history.

🔎 Proposed fix
-			log.Info().Str("user", fmt.Sprintf("%s:%s", tCfg.Username, passwdStr)).Msg("User created")
+			log.Info().Msg("User created successfully")
+			fmt.Printf("User credentials: %s:%s\n", tCfg.Username, passwdStr)
cmd/tinyauth/generate.go (2)

82-93: Avoid logging TOTP secrets.

Line 93 logs the raw TOTP secret, which exposes sensitive authentication material to log outputs. The secret is already displayed to the user via the QR code. This issue was previously flagged and remains unaddressed in the migration to the new CLI framework.

🔎 Proposed fix
-			log.Info().Str("secret", secret).Msg("Generated TOTP secret")
+			log.Info().Msg("Generated TOTP secret (see QR code below)")

109-117: Avoid logging full user credentials including TOTP secret.

Line 114 logs the complete user credentials (username, password hash, and TOTP secret) to structured logs. This exposes sensitive authentication data to log outputs. This issue was previously flagged and remains unaddressed in the migration. Consider printing to stdout instead or removing the structured field.

🔎 Proposed fix
-			log.Info().Str("user", fmt.Sprintf("%s:%s:%s", user.Username, user.Password, user.TotpSecret)).Msg("Add the totp secret to your authenticator app then use the verify command to ensure everything is working correctly.")
+			log.Info().Msg("Add the TOTP secret to your authenticator app, then use the verify command to ensure everything is working correctly.")
+			fmt.Printf("Updated user: %s:%s:%s\n", user.Username, user.Password, user.TotpSecret)
🧹 Nitpick comments (1)
cmd/tinyauth/tinyauth.go (1)

45-49: Variable shadows imported package name.

The local variable loaders shadows the imported package tinyauth/internal/utils/loaders on line 10. While this doesn't cause a runtime issue here since the package isn't used after this point, it reduces code clarity and could cause confusion during maintenance.

🔎 Suggested rename
-	loaders := []cli.ResourceLoader{
+	resourceLoaders := []cli.ResourceLoader{
 		&loaders.FileLoader{},
 		&loaders.FlagLoader{},
 		&loaders.EnvLoader{},
 	}

And update line 55:

-		Resources:     loaders,
+		Resources:     resourceLoaders,
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 195b70b and db4ed94.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (19)
  • .env.example
  • .github/workflows/nightly.yml
  • .github/workflows/release.yml
  • .gitignore
  • Dockerfile
  • Dockerfile.distroless
  • air.toml
  • cmd/tinyauth/create.go
  • cmd/tinyauth/generate.go
  • cmd/tinyauth/healthcheck.go
  • cmd/tinyauth/tinyauth.go
  • cmd/tinyauth/verify.go
  • cmd/tinyauth/version.go
  • go.mod
  • internal/bootstrap/app_bootstrap.go
  • internal/config/config.go
  • internal/service/generic_oauth_service.go
  • internal/service/github_oauth_service.go
  • internal/service/google_oauth_service.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • .github/workflows/release.yml
  • .github/workflows/nightly.yml
  • .gitignore
🧰 Additional context used
🧬 Code graph analysis (5)
internal/service/github_oauth_service.go (1)
internal/service/oauth_broker_service.go (1)
  • Init (11-19)
cmd/tinyauth/generate.go (5)
internal/config/config.go (2)
  • User (108-112)
  • Config (17-32)
internal/utils/user_utils.go (1)
  • ParseUser (63-92)
cmd/generate.go (3)
  • c (52-120)
  • c (32-46)
  • c (48-50)
cmd/verify.go (1)
  • c (55-118)
cmd/create.go (2)
  • c (53-99)
  • c (31-47)
cmd/tinyauth/verify.go (2)
internal/config/config.go (1)
  • User (108-112)
internal/utils/user_utils.go (1)
  • ParseUser (63-92)
cmd/tinyauth/tinyauth.go (4)
internal/config/config.go (6)
  • Config (17-32)
  • ServerConfig (34-39)
  • AuthConfig (41-48)
  • UIConfig (56-60)
  • ExperimentalConfig (71-73)
  • Version (5-5)
internal/utils/loaders/loader_file.go (1)
  • FileLoader (10-10)
internal/utils/loaders/loader_env.go (1)
  • EnvLoader (12-12)
internal/bootstrap/app_bootstrap.go (1)
  • NewBootstrapApp (38-42)
cmd/tinyauth/version.go (1)
internal/config/config.go (3)
  • Version (5-5)
  • CommitHash (6-6)
  • BuildTimestamp (7-7)
🪛 dotenv-linter (4.0.0)
.env.example

[warning] 4-4: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 6-6: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 8-8: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 10-10: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 10-10: [UnorderedKey] The TINYAUTH_DATABASEPATH key should go before the TINYAUTH_LOGLEVEL key

(UnorderedKey)


[warning] 12-12: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 12-12: [UnorderedKey] The TINYAUTH_DISABLEANALYTICS key should go before the TINYAUTH_LOGLEVEL key

(UnorderedKey)


[warning] 14-14: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 14-14: [UnorderedKey] The TINYAUTH_DISABLERESOURCES key should go before the TINYAUTH_LOGLEVEL key

(UnorderedKey)


[warning] 16-16: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 16-16: [UnorderedKey] The TINYAUTH_DISABLEUIWARNINGS key should go before the TINYAUTH_LOGLEVEL key

(UnorderedKey)


[warning] 18-18: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 18-18: [UnorderedKey] The TINYAUTH_LOGJSON key should go before the TINYAUTH_LOGLEVEL key

(UnorderedKey)


[warning] 23-23: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 25-25: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 25-25: [UnorderedKey] The TINYAUTH_SERVER_ADDRESS key should go before the TINYAUTH_SERVER_PORT key

(UnorderedKey)


[warning] 27-27: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 29-29: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 36-36: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 38-38: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 38-38: [UnorderedKey] The TINYAUTH_SECURECOOKIE key should go before the TINYAUTH_USERSFILE key

(UnorderedKey)


[warning] 40-40: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 40-40: [UnorderedKey] The TINYAUTH_SESSIONEXPIRY key should go before the TINYAUTH_USERSFILE key

(UnorderedKey)


[warning] 42-42: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 42-42: [UnorderedKey] The TINYAUTH_LOGINTIMEOUT key should go before the TINYAUTH_SECURECOOKIE key

(UnorderedKey)


[warning] 44-44: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 44-44: [UnorderedKey] The TINYAUTH_LOGINMAXRETRIES key should go before the TINYAUTH_LOGINTIMEOUT key

(UnorderedKey)


[warning] 49-49: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 51-51: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 51-51: [UnorderedKey] The TINYAUTH_OAUTH_AUTOREDIRECT key should go before the TINYAUTH_OAUTH_WHITELIST key

(UnorderedKey)


[warning] 53-53: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 53-53: [UnorderedKey] The TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_CLIENTID key should go before the TINYAUTH_OAUTH_WHITELIST key

(UnorderedKey)


[warning] 54-54: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 54-54: [UnorderedKey] The TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_CLIENTSECRET key should go before the TINYAUTH_OAUTH_WHITELIST key

(UnorderedKey)


[warning] 55-55: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 55-55: [UnorderedKey] The TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_AUTHURL key should go before the TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_CLIENTID key

(UnorderedKey)


[warning] 56-56: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 56-56: [UnorderedKey] The TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_TOKENURL key should go before the TINYAUTH_OAUTH_WHITELIST key

(UnorderedKey)


[warning] 57-57: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 57-57: [UnorderedKey] The TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_USERINFOURL key should go before the TINYAUTH_OAUTH_WHITELIST key

(UnorderedKey)


[warning] 58-58: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 58-58: [UnorderedKey] The TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_REDIRECTURL key should go before the TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_TOKENURL key

(UnorderedKey)


[warning] 59-59: [UnorderedKey] The TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_SCOPES key should go before the TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_TOKENURL key

(UnorderedKey)


[warning] 60-60: [UnorderedKey] The TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_NAME key should go before the TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_REDIRECTURL key

(UnorderedKey)


[warning] 62-62: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 62-62: [UnorderedKey] The TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_INSECURE key should go before the TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_NAME key

(UnorderedKey)


[warning] 67-67: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 69-69: [UnorderedKey] The TINYAUTH_UI_FORGOTPASSWORDMESSAGE key should go before the TINYAUTH_UI_TITLE key

(UnorderedKey)


[warning] 71-71: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 71-71: [UnorderedKey] The TINYAUTH_UI_BACKGROUNDIMAGE key should go before the TINYAUTH_UI_FORGOTPASSWORDMESSAGE key

(UnorderedKey)


[warning] 76-76: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 80-80: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 82-82: [UnorderedKey] The TINYAUTH_LDAP_BASEDN key should go before the TINYAUTH_LDAP_BINDDN key

(UnorderedKey)


[warning] 86-86: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 86-86: [UnorderedKey] The TINYAUTH_LDAP_INSECURE key should go before the TINYAUTH_LDAP_SEARCHFILTER key

(UnorderedKey)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (go)
🔇 Additional comments (32)
go.mod (2)

7-22: Removed direct dependencies are no longer used in code.

Verification confirms that github.com/spf13/cobra, github.com/spf13/viper, github.com/go-playground/validator, and github.com/stoewer/go-strcase have no direct imports in the codebase. These packages may still be present as indirect dependencies of other libraries, but there are no direct usages.


26-29: The new indirect dependencies (BurntSushi/toml, Masterminds utilities, mergo, copystructure, reflectwalk, decimal) align well with the migration to Traefik Paerser and the hierarchical config refactoring. These are expected transitive dependencies when adopting traefik/paerser for configuration loading.

Note: The concern about gopkg.in/yaml.v3 version downgrade is not valid—v3.0.1 is the current stable release; no v3.0.4 release exists.

.env.example (1)

1-86: LGTM! Environment variables properly organized and quoted.

The migration to TINYAUTH_ prefixed environment variables with logical sectioning (Base, Server, Authentication, OAuth, UI, LDAP) improves clarity. The quotes on all values align with past review feedback requesting consistency.

Note: The static analysis warnings about quote characters and key ordering can be safely ignored. The quotes were explicitly requested in previous reviews, and the logical sectioned grouping is more maintainable than strict alphabetical ordering.

air.toml (1)

6-6: LGTM! Build target updated correctly.

The build command now targets ./cmd/tinyauth, consistent with the package restructuring in this PR.

internal/service/google_oauth_service.go (1)

47-55: LGTM! HTTP client timeout improves resilience.

The 30-second timeout prevents indefinite hangs during OAuth flows with Google's endpoints, improving reliability.

internal/service/github_oauth_service.go (1)

52-60: LGTM! HTTP client timeout improves resilience.

The 30-second timeout prevents indefinite hangs during OAuth flows with GitHub's endpoints, consistent with the timeout applied to other OAuth providers.

internal/service/generic_oauth_service.go (2)

29-45: LGTM! Field name simplified.

The field name change from config.InsecureSkipVerify to config.Insecure is more concise and aligns with the config restructuring in this PR.


47-66: LGTM! HTTP client timeout improves resilience.

The 30-second timeout prevents indefinite hangs during OAuth flows with generic providers, consistent with timeouts applied to GitHub and Google OAuth services.

cmd/tinyauth/version.go (1)

10-23: LGTM! Version command properly structured.

The Traefik Paerser CLI-based version command cleanly prints version metadata from the config package.

Dockerfile.distroless (1)

42-42: LGTM! Build target updated correctly.

The build command now targets ./cmd/tinyauth, consistent with the package restructuring.

cmd/tinyauth/healthcheck.go (1)

42-83: LGTM! Healthcheck implementation is robust.

The healthcheck logic properly validates the URL, includes a 30-second timeout, handles errors gracefully, and provides structured logging.

cmd/tinyauth/tinyauth.go (1)

98-124: LGTM!

The runCmd function correctly sets up logging with fallback behavior, initializes the bootstrap app, and propagates errors appropriately. The logging configuration with conditional JSON/console output and caller information is well implemented.

Dockerfile (1)

40-40: LGTM!

The build path correctly points to the new ./cmd/tinyauth package location, and the ldflags properly inject version metadata.

internal/bootstrap/app_bootstrap.go (3)

54-62: LGTM!

The OAuth provider setup correctly loads client secrets from files when specified, clears the file path after loading for security, and properly reassigns the modified provider back to the map.


64-82: LGTM!

The provider configuration logic correctly handles override providers by setting default redirect URLs and provider names with appropriate fallback behavior.


168-190: LGTM!

The server startup logic correctly handles both Unix socket and TCP modes, properly cleans up existing socket files, and uses the nested Server configuration consistently.

cmd/tinyauth/verify.go (1)

109-117: LGTM!

The TOTP validation error handling has been corrected to return a proper error message without incorrectly wrapping the stale err variable from the bcrypt comparison.

cmd/tinyauth/create.go (1)

76-91: LGTM!

The input validation, bcrypt password hashing with default cost, and Docker-specific dollar sign escaping are correctly implemented.

cmd/tinyauth/generate.go (7)

1-17: LGTM!

The imports and package structure are appropriate for the TOTP generation command functionality.


19-22: LGTM!

The configuration struct is well-defined with appropriate description tags for CLI integration.


24-29: LGTM!

The constructor follows standard patterns and initializes with appropriate defaults.


31-44: LGTM!

The command setup properly integrates with the Traefik Paerser CLI framework, and the logger configuration is appropriate for a CLI tool.


46-65: LGTM!

The interactive form implementation is clean, and the error handling is improved compared to the previous Cobra-based implementation.


67-80: LGTM!

The user parsing, Docker detection, and TOTP secret validation logic is correct and includes appropriate error handling.


95-107: LGTM!

The QR code generation and configuration is correct, with output appropriately directed to stdout for user scanning.

internal/config/config.go (7)

17-32: LGTM!

The hierarchical configuration structure is well-designed with comprehensive description and YAML tags. The nested approach improves configuration organization and maintainability.


34-39: LGTM!

The ServerConfig struct is well-defined with appropriate field types and comprehensive tagging.


41-48: LGTM!

The AuthConfig struct is well-defined with appropriate field types and comprehensive tagging for authentication settings.


50-54: LGTM!

The OAuthConfig struct is well-defined. The Providers field now includes both description and yaml tags, addressing the previous review comment.


56-69: LGTM!

The UIConfig and LdapConfig structs are well-defined with comprehensive tagging for their respective configuration domains.


71-77: LGTM!

The ExperimentalConfig struct appropriately excludes ConfigFile from YAML serialization using yaml:"-", and the DefaultNamePrefix constant is well-defined for environment variable loading.


88-99: LGTM!

The OAuthServiceConfig struct is well-defined with comprehensive description tags. The absence of yaml tags is appropriate since this struct is used as a map value in the Providers configuration.

Comment thread cmd/tinyauth/healthcheck.go
Comment thread cmd/tinyauth/verify.go
Comment thread Dockerfile
Comment thread Dockerfile.distroless Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented Dec 22, 2025

Codecov Report

❌ Patch coverage is 1.13636% with 348 lines in your changes missing coverage. Please review.
✅ Project coverage is 20.34%. Comparing base (f3d2e14) to head (0a7e259).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
cmd/tinyauth/tinyauth.go 0.00% 69 Missing ⚠️
cmd/tinyauth/generate.go 0.00% 55 Missing ⚠️
cmd/tinyauth/verify.go 0.00% 55 Missing ⚠️
cmd/tinyauth/create.go 0.00% 43 Missing ⚠️
cmd/tinyauth/healthcheck.go 0.00% 35 Missing ⚠️
internal/bootstrap/app_bootstrap.go 0.00% 28 Missing ⚠️
cmd/tinyauth/version.go 0.00% 12 Missing ⚠️
internal/utils/loaders/loader_file.go 0.00% 12 Missing ⚠️
internal/bootstrap/service_bootstrap.go 0.00% 11 Missing ⚠️
internal/bootstrap/router_bootstrap.go 0.00% 7 Missing ⚠️
... and 7 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #533      +/-   ##
==========================================
- Coverage   23.37%   20.34%   -3.03%     
==========================================
  Files          38       37       -1     
  Lines        2263     2123     -140     
==========================================
- Hits          529      432      -97     
+ Misses       1697     1661      -36     
+ Partials       37       30       -7     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@steveiliop56 steveiliop56 merged commit 03ed183 into main Dec 22, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants