Compare commits

...

3 Commits

Author SHA1 Message Date
Stavros
47d8f1e5aa chore: update utility commands 2025-01-25 20:36:04 +02:00
Stavros
e8d2e059a9 fix: pass cookie expiry to api config 2025-01-25 20:00:07 +02:00
Stavros
2c7a3fc801 refactor: simplify cookie secure logic 2025-01-25 16:29:18 +02:00
4 changed files with 24 additions and 31 deletions

View File

@@ -94,6 +94,7 @@ var rootCmd = &cobra.Command{
AppURL: config.AppURL, AppURL: config.AppURL,
CookieSecure: config.CookieSecure, CookieSecure: config.CookieSecure,
DisableContinue: config.DisableContinue, DisableContinue: config.DisableContinue,
CookieExpiry: config.CookieExpiry,
}, hooks, auth, providers) }, hooks, auth, providers)
// Setup routes // Setup routes
@@ -125,8 +126,8 @@ func init() {
rootCmd.Flags().String("address", "0.0.0.0", "Address to bind the server to.") 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("secret", "", "Secret to use for the cookie.")
rootCmd.Flags().String("app-url", "", "The tinyauth URL.") rootCmd.Flags().String("app-url", "", "The tinyauth URL.")
rootCmd.Flags().String("users", "", "Comma separated list of users in the format username:bcrypt-hashed-password.") 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 username:bcrypt-hashed-password.") rootCmd.Flags().String("users-file", "", "Path to a file containing users in the format email:hash.")
rootCmd.Flags().Bool("cookie-secure", false, "Send cookie over secure connection only.") 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-id", "", "Github OAuth client ID.")
rootCmd.Flags().String("github-client-secret", "", "Github OAuth client secret.") rootCmd.Flags().String("github-client-secret", "", "Github OAuth client secret.")

View File

@@ -12,7 +12,7 @@ import (
) )
var interactive bool var interactive bool
var username string var email string
var password string var password string
var docker bool var docker bool
@@ -24,9 +24,9 @@ var CreateCmd = &cobra.Command{
if interactive { if interactive {
form := huh.NewForm( form := huh.NewForm(
huh.NewGroup( huh.NewGroup(
huh.NewInput().Title("Username").Value(&username).Validate((func(s string) error { huh.NewInput().Title("Email").Value(&email).Validate((func(s string) error {
if s == "" { if s == "" {
return errors.New("username cannot be empty") return errors.New("email cannot be empty")
} }
return nil return nil
})), })),
@@ -49,11 +49,11 @@ var CreateCmd = &cobra.Command{
} }
} }
if username == "" || password == "" { if email == "" || password == "" {
log.Error().Msg("Username and password cannot be empty") log.Error().Msg("Email and password cannot be empty")
} }
log.Info().Str("username", username).Str("password", password).Bool("docker", docker).Msg("Creating user") log.Info().Str("email", email).Str("password", password).Bool("docker", docker).Msg("Creating user")
passwordByte, passwordErr := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) passwordByte, passwordErr := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
@@ -67,13 +67,13 @@ var CreateCmd = &cobra.Command{
passwordString = strings.ReplaceAll(passwordString, "$", "$$") passwordString = strings.ReplaceAll(passwordString, "$", "$$")
} }
log.Info().Str("user", fmt.Sprintf("%s:%s", username, passwordString)).Msg("User created") log.Info().Str("user", fmt.Sprintf("%s:%s", email, passwordString)).Msg("User created")
}, },
} }
func init() { func init() {
CreateCmd.Flags().BoolVar(&interactive, "interactive", false, "Create a user interactively") CreateCmd.Flags().BoolVar(&interactive, "interactive", false, "Create a user interactively")
CreateCmd.Flags().BoolVar(&docker, "docker", false, "Format output for docker") CreateCmd.Flags().BoolVar(&docker, "docker", false, "Format output for docker")
CreateCmd.Flags().StringVar(&username, "username", "", "Username") CreateCmd.Flags().StringVar(&email, "email", "", "Email")
CreateCmd.Flags().StringVar(&password, "password", "", "Password") CreateCmd.Flags().StringVar(&password, "password", "", "Password")
} }

View File

