diff --git a/frontend b/frontend index 56b609be..3e14855e 160000 --- a/frontend +++ b/frontend @@ -1 +1 @@ -Subproject commit 56b609be4f496dfa11f1237490cb167e1c774fb0 +Subproject commit 3e14855e4f9b5719164f79b5ac8ccdf019f6429e diff --git a/http/auth.go b/http/auth.go index 9fd357c0..d13e9bbe 100644 --- a/http/auth.go +++ b/http/auth.go @@ -60,8 +60,10 @@ func withUser(fn handleFunc) handleFunc { return http.StatusForbidden, nil } - if !tk.VerifyExpiresAt(time.Now().Add(time.Hour).Unix(), true) { - // TODO: chek if user info was modified use timestap + expired := !tk.VerifyExpiresAt(time.Now().Add(time.Hour).Unix(), true) + updated := d.store.Users.LastUpdate(tk.User.ID) > tk.IssuedAt + + if expired || updated { w.Header().Add("X-Renew-Token", "true") } @@ -157,6 +159,7 @@ func printToken(w http.ResponseWriter, r *http.Request, d *data, user *users.Use Commands: user.Commands, }, StandardClaims: jwt.StandardClaims{ + IssuedAt: time.Now().Unix(), ExpiresAt: time.Now().Add(time.Hour * 2).Unix(), Issuer: "File Browser", }, diff --git a/search/search.go b/search/search.go index a558176a..c158ffbe 100644 --- a/search/search.go +++ b/search/search.go @@ -19,13 +19,13 @@ func Search(fs afero.Fs, scope, query string, checker rules.Checker, found func( search := parseSearch(query) return afero.Walk(fs, scope, func(path string, f os.FileInfo, err error) error { + path = strings.TrimPrefix(path, "/") + path = strings.Replace(path, "\\", "/", -1) + if !checker.Check(path) { return nil } - path = strings.TrimPrefix(path, "/") - path = strings.Replace(path, "\\", "/", -1) - if !search.CaseSensitive { path = strings.ToLower(path) } diff --git a/users/storage.go b/users/storage.go index 7cc03b3b..5f6031f7 100644 --- a/users/storage.go +++ b/users/storage.go @@ -1,6 +1,9 @@ package users import ( + "sync" + "time" + "github.com/filebrowser/filebrowser/errors" ) @@ -17,12 +20,17 @@ type StorageBackend interface { // Storage is a users storage. type Storage struct { - back StorageBackend + back StorageBackend + updated map[uint]int64 + mux sync.RWMutex } // NewStorage creates a users storage from a backend. func NewStorage(back StorageBackend) *Storage { - return &Storage{back: back} + return &Storage{ + back: back, + updated: map[uint]int64{}, + } } // Get allows you to get a user by its name or username. The provided @@ -72,7 +80,15 @@ func (s *Storage) Update(user *User, fields ...string) error { return err } - return s.back.Update(user, fields...) + err = s.back.Update(user, fields...) + if err != nil { + return err + } + + s.mux.Lock() + s.updated[user.ID] = time.Now().Unix() + s.mux.Unlock() + return nil } // Save saves the user in a storage. @@ -99,3 +115,13 @@ func (s *Storage) Delete(id interface{}) (err error) { return } + +// LastUpdate gets the timestamp for the last update of an user. +func (s *Storage) LastUpdate(id uint) int64 { + s.mux.RLock() + defer s.mux.RUnlock() + if val, ok := s.updated[id]; ok { + return val + } + return 0 +}