diff --git a/app/app.go b/app/app.go index a38c406..7be9975 100644 --- a/app/app.go +++ b/app/app.go @@ -1,48 +1,29 @@ package app import ( - "fmt" "github.com/fossyy/filekeeper/db" - "github.com/fossyy/filekeeper/middleware" - "github.com/fossyy/filekeeper/routes" - "github.com/fossyy/filekeeper/utils" + "github.com/fossyy/filekeeper/email" + "github.com/fossyy/filekeeper/logger" "net/http" ) -type App struct { - http.Server - DB db.Database -} - var Server App -func NewServer(addr string, handler http.Handler, database db.Database) App { +type App struct { + http.Server + DB *db.Database + Logger *logger.AggregatedLogger + Mail *email.SmtpServer +} + +func NewServer(addr string, handler http.Handler, logger logger.AggregatedLogger, database db.Database, mail email.SmtpServer) App { return App{ Server: http.Server{ Addr: addr, Handler: handler, }, - DB: database, - } -} - -func Start() { - serverAddr := fmt.Sprintf("%s:%s", utils.Getenv("SERVER_HOST"), utils.Getenv("SERVER_PORT")) - - dbUser := utils.Getenv("DB_USERNAME") - dbPass := utils.Getenv("DB_PASSWORD") - dbHost := utils.Getenv("DB_HOST") - dbPort := utils.Getenv("DB_PORT") - dbName := utils.Getenv("DB_NAME") - - database := db.NewPostgresDB(dbUser, dbPass, dbHost, dbPort, dbName, db.DisableSSL) - db.DB = database - - Server = NewServer(serverAddr, middleware.Handler(routes.SetupRoutes()), database) - fmt.Printf("Listening on http://%s\n", Server.Addr) - err := Server.ListenAndServe() - if err != nil { - panic(err) - return + Logger: &logger, + DB: &database, + Mail: &mail, } } diff --git a/cache/cache.go b/cache/cache.go index d859b71..b769c3d 100644 --- a/cache/cache.go +++ b/cache/cache.go @@ -2,8 +2,8 @@ package cache import ( "fmt" + "github.com/fossyy/filekeeper/app" "github.com/fossyy/filekeeper/db" - "github.com/fossyy/filekeeper/logger" "github.com/fossyy/filekeeper/utils" "github.com/google/uuid" "sync" @@ -33,12 +33,10 @@ type FileWithExpired struct { mu sync.Mutex } -var log *logger.AggregatedLogger var userCache map[string]*UserWithExpired var fileCache map[string]*FileWithExpired func init() { - log = logger.Logger() userCache = make(map[string]*UserWithExpired) fileCache = make(map[string]*FileWithExpired) @@ -50,7 +48,7 @@ func init() { currentTime := time.Now() cacheClean := 0 cleanID := utils.GenerateRandomString(10) - log.Info(fmt.Sprintf("Cache cleanup [user] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second())) + app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [user] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second())) for _, user := range userCache { user.mu.Lock() @@ -61,7 +59,7 @@ func init() { user.mu.Unlock() } - log.Info(fmt.Sprintf("Cache cleanup [user] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime))) + app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [user] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime))) } }() @@ -71,7 +69,7 @@ func init() { currentTime := time.Now() cacheClean := 0 cleanID := utils.GenerateRandomString(10) - log.Info(fmt.Sprintf("Cache cleanup [files] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second())) + app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [files] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second())) for _, file := range fileCache { file.mu.Lock() @@ -84,7 +82,7 @@ func init() { file.mu.Unlock() } - log.Info(fmt.Sprintf("Cache cleanup [files] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime))) + app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [files] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime))) } }() } diff --git a/email/email.go b/email/email.go index c02a73c..23238ff 100644 --- a/email/email.go +++ b/email/email.go @@ -15,8 +15,8 @@ type Email interface { Send() } -func NewSmtpServer(Host string, Port int, User string, Password string) *SmtpServer { - return &SmtpServer{ +func NewSmtpServer(Host string, Port int, User string, Password string) SmtpServer { + return SmtpServer{ Host: Host, Port: Port, User: User, diff --git a/handler/auth/google/callback/callback.go b/handler/auth/google/callback/callback.go index e765b8f..0ca0b98 100644 --- a/handler/auth/google/callback/callback.go +++ b/handler/auth/google/callback/callback.go @@ -5,11 +5,11 @@ import ( "encoding/json" "errors" "fmt" + "github.com/fossyy/filekeeper/app" "github.com/fossyy/filekeeper/cache" "github.com/fossyy/filekeeper/db" googleOauthSetupHandler "github.com/fossyy/filekeeper/handler/auth/google/setup" signinHandler "github.com/fossyy/filekeeper/handler/signin" - "github.com/fossyy/filekeeper/logger" "github.com/fossyy/filekeeper/session" "github.com/fossyy/filekeeper/types" "github.com/fossyy/filekeeper/utils" @@ -53,11 +53,10 @@ type CsrfToken struct { mu sync.Mutex } -var log *logger.AggregatedLogger var CsrfTokens map[string]*CsrfToken func init() { - log = logger.Logger() + CsrfTokens = make(map[string]*CsrfToken) ticker := time.NewTicker(time.Minute) @@ -67,7 +66,7 @@ func init() { currentTime := time.Now() cacheClean := 0 cleanID := utils.GenerateRandomString(10) - log.Info(fmt.Sprintf("Cache cleanup [csrf_token] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second())) + app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [csrf_token] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second())) for _, data := range CsrfTokens { data.mu.Lock() @@ -78,7 +77,7 @@ func init() { data.mu.Unlock() } - log.Info(fmt.Sprintf("Cache cleanup [csrf_token] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime))) + app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [csrf_token] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime))) } }() } @@ -108,7 +107,7 @@ func GET(w http.ResponseWriter, r *http.Request) { resp, err := http.Post("https://oauth2.googleapis.com/token", "application/x-www-form-urlencoded", bytes.NewBufferString(formData.Encode())) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error("Error:", err) + app.Server.Logger.Error("Error:", err) return } defer resp.Body.Close() @@ -116,7 +115,7 @@ func GET(w http.ResponseWriter, r *http.Request) { var oauthData OauthToken if err := json.NewDecoder(resp.Body).Decode(&oauthData); err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error("Error reading token response body:", err) + app.Server.Logger.Error("Error reading token response body:", err) return } @@ -126,7 +125,7 @@ func GET(w http.ResponseWriter, r *http.Request) { req.Header.Set("Authorization", "Bearer "+oauthData.AccessToken) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error("Error creating user info request:", err) + app.Server.Logger.Error("Error creating user info request:", err) return } @@ -136,13 +135,13 @@ func GET(w http.ResponseWriter, r *http.Request) { var oauthUser OauthUser if err := json.NewDecoder(userInfoResp.Body).Decode(&oauthUser); err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error("Error reading user info response body:", err) + app.Server.Logger.Error("Error reading user info response body:", err) return } if oauthUser.Email == "" { w.WriteHeader(http.StatusInternalServerError) - log.Error("Error reading user info response body: email not found") + app.Server.Logger.Error("Error reading user info response body: email not found") return } @@ -161,7 +160,7 @@ func GET(w http.ResponseWriter, r *http.Request) { if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } diff --git a/handler/auth/google/google.go b/handler/auth/google/google.go index d774536..5e50b1f 100644 --- a/handler/auth/google/google.go +++ b/handler/auth/google/google.go @@ -2,25 +2,19 @@ package googleOauthHandler import ( "fmt" + "github.com/fossyy/filekeeper/app" googleOauthCallbackHandler "github.com/fossyy/filekeeper/handler/auth/google/callback" - "github.com/fossyy/filekeeper/logger" "github.com/fossyy/filekeeper/utils" "net/http" "time" ) -var log *logger.AggregatedLogger - -func init() { - log = logger.Logger() -} - func GET(w http.ResponseWriter, r *http.Request) { token, err := utils.GenerateCSRFToken() googleOauthCallbackHandler.CsrfTokens[token] = &googleOauthCallbackHandler.CsrfToken{Token: token, CreateTime: time.Now()} if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } http.Redirect(w, r, fmt.Sprintf("https://accounts.google.com/o/oauth2/auth?scope=email profile&response_type=code&access_type=offline&state=%s&redirect_uri=%s&client_id=%s", token, utils.Getenv("GOOGLE_CALLBACK"), utils.Getenv("GOOGLE_CLIENT_ID")), http.StatusFound) diff --git a/handler/auth/google/setup/setup.go b/handler/auth/google/setup/setup.go index 8243f6b..0324a61 100644 --- a/handler/auth/google/setup/setup.go +++ b/handler/auth/google/setup/setup.go @@ -2,15 +2,15 @@ package googleOauthSetupHandler import ( "fmt" + "github.com/fossyy/filekeeper/app" "github.com/fossyy/filekeeper/db" signinHandler "github.com/fossyy/filekeeper/handler/signin" - "github.com/fossyy/filekeeper/logger" "github.com/fossyy/filekeeper/session" "github.com/fossyy/filekeeper/types" "github.com/fossyy/filekeeper/types/models" "github.com/fossyy/filekeeper/utils" - authView "github.com/fossyy/filekeeper/view/auth" - signupView "github.com/fossyy/filekeeper/view/signup" + "github.com/fossyy/filekeeper/view/client/auth" + signupView "github.com/fossyy/filekeeper/view/client/signup" "github.com/google/uuid" "net/http" "sync" @@ -24,11 +24,10 @@ type UnregisteredUser struct { mu sync.Mutex } -var log *logger.AggregatedLogger var SetupUser map[string]*UnregisteredUser func init() { - log = logger.Logger() + SetupUser = make(map[string]*UnregisteredUser) ticker := time.NewTicker(time.Minute) @@ -38,7 +37,7 @@ func init() { currentTime := time.Now() cacheClean := 0 cleanID := utils.GenerateRandomString(10) - log.Info(fmt.Sprintf("Cache cleanup [GoogleSetup] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second())) + app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [GoogleSetup] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second())) for _, data := range SetupUser { data.mu.Lock() @@ -50,7 +49,7 @@ func init() { data.mu.Unlock() } - log.Info(fmt.Sprintf("Cache cleanup [GoogleSetup] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime))) + app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [GoogleSetup] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime))) } }() } @@ -68,7 +67,7 @@ func GET(w http.ResponseWriter, r *http.Request) { err := component.Render(r.Context(), w) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } } @@ -83,7 +82,7 @@ func POST(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } username := r.Form.Get("username") @@ -98,7 +97,7 @@ func POST(w http.ResponseWriter, r *http.Request) { err := component.Render(r.Context(), w) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } return @@ -122,7 +121,7 @@ func POST(w http.ResponseWriter, r *http.Request) { err := component.Render(r.Context(), w) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } return diff --git a/handler/auth/totp/totp.go b/handler/auth/totp/totp.go index cce1782..7f3ad23 100644 --- a/handler/auth/totp/totp.go +++ b/handler/auth/totp/totp.go @@ -5,7 +5,7 @@ import ( "github.com/fossyy/filekeeper/session" "github.com/fossyy/filekeeper/types" "github.com/fossyy/filekeeper/utils" - totpView "github.com/fossyy/filekeeper/view/totp" + "github.com/fossyy/filekeeper/view/client/totp" "github.com/xlzd/gotp" "net/http" "strings" diff --git a/handler/download/download.go b/handler/download/download.go index ba353a1..61209ec 100644 --- a/handler/download/download.go +++ b/handler/download/download.go @@ -1,21 +1,15 @@ package downloadHandler import ( + "github.com/fossyy/filekeeper/app" + "github.com/fossyy/filekeeper/view/client/download" "net/http" "github.com/fossyy/filekeeper/db" - "github.com/fossyy/filekeeper/logger" "github.com/fossyy/filekeeper/types" "github.com/fossyy/filekeeper/utils" - downloadView "github.com/fossyy/filekeeper/view/download" ) -var log *logger.AggregatedLogger - -func init() { - log = logger.Logger() -} - func GET(w http.ResponseWriter, r *http.Request) { userSession := r.Context().Value("user").(types.User) files, err := db.DB.GetFiles(userSession.UserID.String()) @@ -38,7 +32,7 @@ func GET(w http.ResponseWriter, r *http.Request) { err = component.Render(r.Context(), w) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } } diff --git a/handler/download/file/file.go b/handler/download/file/file.go index cb17d68..71f0ad3 100644 --- a/handler/download/file/file.go +++ b/handler/download/file/file.go @@ -1,26 +1,20 @@ package downloadFileHandler import ( + "github.com/fossyy/filekeeper/app" "net/http" "os" "path/filepath" "github.com/fossyy/filekeeper/db" - "github.com/fossyy/filekeeper/logger" ) -var log *logger.AggregatedLogger - -func init() { - log = logger.Logger() -} - func GET(w http.ResponseWriter, r *http.Request) { fileID := r.PathValue("id") file, err := db.DB.GetFile(fileID) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } @@ -31,7 +25,7 @@ func GET(w http.ResponseWriter, r *http.Request) { saveFolder := filepath.Join(basePath, file.OwnerID.String(), file.ID.String()) if filepath.Dir(saveFolder) != filepath.Join(basePath, file.OwnerID.String()) { - log.Error("invalid path") + app.Server.Logger.Error("invalid path") w.WriteHeader(http.StatusInternalServerError) return } @@ -39,7 +33,7 @@ func GET(w http.ResponseWriter, r *http.Request) { openFile, err := os.OpenFile(filepath.Join(saveFolder, file.Name), os.O_RDONLY, 0) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } defer openFile.Close() @@ -47,7 +41,7 @@ func GET(w http.ResponseWriter, r *http.Request) { stat, err := openFile.Stat() if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } diff --git a/handler/error/error.go b/handler/error/error.go index 8c8785f..cc1819d 100644 --- a/handler/error/error.go +++ b/handler/error/error.go @@ -2,24 +2,17 @@ package errorHandler import ( "fmt" + "github.com/fossyy/filekeeper/app" + "github.com/fossyy/filekeeper/view/client/error" "net/http" - - "github.com/fossyy/filekeeper/logger" - errorView "github.com/fossyy/filekeeper/view/error" ) -var log *logger.AggregatedLogger - -func init() { - log = logger.Logger() -} - func NotFound(w http.ResponseWriter, r *http.Request) { component := errorView.NotFound("Not Found") err := component.Render(r.Context(), w) if err != nil { fmt.Fprint(w, err.Error()) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } } @@ -29,7 +22,7 @@ func InternalServerError(w http.ResponseWriter, r *http.Request) { err := component.Render(r.Context(), w) if err != nil { fmt.Fprint(w, err.Error()) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } } diff --git a/handler/forgotPassword/forgotPassword.go b/handler/forgotPassword/forgotPassword.go index d5c9df9..2af2053 100644 --- a/handler/forgotPassword/forgotPassword.go +++ b/handler/forgotPassword/forgotPassword.go @@ -5,20 +5,18 @@ import ( "context" "errors" "fmt" + "github.com/fossyy/filekeeper/app" "github.com/fossyy/filekeeper/cache" + "github.com/fossyy/filekeeper/view/client/email" + "github.com/fossyy/filekeeper/view/client/forgotPassword" "github.com/google/uuid" "net/http" - "strconv" "sync" "time" - "github.com/fossyy/filekeeper/email" - "github.com/fossyy/filekeeper/logger" "github.com/fossyy/filekeeper/types" "github.com/fossyy/filekeeper/types/models" "github.com/fossyy/filekeeper/utils" - emailView "github.com/fossyy/filekeeper/view/email" - forgotPasswordView "github.com/fossyy/filekeeper/view/forgotPassword" "gorm.io/gorm" ) @@ -29,25 +27,19 @@ type ForgotPassword struct { CreateTime time.Time } -var log *logger.AggregatedLogger -var mailServer *email.SmtpServer var ListForgotPassword map[string]*ForgotPassword var UserForgotPassword = make(map[string]string) func init() { - log = logger.Logger() ListForgotPassword = make(map[string]*ForgotPassword) - smtpPort, _ := strconv.Atoi(utils.Getenv("SMTP_PORT")) - mailServer = email.NewSmtpServer(utils.Getenv("SMTP_HOST"), smtpPort, utils.Getenv("SMTP_USER"), utils.Getenv("SMTP_PASSWORD")) ticker := time.NewTicker(time.Minute) - //TESTING go func() { for { <-ticker.C currentTime := time.Now() cacheClean := 0 cleanID := utils.GenerateRandomString(10) - log.Info(fmt.Sprintf("Cache cleanup [Forgot Password] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second())) + app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [Forgot Password] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second())) for _, data := range ListForgotPassword { data.mu.Lock() @@ -59,7 +51,7 @@ func init() { data.mu.Unlock() } - log.Info(fmt.Sprintf("Cache cleanup [Forgot Password] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime))) + app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [Forgot Password] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime))) } }() } @@ -72,7 +64,7 @@ func GET(w http.ResponseWriter, r *http.Request) { err := component.Render(r.Context(), w) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } } @@ -81,7 +73,7 @@ func POST(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err != nil { http.Error(w, "Error parsing form", http.StatusBadRequest) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } @@ -96,7 +88,7 @@ func POST(w http.ResponseWriter, r *http.Request) { err := component.Render(r.Context(), w) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } return @@ -112,7 +104,7 @@ func POST(w http.ResponseWriter, r *http.Request) { err = verifyForgot(userData) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } @@ -120,7 +112,7 @@ func POST(w http.ResponseWriter, r *http.Request) { err = component.Render(r.Context(), w) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } return @@ -152,7 +144,7 @@ func verifyForgot(user *models.User) error { UserForgotPassword[code] = user.Email ListForgotPassword[user.Email] = userData - err = mailServer.Send(user.Email, "Password Change Request", buffer.String()) + err = app.Server.Mail.Send(user.Email, "Password Change Request", buffer.String()) if err != nil { return err } diff --git a/handler/forgotPassword/verify/verify.go b/handler/forgotPassword/verify/verify.go index b1c7dbc..72b91a3 100644 --- a/handler/forgotPassword/verify/verify.go +++ b/handler/forgotPassword/verify/verify.go @@ -1,23 +1,20 @@ package forgotPasswordVerifyHandler import ( + "github.com/fossyy/filekeeper/app" "github.com/fossyy/filekeeper/cache" "github.com/fossyy/filekeeper/db" forgotPasswordHandler "github.com/fossyy/filekeeper/handler/forgotPassword" - "github.com/fossyy/filekeeper/logger" "github.com/fossyy/filekeeper/session" "github.com/fossyy/filekeeper/types" "github.com/fossyy/filekeeper/utils" - forgotPasswordView "github.com/fossyy/filekeeper/view/forgotPassword" - signupView "github.com/fossyy/filekeeper/view/signup" - + "github.com/fossyy/filekeeper/view/client/forgotPassword" + signupView "github.com/fossyy/filekeeper/view/client/signup" "net/http" ) -var log *logger.AggregatedLogger - func init() { - log = logger.Logger() + //TESTING } @@ -40,7 +37,7 @@ func GET(w http.ResponseWriter, r *http.Request) { err := component.Render(r.Context(), w) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } } @@ -59,7 +56,7 @@ func POST(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } @@ -73,7 +70,7 @@ func POST(w http.ResponseWriter, r *http.Request) { err := component.Render(r.Context(), w) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } return @@ -82,14 +79,14 @@ func POST(w http.ResponseWriter, r *http.Request) { if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } err = db.DB.UpdateUserPassword(data.User.Email, hashedPassword) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } @@ -104,7 +101,7 @@ func POST(w http.ResponseWriter, r *http.Request) { err = component.Render(r.Context(), w) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } return diff --git a/handler/index/index.go b/handler/index/index.go index 59e07a3..0a16ef2 100644 --- a/handler/index/index.go +++ b/handler/index/index.go @@ -1,26 +1,19 @@ package indexHandler import ( + "github.com/fossyy/filekeeper/app" "github.com/fossyy/filekeeper/session" + "github.com/fossyy/filekeeper/view/client/index" "net/http" - - "github.com/fossyy/filekeeper/logger" - indexView "github.com/fossyy/filekeeper/view/index" ) -var log *logger.AggregatedLogger - -func init() { - log = logger.Logger() -} - func GET(w http.ResponseWriter, r *http.Request) { _, userSession, _ := session.GetSession(r) component := indexView.Main("Secure File Hosting - Filekeeper", userSession) err := component.Render(r.Context(), w) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } } diff --git a/handler/signin/signin.go b/handler/signin/signin.go index edcde52..f1fc30c 100644 --- a/handler/signin/signin.go +++ b/handler/signin/signin.go @@ -3,17 +3,16 @@ package signinHandler import ( "errors" "github.com/a-h/templ" + "github.com/fossyy/filekeeper/app" "github.com/fossyy/filekeeper/cache" - "github.com/fossyy/filekeeper/logger" "github.com/fossyy/filekeeper/session" "github.com/fossyy/filekeeper/types" "github.com/fossyy/filekeeper/utils" - signinView "github.com/fossyy/filekeeper/view/signin" + "github.com/fossyy/filekeeper/view/client/signin" "net/http" "strings" ) -var log *logger.AggregatedLogger var errorMessages = make(map[string]string) func init() { @@ -39,7 +38,7 @@ func init() { "account_selection_required": "Please select an account to proceed with the request.", "consent_required": "Consent is required to proceed. Please provide consent to continue.", } - log = logger.Logger() + } func GET(w http.ResponseWriter, r *http.Request) { @@ -64,7 +63,7 @@ func GET(w http.ResponseWriter, r *http.Request) { err := component.Render(r.Context(), w) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } } @@ -73,7 +72,7 @@ func POST(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err != nil { http.Error(w, "Error parsing form", http.StatusBadRequest) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } email := r.Form.Get("email") @@ -84,11 +83,11 @@ func POST(w http.ResponseWriter, r *http.Request) { Code: 0, Message: "Incorrect Username or Password", }) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) err = component.Render(r.Context(), w) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } return @@ -152,7 +151,7 @@ func POST(w http.ResponseWriter, r *http.Request) { err = component.Render(r.Context(), w) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } } diff --git a/handler/signup/signup.go b/handler/signup/signup.go index 976bed6..a62cc65 100644 --- a/handler/signup/signup.go +++ b/handler/signup/signup.go @@ -4,19 +4,17 @@ import ( "bytes" "context" "fmt" + "github.com/fossyy/filekeeper/app" + "github.com/fossyy/filekeeper/view/client/email" + signupView "github.com/fossyy/filekeeper/view/client/signup" "net/http" - "strconv" "sync" "time" "github.com/fossyy/filekeeper/db" - "github.com/fossyy/filekeeper/email" - "github.com/fossyy/filekeeper/logger" "github.com/fossyy/filekeeper/types" "github.com/fossyy/filekeeper/types/models" "github.com/fossyy/filekeeper/utils" - emailView "github.com/fossyy/filekeeper/view/email" - signupView "github.com/fossyy/filekeeper/view/signup" "github.com/google/uuid" ) @@ -27,15 +25,10 @@ type UnverifiedUser struct { CreateTime time.Time } -var log *logger.AggregatedLogger -var mailServer *email.SmtpServer var VerifyUser map[string]*UnverifiedUser var VerifyEmail map[string]string func init() { - log = logger.Logger() - smtpPort, _ := strconv.Atoi(utils.Getenv("SMTP_PORT")) - mailServer = email.NewSmtpServer(utils.Getenv("SMTP_HOST"), smtpPort, utils.Getenv("SMTP_USER"), utils.Getenv("SMTP_PASSWORD")) VerifyUser = make(map[string]*UnverifiedUser) VerifyEmail = make(map[string]string) @@ -46,7 +39,7 @@ func init() { currentTime := time.Now() cacheClean := 0 cleanID := utils.GenerateRandomString(10) - log.Info(fmt.Sprintf("Cache cleanup [signup] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second())) + app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [signup] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second())) for _, data := range VerifyUser { data.mu.Lock() @@ -58,7 +51,7 @@ func init() { data.mu.Unlock() } - log.Info(fmt.Sprintf("Cache cleanup [signup] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime))) + app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [signup] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime))) } }() } @@ -71,7 +64,7 @@ func GET(w http.ResponseWriter, r *http.Request) { err := component.Render(r.Context(), w) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } } @@ -80,7 +73,7 @@ func POST(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } userEmail := r.Form.Get("email") @@ -95,7 +88,7 @@ func POST(w http.ResponseWriter, r *http.Request) { err := component.Render(r.Context(), w) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } return @@ -117,7 +110,7 @@ func POST(w http.ResponseWriter, r *http.Request) { err = component.Render(r.Context(), w) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } return @@ -126,7 +119,7 @@ func POST(w http.ResponseWriter, r *http.Request) { err = verifyEmail(&newUser) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } @@ -134,7 +127,7 @@ func POST(w http.ResponseWriter, r *http.Request) { err = component.Render(r.Context(), w) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } return @@ -167,7 +160,7 @@ func verifyEmail(user *models.User) error { VerifyUser[code] = &unverifiedUser VerifyEmail[user.Email] = code - err = mailServer.Send(user.Email, "Account Registration Verification", buffer.String()) + err = app.Server.Mail.Send(user.Email, "Account Registration Verification", buffer.String()) if err != nil { return err } diff --git a/handler/signup/verify/verify.go b/handler/signup/verify/verify.go index 13f759c..cfef3b5 100644 --- a/handler/signup/verify/verify.go +++ b/handler/signup/verify/verify.go @@ -1,21 +1,15 @@ package signupVerifyHandler import ( + "github.com/fossyy/filekeeper/app" + signupView "github.com/fossyy/filekeeper/view/client/signup" "net/http" "github.com/fossyy/filekeeper/db" signupHandler "github.com/fossyy/filekeeper/handler/signup" - "github.com/fossyy/filekeeper/logger" "github.com/fossyy/filekeeper/types" - signupView "github.com/fossyy/filekeeper/view/signup" ) -var log *logger.AggregatedLogger - -func init() { - log = logger.Logger() -} - func GET(w http.ResponseWriter, r *http.Request) { code := r.PathValue("code") data, ok := signupHandler.VerifyUser[code] @@ -34,7 +28,7 @@ func GET(w http.ResponseWriter, r *http.Request) { err := component.Render(r.Context(), w) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } return @@ -48,7 +42,7 @@ func GET(w http.ResponseWriter, r *http.Request) { err = component.Render(r.Context(), w) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } } diff --git a/handler/upload/initialisation/initialisation.go b/handler/upload/initialisation/initialisation.go index 9d0b4b1..444d079 100644 --- a/handler/upload/initialisation/initialisation.go +++ b/handler/upload/initialisation/initialisation.go @@ -3,6 +3,7 @@ package initialisation import ( "encoding/json" "errors" + "github.com/fossyy/filekeeper/app" "github.com/fossyy/filekeeper/cache" "io" "net/http" @@ -10,19 +11,12 @@ import ( "path/filepath" "github.com/fossyy/filekeeper/db" - "github.com/fossyy/filekeeper/logger" "github.com/fossyy/filekeeper/types" "github.com/fossyy/filekeeper/types/models" "github.com/google/uuid" "gorm.io/gorm" ) -var log *logger.AggregatedLogger - -func init() { - log = logger.Logger() -} - func POST(w http.ResponseWriter, r *http.Request) { userSession := r.Context().Value("user").(types.User) @@ -64,10 +58,10 @@ func POST(w http.ResponseWriter, r *http.Request) { func handleNewUpload(user types.User, file types.FileInfo) (models.File, error) { uploadDir := "uploads" if _, err := os.Stat(uploadDir); os.IsNotExist(err) { - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) err := os.Mkdir(uploadDir, os.ModePerm) if err != nil { - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return models.File{}, err } } @@ -84,7 +78,7 @@ func handleNewUpload(user types.User, file types.FileInfo) (models.File, error) err := os.MkdirAll(saveFolder, os.ModePerm) if err != nil { - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return models.File{}, err } @@ -101,7 +95,7 @@ func handleNewUpload(user types.User, file types.FileInfo) (models.File, error) err = db.DB.CreateFile(&newFile) if err != nil { - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return models.File{}, err } @@ -122,5 +116,5 @@ func respondErrorJSON(w http.ResponseWriter, err error, statusCode int) { func handleError(w http.ResponseWriter, err error, statusCode int) { http.Error(w, err.Error(), statusCode) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) } diff --git a/handler/upload/upload.go b/handler/upload/upload.go index a27f3fb..b57f2b9 100644 --- a/handler/upload/upload.go +++ b/handler/upload/upload.go @@ -1,10 +1,10 @@ package uploadHandler import ( + "github.com/fossyy/filekeeper/app" "github.com/fossyy/filekeeper/cache" - "github.com/fossyy/filekeeper/logger" "github.com/fossyy/filekeeper/types" - filesView "github.com/fossyy/filekeeper/view/upload" + filesView "github.com/fossyy/filekeeper/view/client/upload" "io" "net/http" "os" @@ -12,12 +12,6 @@ import ( "strconv" ) -var log *logger.AggregatedLogger - -func init() { - log = logger.Logger() -} - func GET(w http.ResponseWriter, r *http.Request) { component := filesView.Main("Filekeeper - Upload") if err := component.Render(r.Context(), w); err != nil { @@ -38,7 +32,7 @@ func POST(w http.ResponseWriter, r *http.Request) { uploadDir := "uploads" if _, err := os.Stat(uploadDir); os.IsNotExist(err) { if err := os.Mkdir(uploadDir, os.ModePerm); err != nil { - log.Error("error getting upload info: " + err.Error()) + app.Server.Logger.Error("error getting upload info: " + err.Error()) w.WriteHeader(http.StatusInternalServerError) return } @@ -46,7 +40,7 @@ func POST(w http.ResponseWriter, r *http.Request) { file, err := cache.GetFile(fileID) if err != nil { - log.Error("error getting upload info: " + err.Error()) + app.Server.Logger.Error("error getting upload info: " + err.Error()) w.WriteHeader(http.StatusInternalServerError) return } @@ -56,14 +50,14 @@ func POST(w http.ResponseWriter, r *http.Request) { saveFolder := filepath.Join(basePath, userSession.UserID.String(), file.ID.String()) if filepath.Dir(saveFolder) != filepath.Join(basePath, userSession.UserID.String()) { - log.Error("invalid path") + app.Server.Logger.Error("invalid path") w.WriteHeader(http.StatusInternalServerError) return } fileByte, fileHeader, err := r.FormFile("chunk") if err != nil { - log.Error("error getting upload info: " + err.Error()) + app.Server.Logger.Error("error getting upload info: " + err.Error()) w.WriteHeader(http.StatusInternalServerError) return } @@ -79,14 +73,14 @@ func POST(w http.ResponseWriter, r *http.Request) { dst, err := os.OpenFile(filepath.Join(saveFolder, file.Name), os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666) if err != nil { - log.Error("error making upload folder: " + err.Error()) + app.Server.Logger.Error("error making upload folder: " + err.Error()) w.WriteHeader(http.StatusInternalServerError) return } defer dst.Close() if _, err := io.Copy(dst, fileByte); err != nil { - log.Error("error copying byte to file dst: " + err.Error()) + app.Server.Logger.Error("error copying byte to file dst: " + err.Error()) w.WriteHeader(http.StatusInternalServerError) return } diff --git a/handler/user/session/terminate/terminate.go b/handler/user/session/terminate/terminate.go index c816ac4..f1dd852 100644 --- a/handler/user/session/terminate/terminate.go +++ b/handler/user/session/terminate/terminate.go @@ -2,7 +2,7 @@ package userSessionTerminateHandler import ( "github.com/fossyy/filekeeper/session" - userView "github.com/fossyy/filekeeper/view/user" + "github.com/fossyy/filekeeper/view/client/user" "net/http" ) diff --git a/handler/user/totp/setup.go b/handler/user/totp/setup.go index 6c60740..90fb057 100644 --- a/handler/user/totp/setup.go +++ b/handler/user/totp/setup.go @@ -5,7 +5,7 @@ import ( "encoding/base64" "fmt" "github.com/fossyy/filekeeper/cache" - userTotpSetupView "github.com/fossyy/filekeeper/view/user/totp" + "github.com/fossyy/filekeeper/view/client/user/totp" "image/png" "net/http" "time" diff --git a/handler/user/user.go b/handler/user/user.go index 0a212cc..fc57ce2 100644 --- a/handler/user/user.go +++ b/handler/user/user.go @@ -2,20 +2,14 @@ package userHandler import ( "github.com/a-h/templ" + "github.com/fossyy/filekeeper/app" "github.com/fossyy/filekeeper/types" + "github.com/fossyy/filekeeper/view/client/user" "net/http" - "github.com/fossyy/filekeeper/logger" "github.com/fossyy/filekeeper/session" - userView "github.com/fossyy/filekeeper/view/user" ) -var log *logger.AggregatedLogger - -func init() { - log = logger.Logger() -} - var errorMessages = map[string]string{ "password_not_match": "The passwords provided do not match. Please try again.", } @@ -43,7 +37,7 @@ func GET(w http.ResponseWriter, r *http.Request) { err := component.Render(r.Context(), w) if err != nil { w.WriteHeader(http.StatusInternalServerError) - log.Error(err.Error()) + app.Server.Logger.Error(err.Error()) return } } diff --git a/logger/logger.go b/logger/logger.go index 10541df..eb3aab1 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -29,11 +29,11 @@ func Logger() *AggregatedLogger { return &AggregatedLogger{} } flag := log.Ldate | log.Ltime - writer := io.MultiWriter(os.Stdout, file) - infoLogger := log.New(writer, "INFO: ", flag) - warnLogger := log.New(writer, "WARN: ", flag) - errorLogger := log.New(writer, "ERROR: ", flag) - panicLogger := log.New(writer, "PANIC: ", flag) + multiLogger := io.MultiWriter(os.Stdout, file) + infoLogger := log.New(file, "INFO: ", flag) + warnLogger := log.New(multiLogger, "WARN: ", flag) + errorLogger := log.New(multiLogger, "ERROR: ", flag) + panicLogger := log.New(multiLogger, "PANIC: ", flag) return &AggregatedLogger{ infoLogger: infoLogger, diff --git a/main.go b/main.go index e529f01..c0e3e3d 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,37 @@ package main -import "github.com/fossyy/filekeeper/app" +import ( + "fmt" + "github.com/fossyy/filekeeper/app" + "github.com/fossyy/filekeeper/db" + "github.com/fossyy/filekeeper/email" + "github.com/fossyy/filekeeper/logger" + "github.com/fossyy/filekeeper/middleware" + "github.com/fossyy/filekeeper/routes" + "github.com/fossyy/filekeeper/utils" + "strconv" +) func main() { - app.Start() + serverAddr := fmt.Sprintf("%s:%s", utils.Getenv("SERVER_HOST"), utils.Getenv("SERVER_PORT")) + + dbUser := utils.Getenv("DB_USERNAME") + dbPass := utils.Getenv("DB_PASSWORD") + dbHost := utils.Getenv("DB_HOST") + dbPort := utils.Getenv("DB_PORT") + dbName := utils.Getenv("DB_NAME") + + database := db.NewPostgresDB(dbUser, dbPass, dbHost, dbPort, dbName, db.DisableSSL) + db.DB = database + + smtpPort, _ := strconv.Atoi(utils.Getenv("SMTP_PORT")) + mailServer := email.NewSmtpServer(utils.Getenv("SMTP_HOST"), smtpPort, utils.Getenv("SMTP_USER"), utils.Getenv("SMTP_PASSWORD")) + + app.Server = app.NewServer(serverAddr, middleware.Handler(routes.SetupRoutes()), *logger.Logger(), database, mailServer) + fmt.Printf("Listening on http://%s\n", app.Server.Addr) + err := app.Server.ListenAndServe() + if err != nil { + panic(err) + return + } } diff --git a/middleware/middleware.go b/middleware/middleware.go index c30578c..6f051dc 100644 --- a/middleware/middleware.go +++ b/middleware/middleware.go @@ -3,21 +3,15 @@ package middleware import ( "context" "fmt" + "github.com/fossyy/filekeeper/app" "net/http" "strings" errorHandler "github.com/fossyy/filekeeper/handler/error" - "github.com/fossyy/filekeeper/logger" "github.com/fossyy/filekeeper/session" "github.com/fossyy/filekeeper/utils" ) -var log *logger.AggregatedLogger - -func init() { - log = logger.Logger() -} - type wrapper struct { http.ResponseWriter request *http.Request @@ -64,7 +58,7 @@ func Handler(next http.Handler) http.Handler { writer.Header().Set("Access-Control-Allow-Methods", fmt.Sprintf("%s, OPTIONS", utils.Getenv("CORS_METHODS"))) writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") next.ServeHTTP(wrappedWriter, request) - log.Info(fmt.Sprintf("%s %s %s %v", utils.ClientIP(request), request.Method, request.RequestURI, wrappedWriter.statusCode)) + app.Server.Logger.Info(fmt.Sprintf("%s %s %s %v", utils.ClientIP(request), request.Method, request.RequestURI, wrappedWriter.statusCode)) }) } diff --git a/public/validatePassword.js b/public/validatePassword.js index 566bec2..6ec6485 100644 --- a/public/validatePassword.js +++ b/public/validatePassword.js @@ -1,5 +1,7 @@ -var isMatch = false -var isValid = false +var isMatch = false; +var isValid = false; +var hasUppercase = false; + function validatePasswords() { var password = document.getElementById('password').value; var confirmPassword = document.getElementById('confirmPassword').value; @@ -7,10 +9,14 @@ function validatePasswords() { var matchBadPath = document.getElementById('matchBadPath'); var lengthGoodPath = document.getElementById('lengthGoodPath'); var lengthBadPath = document.getElementById('lengthBadPath'); + var uppercaseGoodPath = document.getElementById('uppercaseGoodPath'); + var uppercaseBadPath = document.getElementById('uppercaseBadPath'); var matchSvgContainer = document.getElementById('matchSvgContainer'); var lengthSvgContainer = document.getElementById('lengthSvgContainer'); + var uppercaseSvgContainer = document.getElementById('uppercaseSvgContainer'); var matchStatusText = document.getElementById('matchStatusText'); var lengthStatusText = document.getElementById('lengthStatusText'); + var uppercaseStatusText = document.getElementById('uppercaseStatusText'); if (password === confirmPassword && password.length > 0 && confirmPassword.length > 0 && password.length === confirmPassword.length) { matchSvgContainer.classList.remove('bg-red-200'); @@ -20,7 +26,7 @@ function validatePasswords() { matchGoodPath.style.display = 'inline'; matchBadPath.style.display = 'none'; matchStatusText.textContent = "Passwords match"; - isMatch = true + isMatch = true; } else { matchSvgContainer.classList.remove('bg-green-200'); matchSvgContainer.classList.add('bg-red-200'); @@ -29,7 +35,7 @@ function validatePasswords() { matchGoodPath.style.display = 'none'; matchBadPath.style.display = 'inline'; matchStatusText.textContent = "Passwords do not match"; - isMatch = false + isMatch = false; } if (password.length >= 8) { @@ -40,7 +46,7 @@ function validatePasswords() { lengthGoodPath.style.display = 'inline'; lengthBadPath.style.display = 'none'; lengthStatusText.textContent = "Password length meets requirement"; - isValid = true + isValid = true; } else { lengthSvgContainer.classList.remove('bg-green-200'); lengthSvgContainer.classList.add('bg-red-200'); @@ -49,10 +55,30 @@ function validatePasswords() { lengthGoodPath.style.display = 'none'; lengthBadPath.style.display = 'inline'; lengthStatusText.textContent = "Password length must be at least 8 characters"; - isValid = false + isValid = false; } - if ( isValid && isMatch) { + if (/[A-Z]/.test(password)) { + uppercaseSvgContainer.classList.remove('bg-red-200'); + uppercaseSvgContainer.classList.add('bg-green-200'); + uppercaseStatusText.classList.remove('text-red-700'); + uppercaseStatusText.classList.add('text-green-700'); + uppercaseGoodPath.style.display = 'inline'; + uppercaseBadPath.style.display = 'none'; + uppercaseStatusText.textContent = "Password contains an uppercase letter"; + hasUppercase = true; + } else { + uppercaseSvgContainer.classList.remove('bg-green-200'); + uppercaseSvgContainer.classList.add('bg-red-200'); + uppercaseStatusText.classList.remove('text-green-700'); + uppercaseStatusText.classList.add('text-red-700'); + uppercaseGoodPath.style.display = 'none'; + uppercaseBadPath.style.display = 'inline'; + uppercaseStatusText.textContent = "Password must contain at least one uppercase letter"; + hasUppercase = false; + } + + if (isValid && isMatch && hasUppercase) { document.getElementById("submit").disabled = false; } else { document.getElementById("submit").disabled = true; @@ -60,4 +86,4 @@ function validatePasswords() { } document.getElementById('password').addEventListener('input', validatePasswords); -document.getElementById('confirmPassword').addEventListener('input', validatePasswords); \ No newline at end of file +document.getElementById('confirmPassword').addEventListener('input', validatePasswords); diff --git a/session/session.go b/session/session.go index 6f18872..61a7fba 100644 --- a/session/session.go +++ b/session/session.go @@ -2,7 +2,7 @@ package session import ( "fmt" - "github.com/fossyy/filekeeper/logger" + "github.com/fossyy/filekeeper/app" "github.com/fossyy/filekeeper/types" "net/http" "strconv" @@ -41,10 +41,8 @@ const ( var GlobalSessionStore = make(map[string]*Session) var UserSessionInfoList = make(map[string]map[string]*SessionInfo) -var log *logger.AggregatedLogger func init() { - log = logger.Logger() ticker := time.NewTicker(time.Minute) go func() { @@ -53,7 +51,7 @@ func init() { currentTime := time.Now() cacheClean := 0 cleanID := utils.GenerateRandomString(10) - log.Info(fmt.Sprintf("Cache cleanup [Session] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second())) + app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [Session] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second())) for _, data := range GlobalSessionStore { data.mu.Lock() @@ -65,7 +63,7 @@ func init() { data.mu.Unlock() } - log.Info(fmt.Sprintf("Cache cleanup [Session] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime))) + app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [Session] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime))) } }() } diff --git a/utils/utils.go b/utils/utils.go index 4de0821..197da33 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -5,6 +5,7 @@ import ( "crypto/sha1" "encoding/base64" "fmt" + "github.com/fossyy/filekeeper/app" mathRand "math/rand" "net/http" "os" @@ -13,7 +14,6 @@ import ( "time" "unicode" - "github.com/fossyy/filekeeper/logger" "github.com/joho/godotenv" "golang.org/x/crypto/bcrypt" ) @@ -24,7 +24,6 @@ type Env struct { } var env *Env -var log *logger.AggregatedLogger func init() { env = &Env{value: map[string]string{}} @@ -110,7 +109,7 @@ func Getenv(key string) string { if os.Getenv("HOSTNAME") == "" { err := godotenv.Load(".env") if err != nil { - log.Error("Error loading .env file: %s", err) + app.Server.Logger.Error("Error loading .env file: %s", err) } } diff --git a/view/auth/auth.templ b/view/client/auth/auth.templ similarity index 86% rename from view/auth/auth.templ rename to view/client/auth/auth.templ index c74f3dd..02f5027 100644 --- a/view/auth/auth.templ +++ b/view/client/auth/auth.templ @@ -2,7 +2,7 @@ package authView import ( "github.com/fossyy/filekeeper/types" - "github.com/fossyy/filekeeper/view/layout" + "github.com/fossyy/filekeeper/view/client/layout" ) templ form(err types.Message, title string) { @@ -49,6 +49,15 @@ templ form(err types.Message, title string) { Passwords do not match +