@@ -11,7 +11,7 @@ import (
) )
var interactive bool var interactive bool
var username string var email string
var password string var password string
var docker bool var docker bool
var user string var user string
@@ -19,20 +19,20 @@ var user string
var VerifyCmd = &cobra.Command{ var VerifyCmd = &cobra.Command{
Use: "verify", Use: "verify",
Short: "Verify a user is set up correctly", Short: "Verify a user is set up correctly",
Long: `Verify a user is set up correctly meaning that it has a correct password.`, Long: `Verify a user is set up correctly meaning that it has a correct email and password.`,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
if interactive { if interactive {
form := huh.NewForm( form := huh.NewForm(
huh.NewGroup( huh.NewGroup(
huh.NewInput().Title("User (user:hash)").Value(&user).Validate((func(s string) error { huh.NewInput().Title("User (email:hash)").Value(&user).Validate((func(s string) error {
if s == "" { if s == "" {
return errors.New("user cannot be empty") return errors.New("user cannot be empty")
} }
return nil return nil
})), })),
huh.NewInput().Title("Username").Value(&username).Validate((func(s string) error { huh.NewInput().Title("Email").Value(&email).Validate((func(s string) error {
if s == "" { if s == "" {
return errors.New("username cannot be empty") return errors.New("email cannot be empty")
} }
return nil return nil
})), })),
@@ -55,11 +55,11 @@ var VerifyCmd = &cobra.Command{
} }
} }
if username == "" || password == "" || user == "" { if email == "" || password == "" || user == "" {
log.Fatal().Msg("Username, password and user cannot be empty") log.Fatal().Msg("Email, password and user cannot be empty")
} }
log.Info().Str("user", user).Str("username", username).Str("password", password).Bool("docker", docker).Msg("Verifying user") log.Info().Str("user", user).Str("email", email).Str("password", password).Bool("docker", docker).Msg("Verifying user")
userSplit := strings.Split(user, ":") userSplit := strings.Split(user, ":")
@@ -73,8 +73,8 @@ var VerifyCmd = &cobra.Command{
verifyErr := bcrypt.CompareHashAndPassword([]byte(userSplit[1]), []byte(password)) verifyErr := bcrypt.CompareHashAndPassword([]byte(userSplit[1]), []byte(password))
if verifyErr != nil || username != userSplit[0] { if verifyErr != nil || email != userSplit[0] {
log.Fatal().Msg("Username or password incorrect") log.Fatal().Msg("Email or password incorrect")
} else { } else {
log.Info().Msg("Verification successful") log.Info().Msg("Verification successful")
} }
@@ -84,7 +84,7 @@ var VerifyCmd = &cobra.Command{
func init() { func init() {
VerifyCmd.Flags().BoolVarP(&interactive, "interactive", "i", false, "Create a user interactively") 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().BoolVar(&docker, "docker", false, "Is the user formatted for docker?")
VerifyCmd.Flags().StringVar(&username, "username", "", "Username") VerifyCmd.Flags().StringVar(&email, "email", "", "Email")
VerifyCmd.Flags().StringVar(&password, "password", "", "Password") VerifyCmd.Flags().StringVar(&password, "password", "", "Password")
VerifyCmd.Flags().StringVar(&user, "user", "", "Hash (user:hash combination)") VerifyCmd.Flags().StringVar(&user, "user", "", "Hash (user:hash combination)")
} }

View File

@@ -55,20 +55,12 @@ func (api *API) Init() {
domain, domainErr := utils.GetRootURL(api.Config.AppURL) domain, domainErr := utils.GetRootURL(api.Config.AppURL)
log.Info().Str("domain", domain).Msg("Using domain for cookies")
if domainErr != nil { if domainErr != nil {
log.Fatal().Err(domainErr).Msg("Failed to get domain") log.Fatal().Err(domainErr).Msg("Failed to get domain")
os.Exit(1) os.Exit(1)
} }
var isSecure bool log.Info().Str("domain", domain).Msg("Using domain for cookies")
if api.Config.CookieSecure {
isSecure = true
} else {
isSecure = false
}
api.Domain = fmt.Sprintf(".%s", domain) api.Domain = fmt.Sprintf(".%s", domain)
@@ -76,7 +68,7 @@ func (api *API) Init() {
Domain: api.Domain, Domain: api.Domain,
Path: "/", Path: "/",
HttpOnly: true, HttpOnly: true,
Secure: isSecure, Secure: api.Config.CookieSecure,
MaxAge: api.Config.CookieExpiry, MaxAge: api.Config.CookieExpiry,
}) })