From 09e7b0ee0ac9fc06d4def8f0c3ead2a2220d09b0 Mon Sep 17 00:00:00 2001 From: d34dscene Date: Wed, 26 Feb 2025 16:24:26 +0100 Subject: [PATCH] fix: using correct email username --- internal/api/handler/auth.go | 6 +- internal/app/config.go | 7 --- internal/config/setup.go | 26 ++------ internal/mail/mail.go | 4 +- web/src/routes/login/+page.svelte | 99 ++++++++++++++++++++----------- web/src/routes/users/+page.svelte | 16 +++++ 6 files changed, 91 insertions(+), 67 deletions(-) diff --git a/internal/api/handler/auth.go b/internal/api/handler/auth.go index a0bab09..233d192 100644 --- a/internal/api/handler/auth.go +++ b/internal/api/handler/auth.go @@ -192,7 +192,7 @@ func SendResetEmail(a *config.App) http.HandlerFunc { } // Generate OTP - expiresAt := time.Now().Add(10 * time.Minute) + expiresAt := time.Now().Add(15 * time.Minute) token, err := util.GenerateOTP() if err != nil { http.Error(w, "Failed to generate token", http.StatusInternalServerError) @@ -220,7 +220,7 @@ func SendResetEmail(a *config.App) http.HandlerFunc { config.Host = setting.Value case "email_port": config.Port = setting.Value - case "email_username": + case "email_user": config.Username = setting.Value case "email_password": config.Password = setting.Value @@ -230,7 +230,7 @@ func SendResetEmail(a *config.App) http.HandlerFunc { } data := map[string]any{ "Token": token, - "Date": expiresAt.Format(time.RFC3339), + "Date": expiresAt.Format("Jan 2, 2006 at 15:04"), } if err := mail.Send(*user.Email, "reset-password", config, data); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) diff --git a/internal/app/config.go b/internal/app/config.go index aa0f341..eeaee3c 100644 --- a/internal/app/config.go +++ b/internal/app/config.go @@ -12,7 +12,6 @@ import ( // Config holds all application configuration type Config struct { - Admin AdminUser Server ServerConfig Email EmailConfig Traefik TraefikConfig @@ -21,12 +20,6 @@ type Config struct { Secret string `env:"SECRET" envDefault:""` } -type AdminUser struct { - Username string `env:"ADMIN_USERNAME" envDefault:"admin"` - Email string `env:"ADMIN_EMAIL" envDefault:"admin@mantrae"` - Password string `env:"ADMIN_PASSWORD" envDefault:""` -} - type ServerConfig struct { Host string `env:"SERVER_HOST" envDefault:"0.0.0.0"` Port string `env:"SERVER_PORT" envDefault:"3000"` diff --git a/internal/config/setup.go b/internal/config/setup.go index 2634917..2cceaa9 100644 --- a/internal/config/setup.go +++ b/internal/config/setup.go @@ -95,7 +95,7 @@ func (a *App) setupLogger() { func (a *App) setDefaultAdminUser(ctx context.Context) error { // Generate password if not provided - password := a.Config.Admin.Password + password := os.Getenv("ADMIN_PASSWORD") if password == "" { password = util.GenPassword(32) } @@ -108,35 +108,21 @@ func (a *App) setDefaultAdminUser(ctx context.Context) error { // Try to get existing admin user q := a.Conn.GetQuery() user, err := q.GetUser(ctx, 1) - // If user doesn't exist, create new admin + // If admin doesn't exist, create new admin if err != nil { + adminMail := "admin@mantrae" if err = q.CreateUser(ctx, db.CreateUserParams{ - Username: a.Config.Admin.Username, - Email: &a.Config.Admin.Email, + Username: "admin", + Email: &adminMail, Password: hash, IsAdmin: true, }); err != nil { return fmt.Errorf("failed to create default admin user: %w", err) } - slog.Info("Generated default admin user", - "username", a.Config.Admin.Username, - "password", password) + slog.Info("Generated default 'admin' user", "password", password) return nil } - // Update admin info on change - if user.Username != a.Config.Admin.Username || *user.Email != a.Config.Admin.Email { - if err = q.UpdateUser(ctx, db.UpdateUserParams{ - ID: user.ID, - Username: a.Config.Admin.Username, - Email: &a.Config.Admin.Email, - IsAdmin: true, - }); err != nil { - return fmt.Errorf("failed to update default admin user: %w", err) - } - slog.Info("Updated admin user", "username", a.Config.Admin.Username) - } - userPassword, err := q.GetUserPassword(ctx, user.ID) if err != nil { return fmt.Errorf("failed to get user password: %w", err) diff --git a/internal/mail/mail.go b/internal/mail/mail.go index ddc71e5..ef26f97 100644 --- a/internal/mail/mail.go +++ b/internal/mail/mail.go @@ -10,13 +10,14 @@ import ( "github.com/domodwyer/mailyak/v3" ) -func Send(to, templateName string, email app.EmailConfig, data map[string]interface{}) error { +func Send(to, templateName string, email app.EmailConfig, data map[string]any) error { client := mailyak.New( email.Host+":"+email.Port, smtp.PlainAuth("", email.Username, email.Password, email.Host), ) client.To(to) client.From(email.From) + client.FromName("Mantrae") var subject string switch templateName { @@ -40,7 +41,6 @@ func Send(to, templateName string, email app.EmailConfig, data map[string]interf if err := tmpl.ExecuteTemplate(client.HTML(), templateName+".html", data); err != nil { return fmt.Errorf("failed to execute template: %w", err) } - if err := client.Send(); err != nil { return fmt.Errorf("failed to send email: %w, check your SMTP settings", err) } diff --git a/web/src/routes/login/+page.svelte b/web/src/routes/login/+page.svelte index 665b5d3..f12c41e 100644 --- a/web/src/routes/login/+page.svelte +++ b/web/src/routes/login/+page.svelte @@ -9,54 +9,83 @@ import PasswordInput from '$lib/components/ui/password-input/password-input.svelte'; import Separator from '$lib/components/ui/separator/separator.svelte'; import { goto } from '$app/navigation'; + import { user } from '$lib/stores/user'; let username = $state(''); let password = $state(''); let remember = $state(false); - const handleReset = () => { + const handleReset = async () => { if (username.length > 0) { - api.sendResetEmail(username); - goto(`/login/reset?username=${username}`); + const resetPromise = api + .sendResetEmail(username) + .then(() => { + goto(`/login/reset?username=${username}`); + return 'Reset email sent successfully!'; + }) + .catch((error) => { + throw new Error(error.message || 'Failed to send reset email'); + }); + + toast.promise(resetPromise, { + loading: 'Sending reset email...', + success: (message) => message, + error: (error) => (error as Error).message + }); } else { toast.error('Please enter a username!'); } }; const handleSubmit = async () => { - await api.login(username, password, remember); + const loginPromise = api + .login(username, password, remember) + .then(() => { + return 'Logged in successfully!'; + }) + .catch((error) => { + throw new Error(error.message || 'Login failed'); + }); + + toast.promise(loginPromise, { + loading: 'Logging in...', + success: (message) => message, + error: (error) => (error as Error).message + }); }; - - - Login - Login to your account - - -
-
- - -
- -
- - -
-
- -
- -
-
- +{#if !user.isLoggedIn()} + + + Login + Login to your account + + + +
+ +
-
- +
+ + +
+
+ +
+ +
+
+ +
+
- - - - + + + + + + +{/if} diff --git a/web/src/routes/users/+page.svelte b/web/src/routes/users/+page.svelte index d0393d7..dfad56f 100644 --- a/web/src/routes/users/+page.svelte +++ b/web/src/routes/users/+page.svelte @@ -82,6 +82,22 @@ id: 'actions', enableHiding: false, cell: ({ row }) => { + if (row.original.id === 1) { + return renderComponent(TableActions, { + actions: [ + { + label: 'Edit User', + icon: Pencil, + onClick: () => { + modalState = { + isOpen: true, + user: row.original + }; + } + } + ] + }); + } return renderComponent(TableActions, { actions: [ {