mirror of
				https://github.com/steveiliop56/tinyauth.git
				synced 2025-10-31 14:15:50 +00:00 
			
		
		
		
	Compare commits
	
		
			2 Commits
		
	
	
		
			v4.0.0-alp
			...
			feat/analy
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 902574e501 | ||
|   | aac19d4d5a | 
							
								
								
									
										17
									
								
								.env.example
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								.env.example
									
									
									
									
									
								
							| @@ -4,6 +4,20 @@ APP_URL=http://localhost:3000 | |||||||
| USERS=your_user_password_hash | USERS=your_user_password_hash | ||||||
| USERS_FILE=users_file | USERS_FILE=users_file | ||||||
| SECURE_COOKIE=false | SECURE_COOKIE=false | ||||||
|  | GITHUB_CLIENT_ID=github_client_id | ||||||
|  | GITHUB_CLIENT_SECRET=github_client_secret | ||||||
|  | GITHUB_CLIENT_SECRET_FILE=github_client_secret_file | ||||||
|  | GOOGLE_CLIENT_ID=google_client_id | ||||||
|  | GOOGLE_CLIENT_SECRET=google_client_secret | ||||||
|  | GOOGLE_CLIENT_SECRET_FILE=google_client_secret_file | ||||||
|  | GENERIC_CLIENT_ID=generic_client_id | ||||||
|  | GENERIC_CLIENT_SECRET=generic_client_secret | ||||||
|  | GENERIC_CLIENT_SECRET_FILE=generic_client_secret_file | ||||||
|  | GENERIC_SCOPES=generic_scopes | ||||||
|  | GENERIC_AUTH_URL=generic_auth_url | ||||||
|  | GENERIC_TOKEN_URL=generic_token_url | ||||||
|  | GENERIC_USER_URL=generic_user_url | ||||||
|  | DISABLE_CONTINUE=false | ||||||
| OAUTH_WHITELIST= | OAUTH_WHITELIST= | ||||||
| GENERIC_NAME=My OAuth | GENERIC_NAME=My OAuth | ||||||
| SESSION_EXPIRY=7200 | SESSION_EXPIRY=7200 | ||||||
| @@ -17,6 +31,3 @@ BACKGROUND_IMAGE=some_image_url | |||||||
| GENERIC_SKIP_SSL=false | GENERIC_SKIP_SSL=false | ||||||
| RESOURCES_DIR=/data/resources | RESOURCES_DIR=/data/resources | ||||||
| DATABASE_PATH=/data/tinyauth.db | DATABASE_PATH=/data/tinyauth.db | ||||||
| DISABLE_ANALYTICS=false |  | ||||||
| DISABLE_RESOURCES=false |  | ||||||
| TRUSTED_PROXIES= |  | ||||||
							
								
								
									
										4
									
								
								.github/workflows/nightly.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/nightly.yml
									
									
									
									
										vendored
									
									
								
							| @@ -80,7 +80,7 @@ jobs: | |||||||
