From 43148cebf5997caa6f995dd282fe2364499493df Mon Sep 17 00:00:00 2001
From: Arminas <armisss4@gmail.com>
Date: Wed, 4 Jan 2023 12:55:00 +0200
Subject: [PATCH] Revert "Merge from development branch"

---
 custom/js/helper.js           |  28 ----
 handler/routes.go             | 214 ++++---------------------
 handler/routes_wake_on_lan.go |   2 +-
 handler/session.go            |  32 +---
 main.go                       |  25 +--
 model/misc.go                 |   1 -
 model/user.go                 |   1 -
 router/router.go              |   6 -
 store/jsondb/jsondb.go        |  52 +-----
 store/store.go                |   4 +-
 templates/base.html           |  22 +--
 templates/login.html          |   6 +-
 templates/profile.html        | 124 ++++++--------
 templates/users_settings.html | 294 ----------------------------------
 util/config.go                |   1 -
 util/util.go                  |   3 +-
 16 files changed, 99 insertions(+), 716 deletions(-)
 delete mode 100644 templates/users_settings.html

diff --git a/custom/js/helper.js b/custom/js/helper.js
index f337e5d..86f6dc7 100644
--- a/custom/js/helper.js
+++ b/custom/js/helper.js
@@ -78,34 +78,6 @@ function renderClientList(data) {
     });
 }
 
