mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2025-10-28 04:35:40 +00:00
refactor: rename email back to username
This commit is contained in:
@@ -18,7 +18,7 @@ import (
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "tinyauth",
|
||||
Short: "The simplest way to protect your apps with a login screen.",
|
||||
Long: `Tinyauth is a simple authentication middleware that adds simple email/password login or OAuth with Google, Github and any generic OAuth provider to all of your docker apps.`,
|
||||
Long: `Tinyauth is a simple authentication middleware that adds simple username/password login or OAuth with Google, Github and any generic OAuth provider to all of your docker apps.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
// Get config
|
||||
log.Info().Msg("Parsing config")
|
||||
@@ -126,8 +126,8 @@ func init() {
|
||||
rootCmd.Flags().String("address", "0.0.0.0", "Address to bind the server to.")
|
||||
rootCmd.Flags().String("secret", "", "Secret to use for the cookie.")
|
||||
rootCmd.Flags().String("app-url", "", "The tinyauth URL.")
|
||||
rootCmd.Flags().String("users", "", "Comma separated list of users in the format email:hash.")
|
||||
rootCmd.Flags().String("users-file", "", "Path to a file containing users in the format email:hash.")
|
||||
rootCmd.Flags().String("users", "", "Comma separated list of users in the format username:hash.")
|
||||
rootCmd.Flags().String("users-file", "", "Path to a file containing users in the format username:hash.")
|
||||
rootCmd.Flags().Bool("cookie-secure", false, "Send cookie over secure connection only.")
|
||||
rootCmd.Flags().String("github-client-id", "", "Github OAuth client ID.")
|
||||
rootCmd.Flags().String("github-client-secret", "", "Github OAuth client secret.")
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
var interactive bool
|
||||
var email string
|
||||
var username string
|
||||
var password string
|
||||
var docker bool
|
||||
|
||||
@@ -24,9 +24,9 @@ var CreateCmd = &cobra.Command{
|
||||
if interactive {
|
||||
form := huh.NewForm(
|
||||
huh.NewGroup(
|
||||
huh.NewInput().Title("Email").Value(&email).Validate((func(s string) error {
|
||||
huh.NewInput().Title("Username").Value(&username).Validate((func(s string) error {
|
||||
if s == "" {
|
||||
return errors.New("email cannot be empty")
|
||||
return errors.New("username cannot be empty")
|
||||
}
|
||||
return nil
|
||||
})),
|
||||
@@ -49,11 +49,11 @@ var CreateCmd = &cobra.Command{
|
||||
}
|
||||
}
|
||||
|
||||
if email == "" || password == "" {
|
||||
log.Error().Msg("Email and password cannot be empty")
|
||||
if username == "" || password == "" {
|
||||
log.Error().Msg("Username and password cannot be empty")
|
||||
}
|
||||
|
||||
log.Info().Str("email", email).Str("password", password).Bool("docker", docker).Msg("Creating user")
|
||||
log.Info().Str("username", username).Str("password", password).Bool("docker", docker).Msg("Creating user")
|
||||
|
||||
passwordByte, passwordErr := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
|
||||
@@ -67,13 +67,13 @@ var CreateCmd = &cobra.Command{
|
||||
passwordString = strings.ReplaceAll(passwordString, "$", "$$")
|
||||
}
|
||||
|
||||
log.Info().Str("user", fmt.Sprintf("%s:%s", email, passwordString)).Msg("User created")
|
||||
log.Info().Str("user", fmt.Sprintf("%s:%s", username, passwordString)).Msg("User created")
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
CreateCmd.Flags().BoolVar(&interactive, "interactive", false, "Create a user interactively")
|
||||
CreateCmd.Flags().BoolVar(&docker, "docker", false, "Format output for docker")
|
||||
CreateCmd.Flags().StringVar(&email, "email", "", "Email")
|
||||
CreateCmd.Flags().StringVar(&username, "username", "", "Username")
|
||||
CreateCmd.Flags().StringVar(&password, "password", "", "Password")
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
var interactive bool
|
||||
var email string
|
||||
var username string
|
||||
var password string
|
||||
var docker bool
|
||||
var user string
|
||||
@@ -19,20 +19,20 @@ var user string
|
||||
var VerifyCmd = &cobra.Command{
|
||||
Use: "verify",
|
||||
Short: "Verify a user is set up correctly",
|
||||
Long: `Verify a user is set up correctly meaning that it has a correct email and password.`,
|
||||
Long: `Verify a user is set up correctly meaning that it has a correct username and password.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if interactive {
|
||||
form := huh.NewForm(
|
||||
huh.NewGroup(
|
||||
huh.NewInput().Title("User (email:hash)").Value(&user).Validate((func(s string) error {
|
||||
huh.NewInput().Title("User (username:hash)").Value(&user).Validate((func(s string) error {
|
||||
if s == "" {
|
||||
return errors.New("user cannot be empty")
|
||||
}
|
||||
return nil
|
||||
})),
|
||||
huh.NewInput().Title("Email").Value(&email).Validate((func(s string) error {
|
||||
huh.NewInput().Title("Username").Value(&username).Validate((func(s string) error {
|
||||
if s == "" {
|
||||
return errors.New("email cannot be empty")
|
||||
return errors.New("username cannot be empty")
|
||||
}
|
||||
return nil
|
||||
})),
|
||||
@@ -55,11 +55,11 @@ var VerifyCmd = &cobra.Command{
|
||||
}
|
||||
}
|
||||
|
||||
if email == "" || password == "" || user == "" {
|
||||
log.Fatal().Msg("Email, password and user cannot be empty")
|
||||
if username == "" || password == "" || user == "" {
|
||||
log.Fatal().Msg("Username, password and user cannot be empty")
|
||||
}
|
||||
|
||||
log.Info().Str("user", user).Str("email", email).Str("password", password).Bool("docker", docker).Msg("Verifying user")
|
||||
log.Info().Str("user", user).Str("username", username).Str("password", password).Bool("docker", docker).Msg("Verifying user")
|
||||
|
||||
userSplit := strings.Split(user, ":")
|
||||
|
||||
@@ -73,8 +73,8 @@ var VerifyCmd = &cobra.Command{
|
||||
|
||||
verifyErr := bcrypt.CompareHashAndPassword([]byte(userSplit[1]), []byte(password))
|
||||
|
||||
if verifyErr != nil || email != userSplit[0] {
|
||||
log.Fatal().Msg("Email or password incorrect")
|
||||
if verifyErr != nil || username != userSplit[0] {
|
||||
log.Fatal().Msg("Username or password incorrect")
|
||||
} else {
|
||||
log.Info().Msg("Verification successful")
|
||||
}
|
||||
@@ -84,7 +84,7 @@ var VerifyCmd = &cobra.Command{
|
||||
func init() {
|
||||
VerifyCmd.Flags().BoolVarP(&interactive, "interactive", "i", false, "Create a user interactively")
|
||||
VerifyCmd.Flags().BoolVar(&docker, "docker", false, "Is the user formatted for docker?")
|
||||
VerifyCmd.Flags().StringVar(&email, "email", "", "Email")
|
||||
VerifyCmd.Flags().StringVar(&username, "username", "", "Username")
|
||||
VerifyCmd.Flags().StringVar(&password, "password", "", "Password")
|
||||
VerifyCmd.Flags().StringVar(&user, "user", "", "Hash (user:hash combination)")
|
||||
VerifyCmd.Flags().StringVar(&user, "user", "", "Hash (username:hash combination)")
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ func (api *API) SetupRoutes() {
|
||||
return
|
||||
}
|
||||
|
||||
user := api.Auth.GetUser(login.Email)
|
||||
user := api.Auth.GetUser(login.Username)
|
||||
|
||||
if user == nil {
|
||||
c.JSON(401, gin.H{
|
||||
@@ -161,7 +161,7 @@ func (api *API) SetupRoutes() {
|
||||
}
|
||||
|
||||
session := sessions.Default(c)
|
||||
session.Set("tinyauth_sid", fmt.Sprintf("email:%s", login.Email))
|
||||
session.Set("tinyauth_sid", fmt.Sprintf("username:%s", login.Username))
|
||||
session.Save()
|
||||
|
||||
c.JSON(200, gin.H{
|
||||
@@ -199,7 +199,7 @@ func (api *API) SetupRoutes() {
|
||||
c.JSON(200, gin.H{
|
||||
"status": 200,
|
||||
"message": "Unauthenticated",
|
||||
"email": "",
|
||||
"username": "",
|
||||
"isLoggedIn": false,
|
||||
"oauth": false,
|
||||
"provider": "",
|
||||
@@ -212,7 +212,7 @@ func (api *API) SetupRoutes() {
|
||||
c.JSON(200, gin.H{
|
||||
"status": 200,
|
||||
"message": "Authenticated",
|
||||
"email": userContext.Email,
|
||||
"username": userContext.Username,
|
||||
"isLoggedIn": userContext.IsLoggedIn,
|
||||
"oauth": userContext.OAuth,
|
||||
"provider": userContext.Provider,
|
||||
@@ -306,7 +306,7 @@ func (api *API) SetupRoutes() {
|
||||
if !api.Auth.EmailWhitelisted(email) {
|
||||
log.Warn().Str("email", email).Msg("Email not whitelisted")
|
||||
unauthorizedQuery, unauthorizedQueryErr := query.Values(types.UnauthorizedQuery{
|
||||
Email: email,
|
||||
Username: email,
|
||||
})
|
||||
if handleApiError(c, "Failed to build query", unauthorizedQueryErr) {
|
||||
return
|
||||
|
||||
@@ -18,9 +18,9 @@ type Auth struct {
|
||||
OAuthWhitelist []string
|
||||
}
|
||||
|
||||
func (auth *Auth) GetUser(email string) *types.User {
|
||||
func (auth *Auth) GetUser(username string) *types.User {
|
||||
for _, user := range auth.Users {
|
||||
if user.Email == email {
|
||||
if user.Username == username {
|
||||
return &user
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ func (auth *Auth) GetUser(email string) *types.User {
|
||||
}
|
||||
|
||||
func (auth *Auth) CheckPassword(user types.User, password string) bool {
|
||||
hashedPasswordErr := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
|
||||
hashedPasswordErr := bcrypt.CompareHashAndPassword([]byte(user.Username), []byte(password))
|
||||
return hashedPasswordErr == nil
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ func (hooks *Hooks) UseUserContext(c *gin.Context) (types.UserContext, error) {
|
||||
|
||||
if sessionCookie == nil {
|
||||
return types.UserContext{
|
||||
Email: "",
|
||||
Username: "",
|
||||
IsLoggedIn: false,
|
||||
OAuth: false,
|
||||
Provider: "",
|
||||
@@ -39,7 +39,7 @@ func (hooks *Hooks) UseUserContext(c *gin.Context) (types.UserContext, error) {
|
||||
|
||||
if !dataOk {
|
||||
return types.UserContext{
|
||||
Email: "",
|
||||
Username: "",
|
||||
IsLoggedIn: false,
|
||||
OAuth: false,
|
||||
Provider: "",
|
||||
@@ -50,7 +50,7 @@ func (hooks *Hooks) UseUserContext(c *gin.Context) (types.UserContext, error) {
|
||||
|
||||
if len(split) != 2 {
|
||||
return types.UserContext{
|
||||
Email: "",
|
||||
Username: "",
|
||||
IsLoggedIn: false,
|
||||
OAuth: false,
|
||||
Provider: "",
|
||||
@@ -60,18 +60,18 @@ func (hooks *Hooks) UseUserContext(c *gin.Context) (types.UserContext, error) {
|
||||
sessionType := split[0]
|
||||
sessionValue := split[1]
|
||||
|
||||
if sessionType == "email" {
|
||||
if sessionType == "username" {
|
||||
user := hooks.Auth.GetUser(sessionValue)
|
||||
if user == nil {
|
||||
return types.UserContext{
|
||||
Email: "",
|
||||
Username: "",
|
||||
IsLoggedIn: false,
|
||||
OAuth: false,
|
||||
Provider: "",
|
||||
}, nil
|
||||
}
|
||||
return types.UserContext{
|
||||
Email: sessionValue,
|
||||
Username: sessionValue,
|
||||
IsLoggedIn: true,
|
||||
OAuth: false,
|
||||
Provider: "",
|
||||
@@ -82,7 +82,7 @@ func (hooks *Hooks) UseUserContext(c *gin.Context) (types.UserContext, error) {
|
||||
|
||||
if provider == nil {
|
||||
return types.UserContext{
|
||||
Email: "",
|
||||
Username: "",
|
||||
IsLoggedIn: false,
|
||||
OAuth: false,
|
||||
Provider: "",
|
||||
@@ -93,7 +93,7 @@ func (hooks *Hooks) UseUserContext(c *gin.Context) (types.UserContext, error) {
|
||||
session.Delete("tinyauth_sid")
|
||||
session.Save()
|
||||
return types.UserContext{
|
||||
Email: "",
|
||||
Username: "",
|
||||
IsLoggedIn: false,
|
||||
OAuth: false,
|
||||
Provider: "",
|
||||
@@ -101,7 +101,7 @@ func (hooks *Hooks) UseUserContext(c *gin.Context) (types.UserContext, error) {
|
||||
}
|
||||
|
||||
return types.UserContext{
|
||||
Email: sessionValue,
|
||||
Username: sessionValue,
|
||||
IsLoggedIn: true,
|
||||
OAuth: true,
|
||||
Provider: sessionType,
|
||||
|
||||
@@ -7,12 +7,12 @@ type LoginQuery struct {
|
||||
}
|
||||
|
||||
type LoginRequest struct {
|
||||
Email string `json:"email"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
Email string
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ type Config struct {
|
||||
}
|
||||
|
||||
type UserContext struct {
|
||||
Email string
|
||||
Username string
|
||||
IsLoggedIn bool
|
||||
OAuth bool
|
||||
Provider string
|
||||
@@ -83,5 +83,5 @@ type OAuthProviders struct {
|
||||
}
|
||||
|
||||
type UnauthorizedQuery struct {
|
||||
Email string `url:"email"`
|
||||
Username string `url:"username"`
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ func ParseUsers(users string) (types.Users, error) {
|
||||
return types.Users{}, errors.New("invalid user format")
|
||||
}
|
||||
usersParsed = append(usersParsed, types.User{
|
||||
Email: userSplit[0],
|
||||
Username: userSplit[0],
|
||||
Password: userSplit[1],
|
||||
})
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ export const LoginPage = () => {
|
||||
}
|
||||
|
||||
const schema = z.object({
|
||||
email: z.string().email(),
|
||||
username: z.string(),
|
||||
password: z.string(),
|
||||
});
|
||||
|
||||
@@ -41,7 +41,7 @@ export const LoginPage = () => {
|
||||
const form = useForm({
|
||||
mode: "uncontrolled",
|
||||
initialValues: {
|
||||
email: "",
|
||||
username: "",
|
||||
password: "",
|
||||
},
|
||||
validate: zodResolver(schema),
|
||||
@@ -54,7 +54,7 @@ export const LoginPage = () => {
|
||||
onError: () => {
|
||||
notifications.show({
|
||||
title: "Failed to login",
|
||||
message: "Check your email and password",
|
||||
message: "Check your username and password",
|
||||
color: "red",
|
||||
});
|
||||
},
|
||||
@@ -154,7 +154,7 @@ export const LoginPage = () => {
|
||||
)}
|
||||
</Grid>
|
||||
<Divider
|
||||
label="Or continue with email"
|
||||
label="Or continue with password"
|
||||
labelPosition="center"
|
||||
my="lg"
|
||||
/>
|
||||
@@ -162,12 +162,12 @@ export const LoginPage = () => {
|
||||
)}
|
||||
<form onSubmit={form.onSubmit(handleSubmit)}>
|
||||
<TextInput
|
||||
label="Email"
|
||||
label="Username"
|
||||
placeholder="user@example.com"
|
||||
required
|
||||
disabled={loginMutation.isLoading}
|
||||
key={form.key("email")}
|
||||
{...form.getInputProps("email")}
|
||||
key={form.key("username")}
|
||||
{...form.getInputProps("username")}
|
||||
/>
|
||||
<PasswordInput
|
||||
label="Password"
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Layout } from "../components/layouts/layout";
|
||||
import { capitalize } from "../utils/utils";
|
||||
|
||||
export const LogoutPage = () => {
|
||||
const { isLoggedIn, email, oauth, provider } = useUserContext();
|
||||
const { isLoggedIn, username, oauth, provider } = useUserContext();
|
||||
|
||||
if (!isLoggedIn) {
|
||||
return <Navigate to="/login" />;
|
||||
@@ -44,7 +44,7 @@ export const LogoutPage = () => {
|
||||
Logout
|
||||
</Text>
|
||||
<Text>
|
||||
You are currently logged in as <Code>{email}</Code>
|
||||
You are currently logged in as <Code>{username}</Code>
|
||||
{oauth && ` using ${capitalize(provider)}`}. Click the button below to
|
||||
log out.
|
||||
</Text>
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Navigate } from "react-router";
|
||||
export const UnauthorizedPage = () => {
|
||||
const queryString = window.location.search;
|
||||
const params = new URLSearchParams(queryString);
|
||||
const email = params.get("email");
|
||||
const username = params.get("email");
|
||||
|
||||
const { isLoggedIn } = useUserContext();
|
||||
|
||||
@@ -14,7 +14,7 @@ export const UnauthorizedPage = () => {
|
||||
return <Navigate to="/" />;
|
||||
}
|
||||
|
||||
if (email === "null") {
|
||||
if (username === "null") {
|
||||
return <Navigate to="/" />;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ export const UnauthorizedPage = () => {
|
||||
Unauthorized
|
||||
</Text>
|
||||
<Text>
|
||||
The user with email address <Code>{email}</Code> is not authorized to
|
||||
The user with username <Code>{username}</Code> is not authorized to
|
||||
login.
|
||||
</Text>
|
||||
<Button
|
||||
|
||||
@@ -2,7 +2,7 @@ import { z } from "zod";
|
||||
|
||||
export const userContextSchema = z.object({
|
||||
isLoggedIn: z.boolean(),
|
||||
email: z.string(),
|
||||
username: z.string(),
|
||||
oauth: z.boolean(),
|
||||
provider: z.string(),
|
||||
configuredProviders: z.array(z.string()),
|
||||
|
||||
Reference in New Issue
Block a user