|       - name: Build |       - name: Build | ||||||
|         run: | |         run: | | ||||||
|           cp -r frontend/dist internal/assets/dist |           cp -r frontend/dist internal/assets/dist | ||||||
|           go build -ldflags "-s -w -X tinyauth/internal/config.Version=${{ needs.generate-metadata.outputs.VERSION }} -X tinyauth/internal/config.CommitHash=${{ needs.generate-metadata.outputs.COMMIT_HASH }} -X tinyauth/internal/config.BuildTimestamp=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }}" -o tinyauth-amd64 |           go build -ldflags "-s -w -X tinyauth/internal/constants.Version=${{ needs.generate-metadata.outputs.VERSION }} -X tinyauth/internal/constants.CommitHash=${{ needs.generate-metadata.outputs.COMMIT_HASH }} -X tinyauth/internal/constants.BuildTimestamp=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }}" -o tinyauth-amd64 | ||||||
|         env: |         env: | ||||||
|           CGO_ENABLED: 0 |           CGO_ENABLED: 0 | ||||||
|  |  | ||||||
| @@ -126,7 +126,7 @@ jobs: | |||||||
|       - name: Build |       - name: Build | ||||||
|         run: | |         run: | | ||||||
|           cp -r frontend/dist internal/assets/dist |           cp -r frontend/dist internal/assets/dist | ||||||
|           go build -ldflags "-s -w -X tinyauth/internal/config.Version=${{ needs.generate-metadata.outputs.VERSION }} -X tinyauth/internal/config.CommitHash=${{ needs.generate-metadata.outputs.COMMIT_HASH }} -X tinyauth/internal/config.BuildTimestamp=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }}" -o tinyauth-arm64 |           go build -ldflags "-s -w -X tinyauth/internal/constants.Version=${{ needs.generate-metadata.outputs.VERSION }} -X tinyauth/internal/constants.CommitHash=${{ needs.generate-metadata.outputs.COMMIT_HASH }} -X tinyauth/internal/constants.BuildTimestamp=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }}" -o tinyauth-arm64 | ||||||
|         env: |         env: | ||||||
|           CGO_ENABLED: 0 |           CGO_ENABLED: 0 | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							| @@ -58,7 +58,7 @@ jobs: | |||||||
|       - name: Build |       - name: Build | ||||||
|         run: | |         run: | | ||||||
|           cp -r frontend/dist internal/assets/dist |           cp -r frontend/dist internal/assets/dist | ||||||
|           go build -ldflags "-s -w -X tinyauth/internal/config.Version=${{ needs.generate-metadata.outputs.VERSION }} -X tinyauth/internal/config.CommitHash=${{ needs.generate-metadata.outputs.COMMIT_HASH }} -X tinyauth/internal/config.BuildTimestamp=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }}" -o tinyauth-amd64 |           go build -ldflags "-s -w -X tinyauth/internal/constants.Version=${{ needs.generate-metadata.outputs.VERSION }} -X tinyauth/internal/constants.CommitHash=${{ needs.generate-metadata.outputs.COMMIT_HASH }} -X tinyauth/internal/constants.BuildTimestamp=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }}" -o tinyauth-amd64 | ||||||
|         env: |         env: | ||||||
|           CGO_ENABLED: 0 |           CGO_ENABLED: 0 | ||||||
|  |  | ||||||
| @@ -101,7 +101,7 @@ jobs: | |||||||
|       - name: Build |       - name: Build | ||||||
|         run: | |         run: | | ||||||
|           cp -r frontend/dist internal/assets/dist |           cp -r frontend/dist internal/assets/dist | ||||||
|           go build -ldflags "-s -w -X tinyauth/internal/config.Version=${{ needs.generate-metadata.outputs.VERSION }} -X tinyauth/internal/config.CommitHash=${{ needs.generate-metadata.outputs.COMMIT_HASH }} -X tinyauth/internal/config.BuildTimestamp=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }}" -o tinyauth-arm64 |           go build -ldflags "-s -w -X tinyauth/internal/constants.Version=${{ needs.generate-metadata.outputs.VERSION }} -X tinyauth/internal/constants.CommitHash=${{ needs.generate-metadata.outputs.COMMIT_HASH }} -X tinyauth/internal/constants.BuildTimestamp=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }}" -o tinyauth-arm64 | ||||||
|         env: |         env: | ||||||
|           CGO_ENABLED: 0 |           CGO_ENABLED: 0 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -38,7 +38,7 @@ COPY ./cmd ./cmd | |||||||
| COPY ./internal ./internal | COPY ./internal ./internal | ||||||
| COPY --from=frontend-builder /frontend/dist ./internal/assets/dist | COPY --from=frontend-builder /frontend/dist ./internal/assets/dist | ||||||
|  |  | ||||||
| RUN CGO_ENABLED=0 go build -ldflags "-s -w -X tinyauth/internal/config.Version=${VERSION} -X tinyauth/internal/config.CommitHash=${COMMIT_HASH} -X tinyauth/internal/config.BuildTimestamp=${BUILD_TIMESTAMP}"  | RUN CGO_ENABLED=0 go build -ldflags "-s -w -X tinyauth/internal/constants.Version=${VERSION} -X tinyauth/internal/constants.CommitHash=${COMMIT_HASH} -X tinyauth/internal/constants.BuildTimestamp=${BUILD_TIMESTAMP}"  | ||||||
|   |   | ||||||
| # Runner | # Runner | ||||||
| FROM alpine:3.22 AS runner | FROM alpine:3.22 AS runner | ||||||
|   | |||||||
| @@ -95,7 +95,6 @@ func init() { | |||||||
| 		{"database-path", "/data/tinyauth.db", "Path to the Sqlite database file."}, | 		{"database-path", "/data/tinyauth.db", "Path to the Sqlite database file."}, | ||||||
| 		{"trusted-proxies", "", "Comma separated list of trusted proxies (IP addresses or CIDRs) for correct client IP detection."}, | 		{"trusted-proxies", "", "Comma separated list of trusted proxies (IP addresses or CIDRs) for correct client IP detection."}, | ||||||
| 		{"disable-analytics", false, "Disable anonymous version collection."}, | 		{"disable-analytics", false, "Disable anonymous version collection."}, | ||||||
| 		{"disable-resources", false, "Disable the resources server."}, |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for _, opt := range configOptions { | 	for _, opt := range configOptions { | ||||||
|   | |||||||
| @@ -70,7 +70,7 @@ var VerifyCmd = &cobra.Command{ | |||||||
|  |  | ||||||
| 		err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(iPassword)) | 		err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(iPassword)) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Fatal().Msg("Password is incorrect") | 			log.Fatal().Msg("Ppassword is incorrect") | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if user.TotpSecret == "" { | 		if user.TotpSecret == "" { | ||||||
|   | |||||||
| @@ -34,10 +34,6 @@ services: | |||||||
|     build: |     build: | ||||||
|       context: . |       context: . | ||||||
|       dockerfile: Dockerfile.dev |       dockerfile: Dockerfile.dev | ||||||
|       args: |  | ||||||
|         - VERSION=development |  | ||||||
|         - COMMIT_HASH=development |  | ||||||
|         - BUILD_TIMESTAMP=000-00-00T00:00:00Z |  | ||||||
|     env_file: .env |     env_file: .env | ||||||
|     volumes: |     volumes: | ||||||
|       - ./internal:/tinyauth/internal |       - ./internal:/tinyauth/internal | ||||||
|   | |||||||
| @@ -188,18 +188,14 @@ func (app *BootstrapApp) Setup() error { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Create engine | 	// Create engine | ||||||
| 	if config.Version != "development" { |  | ||||||
| 		gin.SetMode(gin.ReleaseMode) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	engine := gin.New() | 	engine := gin.New() | ||||||
|  |  | ||||||
| 	if len(app.config.TrustedProxies) > 0 { | 	if len(app.config.TrustedProxies) > 0 { | ||||||
| 		err := engine.SetTrustedProxies(strings.Split(app.config.TrustedProxies, ",")) | 		engine.SetTrustedProxies(strings.Split(app.config.TrustedProxies, ",")) | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 		if err != nil { | 	if config.Version != "development" { | ||||||
| 			return fmt.Errorf("failed to set trusted proxies: %w", err) | 		gin.SetMode(gin.ReleaseMode) | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Create middlewares | 	// Create middlewares | ||||||
| @@ -255,8 +251,7 @@ func (app *BootstrapApp) Setup() error { | |||||||
| 	}, apiRouter, authService) | 	}, apiRouter, authService) | ||||||
|  |  | ||||||
| 	resourcesController := controller.NewResourcesController(controller.ResourcesControllerConfig{ | 	resourcesController := controller.NewResourcesController(controller.ResourcesControllerConfig{ | ||||||
| 		ResourcesDir:      app.config.ResourcesDir, | 		ResourcesDir: app.config.ResourcesDir, | ||||||
| 		ResourcesDisabled: app.config.DisableResources, |  | ||||||
| 	}, mainRouter) | 	}, mainRouter) | ||||||
|  |  | ||||||
| 	healthController := controller.NewHealthController(apiRouter) | 	healthController := controller.NewHealthController(apiRouter) | ||||||
| @@ -338,8 +333,8 @@ func (app *BootstrapApp) heartbeat() { | |||||||
|  |  | ||||||
| 		res.Body.Close() | 		res.Body.Close() | ||||||
|  |  | ||||||
| 		if res.StatusCode != 200 && res.StatusCode != 201 { | 		if res.StatusCode != 200 { | ||||||
| 			log.Debug().Str("status", res.Status).Msg("Heartbeat returned non-200/201 status") | 			log.Debug().Str("status", res.Status).Msg("Heartbeat returned non-200 status") | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,8 +3,8 @@ package config | |||||||
| // Version information, set at build time | // Version information, set at build time | ||||||
|  |  | ||||||
| var Version = "development" | var Version = "development" | ||||||
| var CommitHash = "development" | var CommitHash = "n/a" | ||||||
| var BuildTimestamp = "0000-00-00T00:00:00Z" | var BuildTimestamp = "n/a" | ||||||
|  |  | ||||||
| // Cookie name templates | // Cookie name templates | ||||||
|  |  | ||||||
| @@ -40,7 +40,6 @@ type Config struct { | |||||||
| 	DatabasePath          string `mapstructure:"database-path" validate:"required"` | 	DatabasePath          string `mapstructure:"database-path" validate:"required"` | ||||||
| 	TrustedProxies        string `mapstructure:"trusted-proxies"` | 	TrustedProxies        string `mapstructure:"trusted-proxies"` | ||||||
| 	DisableAnalytics      bool   `mapstructure:"disable-analytics"` | 	DisableAnalytics      bool   `mapstructure:"disable-analytics"` | ||||||
| 	DisableResources      bool   `mapstructure:"disable-resources"` |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // OAuth/OIDC config | // OAuth/OIDC config | ||||||
|   | |||||||
| @@ -7,8 +7,7 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| type ResourcesControllerConfig struct { | type ResourcesControllerConfig struct { | ||||||
| 	ResourcesDir      string | 	ResourcesDir string | ||||||
| 	ResourcesDisabled bool |  | ||||||
| } | } | ||||||
|  |  | ||||||
| type ResourcesController struct { | type ResourcesController struct { | ||||||
| @@ -39,12 +38,5 @@ func (controller *ResourcesController) resourcesHandler(c *gin.Context) { | |||||||
| 		}) | 		}) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if controller.config.ResourcesDisabled { |  | ||||||
| 		c.JSON(403, gin.H{ |  | ||||||
| 			"status":  403, |  | ||||||
| 			"message": "Resources are disabled", |  | ||||||
| 		}) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	controller.fileServer.ServeHTTP(c.Writer, c.Request) | 	controller.fileServer.ServeHTTP(c.Writer, c.Request) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -50,7 +50,7 @@ func (broker *OAuthBrokerService) Init() error { | |||||||
| 			log.Error().Err(err).Msgf("Failed to initialize OAuth service: %T", name) | 			log.Error().Err(err).Msgf("Failed to initialize OAuth service: %T", name) | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 		log.Info().Str("service", service.GetName()).Msg("Initialized OAuth service") | 		log.Info().Msgf("Initialized OAuth service: %T", name) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
|   | |||||||
| @@ -18,14 +18,10 @@ func NormalizeKeys(keys map[string]string, rootName string, sep string) map[stri | |||||||
|  |  | ||||||
| 		finalKey = append(finalKey, rootName) | 		finalKey = append(finalKey, rootName) | ||||||
| 		finalKey = append(finalKey, "providers") | 		finalKey = append(finalKey, "providers") | ||||||
| 		lowerKey := strings.ToLower(k) | 		cebabKey := strings.ToLower(k) | ||||||
|  |  | ||||||
| 		if !strings.HasPrefix(lowerKey, "providers"+sep) { |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		for _, known := range knownKeys { | 		for _, known := range knownKeys { | ||||||
| 			if strings.HasSuffix(lowerKey, strings.ReplaceAll(known, "-", sep)) { | 			if strings.HasSuffix(cebabKey, strings.ReplaceAll(known, "-", sep)) { | ||||||
| 				suffix = known | 				suffix = known | ||||||
| 				break | 				break | ||||||
| 			} | 			} | ||||||
| @@ -35,11 +31,7 @@ func NormalizeKeys(keys map[string]string, rootName string, sep string) map[stri | |||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if strings.TrimSpace(strings.TrimSuffix(strings.TrimPrefix(lowerKey, "providers"+sep), strings.ReplaceAll(suffix, "-", sep))) == "" { | 		clientNameParts := strings.Split(strings.TrimPrefix(strings.TrimSuffix(cebabKey, sep+strings.ReplaceAll(suffix, "-", sep)), "providers"+sep), sep) | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		clientNameParts := strings.Split(strings.TrimPrefix(strings.TrimSuffix(lowerKey, sep+strings.ReplaceAll(suffix, "-", sep)), "providers"+sep), sep) |  | ||||||
|  |  | ||||||
| 		for i, p := range clientNameParts { | 		for i, p := range clientNameParts { | ||||||
| 			if i == 0 { | 			if i == 0 { | ||||||
| @@ -54,9 +46,9 @@ func NormalizeKeys(keys map[string]string, rootName string, sep string) map[stri | |||||||
|  |  | ||||||
| 		finalKey = append(finalKey, camelClientName) | 		finalKey = append(finalKey, camelClientName) | ||||||
|  |  | ||||||
| 		fieldParts := strings.Split(suffix, "-") | 		filedParts := strings.Split(suffix, "-") | ||||||
|  |  | ||||||
| 		for i, p := range fieldParts { | 		for i, p := range filedParts { | ||||||
| 			if i == 0 { | 			if i == 0 { | ||||||
| 				camelField += p | 				camelField += p | ||||||
| 				continue | 				continue | ||||||
|   | |||||||
| @@ -14,8 +14,6 @@ func TestNormalizeKeys(t *testing.T) { | |||||||
| 		"PROVIDERS_CLIENT1_CLIENT_SECRET":                "my-client-secret", | 		"PROVIDERS_CLIENT1_CLIENT_SECRET":                "my-client-secret", | ||||||
| 		"PROVIDERS_MY_AWESOME_CLIENT_CLIENT_ID":          "my-awesome-client-id", | 		"PROVIDERS_MY_AWESOME_CLIENT_CLIENT_ID":          "my-awesome-client-id", | ||||||
| 		"PROVIDERS_MY_AWESOME_CLIENT_CLIENT_SECRET_FILE": "/path/to/secret", | 		"PROVIDERS_MY_AWESOME_CLIENT_CLIENT_SECRET_FILE": "/path/to/secret", | ||||||
| 		"I_LOOK_LIKE_A_KEY_CLIENT_ID":                    "should-not-appear", |  | ||||||
| 		"PROVIDERS_CLIENT_ID":                            "should-not-appear", |  | ||||||
| 	} | 	} | ||||||
| 	expected := map[string]string{ | 	expected := map[string]string{ | ||||||
| 		"tinyauth.providers.client1.clientId":                 "my-client-id", | 		"tinyauth.providers.client1.clientId":                 "my-client-id", | ||||||
| @@ -33,9 +31,6 @@ func TestNormalizeKeys(t *testing.T) { | |||||||
| 		"providers-client1-client-secret":                "my-client-secret", | 		"providers-client1-client-secret":                "my-client-secret", | ||||||
| 		"providers-my-awesome-client-client-id":          "my-awesome-client-id", | 		"providers-my-awesome-client-client-id":          "my-awesome-client-id", | ||||||
| 		"providers-my-awesome-client-client-secret-file": "/path/to/secret", | 		"providers-my-awesome-client-client-secret-file": "/path/to/secret", | ||||||
| 		"providers-should-not-appear-client":             "should-not-appear", |  | ||||||
| 		"i-look-like-a-key-client-id":                    "should-not-appear", |  | ||||||
| 		"providers-client-id":                            "should-not-appear", |  | ||||||
| 	} | 	} | ||||||
| 	expected = map[string]string{ | 	expected = map[string]string{ | ||||||
| 		"tinyauth.providers.client1.clientId":                 "my-client-id", | 		"tinyauth.providers.client1.clientId":                 "my-client-id", | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user