-function renderUserList(data) {
-    $.each(data, function(index, obj) {
-        let clientStatusHtml = '>'
-
-        // render user html content
-        let html = `<div class="col-sm-6 col-md-6 col-lg-4" id="user_${obj.username}">
-                        <div class="info-box">
-                            <div class="info-box-content">
-                                <div class="btn-group">
-                                     <button type="button" class="btn btn-outline-primary btn-sm" data-toggle="modal" data-target="#modal_edit_user" data-username="${obj.username}">Edit</button>
-                                </div>
-                                <div class="btn-group">
-                                    <button type="button" class="btn btn-outline-danger btn-sm" data-toggle="modal"
-                                        data-target="#modal_remove_user" data-username="${obj.username}">Delete</button>
-                                </div>
-                                <hr>
-                                <span class="info-box-text"><i class="fas fa-user"></i> ${obj.username}</span>
-                                <span class="info-box-text"><i class="fas fa-terminal"></i> ${obj.admin? 'Administrator':'Manager'}</span>
-                                </div>
-                        </div>
-                    </div>`
-
-        // add the user html elements to the list
-        $('#users-list').append(html);
-    });
-}
-
-
 function prettyDateTime(timeStr) {
     const dt = new Date(timeStr);
     const offsetMs = dt.getTimezoneOffset() * 60 * 1000;
diff --git a/handler/routes.go b/handler/routes.go
index 7db2a9e..3ddbb2d 100644
--- a/handler/routes.go
+++ b/handler/routes.go
@@ -42,54 +42,39 @@ func LoginPage() echo.HandlerFunc {
 // Login for signing in handler
 func Login(db store.IStore) echo.HandlerFunc {
 	return func(c echo.Context) error {
-		data := make(map[string]interface{})
-		err := json.NewDecoder(c.Request().Body).Decode(&data)
+		user := new(model.User)
+		c.Bind(user)
 
-		if err != nil {
-			return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, "Bad post data"})
-		}
-
-		username := data["username"].(string)
-		password := data["password"].(string)
-		rememberMe := data["rememberMe"].(bool)
-
-		dbuser, err := db.GetUserByName(username)
+		dbuser, err := db.GetUser()
 		if err != nil {
 			return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot query user from DB"})
 		}
 
-		userCorrect := subtle.ConstantTimeCompare([]byte(username), []byte(dbuser.Username)) == 1
+		userCorrect := subtle.ConstantTimeCompare([]byte(user.Username), []byte(dbuser.Username)) == 1
 
 		var passwordCorrect bool
 		if dbuser.PasswordHash != "" {
-			match, err := util.VerifyHash(dbuser.PasswordHash, password)
+			match, err := util.VerifyHash(dbuser.PasswordHash, user.Password)
 			if err != nil {
 				return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot verify password"})
 			}
 			passwordCorrect = match
 		} else {
-			passwordCorrect = subtle.ConstantTimeCompare([]byte(password), []byte(dbuser.Password)) == 1
+			passwordCorrect = subtle.ConstantTimeCompare([]byte(user.Password), []byte(dbuser.Password)) == 1
 		}
 
 		if userCorrect && passwordCorrect {
 			// TODO: refresh the token
-			ageMax := 0
-			expiration := time.Now().Add(24 * time.Hour)
-			if rememberMe {
-				ageMax = 86400
-				expiration.Add(144 * time.Hour)
-			}
 			sess, _ := session.Get("session", c)
 			sess.Options = &sessions.Options{
 				Path:     util.BasePath,
-				MaxAge:   ageMax,
+				MaxAge:   86400,
 				HttpOnly: true,
 			}
 
 			// set session_token
 			tokenUID := xid.New().String()
-			sess.Values["username"] = dbuser.Username
-			sess.Values["admin"] = dbuser.Admin
+			sess.Values["username"] = user.Username
 			sess.Values["session_token"] = tokenUID
 			sess.Save(c.Request(), c.Response())
 
@@ -97,7 +82,7 @@ func Login(db store.IStore) echo.HandlerFunc {
 			cookie := new(http.Cookie)
 			cookie.Name = "session_token"
 			cookie.Value = tokenUID
-			cookie.Expires = expiration
+			cookie.Expires = time.Now().Add(24 * time.Hour)
 			c.SetCookie(cookie)
 
 			return c.JSON(http.StatusOK, jsonHTTPResponse{true, "Logged in successfully"})
@@ -107,40 +92,6 @@ func Login(db store.IStore) echo.HandlerFunc {
 	}
 }
 
-// GetUsers handler return a JSON list of all users
-func GetUsers(db store.IStore) echo.HandlerFunc {
-	return func(c echo.Context) error {
-
-		usersList, err := db.GetUsers()
-		if err != nil {
-			return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{
-				false, fmt.Sprintf("Cannot get user list: %v", err),
-			})
-		}
-
-		return c.JSON(http.StatusOK, usersList)
-	}
-}
-
-// GetUser handler returns a JSON object of single user
-func GetUser(db store.IStore) echo.HandlerFunc {
-	return func(c echo.Context) error {
-
-		username := c.Param("username")
-
-		if !isAdmin(c) && (username != currentUser(c)) {
-			return c.JSON(http.StatusForbidden, jsonHTTPResponse{false, "Manager cannot access other user data"})
-		}
-
-		userData, err := db.GetUserByName(username)
-		if err != nil {
-			return c.JSON(http.StatusNotFound, jsonHTTPResponse{false, "User not found"})
-		}
-
-		return c.JSON(http.StatusOK, userData)
-	}
-}
-
 // Logout to log a user out
 func Logout() echo.HandlerFunc {
 	return func(c echo.Context) error {
@@ -152,23 +103,21 @@ func Logout() echo.HandlerFunc {
 // LoadProfile to load user information
 func LoadProfile(db store.IStore) echo.HandlerFunc {
 	return func(c echo.Context) error {
+
+		userInfo, err := db.GetUser()
+		if err != nil {
+			log.Error("Cannot get user information: ", err)
+		}
+
 		return c.Render(http.StatusOK, "profile.html", map[string]interface{}{
-			"baseData": model.BaseData{Active: "profile", CurrentUser: currentUser(c), Admin: isAdmin(c)},
+			"baseData": model.BaseData{Active: "profile", CurrentUser: currentUser(c)},
+			"userInfo": userInfo,
 		})
 	}
 }
 
-// UsersSettings handler
-func UsersSettings(db store.IStore) echo.HandlerFunc {
-	return func(c echo.Context) error {
-		return c.Render(http.StatusOK, "users_settings.html", map[string]interface{}{
-			"baseData": model.BaseData{Active: "users-settings", CurrentUser: currentUser(c), Admin: isAdmin(c)},
-		})
-	}
-}
-
-// UpdateUser to update user information
-func UpdateUser(db store.IStore) echo.HandlerFunc {
+// UpdateProfile to update user information
+func UpdateProfile(db store.IStore) echo.HandlerFunc {
 	return func(c echo.Context) error {
 		data := make(map[string]interface{})
 		err := json.NewDecoder(c.Request().Body).Decode(&data)
@@ -179,18 +128,8 @@ func UpdateUser(db store.IStore) echo.HandlerFunc {
 
 		username := data["username"].(string)
 		password := data["password"].(string)
-		previousUsername := data["previous_username"].(string)
-		admin := data["admin"].(bool)
 
-		if !isAdmin(c) && (previousUsername != currentUser(c)) {
-			return c.JSON(http.StatusForbidden, jsonHTTPResponse{false, "Manager cannot access other user data"})
-		}
-
-		if !isAdmin(c) {
-			admin = false
-		}
-
-		user, err := db.GetUserByName(previousUsername)
+		user, err := db.GetUser()
 		if err != nil {
 			return c.JSON(http.StatusNotFound, jsonHTTPResponse{false, err.Error()})
 		}
@@ -201,13 +140,6 @@ func UpdateUser(db store.IStore) echo.HandlerFunc {
 			user.Username = username
 		}
 
-		if username != previousUsername {
-			_, err := db.GetUserByName(username)
-			if err == nil {
-				return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, "This username is taken"})
-			}
-		}
-
 		if password != "" {
 			hash, err := util.HashPassword(password)
 			if err != nil {
@@ -215,93 +147,13 @@ func UpdateUser(db store.IStore) echo.HandlerFunc {
 			}
 			user.PasswordHash = hash
 		}
-		user.Admin = admin
-
-		if err := db.DeleteUser(previousUsername); err != nil {
-			return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, err.Error()})
-		}
-		if err := db.SaveUser(user); err != nil {
-			return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, err.Error()})
-		}
-		log.Infof("Updated user information successfully")
-
-		if previousUsername == currentUser(c) {
-			setUser(c, user.Username, user.Admin)
-		}
-
-		return c.JSON(http.StatusOK, jsonHTTPResponse{true, "Updated user information successfully"})
-	}
-}
-
-// CreateUser to create new user
-func CreateUser(db store.IStore) echo.HandlerFunc {
-	return func(c echo.Context) error {
-		data := make(map[string]interface{})
-		err := json.NewDecoder(c.Request().Body).Decode(&data)
-
-		if err != nil {
-			return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, "Bad post data"})
-		}
-
-		var user model.User
-		username := data["username"].(string)
-		password := data["password"].(string)
-		admin := data["admin"].(bool)
-
-		if username == "" {
-			return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, "Please provide a valid username"})
-		} else {
-			user.Username = username
-		}
-
-		{
-			_, err := db.GetUserByName(username)
-			if err == nil {
-				return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, "This username is taken"})
-			}
-		}
-
-		hash, err := util.HashPassword(password)
-		if err != nil {
-			return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, err.Error()})
-		}
-		user.PasswordHash = hash
-
-		user.Admin = admin
 
 		if err := db.SaveUser(user); err != nil {
 			return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, err.Error()})
 		}
-		log.Infof("Created user successfully")
+		log.Infof("Updated admin user information successfully")
 
-		return c.JSON(http.StatusOK, jsonHTTPResponse{true, "Created user successfully"})
-	}
-}
-
-// RemoveUser handler
-func RemoveUser(db store.IStore) echo.HandlerFunc {
-	return func(c echo.Context) error {
-		data := make(map[string]interface{})
-		err := json.NewDecoder(c.Request().Body).Decode(&data)
-
-		if err != nil {
-			return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, "Bad post data"})
-		}
-
-		username := data["username"].(string)
-		// delete user from database
-
-		if err := db.DeleteUser(username); err != nil {
-			log.Error("Cannot delete user: ", err)
-			return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot delete user from database"})
-		}
-
-		log.Infof("Removed user: %s", username)
-		if username == currentUser(c) {
-			log.Infof("You removed yourself, killing session")
-			clearSession(c)
-		}
-		return c.JSON(http.StatusOK, jsonHTTPResponse{true, "User removed"})
+		return c.JSON(http.StatusOK, jsonHTTPResponse{true, "Updated admin user information successfully"})
 	}
 }
 
