Refactor session package for better structure and naming conventions

This commit is contained in:
2024-04-26 20:33:34 +07:00
parent 769bffe6ff
commit c43fd0232e
11 changed files with 52 additions and 161 deletions

View File

@ -30,9 +30,9 @@ func GET(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
} }
storeSession, err := session.Store.Get(cookie.Value) storeSession, err := session.GlobalSessionStore.Get(cookie.Value)
if err != nil { if err != nil {
if errors.Is(err, &session.SessionNotFound{}) { if errors.Is(err, &session.SessionNotFoundError{}) {
storeSession.Destroy(w) storeSession.Destroy(w)
} }
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)

View File

@ -94,7 +94,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
delete(forgotPasswordHandler.ListForgotPassword, data.User.Email) delete(forgotPasswordHandler.ListForgotPassword, data.User.Email)
delete(forgotPasswordHandler.UserForgotPassword, data.Code) delete(forgotPasswordHandler.UserForgotPassword, data.Code)
session.RemoveAllSession(data.User.Email) session.RemoveAllSessions(data.User.Email)
user.DeleteCache(data.User.Email) user.DeleteCache(data.User.Email)

View File

@ -21,17 +21,17 @@ func GET(w http.ResponseWriter, r *http.Request) {
return return
} }
storeSession, err := session.Store.Get(cookie.Value) storeSession, err := session.GlobalSessionStore.Get(cookie.Value)
if err != nil { if err != nil {
if errors.Is(err, &session.SessionNotFound{}) { if errors.Is(err, &session.SessionNotFoundError{}) {
storeSession.Destroy(w) storeSession.Destroy(w)
} }
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
} }
session.Store.Delete(cookie.Value) session.GlobalSessionStore.Delete(cookie.Value)
session.RemoveSession(storeSession.Values["user"].(types.User).Email, cookie.Value) session.RemoveSessionInfo(storeSession.Values["user"].(types.User).Email, cookie.Value)
http.SetCookie(w, &http.Cookie{ http.SetCookie(w, &http.Cookie{
Name: utils.Getenv("SESSION_NAME"), Name: utils.Getenv("SESSION_NAME"),

View File

@ -57,7 +57,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
} }
if email == userData.Email && utils.CheckPasswordHash(password, userData.Password) { if email == userData.Email && utils.CheckPasswordHash(password, userData.Password) {
storeSession := session.Store.Create() storeSession := session.GlobalSessionStore.Create()
storeSession.Values["user"] = types.User{ storeSession.Values["user"] = types.User{
UserID: userData.UserID, UserID: userData.UserID,
Email: email, Email: email,
@ -79,7 +79,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
} }
storeSession.Save(w) storeSession.Save(w)
session.AppendSession(email, &sessionInfo) session.AddSessionInfo(email, &sessionInfo)
cookie, err := r.Cookie("redirect") cookie, err := r.Cookie("redirect")
if errors.Is(err, http.ErrNoCookie) { if errors.Is(err, http.ErrNoCookie) {

View File

@ -30,9 +30,9 @@ func POST(w http.ResponseWriter, r *http.Request) {
return return
} }
storeSession, err := session.Store.Get(cookie.Value) storeSession, err := session.GlobalSessionStore.Get(cookie.Value)
if err != nil { if err != nil {
if errors.Is(err, &session.SessionNotFound{}) { if errors.Is(err, &session.SessionNotFoundError{}) {
storeSession.Destroy(w) storeSession.Destroy(w)
} }
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)

View File

@ -44,9 +44,9 @@ func POST(w http.ResponseWriter, r *http.Request) {
return return
} }
storeSession, err := session.Store.Get(cookie.Value) storeSession, err := session.GlobalSessionStore.Get(cookie.Value)
if err != nil { if err != nil {
if errors.Is(err, &session.SessionNotFound{}) { if errors.Is(err, &session.SessionNotFoundError{}) {
storeSession.Destroy(w) storeSession.Destroy(w)
} }
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)

View File

@ -20,9 +20,9 @@ func GET(w http.ResponseWriter, r *http.Request) {
if err != nil { if err != nil {
return return
} }
storeSession, err := session.Store.Get(cookie.Value) storeSession, err := session.GlobalSessionStore.Get(cookie.Value)
if err != nil { if err != nil {
if errors.Is(err, &session.SessionNotFound{}) { if errors.Is(err, &session.SessionNotFoundError{}) {
storeSession.Destroy(w) storeSession.Destroy(w)
} }
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
@ -35,7 +35,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
return return
} }
component := userView.Main("User Page", userSession.Email, userSession.Username, session.UserSessions[userSession.Email]) component := userView.Main("User Page", userSession.Email, userSession.Username, session.UserSessionInfoList[userSession.Email])
err = component.Render(r.Context(), w) err = component.Render(r.Context(), w)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)

View File

@ -74,10 +74,10 @@ func Auth(next http.HandlerFunc, w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
} }
storeSession, err := session.Store.Get(cookie.Value) storeSession, err := session.GlobalSessionStore.Get(cookie.Value)
if err != nil { if err != nil {
if errors.Is(err, &session.SessionNotFound{}) { if errors.Is(err, &session.SessionNotFoundError{}) {
storeSession.Destroy(w) storeSession.Destroy(w)
http.Redirect(w, r, "/signin", http.StatusSeeOther) http.Redirect(w, r, "/signin", http.StatusSeeOther)
return return
@ -112,9 +112,9 @@ func Guest(next http.HandlerFunc, w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
} }
storeSession, err := session.Store.Get(cookie.Value) storeSession, err := session.GlobalSessionStore.Get(cookie.Value)
if err != nil { if err != nil {
if errors.Is(err, &session.SessionNotFound{}) { if errors.Is(err, &session.SessionNotFoundError{}) {
http.SetCookie(w, &http.Cookie{ http.SetCookie(w, &http.Cookie{
Name: "Session", Name: "Session",
Value: "", Value: "",

View File

@ -110,106 +110,7 @@
</div> </div>
<script> <script>
var isMatch = false
var isValid = false
var isSecure = false
function validatePasswords() {
var password = document.getElementById('password').value;
var confirmPassword = document.getElementById('confirmPassword').value;
var matchGoodPath = document.getElementById('matchGoodPath');
var matchBadPath = document.getElementById('matchBadPath');
var lengthGoodPath = document.getElementById('lengthGoodPath');
var lengthBadPath = document.getElementById('lengthBadPath');
var requirementsGoodPath = document.getElementById('requirementsGoodPath');
var requirementsBadPath = document.getElementById('requirementsBadPath');
var matchSvgContainer = document.getElementById('matchSvgContainer');
var lengthSvgContainer = document.getElementById('lengthSvgContainer');
var requirementsSvgContainer = document.getElementById('requirementsSvgContainer');
var matchStatusText = document.getElementById('matchStatusText');
var lengthStatusText = document.getElementById('lengthStatusText');
var requirementsStatusText = document.getElementById('requirementsStatusText');
var symbolRegex = /[!@#$%^&*]/;
var uppercaseRegex = /[A-Z]/;
var numberRegex = /\d/g;
if (password === confirmPassword && password.length > 0 && confirmPassword.length > 0 && password.length === confirmPassword.length) {
matchSvgContainer.classList.remove('bg-red-200');
matchSvgContainer.classList.add('bg-green-200');
matchStatusText.classList.remove('text-red-700');
matchStatusText.classList.add('text-green-700');
matchGoodPath.style.display = 'inline';
matchBadPath.style.display = 'none';
matchStatusText.textContent = "Passwords match";
console.log("anjay")
isMatch = true
} else {
matchSvgContainer.classList.remove('bg-green-200');
matchSvgContainer.classList.add('bg-red-200');
matchStatusText.classList.remove('text-green-700');
matchStatusText.classList.add('text-red-700');
matchGoodPath.style.display = 'none';
matchBadPath.style.display = 'inline';
matchStatusText.textContent = "Passwords do not match";
isMatch = false
}
if (password.length >= 8) {
lengthSvgContainer.classList.remove('bg-red-200');
lengthSvgContainer.classList.add('bg-green-200');
lengthStatusText.classList.remove('text-red-700');
lengthStatusText.classList.add('text-green-700');
lengthGoodPath.style.display = 'inline';
lengthBadPath.style.display = 'none';
lengthStatusText.textContent = "Password length meets requirement";
isValid = true
} else {
lengthSvgContainer.classList.remove('bg-green-200');
lengthSvgContainer.classList.add('bg-red-200');
lengthStatusText.classList.remove('text-green-700');
lengthStatusText.classList.add('text-red-700');
lengthGoodPath.style.display = 'none';
lengthBadPath.style.display = 'inline';
lengthStatusText.textContent = "Password length must be at least 8 characters";
isValid = false
}
var symbolCheck = symbolRegex.test(password);
var uppercaseCheck = uppercaseRegex.test(password);
var numberCount = (password.match(numberRegex) || []).length;
if (symbolCheck && uppercaseCheck && numberCount >= 3) {
requirementsSvgContainer.classList.remove('bg-red-200');
requirementsSvgContainer.classList.add('bg-green-200');
requirementsStatusText.classList.remove('text-red-700');
requirementsStatusText.classList.add('text-green-700');
requirementsGoodPath.style.display = 'inline';
requirementsBadPath.style.display = 'none';
requirementsStatusText.textContent = "Password meets additional requirements";
isSecure = true
} else {
requirementsSvgContainer.classList.remove('bg-green-200');
requirementsSvgContainer.classList.add('bg-red-200');
requirementsStatusText.classList.remove('text-green-700');
requirementsStatusText.classList.add('text-red-700');
requirementsGoodPath.style.display = 'none';
requirementsBadPath.style.display = 'inline';
requirementsStatusText.textContent = "The password must contain at least one symbol (!@#$%^&*), one uppercase letter, and three numbers";
isSecure = false
}
console.log(isSecure)
console.log(isValid)
console.log(isSecure)
if (isSecure && isValid && isSecure && password === confirmPassword) {
document.getElementById("submit").disabled = false;
} else {
document.getElementById("submit").disabled = true;
}
}
document.getElementById('password').addEventListener('input', validatePasswords);
document.getElementById('confirmPassword').addEventListener('input', validatePasswords);
</script> </script>
</body> </body>

View File

@ -1,7 +1,6 @@
package routes package routes
import ( import (
"encoding/json"
downloadHandler "github.com/fossyy/filekeeper/handler/download" downloadHandler "github.com/fossyy/filekeeper/handler/download"
downloadFileHandler "github.com/fossyy/filekeeper/handler/download/file" downloadFileHandler "github.com/fossyy/filekeeper/handler/download/file"
forgotPasswordHandler "github.com/fossyy/filekeeper/handler/forgotPassword" forgotPasswordHandler "github.com/fossyy/filekeeper/handler/forgotPassword"
@ -16,7 +15,6 @@ import (
"github.com/fossyy/filekeeper/handler/upload/initialisation" "github.com/fossyy/filekeeper/handler/upload/initialisation"
userHandler "github.com/fossyy/filekeeper/handler/user" userHandler "github.com/fossyy/filekeeper/handler/user"
"github.com/fossyy/filekeeper/middleware" "github.com/fossyy/filekeeper/middleware"
"github.com/fossyy/filekeeper/session"
"net/http" "net/http"
) )
@ -37,10 +35,6 @@ func SetupRoutes() *http.ServeMux {
} }
}) })
handler.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(session.Getses())
})
handler.HandleFunc("/signin", func(w http.ResponseWriter, r *http.Request) { handler.HandleFunc("/signin", func(w http.ResponseWriter, r *http.Request) {
switch r.Method { switch r.Method {
case http.MethodGet: case http.MethodGet:

View File

@ -13,7 +13,7 @@ type Session struct {
Values map[string]interface{} Values map[string]interface{}
} }
type StoreSession struct { type SessionStore struct {
Sessions map[string]*Session Sessions map[string]*Session
mu sync.Mutex mu sync.Mutex
} }
@ -29,27 +29,27 @@ type SessionInfo struct {
AccessAt string AccessAt string
} }
type ListSessionInfo map[string][]*SessionInfo type SessionInfoList map[string][]*SessionInfo
var Store = StoreSession{Sessions: make(map[string]*Session)} var GlobalSessionStore = SessionStore{Sessions: make(map[string]*Session)}
var UserSessions = make(ListSessionInfo) var UserSessionInfoList = make(SessionInfoList)
type SessionNotFound struct{} type SessionNotFoundError struct{}
func (e *SessionNotFound) Error() string { func (e *SessionNotFoundError) Error() string {
return "session not found" return "session not found"
} }
func (s *StoreSession) Get(id string) (*Session, error) { func (s *SessionStore) Get(id string) (*Session, error) {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
if session, ok := s.Sessions[id]; ok { if session, ok := s.Sessions[id]; ok {
return session, nil return session, nil
} }
return nil, &SessionNotFound{} return nil, &SessionNotFoundError{}
} }
func (s *StoreSession) Create() *Session { func (s *SessionStore) Create() *Session {
id := utils.GenerateRandomString(128) id := utils.GenerateRandomString(128)
session := &Session{ session := &Session{
ID: id, ID: id,
@ -59,7 +59,7 @@ func (s *StoreSession) Create() *Session {
return session return session
} }
func (s *StoreSession) Delete(id string) { func (s *SessionStore) Delete(id string) {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
delete(s.Sessions, id) delete(s.Sessions, id)
@ -82,48 +82,44 @@ func (s *Session) Destroy(w http.ResponseWriter) {
}) })
} }
func AppendSession(email string, sessionInfo *SessionInfo) { func AddSessionInfo(email string, sessionInfo *SessionInfo) {
UserSessions[email] = append(UserSessions[email], sessionInfo) UserSessionInfoList[email] = append(UserSessionInfoList[email], sessionInfo)
} }
func RemoveSession(email string, id string) { func RemoveSessionInfo(email string, id string) {
sessions := UserSessions[email] sessionInfos := UserSessionInfoList[email]
var updatedSessions []*SessionInfo var updatedSessionInfos []*SessionInfo
for _, userSession := range sessions { for _, sessionInfo := range sessionInfos {
if userSession.SessionID != id { if sessionInfo.SessionID != id {
updatedSessions = append(updatedSessions, userSession) updatedSessionInfos = append(updatedSessionInfos, sessionInfo)
} }
} }
if len(updatedSessions) > 0 { if len(updatedSessionInfos) > 0 {
UserSessions[email] = updatedSessions UserSessionInfoList[email] = updatedSessionInfos
return return
} }
delete(UserSessions, email) delete(UserSessionInfoList, email)
} }
func RemoveAllSession(email string) { func RemoveAllSessions(email string) {
sessions := UserSessions[email] sessionInfos := UserSessionInfoList[email]
for _, session := range sessions { for _, sessionInfo := range sessionInfos {
delete(Store.Sessions, session.SessionID) delete(GlobalSessionStore.Sessions, sessionInfo.SessionID)
} }
delete(UserSessions, email) delete(UserSessionInfoList, email)
} }
func GetSessionInfo(email string, id string) *SessionInfo { func GetSessionInfo(email string, id string) *SessionInfo {
for _, session := range UserSessions[email] { for _, sessionInfo := range UserSessionInfoList[email] {
if session.SessionID == id { if sessionInfo.SessionID == id {
return session return sessionInfo
} }
} }
return nil return nil
} }
func (user *SessionInfo) UpdateAccessTime() { func (sessionInfo *SessionInfo) UpdateAccessTime() {
currentTime := time.Now() currentTime := time.Now()
formattedTime := currentTime.Format("01-02-2006") formattedTime := currentTime.Format("01-02-2006")
user.AccessAt = formattedTime sessionInfo.AccessAt = formattedTime
}
func Getses() *ListSessionInfo {
return &UserSessions
} }