mirror of
				https://github.com/steveiliop56/tinyauth.git
				synced 2025-10-31 06:05:43 +00:00 
			
		
		
		
	Compare commits
	
		
			11 Commits
		
	
	
		
			v3.0.0-alp
			...
			v3.0.1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 7ee0b645e6 | ||
|   | 5c34ab96a9 | ||
|   | cb6f93d879 | ||
|   | df0c356511 | ||
|   | d1c6ae1ba1 | ||
|   | 0f8d2e7fde | ||
|   | 0da82ae3fe | ||
|   | f9ab9a6406 | ||
|   | 6f35923735 | ||
|   | b1dc5cb4cc | ||
|   | 3c9bc8c67f | 
| @@ -24,7 +24,7 @@ Tinyauth is a simple authentication middleware that adds simple username/passwor | ||||
|  | ||||
| ## Discord | ||||
|  | ||||
| I just made a Discord server for Tinyauth! It is not only for Tinyauth but general self-hosting because I just like chatting with people! The link is [here](https://discord.gg/gWpzrksk), see you there! | ||||
| I just made a Discord server for Tinyauth! It is not only for Tinyauth but general self-hosting because I just like chatting with people! The link is [here](https://discord.gg/eHzVaCzRRd), see you there! | ||||
|  | ||||
| ## Getting Started | ||||
|  | ||||
| @@ -46,5 +46,5 @@ Tinyauth is licensed under the GNU General Public License v3.0. TL;DR — You ma | ||||
|  | ||||
| Credits for the logo of this app go to: | ||||
|  | ||||
| - **Freepik** for providing the police hat and logo. | ||||
| - **Freepik** for providing the police hat and badge. | ||||
| - **Renee French** for the original gopher logo. | ||||
|   | ||||
| @@ -62,7 +62,9 @@ var rootCmd = &cobra.Command{ | ||||
| 		} | ||||
|  | ||||
| 		// Create oauth whitelist | ||||
| 		oauthWhitelist := strings.Split(config.OAuthWhitelist, ",") | ||||
| 		oauthWhitelist := utils.Filter(strings.Split(config.OAuthWhitelist, ","), func(val string) bool { | ||||
| 			return val != "" | ||||
| 		}) | ||||
| 		log.Debug().Msg("Parsed OAuth whitelist") | ||||
|  | ||||
| 		// Create OAuth config | ||||
|   | ||||
| @@ -30,4 +30,4 @@ services: | ||||
|       traefik.enable: true | ||||
|       traefik.http.routers.tinyauth.rule: Host(`tinyauth.dev.local`) | ||||
|       traefik.http.services.tinyauth.loadbalancer.server.port: 3000 | ||||
|       traefik.http.middlewares.tinyauth.forwardauth.address: http://tinyauth:3000/api/auth | ||||
|       traefik.http.middlewares.tinyauth.forwardauth.address: http://tinyauth:3000/api/auth/traefik | ||||
|   | ||||
| @@ -28,4 +28,4 @@ services: | ||||
|       traefik.enable: true | ||||
|       traefik.http.routers.tinyauth.rule: Host(`tinyauth.example.com`) | ||||
|       traefik.http.services.tinyauth.loadbalancer.server.port: 3000 | ||||
|       traefik.http.middlewares.tinyauth.forwardauth.address: http://tinyauth:3000/api/auth | ||||
|       traefik.http.middlewares.tinyauth.forwardauth.address: http://tinyauth:3000/api/auth/traefik | ||||
|   | ||||
| @@ -533,10 +533,7 @@ func (api *API) SetupRoutes() { | ||||
|  | ||||
| 		// If it is empty it means that no redirect_uri was provided to the login screen so we just log in | ||||
| 		if redirectURIErr != nil { | ||||
| 			c.JSON(200, gin.H{ | ||||
| 				"status":  200, | ||||
| 				"message": "Logged in", | ||||
| 			}) | ||||
| 			c.Redirect(http.StatusPermanentRedirect, api.Config.AppURL) | ||||
| 		} | ||||
|  | ||||
| 		log.Debug().Str("redirectURI", redirectURI).Msg("Got redirect URI") | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| v3.0.0 | ||||
| v3.0.1 | ||||
| @@ -207,3 +207,13 @@ func GetTinyauthLabels(labels map[string]string) types.TinyauthLabels { | ||||
| func OAuthConfigured(config types.Config) bool { | ||||
| 	return (config.GithubClientId != "" && config.GithubClientSecret != "") || (config.GoogleClientId != "" && config.GoogleClientSecret != "") || (config.GenericClientId != "" && config.GenericClientSecret != "") || (config.TailscaleClientId != "" && config.TailscaleClientSecret != "") | ||||
| } | ||||
|  | ||||
| // Filter helper function | ||||
| func Filter[T any](slice []T, test func(T) bool) (res []T) { | ||||
| 	for _, value := range slice { | ||||
| 		if test(value) { | ||||
| 			res = append(res, value) | ||||
| 		} | ||||
| 	} | ||||
| 	return res | ||||
| } | ||||
|   | ||||
| @@ -313,3 +313,22 @@ func TestGetTinyauthLabels(t *testing.T) { | ||||
| 		t.Fatalf("Expected %v, got %v", expected, result) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Test the filter function | ||||
| func TestFilter(t *testing.T) { | ||||
| 	t.Log("Testing filter helper") | ||||
|  | ||||
| 	// Create variables | ||||
| 	data := []string{"", "val1", "", "val2", "", "val3", ""} | ||||
| 	expected := []string{"val1", "val2", "val3"} | ||||
|  | ||||
| 	// Test the filter function | ||||
| 	result := utils.Filter(data, func(val string) bool { | ||||
| 		return val != "" | ||||
| 	}) | ||||
|  | ||||
| 	// Check if the result is equal to the expected | ||||
| 	if !reflect.DeepEqual(expected, result) { | ||||
| 		t.Fatalf("Expected %v, got %v", expected, result) | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import { Navigate } from "react-router"; | ||||
| import { useUserContext } from "../context/user-context"; | ||||
| import { Layout } from "../components/layouts/layout"; | ||||
| import { ReactNode } from "react"; | ||||
| import { isQueryValid } from "../utils/utils"; | ||||
|  | ||||
| export const ContinuePage = () => { | ||||
|   const queryString = window.location.search; | ||||
| @@ -16,7 +17,7 @@ export const ContinuePage = () => { | ||||
|     return <Navigate to={`/login?redirect_uri=${redirectUri}`} />; | ||||
|   } | ||||
|  | ||||
|   if (redirectUri === "null" || redirectUri === "") { | ||||
|   if (!isQueryValid(redirectUri)) { | ||||
|     return <Navigate to="/" />; | ||||
|   } | ||||
|  | ||||
| @@ -31,9 +32,11 @@ export const ContinuePage = () => { | ||||
|     }, 500); | ||||
|   }; | ||||
|  | ||||
|   const urlParsed = URL.parse(redirectUri); | ||||
|   let uri; | ||||
|  | ||||
|   if (urlParsed === null) { | ||||
|   try { | ||||
|     uri = new URL(redirectUri); | ||||
|   } catch { | ||||
|     return ( | ||||
|       <ContinuePageLayout> | ||||
|         <Text size="xl" fw={700}> | ||||
| @@ -49,7 +52,7 @@ export const ContinuePage = () => { | ||||
|  | ||||
|   if ( | ||||
|     window.location.protocol === "https:" && | ||||
|     urlParsed.protocol === "http:" | ||||
|     uri.protocol === "http:" | ||||
|   ) { | ||||
|     return ( | ||||
|       <ContinuePageLayout> | ||||
|   | ||||
| @@ -20,6 +20,7 @@ import { GoogleIcon } from "../icons/google"; | ||||
| import { GithubIcon } from "../icons/github"; | ||||
| import { OAuthIcon } from "../icons/oauth"; | ||||
| import { TailscaleIcon } from "../icons/tailscale"; | ||||
| import { isQueryValid } from "../utils/utils"; | ||||
|  | ||||
| export const LoginPage = () => { | ||||
|   const queryString = window.location.search; | ||||
| @@ -70,7 +71,7 @@ export const LoginPage = () => { | ||||
|         color: "green", | ||||
|       }); | ||||
|       setTimeout(() => { | ||||
|         if (redirectUri === "null" || redirectUri === "") { | ||||
|         if (!isQueryValid(redirectUri)) { | ||||
|           window.location.replace("/"); | ||||
|         } else { | ||||
|           window.location.replace(`/continue?redirect_uri=${redirectUri}`); | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| import { Button, Code, Paper, Text } from "@mantine/core"; | ||||
| import { Layout } from "../components/layouts/layout"; | ||||
| import { Navigate } from "react-router"; | ||||
| import { isQueryValid } from "../utils/utils"; | ||||
|  | ||||
| export const UnauthorizedPage = () => { | ||||
|   const queryString = window.location.search; | ||||
| @@ -8,7 +9,7 @@ export const UnauthorizedPage = () => { | ||||
|   const username = params.get("username") ?? ""; | ||||
|   const resource = params.get("resource") ?? ""; | ||||
|  | ||||
|   if (username === "null" || username === "") { | ||||
|   if (!isQueryValid(username)) { | ||||
|     return <Navigate to="/" />; | ||||
|   } | ||||
|  | ||||
| @@ -20,7 +21,7 @@ export const UnauthorizedPage = () => { | ||||
|         </Text> | ||||
|         <Text> | ||||
|           The user with username <Code>{username}</Code> is not authorized to{" "} | ||||
|           {resource !== "null" && resource !== "" ? ( | ||||
|           {isQueryValid(resource) ? ( | ||||
|             <span> | ||||
|               access the <Code>{resource}</Code> resource. | ||||
|             </span> | ||||
|   | ||||
| @@ -1 +1,2 @@ | ||||
| export const capitalize = (s: string) => s.charAt(0).toUpperCase() + s.slice(1); | ||||
| export const isQueryValid = (value: string) => value.trim() !== "" && value !== "null"; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user