mirror of
				https://github.com/steveiliop56/tinyauth.git
				synced 2025-10-29 21:25:43 +00:00 
			
		
		
		
	Compare commits
	
		
			8 Commits
		
	
	
		
			v3.6.0
			...
			v3.6.1-bet
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 3215bb6baa | ||
|   | a11aba72d8 | ||
|   | 10d1b48505 | ||
|   | f73eb9571f | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | da2877a682 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 33cbfef02a | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | c1a6428ed3 | ||
| ![github-actions[bot]](/assets/img/avatar_default.png)  | 2ee7932cba | 
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -13,9 +13,6 @@ users.txt | |||||||
| # secret test file | # secret test file | ||||||
| secret* | secret* | ||||||
|  |  | ||||||
| # vscode |  | ||||||
| .vscode |  | ||||||
|  |  | ||||||
| # apple stuff | # apple stuff | ||||||
| .DS_Store | .DS_Store | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | { | ||||||
|  |   "version": "0.2.0", | ||||||
|  |   "configurations": [ | ||||||
|  |     { | ||||||
|  |       "name": "Connect to server", | ||||||
|  |       "type": "go", | ||||||
|  |       "request": "attach", | ||||||
|  |       "mode": "remote", | ||||||
|  |       "remotePath": "/tinyauth", | ||||||
|  |       "port": 4000, | ||||||
|  |       "host": "127.0.0.1", | ||||||
|  |       "debugAdapter": "legacy" | ||||||
|  |     } | ||||||
|  |   ] | ||||||
|  | } | ||||||
| @@ -53,7 +53,7 @@ Tinyauth is licensed under the GNU General Public License v3.0. TL;DR — You ma | |||||||
|  |  | ||||||
| A big thank you to the following people for providing me with more coffee: | A big thank you to the following people for providing me with more coffee: | ||||||
|  |  | ||||||
| <!-- sponsors --><a href="https://github.com/erwinkramer"><img src="https://github.com/erwinkramer.png" width="64px" alt="User avatar: erwinkramer" /></a>  <a href="https://github.com/nicotsx"><img src="https://github.com/nicotsx.png" width="64px" alt="User avatar: nicotsx" /></a>  <a href="https://github.com/SimpleHomelab"><img src="https://github.com/SimpleHomelab.png" width="64px" alt="User avatar: SimpleHomelab" /></a>  <a href="https://github.com/jmadden91"><img src="https://github.com/jmadden91.png" width="64px" alt="User avatar: jmadden91" /></a>  <a href="https://github.com/tribor"><img src="https://github.com/tribor.png" width="64px" alt="User avatar: tribor" /></a>  <a href="https://github.com/eliasbenb"><img src="https://github.com/eliasbenb.png" width="64px" alt="User avatar: eliasbenb" /></a>  <!-- sponsors --> | <!-- sponsors --><a href="https://github.com/erwinkramer"><img src="https://github.com/erwinkramer.png" width="64px" alt="User avatar: erwinkramer" /></a>  <a href="https://github.com/nicotsx"><img src="https://github.com/nicotsx.png" width="64px" alt="User avatar: nicotsx" /></a>  <a href="https://github.com/SimpleHomelab"><img src="https://github.com/SimpleHomelab.png" width="64px" alt="User avatar: SimpleHomelab" /></a>  <a href="https://github.com/jmadden91"><img src="https://github.com/jmadden91.png" width="64px" alt="User avatar: jmadden91" /></a>  <a href="https://github.com/tribor"><img src="https://github.com/tribor.png" width="64px" alt="User avatar: tribor" /></a>  <a href="https://github.com/eliasbenb"><img src="https://github.com/eliasbenb.png" width="64px" alt="User avatar: eliasbenb" /></a>  <a href="https://github.com/afunworm"><img src="https://github.com/afunworm.png" width="64px" alt="User avatar: afunworm" /></a>  <!-- sponsors --> | ||||||
|  |  | ||||||
| ## Acknowledgements | ## Acknowledgements | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								air.toml
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								air.toml
									
									
									
									
									
								
							| @@ -2,9 +2,9 @@ root = "/tinyauth" | |||||||