@@ -317,7 +169,7 @@ func WireGuardClients(db store.IStore) echo.HandlerFunc {
 		}
 
 		return c.Render(http.StatusOK, "clients.html", map[string]interface{}{
-			"baseData":       model.BaseData{Active: "", CurrentUser: currentUser(c), Admin: isAdmin(c)},
+			"baseData":       model.BaseData{Active: "", CurrentUser: currentUser(c)},
 			"clientDataList": clientDataList,
 		})
 	}
@@ -670,7 +522,7 @@ func WireGuardServer(db store.IStore) echo.HandlerFunc {
 		}
 
 		return c.Render(http.StatusOK, "server.html", map[string]interface{}{
-			"baseData":        model.BaseData{Active: "wg-server", CurrentUser: currentUser(c), Admin: isAdmin(c)},
+			"baseData":        model.BaseData{Active: "wg-server", CurrentUser: currentUser(c)},
 			"serverInterface": server.Interface,
 			"serverKeyPair":   server.KeyPair,
 		})
@@ -738,7 +590,7 @@ func GlobalSettings(db store.IStore) echo.HandlerFunc {
 		}
 
 		return c.Render(http.StatusOK, "global_settings.html", map[string]interface{}{
-			"baseData":       model.BaseData{Active: "global-settings", CurrentUser: currentUser(c), Admin: isAdmin(c)},
+			"baseData":       model.BaseData{Active: "global-settings", CurrentUser: currentUser(c)},
 			"globalSettings": globalSettings,
 		})
 	}
