45
app/app.go
45
app/app.go
@ -1,48 +1,29 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"github.com/fossyy/filekeeper/db"
|
"github.com/fossyy/filekeeper/db"
|
||||||
"github.com/fossyy/filekeeper/middleware"
|
"github.com/fossyy/filekeeper/email"
|
||||||
"github.com/fossyy/filekeeper/routes"
|
"github.com/fossyy/filekeeper/logger"
|
||||||
"github.com/fossyy/filekeeper/utils"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
type App struct {
|
|
||||||
http.Server
|
|
||||||
DB db.Database
|
|
||||||
}
|
|
||||||
|
|
||||||
var Server App
|
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{
|
return App{
|
||||||
Server: http.Server{
|
Server: http.Server{
|
||||||
Addr: addr,
|
Addr: addr,
|
||||||
Handler: handler,
|
Handler: handler,
|
||||||
},
|
},
|
||||||
DB: database,
|
Logger: &logger,
|
||||||
}
|
DB: &database,
|
||||||
}
|
Mail: &mail,
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
12
cache/cache.go
vendored
12
cache/cache.go
vendored
@ -2,8 +2,8 @@ package cache
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/fossyy/filekeeper/app"
|
||||||
"github.com/fossyy/filekeeper/db"
|
"github.com/fossyy/filekeeper/db"
|
||||||
"github.com/fossyy/filekeeper/logger"
|
|
||||||
"github.com/fossyy/filekeeper/utils"
|
"github.com/fossyy/filekeeper/utils"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"sync"
|
"sync"
|
||||||
@ -33,12 +33,10 @@ type FileWithExpired struct {
|
|||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
var log *logger.AggregatedLogger
|
|
||||||
var userCache map[string]*UserWithExpired
|
var userCache map[string]*UserWithExpired
|
||||||
var fileCache map[string]*FileWithExpired
|
var fileCache map[string]*FileWithExpired
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
log = logger.Logger()
|
|
||||||
|
|
||||||
userCache = make(map[string]*UserWithExpired)
|
userCache = make(map[string]*UserWithExpired)
|
||||||
fileCache = make(map[string]*FileWithExpired)
|
fileCache = make(map[string]*FileWithExpired)
|
||||||
@ -50,7 +48,7 @@ func init() {
|
|||||||
currentTime := time.Now()
|
currentTime := time.Now()
|
||||||
cacheClean := 0
|
cacheClean := 0
|
||||||
cleanID := utils.GenerateRandomString(10)
|
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 {
|
for _, user := range userCache {
|
||||||
user.mu.Lock()
|
user.mu.Lock()
|
||||||
@ -61,7 +59,7 @@ func init() {
|
|||||||
user.mu.Unlock()
|
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()
|
currentTime := time.Now()
|
||||||
cacheClean := 0
|
cacheClean := 0
|
||||||
cleanID := utils.GenerateRandomString(10)
|
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 {
|
for _, file := range fileCache {
|
||||||
file.mu.Lock()
|
file.mu.Lock()
|
||||||
@ -84,7 +82,7 @@ func init() {
|
|||||||
file.mu.Unlock()
|
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)))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,8 @@ type Email interface {
|
|||||||
Send()
|
Send()
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSmtpServer(Host string, Port int, User string, Password string) *SmtpServer {
|
func NewSmtpServer(Host string, Port int, User string, Password string) SmtpServer {
|
||||||
return &SmtpServer{
|
return SmtpServer{
|
||||||
Host: Host,
|
Host: Host,
|
||||||
Port: Port,
|
Port: Port,
|
||||||
User: User,
|
User: User,
|
||||||
|
@ -5,11 +5,11 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/fossyy/filekeeper/app"
|
||||||
"github.com/fossyy/filekeeper/cache"
|
"github.com/fossyy/filekeeper/cache"
|
||||||
"github.com/fossyy/filekeeper/db"
|
"github.com/fossyy/filekeeper/db"
|
||||||
googleOauthSetupHandler "github.com/fossyy/filekeeper/handler/auth/google/setup"
|
googleOauthSetupHandler "github.com/fossyy/filekeeper/handler/auth/google/setup"
|
||||||
signinHandler "github.com/fossyy/filekeeper/handler/signin"
|
signinHandler "github.com/fossyy/filekeeper/handler/signin"
|
||||||
"github.com/fossyy/filekeeper/logger"
|
|
||||||
"github.com/fossyy/filekeeper/session"
|
"github.com/fossyy/filekeeper/session"
|
||||||
"github.com/fossyy/filekeeper/types"
|
"github.com/fossyy/filekeeper/types"
|
||||||
"github.com/fossyy/filekeeper/utils"
|
"github.com/fossyy/filekeeper/utils"
|
||||||
@ -53,11 +53,10 @@ type CsrfToken struct {
|
|||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
var log *logger.AggregatedLogger
|
|
||||||
var CsrfTokens map[string]*CsrfToken
|
var CsrfTokens map[string]*CsrfToken
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
log = logger.Logger()
|
|
||||||
CsrfTokens = make(map[string]*CsrfToken)
|
CsrfTokens = make(map[string]*CsrfToken)
|
||||||
|
|
||||||
ticker := time.NewTicker(time.Minute)
|
ticker := time.NewTicker(time.Minute)
|
||||||
@ -67,7 +66,7 @@ func init() {
|
|||||||
currentTime := time.Now()
|
currentTime := time.Now()
|
||||||
cacheClean := 0
|
cacheClean := 0
|
||||||
cleanID := utils.GenerateRandomString(10)
|
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 {
|
for _, data := range CsrfTokens {
|
||||||
data.mu.Lock()
|
data.mu.Lock()
|
||||||
@ -78,7 +77,7 @@ func init() {
|
|||||||
data.mu.Unlock()
|
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()))
|
resp, err := http.Post("https://oauth2.googleapis.com/token", "application/x-www-form-urlencoded", bytes.NewBufferString(formData.Encode()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error("Error:", err)
|
app.Server.Logger.Error("Error:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
@ -116,7 +115,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
|
|||||||
var oauthData OauthToken
|
var oauthData OauthToken
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&oauthData); err != nil {
|
if err := json.NewDecoder(resp.Body).Decode(&oauthData); err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error("Error reading token response body:", err)
|
app.Server.Logger.Error("Error reading token response body:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +125,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
|
|||||||
req.Header.Set("Authorization", "Bearer "+oauthData.AccessToken)
|
req.Header.Set("Authorization", "Bearer "+oauthData.AccessToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error("Error creating user info request:", err)
|
app.Server.Logger.Error("Error creating user info request:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,13 +135,13 @@ func GET(w http.ResponseWriter, r *http.Request) {
|
|||||||
var oauthUser OauthUser
|
var oauthUser OauthUser
|
||||||
if err := json.NewDecoder(userInfoResp.Body).Decode(&oauthUser); err != nil {
|
if err := json.NewDecoder(userInfoResp.Body).Decode(&oauthUser); err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if oauthUser.Email == "" {
|
if oauthUser.Email == "" {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,7 +160,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,25 +2,19 @@ package googleOauthHandler
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/fossyy/filekeeper/app"
|
||||||
googleOauthCallbackHandler "github.com/fossyy/filekeeper/handler/auth/google/callback"
|
googleOauthCallbackHandler "github.com/fossyy/filekeeper/handler/auth/google/callback"
|
||||||
"github.com/fossyy/filekeeper/logger"
|
|
||||||
"github.com/fossyy/filekeeper/utils"
|
"github.com/fossyy/filekeeper/utils"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var log *logger.AggregatedLogger
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
log = logger.Logger()
|
|
||||||
}
|
|
||||||
|
|
||||||
func GET(w http.ResponseWriter, r *http.Request) {
|
func GET(w http.ResponseWriter, r *http.Request) {
|
||||||
token, err := utils.GenerateCSRFToken()
|
token, err := utils.GenerateCSRFToken()
|
||||||
googleOauthCallbackHandler.CsrfTokens[token] = &googleOauthCallbackHandler.CsrfToken{Token: token, CreateTime: time.Now()}
|
googleOauthCallbackHandler.CsrfTokens[token] = &googleOauthCallbackHandler.CsrfToken{Token: token, CreateTime: time.Now()}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
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)
|
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)
|
||||||
|
@ -2,15 +2,15 @@ package googleOauthSetupHandler
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/fossyy/filekeeper/app"
|
||||||
"github.com/fossyy/filekeeper/db"
|
"github.com/fossyy/filekeeper/db"
|
||||||
signinHandler "github.com/fossyy/filekeeper/handler/signin"
|
signinHandler "github.com/fossyy/filekeeper/handler/signin"
|
||||||
"github.com/fossyy/filekeeper/logger"
|
|
||||||
"github.com/fossyy/filekeeper/session"
|
"github.com/fossyy/filekeeper/session"
|
||||||
"github.com/fossyy/filekeeper/types"
|
"github.com/fossyy/filekeeper/types"
|
||||||
"github.com/fossyy/filekeeper/types/models"
|
"github.com/fossyy/filekeeper/types/models"
|
||||||
"github.com/fossyy/filekeeper/utils"
|
"github.com/fossyy/filekeeper/utils"
|
||||||
authView "github.com/fossyy/filekeeper/view/auth"
|
"github.com/fossyy/filekeeper/view/client/auth"
|
||||||
signupView "github.com/fossyy/filekeeper/view/signup"
|
signupView "github.com/fossyy/filekeeper/view/client/signup"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync"
|
"sync"
|
||||||
@ -24,11 +24,10 @@ type UnregisteredUser struct {
|
|||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
var log *logger.AggregatedLogger
|
|
||||||
var SetupUser map[string]*UnregisteredUser
|
var SetupUser map[string]*UnregisteredUser
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
log = logger.Logger()
|
|
||||||
SetupUser = make(map[string]*UnregisteredUser)
|
SetupUser = make(map[string]*UnregisteredUser)
|
||||||
|
|
||||||
ticker := time.NewTicker(time.Minute)
|
ticker := time.NewTicker(time.Minute)
|
||||||
@ -38,7 +37,7 @@ func init() {
|
|||||||
currentTime := time.Now()
|
currentTime := time.Now()
|
||||||
cacheClean := 0
|
cacheClean := 0
|
||||||
cleanID := utils.GenerateRandomString(10)
|
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 {
|
for _, data := range SetupUser {
|
||||||
data.mu.Lock()
|
data.mu.Lock()
|
||||||
@ -50,7 +49,7 @@ func init() {
|
|||||||
data.mu.Unlock()
|
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)
|
err := component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,7 +82,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
|
|||||||
err := r.ParseForm()
|
err := r.ParseForm()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
username := r.Form.Get("username")
|
username := r.Form.Get("username")
|
||||||
@ -98,7 +97,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
|
|||||||
err := component.Render(r.Context(), w)
|
err := component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -122,7 +121,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
|
|||||||
err := component.Render(r.Context(), w)
|
err := component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
"github.com/fossyy/filekeeper/session"
|
"github.com/fossyy/filekeeper/session"
|
||||||
"github.com/fossyy/filekeeper/types"
|
"github.com/fossyy/filekeeper/types"
|
||||||
"github.com/fossyy/filekeeper/utils"
|
"github.com/fossyy/filekeeper/utils"
|
||||||
totpView "github.com/fossyy/filekeeper/view/totp"
|
"github.com/fossyy/filekeeper/view/client/totp"
|
||||||
"github.com/xlzd/gotp"
|
"github.com/xlzd/gotp"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -1,21 +1,15 @@
|
|||||||
package downloadHandler
|
package downloadHandler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/fossyy/filekeeper/app"
|
||||||
|
"github.com/fossyy/filekeeper/view/client/download"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/fossyy/filekeeper/db"
|
"github.com/fossyy/filekeeper/db"
|
||||||
"github.com/fossyy/filekeeper/logger"
|
|
||||||
"github.com/fossyy/filekeeper/types"
|
"github.com/fossyy/filekeeper/types"
|
||||||
"github.com/fossyy/filekeeper/utils"
|
"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) {
|
func GET(w http.ResponseWriter, r *http.Request) {
|
||||||
userSession := r.Context().Value("user").(types.User)
|
userSession := r.Context().Value("user").(types.User)
|
||||||
files, err := db.DB.GetFiles(userSession.UserID.String())
|
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)
|
err = component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,20 @@
|
|||||||
package downloadFileHandler
|
package downloadFileHandler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/fossyy/filekeeper/app"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/fossyy/filekeeper/db"
|
"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) {
|
func GET(w http.ResponseWriter, r *http.Request) {
|
||||||
fileID := r.PathValue("id")
|
fileID := r.PathValue("id")
|
||||||
file, err := db.DB.GetFile(fileID)
|
file, err := db.DB.GetFile(fileID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,7 +25,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
|
|||||||
saveFolder := filepath.Join(basePath, file.OwnerID.String(), file.ID.String())
|
saveFolder := filepath.Join(basePath, file.OwnerID.String(), file.ID.String())
|
||||||
|
|
||||||
if filepath.Dir(saveFolder) != filepath.Join(basePath, file.OwnerID.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)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
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)
|
openFile, err := os.OpenFile(filepath.Join(saveFolder, file.Name), os.O_RDONLY, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer openFile.Close()
|
defer openFile.Close()
|
||||||
@ -47,7 +41,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
|
|||||||
stat, err := openFile.Stat()
|
stat, err := openFile.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,24 +2,17 @@ package errorHandler
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/fossyy/filekeeper/app"
|
||||||
|
"github.com/fossyy/filekeeper/view/client/error"
|
||||||
"net/http"
|
"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) {
|
func NotFound(w http.ResponseWriter, r *http.Request) {
|
||||||
component := errorView.NotFound("Not Found")
|
component := errorView.NotFound("Not Found")
|
||||||
err := component.Render(r.Context(), w)
|
err := component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprint(w, err.Error())
|
fmt.Fprint(w, err.Error())
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -29,7 +22,7 @@ func InternalServerError(w http.ResponseWriter, r *http.Request) {
|
|||||||
err := component.Render(r.Context(), w)
|
err := component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprint(w, err.Error())
|
fmt.Fprint(w, err.Error())
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,20 +5,18 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/fossyy/filekeeper/app"
|
||||||
"github.com/fossyy/filekeeper/cache"
|
"github.com/fossyy/filekeeper/cache"
|
||||||
|
"github.com/fossyy/filekeeper/view/client/email"
|
||||||
|
"github.com/fossyy/filekeeper/view/client/forgotPassword"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fossyy/filekeeper/email"
|
|
||||||
"github.com/fossyy/filekeeper/logger"
|
|
||||||
"github.com/fossyy/filekeeper/types"
|
"github.com/fossyy/filekeeper/types"
|
||||||
"github.com/fossyy/filekeeper/types/models"
|
"github.com/fossyy/filekeeper/types/models"
|
||||||
"github.com/fossyy/filekeeper/utils"
|
"github.com/fossyy/filekeeper/utils"
|
||||||
emailView "github.com/fossyy/filekeeper/view/email"
|
|
||||||
forgotPasswordView "github.com/fossyy/filekeeper/view/forgotPassword"
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -29,25 +27,19 @@ type ForgotPassword struct {
|
|||||||
CreateTime time.Time
|
CreateTime time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
var log *logger.AggregatedLogger
|
|
||||||
var mailServer *email.SmtpServer
|
|
||||||
var ListForgotPassword map[string]*ForgotPassword
|
var ListForgotPassword map[string]*ForgotPassword
|
||||||
var UserForgotPassword = make(map[string]string)
|
var UserForgotPassword = make(map[string]string)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
log = logger.Logger()
|
|
||||||
ListForgotPassword = make(map[string]*ForgotPassword)
|
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)
|
ticker := time.NewTicker(time.Minute)
|
||||||
//TESTING
|
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
<-ticker.C
|
<-ticker.C
|
||||||
currentTime := time.Now()
|
currentTime := time.Now()
|
||||||
cacheClean := 0
|
cacheClean := 0
|
||||||
cleanID := utils.GenerateRandomString(10)
|
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 {
|
for _, data := range ListForgotPassword {
|
||||||
data.mu.Lock()
|
data.mu.Lock()
|
||||||
@ -59,7 +51,7 @@ func init() {
|
|||||||
data.mu.Unlock()
|
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)
|
err := component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,7 +73,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
|
|||||||
err := r.ParseForm()
|
err := r.ParseForm()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Error parsing form", http.StatusBadRequest)
|
http.Error(w, "Error parsing form", http.StatusBadRequest)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +88,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
|
|||||||
err := component.Render(r.Context(), w)
|
err := component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -112,7 +104,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
|
|||||||
err = verifyForgot(userData)
|
err = verifyForgot(userData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +112,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
|
|||||||
err = component.Render(r.Context(), w)
|
err = component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -152,7 +144,7 @@ func verifyForgot(user *models.User) error {
|
|||||||
UserForgotPassword[code] = user.Email
|
UserForgotPassword[code] = user.Email
|
||||||
ListForgotPassword[user.Email] = userData
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,20 @@
|
|||||||
package forgotPasswordVerifyHandler
|
package forgotPasswordVerifyHandler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/fossyy/filekeeper/app"
|
||||||
"github.com/fossyy/filekeeper/cache"
|
"github.com/fossyy/filekeeper/cache"
|
||||||
"github.com/fossyy/filekeeper/db"
|
"github.com/fossyy/filekeeper/db"
|
||||||
forgotPasswordHandler "github.com/fossyy/filekeeper/handler/forgotPassword"
|
forgotPasswordHandler "github.com/fossyy/filekeeper/handler/forgotPassword"
|
||||||
"github.com/fossyy/filekeeper/logger"
|
|
||||||
"github.com/fossyy/filekeeper/session"
|
"github.com/fossyy/filekeeper/session"
|
||||||
"github.com/fossyy/filekeeper/types"
|
"github.com/fossyy/filekeeper/types"
|
||||||
"github.com/fossyy/filekeeper/utils"
|
"github.com/fossyy/filekeeper/utils"
|
||||||
forgotPasswordView "github.com/fossyy/filekeeper/view/forgotPassword"
|
"github.com/fossyy/filekeeper/view/client/forgotPassword"
|
||||||
signupView "github.com/fossyy/filekeeper/view/signup"
|
signupView "github.com/fossyy/filekeeper/view/client/signup"
|
||||||
|
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
var log *logger.AggregatedLogger
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
log = logger.Logger()
|
|
||||||
//TESTING
|
//TESTING
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -40,7 +37,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
|
|||||||
err := component.Render(r.Context(), w)
|
err := component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -59,7 +56,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
|
|||||||
err := r.ParseForm()
|
err := r.ParseForm()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +70,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
|
|||||||
err := component.Render(r.Context(), w)
|
err := component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -82,14 +79,14 @@ func POST(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = db.DB.UpdateUserPassword(data.User.Email, hashedPassword)
|
err = db.DB.UpdateUserPassword(data.User.Email, hashedPassword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +101,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
|
|||||||
err = component.Render(r.Context(), w)
|
err = component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -1,26 +1,19 @@
|
|||||||
package indexHandler
|
package indexHandler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/fossyy/filekeeper/app"
|
||||||
"github.com/fossyy/filekeeper/session"
|
"github.com/fossyy/filekeeper/session"
|
||||||
|
"github.com/fossyy/filekeeper/view/client/index"
|
||||||
"net/http"
|
"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) {
|
func GET(w http.ResponseWriter, r *http.Request) {
|
||||||
_, userSession, _ := session.GetSession(r)
|
_, userSession, _ := session.GetSession(r)
|
||||||
component := indexView.Main("Secure File Hosting - Filekeeper", userSession)
|
component := indexView.Main("Secure File Hosting - Filekeeper", userSession)
|
||||||
err := component.Render(r.Context(), w)
|
err := component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,17 +3,16 @@ package signinHandler
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/a-h/templ"
|
"github.com/a-h/templ"
|
||||||
|
"github.com/fossyy/filekeeper/app"
|
||||||
"github.com/fossyy/filekeeper/cache"
|
"github.com/fossyy/filekeeper/cache"
|
||||||
"github.com/fossyy/filekeeper/logger"
|
|
||||||
"github.com/fossyy/filekeeper/session"
|
"github.com/fossyy/filekeeper/session"
|
||||||
"github.com/fossyy/filekeeper/types"
|
"github.com/fossyy/filekeeper/types"
|
||||||
"github.com/fossyy/filekeeper/utils"
|
"github.com/fossyy/filekeeper/utils"
|
||||||
signinView "github.com/fossyy/filekeeper/view/signin"
|
"github.com/fossyy/filekeeper/view/client/signin"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var log *logger.AggregatedLogger
|
|
||||||
var errorMessages = make(map[string]string)
|
var errorMessages = make(map[string]string)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -39,7 +38,7 @@ func init() {
|
|||||||
"account_selection_required": "Please select an account to proceed with the request.",
|
"account_selection_required": "Please select an account to proceed with the request.",
|
||||||
"consent_required": "Consent is required to proceed. Please provide consent to continue.",
|
"consent_required": "Consent is required to proceed. Please provide consent to continue.",
|
||||||
}
|
}
|
||||||
log = logger.Logger()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GET(w http.ResponseWriter, r *http.Request) {
|
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)
|
err := component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,7 +72,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
|
|||||||
err := r.ParseForm()
|
err := r.ParseForm()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Error parsing form", http.StatusBadRequest)
|
http.Error(w, "Error parsing form", http.StatusBadRequest)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
email := r.Form.Get("email")
|
email := r.Form.Get("email")
|
||||||
@ -84,11 +83,11 @@ func POST(w http.ResponseWriter, r *http.Request) {
|
|||||||
Code: 0,
|
Code: 0,
|
||||||
Message: "Incorrect Username or Password",
|
Message: "Incorrect Username or Password",
|
||||||
})
|
})
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
err = component.Render(r.Context(), w)
|
err = component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -152,7 +151,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
|
|||||||
err = component.Render(r.Context(), w)
|
err = component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,19 +4,17 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/fossyy/filekeeper/app"
|
||||||
|
"github.com/fossyy/filekeeper/view/client/email"
|
||||||
|
signupView "github.com/fossyy/filekeeper/view/client/signup"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fossyy/filekeeper/db"
|
"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"
|
||||||
"github.com/fossyy/filekeeper/types/models"
|
"github.com/fossyy/filekeeper/types/models"
|
||||||
"github.com/fossyy/filekeeper/utils"
|
"github.com/fossyy/filekeeper/utils"
|
||||||
emailView "github.com/fossyy/filekeeper/view/email"
|
|
||||||
signupView "github.com/fossyy/filekeeper/view/signup"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -27,15 +25,10 @@ type UnverifiedUser struct {
|
|||||||
CreateTime time.Time
|
CreateTime time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
var log *logger.AggregatedLogger
|
|
||||||
var mailServer *email.SmtpServer
|
|
||||||
var VerifyUser map[string]*UnverifiedUser
|
var VerifyUser map[string]*UnverifiedUser
|
||||||
var VerifyEmail map[string]string
|
var VerifyEmail map[string]string
|
||||||
|
|
||||||
func init() {
|
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)
|
VerifyUser = make(map[string]*UnverifiedUser)
|
||||||
VerifyEmail = make(map[string]string)
|
VerifyEmail = make(map[string]string)
|
||||||
|
|
||||||
@ -46,7 +39,7 @@ func init() {
|
|||||||
currentTime := time.Now()
|
currentTime := time.Now()
|
||||||
cacheClean := 0
|
cacheClean := 0
|
||||||
cleanID := utils.GenerateRandomString(10)
|
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 {
|
for _, data := range VerifyUser {
|
||||||
data.mu.Lock()
|
data.mu.Lock()
|
||||||
@ -58,7 +51,7 @@ func init() {
|
|||||||
data.mu.Unlock()
|
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)
|
err := component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,7 +73,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
|
|||||||
err := r.ParseForm()
|
err := r.ParseForm()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
userEmail := r.Form.Get("email")
|
userEmail := r.Form.Get("email")
|
||||||
@ -95,7 +88,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
|
|||||||
err := component.Render(r.Context(), w)
|
err := component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -117,7 +110,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
|
|||||||
err = component.Render(r.Context(), w)
|
err = component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -126,7 +119,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
|
|||||||
err = verifyEmail(&newUser)
|
err = verifyEmail(&newUser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +127,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
|
|||||||
err = component.Render(r.Context(), w)
|
err = component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -167,7 +160,7 @@ func verifyEmail(user *models.User) error {
|
|||||||
VerifyUser[code] = &unverifiedUser
|
VerifyUser[code] = &unverifiedUser
|
||||||
VerifyEmail[user.Email] = code
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,15 @@
|
|||||||
package signupVerifyHandler
|
package signupVerifyHandler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/fossyy/filekeeper/app"
|
||||||
|
signupView "github.com/fossyy/filekeeper/view/client/signup"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/fossyy/filekeeper/db"
|
"github.com/fossyy/filekeeper/db"
|
||||||
signupHandler "github.com/fossyy/filekeeper/handler/signup"
|
signupHandler "github.com/fossyy/filekeeper/handler/signup"
|
||||||
"github.com/fossyy/filekeeper/logger"
|
|
||||||
"github.com/fossyy/filekeeper/types"
|
"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) {
|
func GET(w http.ResponseWriter, r *http.Request) {
|
||||||
code := r.PathValue("code")
|
code := r.PathValue("code")
|
||||||
data, ok := signupHandler.VerifyUser[code]
|
data, ok := signupHandler.VerifyUser[code]
|
||||||
@ -34,7 +28,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
|
|||||||
err := component.Render(r.Context(), w)
|
err := component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -48,7 +42,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
|
|||||||
err = component.Render(r.Context(), w)
|
err = component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package initialisation
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"github.com/fossyy/filekeeper/app"
|
||||||
"github.com/fossyy/filekeeper/cache"
|
"github.com/fossyy/filekeeper/cache"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -10,19 +11,12 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/fossyy/filekeeper/db"
|
"github.com/fossyy/filekeeper/db"
|
||||||
"github.com/fossyy/filekeeper/logger"
|
|
||||||
"github.com/fossyy/filekeeper/types"
|
"github.com/fossyy/filekeeper/types"
|
||||||
"github.com/fossyy/filekeeper/types/models"
|
"github.com/fossyy/filekeeper/types/models"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
var log *logger.AggregatedLogger
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
log = logger.Logger()
|
|
||||||
}
|
|
||||||
|
|
||||||
func POST(w http.ResponseWriter, r *http.Request) {
|
func POST(w http.ResponseWriter, r *http.Request) {
|
||||||
userSession := r.Context().Value("user").(types.User)
|
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) {
|
func handleNewUpload(user types.User, file types.FileInfo) (models.File, error) {
|
||||||
uploadDir := "uploads"
|
uploadDir := "uploads"
|
||||||
if _, err := os.Stat(uploadDir); os.IsNotExist(err) {
|
if _, err := os.Stat(uploadDir); os.IsNotExist(err) {
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
err := os.Mkdir(uploadDir, os.ModePerm)
|
err := os.Mkdir(uploadDir, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return models.File{}, err
|
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)
|
err := os.MkdirAll(saveFolder, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return models.File{}, err
|
return models.File{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +95,7 @@ func handleNewUpload(user types.User, file types.FileInfo) (models.File, error)
|
|||||||
|
|
||||||
err = db.DB.CreateFile(&newFile)
|
err = db.DB.CreateFile(&newFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return models.File{}, err
|
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) {
|
func handleError(w http.ResponseWriter, err error, statusCode int) {
|
||||||
http.Error(w, err.Error(), statusCode)
|
http.Error(w, err.Error(), statusCode)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package uploadHandler
|
package uploadHandler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/fossyy/filekeeper/app"
|
||||||
"github.com/fossyy/filekeeper/cache"
|
"github.com/fossyy/filekeeper/cache"
|
||||||
"github.com/fossyy/filekeeper/logger"
|
|
||||||
"github.com/fossyy/filekeeper/types"
|
"github.com/fossyy/filekeeper/types"
|
||||||
filesView "github.com/fossyy/filekeeper/view/upload"
|
filesView "github.com/fossyy/filekeeper/view/client/upload"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@ -12,12 +12,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
var log *logger.AggregatedLogger
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
log = logger.Logger()
|
|
||||||
}
|
|
||||||
|
|
||||||
func GET(w http.ResponseWriter, r *http.Request) {
|
func GET(w http.ResponseWriter, r *http.Request) {
|
||||||
component := filesView.Main("Filekeeper - Upload")
|
component := filesView.Main("Filekeeper - Upload")
|
||||||
if err := component.Render(r.Context(), w); err != nil {
|
if err := component.Render(r.Context(), w); err != nil {
|
||||||
@ -38,7 +32,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
|
|||||||
uploadDir := "uploads"
|
uploadDir := "uploads"
|
||||||
if _, err := os.Stat(uploadDir); os.IsNotExist(err) {
|
if _, err := os.Stat(uploadDir); os.IsNotExist(err) {
|
||||||
if err := os.Mkdir(uploadDir, os.ModePerm); err != nil {
|
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)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -46,7 +40,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
file, err := cache.GetFile(fileID)
|
file, err := cache.GetFile(fileID)
|
||||||
if err != nil {
|
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)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -56,14 +50,14 @@ func POST(w http.ResponseWriter, r *http.Request) {
|
|||||||
saveFolder := filepath.Join(basePath, userSession.UserID.String(), file.ID.String())
|
saveFolder := filepath.Join(basePath, userSession.UserID.String(), file.ID.String())
|
||||||
|
|
||||||
if filepath.Dir(saveFolder) != filepath.Join(basePath, userSession.UserID.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)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fileByte, fileHeader, err := r.FormFile("chunk")
|
fileByte, fileHeader, err := r.FormFile("chunk")
|
||||||
if err != nil {
|
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)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
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)
|
dst, err := os.OpenFile(filepath.Join(saveFolder, file.Name), os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
|
||||||
if err != nil {
|
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)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
defer dst.Close()
|
defer dst.Close()
|
||||||
if _, err := io.Copy(dst, fileByte); err != nil {
|
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)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ package userSessionTerminateHandler
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/fossyy/filekeeper/session"
|
"github.com/fossyy/filekeeper/session"
|
||||||
userView "github.com/fossyy/filekeeper/view/user"
|
"github.com/fossyy/filekeeper/view/client/user"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/fossyy/filekeeper/cache"
|
"github.com/fossyy/filekeeper/cache"
|
||||||
userTotpSetupView "github.com/fossyy/filekeeper/view/user/totp"
|
"github.com/fossyy/filekeeper/view/client/user/totp"
|
||||||
"image/png"
|
"image/png"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
@ -2,20 +2,14 @@ package userHandler
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/a-h/templ"
|
"github.com/a-h/templ"
|
||||||
|
"github.com/fossyy/filekeeper/app"
|
||||||
"github.com/fossyy/filekeeper/types"
|
"github.com/fossyy/filekeeper/types"
|
||||||
|
"github.com/fossyy/filekeeper/view/client/user"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/fossyy/filekeeper/logger"
|
|
||||||
"github.com/fossyy/filekeeper/session"
|
"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{
|
var errorMessages = map[string]string{
|
||||||
"password_not_match": "The passwords provided do not match. Please try again.",
|
"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)
|
err := component.Render(r.Context(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
log.Error(err.Error())
|
app.Server.Logger.Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,11 +29,11 @@ func Logger() *AggregatedLogger {
|
|||||||
return &AggregatedLogger{}
|
return &AggregatedLogger{}
|
||||||
}
|
}
|
||||||
flag := log.Ldate | log.Ltime
|
flag := log.Ldate | log.Ltime
|
||||||
writer := io.MultiWriter(os.Stdout, file)
|
multiLogger := io.MultiWriter(os.Stdout, file)
|
||||||
infoLogger := log.New(writer, "INFO: ", flag)
|
infoLogger := log.New(file, "INFO: ", flag)
|
||||||
warnLogger := log.New(writer, "WARN: ", flag)
|
warnLogger := log.New(multiLogger, "WARN: ", flag)
|
||||||
errorLogger := log.New(writer, "ERROR: ", flag)
|
errorLogger := log.New(multiLogger, "ERROR: ", flag)
|
||||||
panicLogger := log.New(writer, "PANIC: ", flag)
|
panicLogger := log.New(multiLogger, "PANIC: ", flag)
|
||||||
|
|
||||||
return &AggregatedLogger{
|
return &AggregatedLogger{
|
||||||
infoLogger: infoLogger,
|
infoLogger: infoLogger,
|
||||||
|
34
main.go
34
main.go
@ -1,7 +1,37 @@
|
|||||||
package main
|
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() {
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,21 +3,15 @@ package middleware
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/fossyy/filekeeper/app"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
errorHandler "github.com/fossyy/filekeeper/handler/error"
|
errorHandler "github.com/fossyy/filekeeper/handler/error"
|
||||||
"github.com/fossyy/filekeeper/logger"
|
|
||||||
"github.com/fossyy/filekeeper/session"
|
"github.com/fossyy/filekeeper/session"
|
||||||
"github.com/fossyy/filekeeper/utils"
|
"github.com/fossyy/filekeeper/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var log *logger.AggregatedLogger
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
log = logger.Logger()
|
|
||||||
}
|
|
||||||
|
|
||||||
type wrapper struct {
|
type wrapper struct {
|
||||||
http.ResponseWriter
|
http.ResponseWriter
|
||||||
request *http.Request
|
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-Methods", fmt.Sprintf("%s, OPTIONS", utils.Getenv("CORS_METHODS")))
|
||||||
writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
|
writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
|
||||||
next.ServeHTTP(wrappedWriter, request)
|
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))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
var isMatch = false
|
var isMatch = false;
|
||||||
var isValid = false
|
var isValid = false;
|
||||||
|
var hasUppercase = false;
|
||||||
|
|
||||||
function validatePasswords() {
|
function validatePasswords() {
|
||||||
var password = document.getElementById('password').value;
|
var password = document.getElementById('password').value;
|
||||||
var confirmPassword = document.getElementById('confirmPassword').value;
|
var confirmPassword = document.getElementById('confirmPassword').value;
|
||||||
@ -7,10 +9,14 @@ function validatePasswords() {
|
|||||||
var matchBadPath = document.getElementById('matchBadPath');
|
var matchBadPath = document.getElementById('matchBadPath');
|
||||||
var lengthGoodPath = document.getElementById('lengthGoodPath');
|
var lengthGoodPath = document.getElementById('lengthGoodPath');
|
||||||
var lengthBadPath = document.getElementById('lengthBadPath');
|
var lengthBadPath = document.getElementById('lengthBadPath');
|
||||||
|
var uppercaseGoodPath = document.getElementById('uppercaseGoodPath');
|
||||||
|
var uppercaseBadPath = document.getElementById('uppercaseBadPath');
|
||||||
var matchSvgContainer = document.getElementById('matchSvgContainer');
|
var matchSvgContainer = document.getElementById('matchSvgContainer');
|
||||||
var lengthSvgContainer = document.getElementById('lengthSvgContainer');
|
var lengthSvgContainer = document.getElementById('lengthSvgContainer');
|
||||||
|
var uppercaseSvgContainer = document.getElementById('uppercaseSvgContainer');
|
||||||
var matchStatusText = document.getElementById('matchStatusText');
|
var matchStatusText = document.getElementById('matchStatusText');
|
||||||
var lengthStatusText = document.getElementById('lengthStatusText');
|
var lengthStatusText = document.getElementById('lengthStatusText');
|
||||||
|
var uppercaseStatusText = document.getElementById('uppercaseStatusText');
|
||||||
|
|
||||||
if (password === confirmPassword && password.length > 0 && confirmPassword.length > 0 && password.length === confirmPassword.length) {
|
if (password === confirmPassword && password.length > 0 && confirmPassword.length > 0 && password.length === confirmPassword.length) {
|
||||||
matchSvgContainer.classList.remove('bg-red-200');
|
matchSvgContainer.classList.remove('bg-red-200');
|
||||||
@ -20,7 +26,7 @@ function validatePasswords() {
|
|||||||
matchGoodPath.style.display = 'inline';
|
matchGoodPath.style.display = 'inline';
|
||||||
matchBadPath.style.display = 'none';
|
matchBadPath.style.display = 'none';
|
||||||
matchStatusText.textContent = "Passwords match";
|
matchStatusText.textContent = "Passwords match";
|
||||||
isMatch = true
|
isMatch = true;
|
||||||
} else {
|
} else {
|
||||||
matchSvgContainer.classList.remove('bg-green-200');
|
matchSvgContainer.classList.remove('bg-green-200');
|
||||||
matchSvgContainer.classList.add('bg-red-200');
|
matchSvgContainer.classList.add('bg-red-200');
|
||||||
@ -29,7 +35,7 @@ function validatePasswords() {
|
|||||||
matchGoodPath.style.display = 'none';
|
matchGoodPath.style.display = 'none';
|
||||||
matchBadPath.style.display = 'inline';
|
matchBadPath.style.display = 'inline';
|
||||||
matchStatusText.textContent = "Passwords do not match";
|
matchStatusText.textContent = "Passwords do not match";
|
||||||
isMatch = false
|
isMatch = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (password.length >= 8) {
|
if (password.length >= 8) {
|
||||||
@ -40,7 +46,7 @@ function validatePasswords() {
|
|||||||
lengthGoodPath.style.display = 'inline';
|
lengthGoodPath.style.display = 'inline';
|
||||||
lengthBadPath.style.display = 'none';
|
lengthBadPath.style.display = 'none';
|
||||||
lengthStatusText.textContent = "Password length meets requirement";
|
lengthStatusText.textContent = "Password length meets requirement";
|
||||||
isValid = true
|
isValid = true;
|
||||||
} else {
|
} else {
|
||||||
lengthSvgContainer.classList.remove('bg-green-200');
|
lengthSvgContainer.classList.remove('bg-green-200');
|
||||||
lengthSvgContainer.classList.add('bg-red-200');
|
lengthSvgContainer.classList.add('bg-red-200');
|
||||||
@ -49,10 +55,30 @@ function validatePasswords() {
|
|||||||
lengthGoodPath.style.display = 'none';
|
lengthGoodPath.style.display = 'none';
|
||||||
lengthBadPath.style.display = 'inline';
|
lengthBadPath.style.display = 'inline';
|
||||||
lengthStatusText.textContent = "Password length must be at least 8 characters";
|
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;
|
document.getElementById("submit").disabled = false;
|
||||||
} else {
|
} else {
|
||||||
document.getElementById("submit").disabled = true;
|
document.getElementById("submit").disabled = true;
|
||||||
|
@ -2,7 +2,7 @@ package session
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/fossyy/filekeeper/logger"
|
"github.com/fossyy/filekeeper/app"
|
||||||
"github.com/fossyy/filekeeper/types"
|
"github.com/fossyy/filekeeper/types"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -41,10 +41,8 @@ const (
|
|||||||
|
|
||||||
var GlobalSessionStore = make(map[string]*Session)
|
var GlobalSessionStore = make(map[string]*Session)
|
||||||
var UserSessionInfoList = make(map[string]map[string]*SessionInfo)
|
var UserSessionInfoList = make(map[string]map[string]*SessionInfo)
|
||||||
var log *logger.AggregatedLogger
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
log = logger.Logger()
|
|
||||||
|
|
||||||
ticker := time.NewTicker(time.Minute)
|
ticker := time.NewTicker(time.Minute)
|
||||||
go func() {
|
go func() {
|
||||||
@ -53,7 +51,7 @@ func init() {
|
|||||||
currentTime := time.Now()
|
currentTime := time.Now()
|
||||||
cacheClean := 0
|
cacheClean := 0
|
||||||
cleanID := utils.GenerateRandomString(10)
|
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 {
|
for _, data := range GlobalSessionStore {
|
||||||
data.mu.Lock()
|
data.mu.Lock()
|
||||||
@ -65,7 +63,7 @@ func init() {
|
|||||||
data.mu.Unlock()
|
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)))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/fossyy/filekeeper/app"
|
||||||
mathRand "math/rand"
|
mathRand "math/rand"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@ -13,7 +14,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"github.com/fossyy/filekeeper/logger"
|
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
)
|
)
|
||||||
@ -24,7 +24,6 @@ type Env struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var env *Env
|
var env *Env
|
||||||
var log *logger.AggregatedLogger
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
env = &Env{value: map[string]string{}}
|
env = &Env{value: map[string]string{}}
|
||||||
@ -110,7 +109,7 @@ func Getenv(key string) string {
|
|||||||
if os.Getenv("HOSTNAME") == "" {
|
if os.Getenv("HOSTNAME") == "" {
|
||||||
err := godotenv.Load(".env")
|
err := godotenv.Load(".env")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error loading .env file: %s", err)
|
app.Server.Logger.Error("Error loading .env file: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ package authView
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/fossyy/filekeeper/types"
|
"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) {
|
templ form(err types.Message, title string) {
|
||||||
@ -49,6 +49,15 @@ templ form(err types.Message, title string) {
|
|||||||
</div>
|
</div>
|
||||||
<span id="matchStatusText" class="font-medium text-sm ml-3 text-red-700"> Passwords do not match</span>
|
<span id="matchStatusText" class="font-medium text-sm ml-3 text-red-700"> Passwords do not match</span>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="flex items-center py-1">
|
||||||
|
<div id="uppercaseSvgContainer" class="rounded-full p-1 fill-current bg-red-200 text-green-700">
|
||||||
|
<svg id="uppercaseSvgIcon" class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path id="uppercaseGoodPath" style="display: none;" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
||||||
|
<path id="uppercaseBadPath" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<span id="uppercaseStatusText" class="font-medium text-sm ml-3 text-red-700"> Password must contain at least one uppercase letter</span>
|
||||||
|
</li>
|
||||||
<li class="flex items-center py-1">
|
<li class="flex items-center py-1">
|
||||||
<div id="lengthSvgContainer" class="rounded-full p-1 fill-current bg-red-200 text-green-700">
|
<div id="lengthSvgContainer" class="rounded-full p-1 fill-current bg-red-200 text-green-700">
|
||||||
<svg id="lengthSvgIcon" class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<svg id="lengthSvgIcon" class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
@ -1,7 +1,7 @@
|
|||||||
package downloadView
|
package downloadView
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/fossyy/filekeeper/view/layout"
|
"github.com/fossyy/filekeeper/view/client/layout"
|
||||||
"github.com/fossyy/filekeeper/types"
|
"github.com/fossyy/filekeeper/types"
|
||||||
)
|
)
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
package errorView
|
package errorView
|
||||||
|
|
||||||
import "github.com/fossyy/filekeeper/view/layout"
|
import "github.com/fossyy/filekeeper/view/client/layout"
|
||||||
|
|
||||||
templ NotFound(title string){
|
templ NotFound(title string){
|
||||||
@layout.Base(title){
|
@layout.Base(title){
|
@ -2,7 +2,7 @@ package forgotPasswordView
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/fossyy/filekeeper/types"
|
"github.com/fossyy/filekeeper/types"
|
||||||
"github.com/fossyy/filekeeper/view/layout"
|
"github.com/fossyy/filekeeper/view/client/layout"
|
||||||
)
|
)
|
||||||
|
|
||||||
templ content(title string, err types.Message) {
|
templ content(title string, err types.Message) {
|
@ -2,7 +2,7 @@ package indexView
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/fossyy/filekeeper/types"
|
"github.com/fossyy/filekeeper/types"
|
||||||
"github.com/fossyy/filekeeper/view/layout"
|
"github.com/fossyy/filekeeper/view/client/layout"
|
||||||
)
|
)
|
||||||
|
|
||||||
templ content(title string, user types.User) {
|
templ content(title string, user types.User) {
|
@ -2,7 +2,7 @@ package signinView
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/fossyy/filekeeper/types"
|
"github.com/fossyy/filekeeper/types"
|
||||||
"github.com/fossyy/filekeeper/view/layout"
|
"github.com/fossyy/filekeeper/view/client/layout"
|
||||||
)
|
)
|
||||||
|
|
||||||
templ content(err types.Message, title string) {
|
templ content(err types.Message, title string) {
|
@ -2,7 +2,7 @@ package signup
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/fossyy/filekeeper/types"
|
"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) {
|
templ form(err types.Message, title string) {
|
||||||
@ -55,6 +55,15 @@ templ form(err types.Message, title string) {
|
|||||||
</div>
|
</div>
|
||||||
<span id="matchStatusText" class="font-medium text-sm ml-3 text-red-700"> Passwords do not match</span>
|
<span id="matchStatusText" class="font-medium text-sm ml-3 text-red-700"> Passwords do not match</span>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="flex items-center py-1">
|
||||||
|
<div id="uppercaseSvgContainer" class="rounded-full p-1 fill-current bg-red-200 text-green-700">
|
||||||
|
<svg id="uppercaseSvgIcon" class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path id="uppercaseGoodPath" style="display: none;" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
||||||
|
<path id="uppercaseBadPath" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<span id="uppercaseStatusText" class="font-medium text-sm ml-3 text-red-700"> Password must contain at least one uppercase letter</span>
|
||||||
|
</li>
|
||||||
<li class="flex items-center py-1">
|
<li class="flex items-center py-1">
|
||||||
<div id="lengthSvgContainer" class="rounded-full p-1 fill-current bg-red-200 text-green-700">
|
<div id="lengthSvgContainer" class="rounded-full p-1 fill-current bg-red-200 text-green-700">
|
||||||
<svg id="lengthSvgIcon" class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<svg id="lengthSvgIcon" class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
@ -1,7 +1,7 @@
|
|||||||
package totpView
|
package totpView
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/fossyy/filekeeper/view/layout"
|
"github.com/fossyy/filekeeper/view/client/layout"
|
||||||
"github.com/fossyy/filekeeper/types"
|
"github.com/fossyy/filekeeper/types"
|
||||||
)
|
)
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
package uploadView
|
package uploadView
|
||||||
|
|
||||||
import "github.com/fossyy/filekeeper/view/layout"
|
import "github.com/fossyy/filekeeper/view/client/layout"
|
||||||
|
|
||||||
templ content(title string) {
|
templ content(title string) {
|
||||||
@layout.Base(title){
|
@layout.Base(title){
|
@ -1,7 +1,7 @@
|
|||||||
package userTotpSetupView
|
package userTotpSetupView
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/fossyy/filekeeper/view/layout"
|
"github.com/fossyy/filekeeper/view/client/layout"
|
||||||
"github.com/fossyy/filekeeper/types"
|
"github.com/fossyy/filekeeper/types"
|
||||||
)
|
)
|
||||||
|
|
@ -2,7 +2,7 @@ package userView
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/fossyy/filekeeper/types"
|
"github.com/fossyy/filekeeper/types"
|
||||||
"github.com/fossyy/filekeeper/view/layout"
|
"github.com/fossyy/filekeeper/view/client/layout"
|
||||||
"github.com/fossyy/filekeeper/session"
|
"github.com/fossyy/filekeeper/session"
|
||||||
)
|
)
|
||||||
|
|
Reference in New Issue
Block a user