| tmp_dir = "tmp" | tmp_dir = "tmp" | ||||||
|  |  | ||||||
| [build] | [build] | ||||||
| pre_cmd = ["mkdir -p internal/assets/dist", "echo 'backend running' > internal/assets/dist/index.html"] | pre_cmd = ["mkdir -p internal/assets/dist", "echo 'backend running' > internal/assets/dist/index.html", "go install github.com/go-delve/delve/cmd/dlv@v1.25.0"] | ||||||
| cmd = "CGO_ENABLED=0 go build -o ./tmp/tinyauth ." | cmd = "CGO_ENABLED=0 go build -gcflags=\"all=-N -l\" -o tmp/tinyauth ." | ||||||
| bin = "tmp/tinyauth" | bin = "/go/bin/dlv --listen :4000 --headless=true --api-version=2 --accept-multiclient --log=true exec tmp/tinyauth --continue" | ||||||
| include_ext = ["go"] | include_ext = ["go"] | ||||||
| exclude_dir = ["internal/assets/dist"] | exclude_dir = ["internal/assets/dist"] | ||||||
| exclude_regex = [".*_test\\.go"] | exclude_regex = [".*_test\\.go"] | ||||||
|   | |||||||
| @@ -243,7 +243,7 @@ func init() { | |||||||
| 	rootCmd.Flags().Int("login-max-retries", 5, "Maximum login attempts before timeout (0 to disable).") | 	rootCmd.Flags().Int("login-max-retries", 5, "Maximum login attempts before timeout (0 to disable).") | ||||||
| 	rootCmd.Flags().Int("log-level", 1, "Log level.") | 	rootCmd.Flags().Int("log-level", 1, "Log level.") | ||||||
| 	rootCmd.Flags().String("app-title", "Tinyauth", "Title of the app.") | 	rootCmd.Flags().String("app-title", "Tinyauth", "Title of the app.") | ||||||
| 	rootCmd.Flags().String("forgot-password-message", "You can reset your password by changing the `USERS` environment variable.", "Message to show on the forgot password page.") | 	rootCmd.Flags().String("forgot-password-message", "", "Message to show on the forgot password page.") | ||||||
| 	rootCmd.Flags().String("background-image", "/background.jpg", "Background image URL for the login page.") | 	rootCmd.Flags().String("background-image", "/background.jpg", "Background image URL for the login page.") | ||||||
| 	rootCmd.Flags().String("ldap-address", "", "LDAP server address (e.g. ldap://localhost:389).") | 	rootCmd.Flags().String("ldap-address", "", "LDAP server address (e.g. ldap://localhost:389).") | ||||||
| 	rootCmd.Flags().String("ldap-bind-dn", "", "LDAP bind DN (e.g. uid=user,dc=example,dc=com).") | 	rootCmd.Flags().String("ldap-bind-dn", "", "LDAP bind DN (e.g. uid=user,dc=example,dc=com).") | ||||||
|   | |||||||
| @@ -42,6 +42,7 @@ services: | |||||||
|       - /var/run/docker.sock:/var/run/docker.sock |       - /var/run/docker.sock:/var/run/docker.sock | ||||||
|     ports: |     ports: | ||||||
|       - 3000:3000 |       - 3000:3000 | ||||||
|  |       - 4000:4000 | ||||||
|     labels: |     labels: | ||||||
|       traefik.enable: true |       traefik.enable: true | ||||||
|       traefik.http.middlewares.tinyauth.forwardauth.address: http://tinyauth-backend:3000/api/auth/traefik |       traefik.http.middlewares.tinyauth.forwardauth.address: http://tinyauth-backend:3000/api/auth/traefik | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ | |||||||
|         "@radix-ui/react-separator": "^1.1.7", |         "@radix-ui/react-separator": "^1.1.7", | ||||||
|         "@radix-ui/react-slot": "^1.2.3", |         "@radix-ui/react-slot": "^1.2.3", | ||||||
|         "@tailwindcss/vite": "^4.1.11", |         "@tailwindcss/vite": "^4.1.11", | ||||||
|         "@tanstack/react-query": "^5.81.5", |         "@tanstack/react-query": "^5.82.0", | ||||||
|         "axios": "^1.10.0", |         "axios": "^1.10.0", | ||||||
|         "class-variance-authority": "^0.7.1", |         "class-variance-authority": "^0.7.1", | ||||||
|         "clsx": "^2.1.1", |         "clsx": "^2.1.1", | ||||||
| @@ -30,12 +30,12 @@ | |||||||
|         "sonner": "^2.0.6", |         "sonner": "^2.0.6", | ||||||
|         "tailwind-merge": "^3.3.1", |         "tailwind-merge": "^3.3.1", | ||||||
|         "tailwindcss": "^4.1.11", |         "tailwindcss": "^4.1.11", | ||||||
|         "zod": "^3.25.76", |         "zod": "^4.0.2", | ||||||
|       }, |       }, | ||||||
|       "devDependencies": { |       "devDependencies": { | ||||||
|         "@eslint/js": "^9.30.1", |         "@eslint/js": "^9.30.1", | ||||||
|         "@tanstack/eslint-plugin-query": "^5.81.2", |         "@tanstack/eslint-plugin-query": "^5.81.2", | ||||||
|         "@types/node": "^24.0.12", |         "@types/node": "^24.0.13", | ||||||
|         "@types/react": "^19.1.8", |         "@types/react": "^19.1.8", | ||||||
|         "@types/react-dom": "^19.1.6", |         "@types/react-dom": "^19.1.6", | ||||||
|         "@vitejs/plugin-react": "^4.6.0", |         "@vitejs/plugin-react": "^4.6.0", | ||||||
| @@ -47,7 +47,7 @@ | |||||||
|         "tw-animate-css": "^1.3.5", |         "tw-animate-css": "^1.3.5", | ||||||
|         "typescript": "~5.8.3", |         "typescript": "~5.8.3", | ||||||
|         "typescript-eslint": "^8.36.0", |         "typescript-eslint": "^8.36.0", | ||||||
|         "vite": "^7.0.3", |         "vite": "^7.0.4", | ||||||
|       }, |       }, | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
| @@ -328,9 +328,9 @@ | |||||||
|  |  | ||||||
|     "@tanstack/eslint-plugin-query": ["@tanstack/eslint-plugin-query@5.81.2", "", { "dependencies": { "@typescript-eslint/utils": "^8.18.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0" } }, "sha512-h4k6P6fm5VhKP5NkK+0TTVpGGyKQdx6tk7NYYG7J7PkSu7ClpLgBihw7yzK8N3n5zPaF3IMyErxfoNiXWH/3/A=="], |     "@tanstack/eslint-plugin-query": ["@tanstack/eslint-plugin-query@5.81.2", "", { "dependencies": { "@typescript-eslint/utils": "^8.18.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0" } }, "sha512-h4k6P6fm5VhKP5NkK+0TTVpGGyKQdx6tk7NYYG7J7PkSu7ClpLgBihw7yzK8N3n5zPaF3IMyErxfoNiXWH/3/A=="], | ||||||
|  |  | ||||||
|     "@tanstack/query-core": ["@tanstack/query-core@5.81.5", "", {}, "sha512-ZJOgCy/z2qpZXWaj/oxvodDx07XcQa9BF92c0oINjHkoqUPsmm3uG08HpTaviviZ/N9eP1f9CM7mKSEkIo7O1Q=="], |     "@tanstack/query-core": ["@tanstack/query-core@5.82.0", "", {}, "sha512-JrjoVuaajBQtnoWSg8iaPHaT4mW73lK2t+exxHNOSMqy0+13eKLqJgTKXKImLejQIfdAHQ6Un0njEhOvUtOd5w=="], | ||||||
|  |  | ||||||
|     "@tanstack/react-query": ["@tanstack/react-query@5.81.5", "", { "dependencies": { "@tanstack/query-core": "5.81.5" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-lOf2KqRRiYWpQT86eeeftAGnjuTR35myTP8MXyvHa81VlomoAWNEd8x5vkcAfQefu0qtYCvyqLropFZqgI2EQw=="], |     "@tanstack/react-query": ["@tanstack/react-query@5.82.0", "", { "dependencies": { "@tanstack/query-core": "5.82.0" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-mnk8/ofKEthFeMdhV1dV8YXRf+9HqvXAcciXkoo755d/ocfWq7N/Y9jGOzS3h7ZW9dDGwSIhs3/HANWUBsyqYg=="], | ||||||
|  |  | ||||||
|     "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], |     "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], | ||||||
|  |  | ||||||
| @@ -354,7 +354,7 @@ | |||||||
|  |  | ||||||
|     "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], |     "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], | ||||||
|  |  | ||||||
|     "@types/node": ["@types/node@24.0.12", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-LtOrbvDf5ndC9Xi+4QZjVL0woFymF/xSTKZKPgrrl7H7XoeDvnD+E2IclKVDyaK9UM756W/3BXqSU+JEHopA9g=="], |     "@types/node": ["@types/node@24.0.13", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-Qm9OYVOFHFYg3wJoTSrz80hoec5Lia/dPp84do3X7dZvLikQvM1YpmvTBEdIr/e+U8HTkFjLHLnl78K/qjf+jQ=="], | ||||||
|  |  | ||||||
|     "@types/react": ["@types/react@19.1.8", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g=="], |     "@types/react": ["@types/react@19.1.8", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g=="], | ||||||
|  |  | ||||||
| @@ -900,7 +900,7 @@ | |||||||
|  |  | ||||||
|     "vfile-message": ["vfile-message@4.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw=="], |     "vfile-message": ["vfile-message@4.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw=="], | ||||||
|  |  | ||||||
|     "vite": ["vite@7.0.3", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.6", "picomatch": "^4.0.2", "postcss": "^8.5.6", "rollup": "^4.40.0", "tinyglobby": "^0.2.14" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-y2L5oJZF7bj4c0jgGYgBNSdIu+5HF+m68rn2cQXFbGoShdhV1phX9rbnxy9YXj82aS8MMsCLAAFkRxZeWdldrQ=="], |     "vite": ["vite@7.0.4", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.6", "picomatch": "^4.0.2", "postcss": "^8.5.6", "rollup": "^4.40.0", "tinyglobby": "^0.2.14" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-SkaSguuS7nnmV7mfJ8l81JGBFV7Gvzp8IzgE8A8t23+AxuNX61Q5H1Tpz5efduSN7NHC8nQXD3sKQKZAu5mNEA=="], | ||||||
|  |  | ||||||
|     "void-elements": ["void-elements@3.1.0", "", {}, "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w=="], |     "void-elements": ["void-elements@3.1.0", "", {}, "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w=="], | ||||||
|  |  | ||||||
| @@ -912,7 +912,7 @@ | |||||||
|  |  | ||||||
|     "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], |     "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], | ||||||
|  |  | ||||||
|     "zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], |     "zod": ["zod@4.0.2", "", {}, "sha512-X2niJNY54MGam4L6Kj0AxeedeDIi/E5QFW0On2faSX5J4/pfLk1tW+cRMIMoojnCavn/u5W/kX17e1CSGnKMxA=="], | ||||||
|  |  | ||||||
|     "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], |     "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], | ||||||
|  |  | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ | |||||||
|     "@radix-ui/react-separator": "^1.1.7", |     "@radix-ui/react-separator": "^1.1.7", | ||||||
|     "@radix-ui/react-slot": "^1.2.3", |     "@radix-ui/react-slot": "^1.2.3", | ||||||
|     "@tailwindcss/vite": "^4.1.11", |     "@tailwindcss/vite": "^4.1.11", | ||||||
|     "@tanstack/react-query": "^5.81.5", |     "@tanstack/react-query": "^5.82.0", | ||||||
|     "axios": "^1.10.0", |     "axios": "^1.10.0", | ||||||
|     "class-variance-authority": "^0.7.1", |     "class-variance-authority": "^0.7.1", | ||||||
|     "clsx": "^2.1.1", |     "clsx": "^2.1.1", | ||||||
| @@ -36,12 +36,12 @@ | |||||||
|     "sonner": "^2.0.6", |     "sonner": "^2.0.6", | ||||||
|     "tailwind-merge": "^3.3.1", |     "tailwind-merge": "^3.3.1", | ||||||
|     "tailwindcss": "^4.1.11", |     "tailwindcss": "^4.1.11", | ||||||
|     "zod": "^3.25.76" |     "zod": "^4.0.2" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "@eslint/js": "^9.30.1", |     "@eslint/js": "^9.30.1", | ||||||
|     "@tanstack/eslint-plugin-query": "^5.81.2", |     "@tanstack/eslint-plugin-query": "^5.81.2", | ||||||
|     "@types/node": "^24.0.12", |     "@types/node": "^24.0.13", | ||||||
|     "@types/react": "^19.1.8", |     "@types/react": "^19.1.8", | ||||||
|     "@types/react-dom": "^19.1.6", |     "@types/react-dom": "^19.1.6", | ||||||
|     "@vitejs/plugin-react": "^4.6.0", |     "@vitejs/plugin-react": "^4.6.0", | ||||||
| @@ -53,6 +53,6 @@ | |||||||
|     "tw-animate-css": "^1.3.5", |     "tw-animate-css": "^1.3.5", | ||||||
|     "typescript": "~5.8.3", |     "typescript": "~5.8.3", | ||||||
|     "typescript-eslint": "^8.36.0", |     "typescript-eslint": "^8.36.0", | ||||||
|     "vite": "^7.0.3" |     "vite": "^7.0.4" | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @@ -50,5 +50,6 @@ | |||||||
|     "forgotPasswordTitle": "Forgot your password?", |     "forgotPasswordTitle": "Forgot your password?", | ||||||
|     "failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.", |     "failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.", | ||||||
|     "errorTitle": "An error occurred", |     "errorTitle": "An error occurred", | ||||||
|     "errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information." |     "errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information.", | ||||||
|  |     "forgotPasswordMessage": "You can reset your password by changing the `USERS` environment variable." | ||||||
| } | } | ||||||
| @@ -50,5 +50,6 @@ | |||||||
|     "forgotPasswordTitle": "Forgot your password?", |     "forgotPasswordTitle": "Forgot your password?", | ||||||
|     "failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.", |     "failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.", | ||||||
|     "errorTitle": "An error occurred", |     "errorTitle": "An error occurred", | ||||||
|     "errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information." |     "errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information.", | ||||||
|  |     "forgotPasswordMessage": "You can reset your password by changing the `USERS` environment variable." | ||||||
| } | } | ||||||
| @@ -17,7 +17,7 @@ export const ForgotPasswordPage = () => { | |||||||
|       <CardHeader> |       <CardHeader> | ||||||
|         <CardTitle className="text-3xl">{t("forgotPasswordTitle")}</CardTitle> |         <CardTitle className="text-3xl">{t("forgotPasswordTitle")}</CardTitle> | ||||||
|         <CardDescription> |         <CardDescription> | ||||||
|           <Markdown>{forgotPasswordMessage}</Markdown> |           <Markdown>{forgotPasswordMessage !== "" ? forgotPasswordMessage : t('forgotPasswordMessage')}</Markdown> | ||||||
|         </CardDescription> |         </CardDescription> | ||||||
|       </CardHeader> |       </CardHeader> | ||||||
|     </Card> |     </Card> | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								go.mod
									
									
									
									
									
								
							| @@ -12,7 +12,7 @@ require ( | |||||||
| 	github.com/spf13/cobra v1.9.1 | 	github.com/spf13/cobra v1.9.1 | ||||||
| 	github.com/spf13/viper v1.20.1 | 	github.com/spf13/viper v1.20.1 | ||||||
| 	github.com/traefik/paerser v0.2.2 | 	github.com/traefik/paerser v0.2.2 | ||||||
| 	golang.org/x/crypto v0.39.0 | 	golang.org/x/crypto v0.40.0 | ||||||
| ) | ) | ||||||
|  |  | ||||||
| require ( | require ( | ||||||
| @@ -31,7 +31,7 @@ require ( | |||||||
| 	go.opentelemetry.io/auto/sdk v1.1.0 // indirect | 	go.opentelemetry.io/auto/sdk v1.1.0 // indirect | ||||||
| 	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect | 	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect | ||||||
| 	go.opentelemetry.io/otel/sdk v1.34.0 // indirect | 	go.opentelemetry.io/otel/sdk v1.34.0 // indirect | ||||||
| 	golang.org/x/term v0.32.0 // indirect | 	golang.org/x/term v0.33.0 // indirect | ||||||
| 	gotest.tools/v3 v3.5.2 // indirect | 	gotest.tools/v3 v3.5.2 // indirect | ||||||
| 	rsc.io/qr v0.2.0 // indirect | 	rsc.io/qr v0.2.0 // indirect | ||||||
| ) | ) | ||||||
| @@ -53,7 +53,7 @@ require ( | |||||||
| 	github.com/charmbracelet/x/term v0.2.1 // indirect | 	github.com/charmbracelet/x/term v0.2.1 // indirect | ||||||
| 	github.com/cloudwego/base64x v0.1.4 // indirect | 	github.com/cloudwego/base64x v0.1.4 // indirect | ||||||
| 	github.com/distribution/reference v0.6.0 // indirect | 	github.com/distribution/reference v0.6.0 // indirect | ||||||
| 	github.com/docker/docker v28.3.1+incompatible | 	github.com/docker/docker v28.3.2+incompatible | ||||||
| 	github.com/docker/go-connections v0.5.0 // indirect | 	github.com/docker/go-connections v0.5.0 // indirect | ||||||
| 	github.com/docker/go-units v0.5.0 // indirect | 	github.com/docker/go-units v0.5.0 // indirect | ||||||
| 	github.com/dustin/go-humanize v1.0.1 // indirect | 	github.com/dustin/go-humanize v1.0.1 // indirect | ||||||
| @@ -109,11 +109,11 @@ require ( | |||||||
| 	go.uber.org/atomic v1.9.0 // indirect | 	go.uber.org/atomic v1.9.0 // indirect | ||||||
| 	go.uber.org/multierr v1.9.0 // indirect | 	go.uber.org/multierr v1.9.0 // indirect | ||||||
| 	golang.org/x/arch v0.13.0 // indirect | 	golang.org/x/arch v0.13.0 // indirect | ||||||
| 	golang.org/x/net v0.38.0 // indirect | 	golang.org/x/net v0.41.0 // indirect | ||||||
| 	golang.org/x/oauth2 v0.30.0 | 	golang.org/x/oauth2 v0.30.0 | ||||||
| 	golang.org/x/sync v0.15.0 // indirect | 	golang.org/x/sync v0.16.0 // indirect | ||||||
| 	golang.org/x/sys v0.33.0 // indirect | 	golang.org/x/sys v0.34.0 // indirect | ||||||
| 	golang.org/x/text v0.26.0 // indirect | 	golang.org/x/text v0.27.0 // indirect | ||||||
| 	google.golang.org/protobuf v1.36.3 // indirect | 	google.golang.org/protobuf v1.36.3 // indirect | ||||||
| 	gopkg.in/yaml.v3 v3.0.1 // indirect | 	gopkg.in/yaml.v3 v3.0.1 // indirect | ||||||
| ) | ) | ||||||
|   | |||||||
							
								
								
									
										28
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								go.sum
									
									
									
									
									
								
							| @@ -72,8 +72,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c | |||||||
| github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||||
| github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= | github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= | ||||||
| github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= | github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= | ||||||
| github.com/docker/docker v28.3.1+incompatible h1:20+BmuA9FXlCX4ByQ0vYJcUEnOmRM6XljDnFWR+jCyY= | github.com/docker/docker v28.3.2+incompatible h1:wn66NJ6pWB1vBZIilP8G3qQPqHy5XymfYn5vsqeA5oA= | ||||||
| github.com/docker/docker v28.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= | github.com/docker/docker v28.3.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= | ||||||
| github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= | github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= | ||||||
| github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= | github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= | ||||||
| github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= | github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= | ||||||
| @@ -297,8 +297,8 @@ golang.org/x/arch v0.13.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= | |||||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||||
| golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||||
| golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||||||
| golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= | golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= | ||||||
| golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= | golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= | ||||||
| golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= | golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= | ||||||
| golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= | golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= | ||||||
| golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= | ||||||
| @@ -307,15 +307,15 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn | |||||||
| golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||||
| golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||||
| golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= | ||||||
| golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= | golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= | ||||||
| golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= | golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= | ||||||
| golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= | golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= | ||||||
| golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= | golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= | ||||||
| golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
| golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
| golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
| golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= | golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= | ||||||
| golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= | golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= | ||||||
| golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||||
| golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||||
| golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| @@ -325,14 +325,14 @@ golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBc | |||||||
| golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
| golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
| golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
| golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= | golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= | ||||||
| golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= | golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= | ||||||
| golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= | golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg= | ||||||
| golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= | golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0= | ||||||
| golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||||
| golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||||
| golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= | golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= | ||||||
| golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= | golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= | ||||||
| golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= | golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= | ||||||
| golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= | golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= | ||||||
| golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||||
|   | |||||||
| @@ -3,38 +3,61 @@ package ldap | |||||||
| import ( | import ( | ||||||
| 	"crypto/tls" | 	"crypto/tls" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"time" | ||||||
| 	"tinyauth/internal/types" | 	"tinyauth/internal/types" | ||||||
|  |  | ||||||
| 	ldapgo "github.com/go-ldap/ldap/v3" | 	ldapgo "github.com/go-ldap/ldap/v3" | ||||||
|  | 	"github.com/rs/zerolog/log" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type LDAP struct { | type LDAP struct { | ||||||
| 	Config types.LdapConfig | 	Config types.LdapConfig | ||||||
| 	Conn   *ldapgo.Conn | 	Conn   *ldapgo.Conn | ||||||
| 	BaseDN string |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func NewLDAP(config types.LdapConfig) (*LDAP, error) { | func NewLDAP(config types.LdapConfig) (*LDAP, error) { | ||||||
|  | 	// Create a new LDAP instance with the provided configuration | ||||||
|  | 	ldap := &LDAP{ | ||||||
|  | 		Config: config, | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// Connect to the LDAP server | 	// Connect to the LDAP server | ||||||
| 	conn, err := ldapgo.DialURL(config.Address, ldapgo.DialWithTLSConfig(&tls.Config{ | 	if err := ldap.Connect(); err != nil { | ||||||
| 		InsecureSkipVerify: config.Insecure, | 		return nil, fmt.Errorf("failed to connect to LDAP server: %w", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Start heartbeat goroutine | ||||||
|  | 	go func() { | ||||||
|  | 		for range time.Tick(time.Duration(5) * time.Minute) { | ||||||
|  | 			err := ldap.heartbeat() | ||||||
|  | 			if err != nil { | ||||||
|  | 				log.Error().Err(err).Msg("LDAP connection heartbeat failed") | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	}() | ||||||
|  |  | ||||||
|  | 	return ldap, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (l *LDAP) Connect() error { | ||||||
|  | 	// Connect to the LDAP server | ||||||
|  | 	conn, err := ldapgo.DialURL(l.Config.Address, ldapgo.DialWithTLSConfig(&tls.Config{ | ||||||
|  | 		InsecureSkipVerify: l.Config.Insecure, | ||||||
| 		MinVersion:         tls.VersionTLS12, | 		MinVersion:         tls.VersionTLS12, | ||||||
| 	})) | 	})) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Bind to the LDAP server with the provided credentials | 	// Bind to the LDAP server with the provided credentials | ||||||
| 	err = conn.Bind(config.BindDN, config.BindPassword) | 	err = conn.Bind(l.Config.BindDN, l.Config.BindPassword) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return &LDAP{ | 	// Store the connection in the LDAP struct | ||||||
| 		Config: config, | 	l.Conn = conn | ||||||
| 		Conn:   conn, | 	return nil | ||||||
| 		BaseDN: config.BaseDN, |  | ||||||
| 	}, nil |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func (l *LDAP) Search(username string) (string, error) { | func (l *LDAP) Search(username string) (string, error) { | ||||||
| @@ -44,7 +67,7 @@ func (l *LDAP) Search(username string) (string, error) { | |||||||
|  |  | ||||||
| 	// Create a search request to find the user by username | 	// Create a search request to find the user by username | ||||||
| 	searchRequest := ldapgo.NewSearchRequest( | 	searchRequest := ldapgo.NewSearchRequest( | ||||||
| 		l.BaseDN, | 		l.Config.BaseDN, | ||||||
| 		ldapgo.ScopeWholeSubtree, ldapgo.NeverDerefAliases, 0, 0, false, | 		ldapgo.ScopeWholeSubtree, ldapgo.NeverDerefAliases, 0, 0, false, | ||||||
| 		filter, | 		filter, | ||||||
| 		[]string{"dn"}, | 		[]string{"dn"}, | ||||||
| @@ -75,3 +98,25 @@ func (l *LDAP) Bind(userDN string, password string) error { | |||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (l *LDAP) heartbeat() error { | ||||||
|  | 	// Perform a simple search to check if the connection is alive | ||||||
|  | 	log.Info().Msg("Performing LDAP connection heartbeat") | ||||||
|  |  | ||||||
|  | 	// Create a search request to find the user by username | ||||||
|  | 	searchRequest := ldapgo.NewSearchRequest( | ||||||
|  | 		"", | ||||||
|  | 		ldapgo.ScopeBaseObject, ldapgo.NeverDerefAliases, 0, 0, false, | ||||||
|  | 		"(objectClass=*)", | ||||||
|  | 		[]string{}, | ||||||
|  | 		nil, | ||||||
|  | 	) | ||||||
|  |  | ||||||
|  | 	// Perform the search | ||||||
|  | 	_, err := l.Conn.Search(searchRequest) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	// No error means the connection is alive | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|   | |||||||
| @@ -34,7 +34,7 @@ type Config struct { | |||||||
| 	EnvFile                 string `mapstructure:"env-file"` | 	EnvFile                 string `mapstructure:"env-file"` | ||||||
| 	LoginTimeout            int    `mapstructure:"login-timeout"` | 	LoginTimeout            int    `mapstructure:"login-timeout"` | ||||||
| 	LoginMaxRetries         int    `mapstructure:"login-max-retries"` | 	LoginMaxRetries         int    `mapstructure:"login-max-retries"` | ||||||
| 	FogotPasswordMessage    string `mapstructure:"forgot-password-message" validate:"required"` | 	FogotPasswordMessage    string `mapstructure:"forgot-password-message"` | ||||||
| 	BackgroundImage         string `mapstructure:"background-image" validate:"required"` | 	BackgroundImage         string `mapstructure:"background-image" validate:"required"` | ||||||
| 	LdapAddress             string `mapstructure:"ldap-address"` | 	LdapAddress             string `mapstructure:"ldap-address"` | ||||||
| 	LdapBindDN              string `mapstructure:"ldap-bind-dn"` | 	LdapBindDN              string `mapstructure:"ldap-bind-dn"` | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user