@@ -766,7 +618,7 @@ func Status(db store.IStore) echo.HandlerFunc {
 		wgClient, err := wgctrl.New()
 		if err != nil {
 			return c.Render(http.StatusInternalServerError, "status.html", map[string]interface{}{
-				"baseData": model.BaseData{Active: "status", CurrentUser: currentUser(c), Admin: isAdmin(c)},
+				"baseData": model.BaseData{Active: "status", CurrentUser: currentUser(c)},
 				"error":    err.Error(),
 				"devices":  nil,
 			})
@@ -775,7 +627,7 @@ func Status(db store.IStore) echo.HandlerFunc {
 		devices, err := wgClient.Devices()
 		if err != nil {
 			return c.Render(http.StatusInternalServerError, "status.html", map[string]interface{}{
-				"baseData": model.BaseData{Active: "status", CurrentUser: currentUser(c), Admin: isAdmin(c)},
+				"baseData": model.BaseData{Active: "status", CurrentUser: currentUser(c)},
 				"error":    err.Error(),
 				"devices":  nil,
 			})
@@ -787,7 +639,7 @@ func Status(db store.IStore) echo.HandlerFunc {
 			clients, err := db.GetClients(false)
 			if err != nil {
 				return c.Render(http.StatusInternalServerError, "status.html", map[string]interface{}{
-					"baseData": model.BaseData{Active: "status", CurrentUser: currentUser(c), Admin: isAdmin(c)},
+					"baseData": model.BaseData{Active: "status", CurrentUser: currentUser(c)},
 					"error":    err.Error(),
 					"devices":  nil,
 				})
@@ -824,7 +676,7 @@ func Status(db store.IStore) echo.HandlerFunc {
 		}
 
 		return c.Render(http.StatusOK, "status.html", map[string]interface{}{
-			"baseData": model.BaseData{Active: "status", CurrentUser: currentUser(c), Admin: isAdmin(c)},
+			"baseData": model.BaseData{Active: "status", CurrentUser: currentUser(c)},
 			"devices":  devicesVm,
 			"error":    "",
 		})
@@ -938,12 +790,6 @@ func ApplyServerConfig(db store.IStore, tmplBox *rice.Box) echo.HandlerFunc {
 			return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot get client config"})
 		}
 
-		users, err := db.GetUsers()
-		if err != nil {
-			log.Error("Cannot get users config: ", err)
-			return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot get users config"})
-		}
-
 		settings, err := db.GetGlobalSettings()
 		if err != nil {
 			log.Error("Cannot get global settings: ", err)
@@ -951,7 +797,7 @@ func ApplyServerConfig(db store.IStore, tmplBox *rice.Box) echo.HandlerFunc {
 		}
 
 		// Write config file
-		err = util.WriteWireGuardServerConfig(tmplBox, server, clients, users, settings)
+		err = util.WriteWireGuardServerConfig(tmplBox, server, clients, settings)
 		if err != nil {
 			log.Error("Cannot apply server config: ", err)
 			return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{
diff --git a/handler/routes_wake_on_lan.go b/handler/routes_wake_on_lan.go
index 43a6186..40cd387 100644
--- a/handler/routes_wake_on_lan.go
+++ b/handler/routes_wake_on_lan.go
@@ -37,7 +37,7 @@ func GetWakeOnLanHosts(db store.IStore) echo.HandlerFunc {
 		}
 
 		err = c.Render(http.StatusOK, "wake_on_lan_hosts.html", map[string]interface{}{
-			"baseData": model.BaseData{Active: "wake_on_lan_hosts", CurrentUser: currentUser(c), Admin: isAdmin(c)},
+			"baseData": model.BaseData{Active: "wake_on_lan_hosts", CurrentUser: currentUser(c)},
 			"hosts":    hosts,
 			"error":    "",
 		})
diff --git a/handler/session.go b/handler/session.go
index 4cede6e..9975e0d 100644
--- a/handler/session.go
+++ b/handler/session.go
@@ -14,24 +14,15 @@ func ValidSession(next echo.HandlerFunc) echo.HandlerFunc {
 		if !isValidSession(c) {
 			nextURL := c.Request().URL
 			if nextURL != nil && c.Request().Method == http.MethodGet {
-				return c.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf(util.BasePath+"/login?next=%s", c.Request().URL))
+				return c.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf(util.BasePath + "/login?next=%s", c.Request().URL))
 			} else {
-				return c.Redirect(http.StatusTemporaryRedirect, util.BasePath+"/login")
+				return c.Redirect(http.StatusTemporaryRedirect, util.BasePath + "/login")
 			}
 		}
 		return next(c)
 	}
 }
 
-func NeedsAdmin(next echo.HandlerFunc) echo.HandlerFunc {
-	return func(c echo.Context) error {
-		if !isAdmin(c) {
-			return c.Redirect(http.StatusTemporaryRedirect, util.BasePath+"/")
-		}
-		return next(c)
-	}
-}
-
 func isValidSession(c echo.Context) bool {
 	if util.DisableLogin {
 		return true
@@ -55,29 +46,10 @@ func currentUser(c echo.Context) string {
 	return username
 }
 
-// isAdmin to get user type: admin or manager
-func isAdmin(c echo.Context) bool {
-	if util.DisableLogin {
-		return true
-	}
-
-	sess, _ := session.Get("session", c)
-	admin := fmt.Sprintf("%t", sess.Values["admin"])
-	return admin == "true"
-}
-
-func setUser(c echo.Context, username string, admin bool) {
-	sess, _ := session.Get("session", c)
-	sess.Values["username"] = username
-	sess.Values["admin"] = admin
-	sess.Save(c.Request(), c.Response())
-}
-
 // clearSession to remove current session
 func clearSession(c echo.Context) {
 	sess, _ := session.Get("session", c)
 	sess.Values["username"] = ""
-	sess.Values["admin"] = false
 	sess.Values["session_token"] = ""
 	sess.Save(c.Request(), c.Response())
 }
diff --git a/main.go b/main.go
index aefc0bb..3f0cd13 100644
--- a/main.go
+++ b/main.go
@@ -137,12 +137,7 @@ func main() {
 		app.POST(util.BasePath+"/login", handler.Login(db))
 		app.GET(util.BasePath+"/logout", handler.Logout(), handler.ValidSession)
 		app.GET(util.BasePath+"/profile", handler.LoadProfile(db), handler.ValidSession)
-		app.GET(util.BasePath+"/users-settings", handler.UsersSettings(db), handler.ValidSession, handler.NeedsAdmin)
-		app.POST(util.BasePath+"/update-user", handler.UpdateUser(db), handler.ValidSession)
-		app.POST(util.BasePath+"/create-user", handler.CreateUser(db), handler.ValidSession, handler.NeedsAdmin)
-		app.POST(util.BasePath+"/remove-user", handler.RemoveUser(db), handler.ValidSession, handler.NeedsAdmin)
-		app.GET(util.BasePath+"/getusers", handler.GetUsers(db), handler.ValidSession, handler.NeedsAdmin)
-		app.GET(util.BasePath+"/api/user/:username", handler.GetUser(db), handler.ValidSession)
+		app.POST(util.BasePath+"/profile", handler.UpdateProfile(db), handler.ValidSession)
 	}
 
 	var sendmail emailer.Emailer
@@ -159,12 +154,11 @@ func main() {
 	app.POST(util.BasePath+"/client/set-status", handler.SetClientStatus(db), handler.ValidSession, handler.ContentTypeJson)
 	app.POST(util.BasePath+"/remove-client", handler.RemoveClient(db), handler.ValidSession, handler.ContentTypeJson)
 	app.GET(util.BasePath+"/download", handler.DownloadClient(db), handler.ValidSession)
-	app.GET(util.BasePath+"/wg-server", handler.WireGuardServer(db), handler.ValidSession, handler.NeedsAdmin)
-	app.POST(util.BasePath+"/wg-server/interfaces", handler.WireGuardServerInterfaces(db), handler.ValidSession, handler.ContentTypeJson, handler.NeedsAdmin)
-	app.POST(util.BasePath+"/wg-server/keypair", handler.WireGuardServerKeyPair(db), handler.ValidSession, handler.ContentTypeJson, handler.NeedsAdmin)
-	app.GET(util.BasePath+"/global-settings", handler.GlobalSettings(db), handler.ValidSession, handler.NeedsAdmin)
-
-	app.POST(util.BasePath+"/global-settings", handler.GlobalSettingSubmit(db), handler.ValidSession, handler.ContentTypeJson, handler.NeedsAdmin)
+	app.GET(util.BasePath+"/wg-server", handler.WireGuardServer(db), handler.ValidSession)
+	app.POST(util.BasePath+"/wg-server/interfaces", handler.WireGuardServerInterfaces(db), handler.ValidSession, handler.ContentTypeJson)
+	app.POST(util.BasePath+"/wg-server/keypair", handler.WireGuardServerKeyPair(db), handler.ValidSession, handler.ContentTypeJson)
+	app.GET(util.BasePath+"/global-settings", handler.GlobalSettings(db), handler.ValidSession)
+	app.POST(util.BasePath+"/global-settings", handler.GlobalSettingSubmit(db), handler.ValidSession, handler.ContentTypeJson)
 	app.GET(util.BasePath+"/status", handler.Status(db), handler.ValidSession)
 	app.GET(util.BasePath+"/api/clients", handler.GetClients(db), handler.ValidSession)
 	app.GET(util.BasePath+"/api/client/:id", handler.GetClient(db), handler.ValidSession)
@@ -203,13 +197,8 @@ func initServerConfig(db store.IStore, tmplBox *rice.Box) {
 		log.Fatalf("Cannot get client config: ", err)
 	}
 
-	users, err := db.GetUsers()
-	if err != nil {
-		log.Fatalf("Cannot get user config: ", err)
-	}
-
 	// write config file
-	err = util.WriteWireGuardServerConfig(tmplBox, server, clients, users, settings)
+	err = util.WriteWireGuardServerConfig(tmplBox, server, clients, settings)
 	if err != nil {
 		log.Fatalf("Cannot create server config: ", err)
 	}
diff --git a/model/misc.go b/model/misc.go
index d8f2cf5..12d6906 100644
--- a/model/misc.go
+++ b/model/misc.go
@@ -10,5 +10,4 @@ type Interface struct {
 type BaseData struct {
 	Active      string
 	CurrentUser string
-	Admin       bool
 }
diff --git a/model/user.go b/model/user.go
index 71f4d13..711ebd1 100644
--- a/model/user.go
+++ b/model/user.go
@@ -6,5 +6,4 @@ type User struct {
 	Password string `json:"password"`
 	// PasswordHash takes precedence over Password.
 	PasswordHash string `json:"password_hash"`
-	Admin        bool   `json:"admin"`
 }
diff --git a/router/router.go b/router/router.go
index f262243..0f9facc 100644
--- a/router/router.go
+++ b/router/router.go
@@ -83,11 +83,6 @@ func New(tmplBox *rice.Box, extraData map[string]string, secret []byte) *echo.Ec
 		log.Fatal(err)
 	}
 
-	tmplUsersSettingsString, err := tmplBox.String("users_settings.html")
-	if err != nil {
-		log.Fatal(err)
-	}
-
 	tmplStatusString, err := tmplBox.String("status.html")
 	if err != nil {
 		log.Fatal(err)
@@ -108,7 +103,6 @@ func New(tmplBox *rice.Box, extraData map[string]string, secret []byte) *echo.Ec
 	templates["clients.html"] = template.Must(template.New("clients").Funcs(funcs).Parse(tmplBaseString + tmplClientsString))
 	templates["server.html"] = template.Must(template.New("server").Funcs(funcs).Parse(tmplBaseString + tmplServerString))
 	templates["global_settings.html"] = template.Must(template.New("global_settings").Funcs(funcs).Parse(tmplBaseString + tmplGlobalSettingsString))
-	templates["users_settings.html"] = template.Must(template.New("users_settings").Funcs(funcs).Parse(tmplBaseString + tmplUsersSettingsString))
 	templates["status.html"] = template.Must(template.New("status").Funcs(funcs).Parse(tmplBaseString + tmplStatusString))
 	templates["wake_on_lan_hosts.html"] = template.Must(template.New("wake_on_lan_hosts").Funcs(funcs).Parse(tmplBaseString + tmplWakeOnLanHostsString))
 
diff --git a/store/jsondb/jsondb.go b/store/jsondb/jsondb.go
index e6ebfb2..f39a452 100644
--- a/store/jsondb/jsondb.go
+++ b/store/jsondb/jsondb.go
@@ -42,7 +42,7 @@ func (o *JsonDB) Init() error {
 	var serverInterfacePath string = path.Join(serverPath, "interfaces.json")
 	var serverKeyPairPath string = path.Join(serverPath, "keypair.json")
 	var globalSettingPath string = path.Join(serverPath, "global_settings.json")
-	var userPath string = path.Join(o.dbPath, "users")
+	var userPath string = path.Join(serverPath, "users.json")
 	// create directories if they do not exist
 	if _, err := os.Stat(clientPath); os.IsNotExist(err) {
 		os.MkdirAll(clientPath, os.ModePerm)
@@ -53,9 +53,6 @@ func (o *JsonDB) Init() error {
 	if _, err := os.Stat(wakeOnLanHostsPath); os.IsNotExist(err) {
 		os.MkdirAll(wakeOnLanHostsPath, os.ModePerm)
 	}
-	if _, err := os.Stat(userPath); os.IsNotExist(err) {
-		os.MkdirAll(userPath, os.ModePerm)
-	}
 
 	// server's interface
 	if _, err := os.Stat(serverInterfacePath); os.IsNotExist(err) {
@@ -106,11 +103,9 @@ func (o *JsonDB) Init() error {
 	}
 
 	// user info
-	results, err := o.conn.ReadAll("users")
-	if err != nil || len(results) < 1 {
+	if _, err := os.Stat(userPath); os.IsNotExist(err) {
 		user := new(model.User)
 		user.Username = util.LookupEnvOrString(util.UsernameEnvVar, util.DefaultUsername)
-		user.Admin = util.DefaultIsAdmin
 		user.PasswordHash = util.LookupEnvOrString(util.PasswordHashEnvVar, "")
 		if user.PasswordHash == "" {
 			plaintext := util.LookupEnvOrString(util.PasswordEnvVar, util.DefaultPassword)
@@ -120,7 +115,7 @@ func (o *JsonDB) Init() error {
 			}
 			user.PasswordHash = hash
 		}
-		o.conn.Write("users", user.Username, user)
+		o.conn.Write("server", "users", user)
 	}
 
 	return nil
@@ -132,44 +127,9 @@ func (o *JsonDB) GetUser() (model.User, error) {
 	return user, o.conn.Read("server", "users", &user)
 }
 
-// GetUsers func to get all users from the database
-func (o *JsonDB) GetUsers() ([]model.User, error) {
-	var users []model.User
-	results, err := o.conn.ReadAll("users")
-	if err != nil {
-		return users, err
-	}
-	for _, i := range results {
-		user := model.User{}
-
-		if err := json.Unmarshal([]byte(i), &user); err != nil {
-			return users, fmt.Errorf("cannot decode user json structure: %v", err)
-		}
-		users = append(users, user)
-
-	}
-	return users, err
-}
-
-// GetUserByName func to get single user from the database
-func (o *JsonDB) GetUserByName(username string) (model.User, error) {
-	user := model.User{}
-
-	if err := o.conn.Read("users", username, &user); err != nil {
-		return user, err
-	}
-
-	return user, nil
-}
-
-// SaveUser func to save user in the database
+// SaveUser func to user info to the database
 func (o *JsonDB) SaveUser(user model.User) error {
-	return o.conn.Write("users", user.Username, user)
-}
-
-// DeleteUser func to remove user from the database
-func (o *JsonDB) DeleteUser(username string) error {
-	return o.conn.Delete("users", username)
+	return o.conn.Write("server", "users", user)
 }
 
 // GetGlobalSettings func to query global settings from the database
@@ -253,7 +213,7 @@ func (o *JsonDB) GetClientByID(clientID string, qrCodeSettings model.QRCodeSetti
 		server, _ := o.GetServer()
 		globalSettings, _ := o.GetGlobalSettings()
 		client := client
-		if !qrCodeSettings.IncludeDNS {
+		if !qrCodeSettings.IncludeDNS{
 			globalSettings.DNSServers = []string{}
 		}
 		if !qrCodeSettings.IncludeMTU {
diff --git a/store/store.go b/store/store.go
index 166bc3d..86d6224 100644
--- a/store/store.go
+++ b/store/store.go
@@ -6,10 +6,8 @@ import (
 
 type IStore interface {
 	Init() error
-	GetUsers() ([]model.User, error)
-	GetUserByName(username string) (model.User, error)
+	GetUser() (model.User, error)
 	SaveUser(user model.User) error
-	DeleteUser(username string) error
 	GetGlobalSettings() (model.GlobalSetting, error)
 	GetServer() (model.Server, error)
 	GetClients(hasQRCode bool) ([]model.ClientData, error)
diff --git a/templates/base.html b/templates/base.html
index 227e35d..fd337a7 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -88,13 +88,7 @@
                     </div>
                     <div class="info">
                         {{if .baseData.CurrentUser}}
-
-                        {{if .baseData.Admin}}
-                        <a href="{{.basePath}}/profile" class="d-block">Administrator: {{.baseData.CurrentUser}}</a>
-                        {{else}}
-                        <a href="{{.basePath}}/profile" class="d-block">Manager: {{.baseData.CurrentUser}}</a>
-                        {{end}}
-
+                        <a href="{{.basePath}}/profile" class="d-block">{{.baseData.CurrentUser}}</a>
                         {{else}}
                         <a href="#" class="d-block">Administrator</a>
                         {{end}}
@@ -113,8 +107,6 @@
                                 </p>
                             </a>
                         </li>
-
-                        {{if .baseData.Admin}}
                         <li class="nav-item">
                             <a href="{{.basePath}}/wg-server" class="nav-link {{if eq .baseData.Active "wg-server" }}active{{end}}">
                                 <i class="nav-icon fas fa-server"></i>
@@ -123,8 +115,6 @@
                                 </p>
                             </a>
                         </li>
-
-
                         <li class="nav-header">SETTINGS</li>
                         <li class="nav-item">
                             <a href="{{.basePath}}/global-settings" class="nav-link {{if eq .baseData.Active "global-settings" }}active{{end}}">
@@ -134,16 +124,6 @@
                                 </p>
                             </a>
                         </li>
-                        <li class="nav-item">
-                            <a href="{{.basePath}}/users-settings" class="nav-link {{if eq .baseData.Active "users-settings" }}active{{end}}">
-                            <i class="nav-icon fas fa-cog"></i>
-                            <p>
-                                Users Settings
-                            </p>
-                            </a>
-                        </li>
-                        {{end}}
-
                         <li class="nav-header">UTILITIES</li>
                         <li class="nav-item">
                             <a href="{{.basePath}}/status" class="nav-link {{if eq .baseData.Active "status" }}active{{end}}">
diff --git a/templates/login.html b/templates/login.html
index db0ba24..c75aa39 100644
--- a/templates/login.html
+++ b/templates/login.html
@@ -99,11 +99,7 @@
         $("#btn_login").click(function () {
             const username = $("#username").val();
             const password = $("#password").val();
-            let rememberMe = false;
-            if ($("#remember").is(':checked')){
-                rememberMe = true;
-            }
-            const data = {"username": username, "password": password, "rememberMe": rememberMe}
+            const data = {"username": username, "password": password}
 
             $.ajax({
                 cache: false,
diff --git a/templates/profile.html b/templates/profile.html
index fa80157..c2d3b95 100644
--- a/templates/profile.html
+++ b/templates/profile.html
@@ -31,7 +31,7 @@ Profile
                             <div class="form-group">
                                 <label for="username" class="control-label">Username</label>
                                 <input type="text" class="form-control" name="username" id="username"
-                                       value="">
+                                       value="{{ .userInfo.Username }}">
                             </div>
                             <div class="form-group">
                                 <label for="password" class="control-label">Password</label>
@@ -55,82 +55,56 @@ Profile
 
 {{ define "bottom_js"}}
 <script>
-    {
-        var previous_username;
-        var admin;
-    }
-    $(document).ready(function () {
-        $.ajax({
-            cache: false,
-            method: 'GET',
-            url: '{{.basePath}}/api/user/{{.baseData.CurrentUser}}',
-            dataType: 'json',
-            contentType: "application/json",
-            success: function (resp) {
-                const user = resp;
-                $("#username").val(user.username);
-                previous_username = user.username;
-                admin = user.admin;
-            },
-            error: function (jqXHR, exception) {
-                const responseJson = jQuery.parseJSON(jqXHR.responseText);
-                toastr.error(responseJson['message']);
-            }
-        });
+  function updateUserInfo() {
+    const username = $("#username").val();
+    const password = $("#password").val();
+    const data = {"username": username, "password": password};
+    $.ajax({
+      cache: false,
+      method: 'POST',
+      url: '{{.basePath}}/profile',
+      dataType: 'json',
+      contentType: "application/json",
+      data: JSON.stringify(data),
+      success: function (data) {
+        toastr.success("Updated admin user information successfully");
+      },
+      error: function (jqXHR, exception) {
+        const responseJson = jQuery.parseJSON(jqXHR.responseText);
+        toastr.error(responseJson['message']);
+      }
     });
+  }
 
-
-    function updateUserInfo() {
-        const username = $("#username").val();
-        const password = $("#password").val();
-        const data = {"username": username, "password": password, "previous_username": previous_username, "admin":admin};
-        $.ajax({
-            cache: false,
-            method: 'POST',
-            url: '{{.basePath}}/update-user',
-            dataType: 'json',
-            contentType: "application/json",
-            data: JSON.stringify(data),
-            success: function (data) {
-                toastr.success("Updated user information successfully");
-                location.reload();
-            },
-            error: function (jqXHR, exception) {
-                const responseJson = jQuery.parseJSON(jqXHR.responseText);
-                toastr.error(responseJson['message']);
-            }
-        });
-    }
-
-    $(document).ready(function () {
-        $.validator.setDefaults({
-            submitHandler: function () {
-                updateUserInfo();
-            }
-        });
-        $("#frm_profile").validate({
-            rules: {
-                username: {
-                    required: true
-                }
-            },
-            messages: {
-                username: {
-                    required: "Please enter a username",
-                }
-            },
-            errorElement: 'span',
-            errorPlacement: function (error, element) {
-                error.addClass('invalid-feedback');
-                element.closest('.form-group').append(error);
-            },
-            highlight: function (element, errorClass, validClass) {
-                $(element).addClass('is-invalid');
-            },
-            unhighlight: function (element, errorClass, validClass) {
-                $(element).removeClass('is-invalid');
-            }
-        });
+  $(document).ready(function () {
+    $.validator.setDefaults({
+      submitHandler: function () {
+        updateUserInfo();
+      }
     });
+    $("#frm_profile").validate({
+      rules: {
+        username: {
+          required: true
+        }
+      },
+      messages: {
+        username: {
+          required: "Please enter a username",
+        }
+      },
+      errorElement: 'span',
+      errorPlacement: function (error, element) {
+        error.addClass('invalid-feedback');
+        element.closest('.form-group').append(error);
+      },
+      highlight: function (element, errorClass, validClass) {
+        $(element).addClass('is-invalid');
+      },
+      unhighlight: function (element, errorClass, validClass) {
+        $(element).removeClass('is-invalid');
+      }
+    });
+  });
 </script>
 {{ end }}
diff --git a/templates/users_settings.html b/templates/users_settings.html
deleted file mode 100644
index 05d8878..0000000
--- a/templates/users_settings.html
+++ /dev/null
@@ -1,294 +0,0 @@
-{{define "title"}}
-Users Settings
-{{end}}
-
-{{define "top_css"}}
-{{end}}
-
-{{define "username"}}
-{{ .username }}
-{{end}}
-
-{{define "page_title"}}
-Users Settings
-{{end}}
-
-{{define "page_content"}}
-<section class="content">
-    <div class="container-fluid">
-        <div class="row" id="users-list">
-        </div>
-    </div>
-</section>
-
-<div class="modal fade" id="modal_edit_user">
-    <div class="modal-dialog">
-        <div class="modal-content">
-            <div class="modal-header">
-                <h4 class="modal-title">Edit User</h4>
-                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
-                    <span aria-hidden="true">&times;</span>
-                </button>
-            </div>
-            <form name="frm_edit_user" id="frm_edit_user">
-                <div class="modal-body">
-                    <div class="form-group" style="display:none">
-                        <input type="text" style="display:none" class="form-control" id="_previous_user_name"
-                               name="_previous_user_name">
-                    </div>
-                    <div class="form-group">
-                        <label for="_user_name" class="control-label">Name</label>
-                        <input type="text" class="form-control" id="_user_name" name="_user_name">
-                    </div>
-                    <div class="form-group">
-                        <label for="_user_password" class="control-label">Password</label>
-                        <input type="text" class="form-control" id="_user_password" name="_user_password" value=""
-                               placeholder="Leave empty to keep the password unchanged">
-                    </div>
-                    <div class="form-group">
-                        <div class="icheck-primary d-inline">
-                            <input type="checkbox" id="_admin">
-                            <label for="_admin">
-                                Admin
-                            </label>
-                        </div>
-                    </div>
-
-                </div>
-                <div class="modal-footer justify-content-between">
-                    <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
-                    <button type="submit" class="btn btn-success">Save</button>
-                </div>
-            </form>
-        </div>
-        <!-- /.modal-content -->
-    </div>
-    <!-- /.modal-dialog -->
-</div>
-<!-- /.modal -->
-
-<div class="modal fade" id="modal_remove_user">
-    <div class="modal-dialog">
-        <div class="modal-content bg-danger">
-            <div class="modal-header">
-                <h4 class="modal-title">Remove</h4>
-                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
-                    <span aria-hidden="true">&times;</span>
-                </button>
-            </div>
-            <div class="modal-body">
-            </div>
-            <div class="modal-footer justify-content-between">
-                <button type="button" class="btn btn-outline-dark" data-dismiss="modal">Cancel</button>
-                <button type="button" class="btn btn-outline-dark" id="remove_user_confirm">Apply</button>
-            </div>
-        </div>
-        <!-- /.modal-content -->
-    </div>
-    <!-- /.modal-dialog -->
-</div>
-<!-- /.modal -->
-{{end}}
-
-{{define "bottom_js"}}
-<script>
-    function populateUsersList() {
-        $.ajax({
-            cache: false,
-            method: 'GET',
-            url: '{{.basePath}}/getusers',
-            dataType: 'json',
-            contentType: "application/json",
-            success: function (data) {
-                renderUserList(data);
-            },
-            error: function (jqXHR, exception) {
-                const responseJson = jQuery.parseJSON(jqXHR.responseText);
-                toastr.error(responseJson['message']);
-            }
-        });
-    }
-</script>
-<script>
-    // load user list
-    $(document).ready(function () {
-        populateUsersList();
-        let newUserHtml = '<div class="col-sm-2 offset-md-4" style=" text-align: right;">' +
-            '<button style="" id="btn_new_user" type="button" class="btn btn-outline-primary btn-sm" ' +
-            'data-toggle="modal" data-target="#modal_edit_user" data-username="">' +
-            '<i class="nav-icon fas fa-plus"></i> New User</button></div>';
-        $('h1').parents(".row").append(newUserHtml);
-    })
-
-    // modal_remove_user modal event
-    $("#modal_remove_user").on('show.bs.modal', function (event) {
-        const button = $(event.relatedTarget);
-        const user_name = button.data('username');
-        const modal = $(this);
-        modal.find('.modal-body').text("You are about to remove user " + user_name);
-        modal.find('#remove_user_confirm').val(user_name);
-    })
-
-    // remove_user_confirm button event
-    $(document).ready(function () {
-        $("#remove_user_confirm").click(function () {
-            const user_name = $(this).val();
-            const data = {"username": user_name};
-            $.ajax({
-                cache: false,
-                method: 'POST',
-                url: '{{.basePath}}/remove-user',
-                dataType: 'json',
-                contentType: "application/json",
-                data: JSON.stringify(data),
-                success: function (data) {
-                    $("#modal_remove_user").modal('hide');
-                    toastr.success('Removed user successfully');
-                    const divElement = document.getElementById('user_' + user_name);
-                    divElement.style.display = "none";
-                    location.reload()
-                },
-                error: function (jqXHR, exception) {
-                    const responseJson = jQuery.parseJSON(jqXHR.responseText);
-                    toastr.error(responseJson['message']);
-                }
-            });
-        });
-    });
-
-    // Edit user modal event
-    $(document).ready(function () {
-        $("#modal_edit_user").on('show.bs.modal', function (event) {
-            let modal = $(this);
-            const button = $(event.relatedTarget);
-            const user_name = button.data('username');
-
-            // update user modal data
-            if (user_name !== "") {
-                $.ajax({
-                    cache: false,
-                    method: 'GET',
-                    url: '{{.basePath}}/api/user/' + user_name,
-                    dataType: 'json',
-                    contentType: "application/json",
-                    success: function (resp) {
-                        const user = resp;
-
-                        modal.find(".modal-title").text("Edit user " + user.username);
-                        modal.find("#_user_name").val(user.username);
-                        modal.find("#_previous_user_name").val(user.username);
-                        modal.find("#_user_password").val("");
-                        modal.find("#_user_password").prop("placeholder", "Leave empty to keep the password unchanged")
-                        modal.find("#_admin").prop("checked", user.admin);
-                    },
-                    error: function (jqXHR, exception) {
-                        const responseJson = jQuery.parseJSON(jqXHR.responseText);
-                        toastr.error(responseJson['message']);
-                    }
-                });
-            } else {
-                modal.find(".modal-title").text("Add new user");
-                modal.find("#_user_name").val("");
-                modal.find("#_previous_user_name").val("");
-                modal.find("#_user_password").val("");
-                modal.find("#_user_password").prop("placeholder", "")
-                modal.find("#_admin").prop("checked", false);
-            }
-        });
-    });
-
-    function updateUserInfo() {
-        const username = $("#_user_name").val();
-        const previous_username = $("#_previous_user_name").val();
-        const password = $("#_user_password").val();
-        let admin = false;
-        if ($("#_admin").is(':checked')) {
-            admin = true;
-        }
-        const data = {
-            "username": username,
-            "password": password,
-            "previous_username": previous_username,
-            "admin": admin
-        };
-
-        if (previous_username !== "") {
-            $.ajax({
-                cache: false,
-                method: 'POST',
-                url: '{{.basePath}}/update-user',
-                dataType: 'json',
-                contentType: "application/json",
-                data: JSON.stringify(data),
-                success: function (data) {
-                    toastr.success("Updated user information successfully");
-                    location.reload();
-                },
-                error: function (jqXHR, exception) {
-                    const responseJson = jQuery.parseJSON(jqXHR.responseText);
-                    toastr.error(responseJson['message']);
-                }
-            });
-        } else {
-            $.ajax({
-                cache: false,
-                method: 'POST',
-                url: '{{.basePath}}/create-user',
-                dataType: 'json',
-                contentType: "application/json",
-                data: JSON.stringify(data),
-                success: function (data) {
-                    toastr.success("Created user successfully");
-                    location.reload();
-                },
-                error: function (jqXHR, exception) {
-                    const responseJson = jQuery.parseJSON(jqXHR.responseText);
-                    toastr.error(responseJson['message']);
-                }
-            });
-
-        }
-    }
-
-    $(document).ready(function () {
-        $.validator.setDefaults({
-            submitHandler: function (form) {
-                updateUserInfo();
-            }
-        });
-        // Edit user form validation
-        $("#frm_edit_user").validate({
-            rules: {
-                _user_name: {
-                    required: true
-                },
-                _user_password: {
-                    required: function () {
-                        return $("#_previous_user_name").val() === "";
-                    }
-                },
-            },
-            messages: {
-                _user_name: {
-                    required: "Please enter a username"
-                },
-                _user_password: {
-                    required: "Please input a password"
-                },
-            },
-            errorElement: 'span',
-            errorPlacement: function (error, element) {
-                error.addClass('invalid-feedback');
-                element.closest('.form-group').append(error);
-            },
-            highlight: function (element, errorClass, validClass) {
-                $(element).addClass('is-invalid');
-            },
-            unhighlight: function (element, errorClass, validClass) {
-                $(element).removeClass('is-invalid');
-            }
-        });
-        //
-    });
-</script>
-{{end}}
diff --git a/util/config.go b/util/config.go
index 16c182f..63044ca 100644
--- a/util/config.go
+++ b/util/config.go
@@ -24,7 +24,6 @@ var (
 const (
 	DefaultUsername                        = "admin"
 	DefaultPassword                        = "admin"
-	DefaultIsAdmin                         = true
 	DefaultServerAddress                   = "10.252.1.0/24"
 	DefaultServerPort                      = 51820
 	DefaultDNS                             = "1.1.1.1"
diff --git a/util/util.go b/util/util.go
index d3b7c14..40eb357 100644
--- a/util/util.go
+++ b/util/util.go
@@ -381,7 +381,7 @@ func ValidateIPAllocation(serverAddresses []string, ipAllocatedList []string, ip
 }
 
 // WriteWireGuardServerConfig to write Wireguard server config. e.g. wg0.conf
-func WriteWireGuardServerConfig(tmplBox *rice.Box, serverConfig model.Server, clientDataList []model.ClientData, usersList []model.User, globalSettings model.GlobalSetting) error {
+func WriteWireGuardServerConfig(tmplBox *rice.Box, serverConfig model.Server, clientDataList []model.ClientData, globalSettings model.GlobalSetting) error {
 	var tmplWireguardConf string
 
 	// if set, read wg.conf template from WgConfTemplate
@@ -416,7 +416,6 @@ func WriteWireGuardServerConfig(tmplBox *rice.Box, serverConfig model.Server, cl
 		"serverConfig":   serverConfig,
 		"clientDataList": clientDataList,
 		"globalSettings": globalSettings,
-		"usersList":      usersList,
 	}
 
 	err = t.Execute(f, config)