diff --git a/backend/go-app/main.go b/backend/go-app/main.go index f5ba1921..884ee356 100644 --- a/backend/go-app/main.go +++ b/backend/go-app/main.go @@ -155,27 +155,29 @@ type Environment struct { } type User struct { - Username string `datastore:"Username"` - Password string `datastore:"password,noindex"` - Session string `datastore:"session,noindex"` - Verified bool `datastore:"verified,noindex"` - PrivateApps []WorkflowApp `datastore:"privateapps"` - Role string `datastore:"role"` - VerificationToken string `datastore:"verification_token"` - ApiKey string `datastore:"apikey"` - ResetReference string `datastore:"reset_reference"` + Username string `datastore:"Username" json:"username"` + Password string `datastore:"password,noindex" password:"password,omitempty"` + Session string `datastore:"session,noindex" json:"session"` + Verified bool `datastore:"verified,noindex" json:"verified"` + PrivateApps []WorkflowApp `datastore:"privateapps" json:"privateapps":` + Role string `datastore:"role" json:"role"` + VerificationToken string `datastore:"verification_token" json:"verification_token"` + ApiKey string `datastore:"apikey" json:"apikey"` + ResetReference string `datastore:"reset_reference" json:"reset_reference"` Executions ExecutionInfo `datastore:"executions" json:"executions"` Limits UserLimits `datastore:"limits" json:"limits"` Authentication []UserAuth `datastore:"authentication,noindex" json:"authentication"` - ResetTimeout int64 `datastore:"reset_timeout,noindex"` + ResetTimeout int64 `datastore:"reset_timeout,noindex" json:"reset_timeout"` Id string `datastore:"id" json:"id"` Orgs string `datastore:"orgs" json:"orgs"` CreationTime int64 `datastore:"creation_time" json:"creation_time"` + Active bool `datastore:"active" json:"active"` } // timeout maybe? idk type session struct { Username string `datastore:"Username,noindex"` + Id string `datastore:"Id,noindex"` Session string `datastore:"session,noindex"` } @@ -709,9 +711,9 @@ func handleApiAuthentication(resp http.ResponseWriter, request *http.Request) (U // Get session first // Should basically never happen - Userdata, err := getUser(ctx, session.Username) + Userdata, err := getUser(ctx, session.Id) if err != nil { - log.Printf("Username %s doesn't exist: %s", session.Username, err) + log.Printf("Username %s doesn't exist (authcheck): %s", session.Username, err) return User{}, err } @@ -879,8 +881,8 @@ func handleRegisterVerification(resp http.ResponseWriter, request *http.Request) _, err := dbclient.GetAll(ctx, q, &users) if err != nil { log.Printf("Failed getting users for verification token: %s", err) - resp.WriteHeader(200) - resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "%s"}`, defaultMessage))) + resp.WriteHeader(401) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, defaultMessage))) return } @@ -1008,11 +1010,12 @@ func handleRegister(resp http.ResponseWriter, request *http.Request) { } } - //log.Printf("User role: %s", user.Role) - if err == nil && user.Role != "admin" && count > 0 { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false, "reason": "Can't register without being admin (2)"}`)) - return + if count != 0 { + if user.Role != "admin" { + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false, "reason": "Can't register without being admin (2)"}`)) + return + } } // Gets a struct of Username, password @@ -1042,10 +1045,18 @@ func handleRegister(resp http.ResponseWriter, request *http.Request) { return } - // FIXME - use it somehow ctx := context.Background() - _, err = getUser(ctx, data.Username) - if err == nil { + q := datastore.NewQuery("Users").Filter("Username =", data.Username) + var users []User + _, err = dbclient.GetAll(ctx, q, &users) + if err != nil { + log.Printf("Failed getting user for registration: %s", err) + resp.WriteHeader(401) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed getting username"}`))) + return + } + + if len(users) > 0 { log.Printf("Username %s exists and can't register", data.Username) resp.WriteHeader(401) resp.Write([]byte(`{"success": false, "reason": "Username and/or password is incorrect"}`)) @@ -1064,14 +1075,17 @@ func handleRegister(resp http.ResponseWriter, request *http.Request) { newUser.Username = data.Username newUser.Password = string(hashedPassword) newUser.Verified = false - newUser.Role = "user" newUser.CreationTime = time.Now().Unix() + newUser.Active = true // FIXME - Remove this later - newUser.Role = "admin" + if count == 0 { + newUser.Role = "admin" + } else { + newUser.Role = "user" + } // set limits - // WorkflowExecutions > CloudExecutions simply because of onprem newUser.Limits.DailyApiUsage = 100 newUser.Limits.DailyWorkflowExecutions = 1000 newUser.Limits.DailyCloudExecutions = 100 @@ -1124,35 +1138,14 @@ Registration URL :) log.Printf("Couldn't send email: %v", err) } - //sessionToken := uuid.NewV4() - - //// Finally, we set the client cookie for "session_token" as the session token we just generated - //// we also set an expiry time of 120 seconds, the same as the cache - //http.SetCookie(resp, &http.Cookie{ - // Name: "session_token", - // Value: sessionToken.String(), - // Expires: time.Now().Add(1200 * time.Second), - //}) - - //log.Println(Userdata) resp.WriteHeader(200) resp.Write([]byte(`{"success": true}`)) log.Printf("%s Successfully registered.", data.Username) - //err = SetSession(*newUser, sessionToken.String()) - //if err != nil { - // log.Printf("Error adding session to database: %s", err) - //} - - //err = SetApikey(*newUser) - //if err != nil { - // log.Printf("Error adding apikey to database: %s", err) - //} - - //err = SetSession(*newUser, sessionToken.String()) - //if err != nil { - // log.Printf("Error adding apikey to database: %s", err) - //} + err = increaseStatisticsField(ctx, "successful_register", data.Username, 1) + if err != nil { + log.Printf("Failed to increase total apps loaded stats: %s", err) + } } func handleCookie(request *http.Request) bool { @@ -1212,9 +1205,9 @@ func handleLogout(resp http.ResponseWriter, request *http.Request) { // Get session first // Should basically never happen - _, err = getUser(ctx, session.Username) + _, err = getUser(ctx, session.Id) if err != nil { - log.Printf("Username %s doesn't exist: %s", session.Username, err) + log.Printf("Username %s doesn't exist (logout): %s", session.Username, err) resp.WriteHeader(401) resp.Write([]byte(`{"success": false, "reason": "Username and/or password is incorrect"}`)) return @@ -1306,9 +1299,9 @@ func handleApiGeneration(resp http.ResponseWriter, request *http.Request) { // Get session first // Should basically never happen - userInfo, err := getUser(ctx, session.Username) + userInfo, err := getUser(ctx, session.Id) if err != nil { - log.Printf("Username %s doesn't exist: %s", session.Username, err) + log.Printf("Username %s doesn't exist (apigen): %s", session.Username, err) resp.WriteHeader(401) resp.Write([]byte(`{"success": false, "reason": ""}`)) return @@ -1366,9 +1359,9 @@ func handleSettings(resp http.ResponseWriter, request *http.Request) { // Get session first // Should basically never happen - UserInfo, err := getUser(ctx, session.Username) + UserInfo, err := getUser(ctx, session.Id) if err != nil { - log.Printf("Username %s doesn't exist: %s", session.Username, err) + log.Printf("Username %s doesn't exist (settings): %s", session.Username, err) resp.WriteHeader(401) resp.Write([]byte(`{"success": false, "reason": ""}`)) return @@ -1409,22 +1402,75 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) { if err != nil { //log.Printf("Session %#v doesn't exist: %s", session, err) resp.WriteHeader(401) - resp.Write([]byte(`{"success": false, "reason": ""}`)) + resp.Write([]byte(`{"success": false, "reason": "No session"}`)) return } // Get session first // Should basically never happen - UserInfo, err := getUser(ctx, session.Username) + userInfo, err := getUser(ctx, session.Id) if err != nil { - log.Printf("Username %s doesn't exist: %s", session.Username, err) + log.Printf("Username %s doesn't exist (info): %s", session.Username, err) resp.WriteHeader(401) resp.Write([]byte(`{"success": false, "reason": ""}`)) return } + // This is a long check to see if an inactive admin can access the portal + if !userInfo.Active { + if userInfo.Role == "admin" { + ctx := context.Background() + q := datastore.NewQuery("Users") + var users []User + _, err = dbclient.GetAll(ctx, q, &users) + if err != nil { + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false, "reason": "Failed to get other users when verifying admin user"}`)) + return + } + + activeFound := false + adminFound := false + for _, user := range users { + if user.Id == userInfo.Id { + continue + } + + if user.Role != "admin" { + continue + } + + if user.Active { + activeFound = true + } + + adminFound = true + } + + // Must ALWAYS be an active admin + // Will return no access if another admin is active + if !adminFound { + log.Printf("NO OTHER ADMINS FOUND - CONTINUE!") + } else { + // + if activeFound { + log.Printf("OTHER ACTIVE ADMINS FOUND - CAN'T PASS") + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false, "reason": "This user is locked"}`)) + return + } else { + log.Printf("NO OTHER ADMINS FOUND - CONTINUE!") + } + } + } else { + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false, "reason": "This user is locked"}`)) + return + } + } + //log.Printf("%s %s", session.Session, UserInfo.Session) - if session.Session != UserInfo.Session { + if session.Session != userInfo.Session { log.Printf("Session %s is not the latest. %s", session.Username, err) resp.WriteHeader(401) resp.Write([]byte(`{"success": false, "reason": ""}`)) @@ -1434,11 +1480,11 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) { expiration := time.Now().Add(3600 * time.Second) http.SetCookie(resp, &http.Cookie{ Name: "session_token", - Value: UserInfo.Session, + Value: userInfo.Session, Expires: expiration, }) - returnData := fmt.Sprintf(`{"success": true, "cookies": [{"key": "session_token", "value": "%s", "expiration": %d}]}`, UserInfo.Session, expiration.Unix()) + returnData := fmt.Sprintf(`{"success": true, "cookies": [{"key": "session_token", "value": "%s", "expiration": %d}]}`, userInfo.Session, expiration.Unix()) resp.WriteHeader(200) resp.Write([]byte(returnData)) @@ -1489,7 +1535,7 @@ func handlePasswordResetMail(resp http.ResponseWriter, request *http.Request) { ctx := context.Background() Userdata, err := getUser(ctx, t.Username) if err != nil { - log.Printf("Username %s doesn't exist: %s", t.Username, err) + log.Printf("Username %s doesn't exist (pw reset mail): %s", t.Username, err) resp.WriteHeader(200) resp.Write([]byte(fmt.Sprintf(`{"success": true}`))) return @@ -1589,8 +1635,8 @@ func handlePasswordReset(resp http.ResponseWriter, request *http.Request) { _, err = dbclient.GetAll(ctx, q, &users) if err != nil { log.Printf("Failed getting users: %s", err) - resp.WriteHeader(200) - resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "%s"}`, defaultMessage))) + resp.WriteHeader(401) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, defaultMessage))) return } @@ -1697,9 +1743,9 @@ func handlePasswordChange(resp http.ResponseWriter, request *http.Request) { // Get session first // Should basically never happen - Userdata, err := getUser(ctx, session.Username) + Userdata, err := getUser(ctx, session.Id) if err != nil { - log.Printf("Username %s doesn't exist: %s", session.Username, err) + log.Printf("Username %s doesn't exist (pw change): %s", session.Username, err) resp.WriteHeader(401) resp.Write([]byte(`{"success": false, "reason": "Username and/or password is incorrect"}`)) return @@ -1942,12 +1988,10 @@ func handleGetUsers(resp http.ResponseWriter, request *http.Request) { } func checkAdminLogin(resp http.ResponseWriter, request *http.Request) { - log.Printf("HELLO?") cors := handleCors(resp, request) if cors { return } - log.Printf("HELLO2?") count, err := getUserCount() if err != nil { @@ -1991,14 +2035,24 @@ func handleLogin(resp http.ResponseWriter, request *http.Request) { } ctx := context.Background() - Userdata, err := getUser(ctx, data.Username) + q := datastore.NewQuery("Users").Filter("Username =", strings.ToLower(data.Username)) + var users []User + _, err = dbclient.GetAll(ctx, q, &users) if err != nil { - log.Printf("Username %s doesn't exist: %s", data.Username, err) + log.Printf("Failed getting user %s", data.Username) resp.WriteHeader(401) resp.Write([]byte(`{"success": false, "reason": "Username and/or password is incorrect"}`)) return } + if len(users) != 1 { + log.Printf(`Found multiple users with the same username: %s: %d`, data.Username, len(users)) + resp.WriteHeader(401) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Found multiple users with the same username: %s"}`, data.Username))) + return + } + + Userdata := users[0] err = bcrypt.CompareHashAndPassword([]byte(Userdata.Password), []byte(data.Password)) if err != nil { log.Printf("Password for %s is incorrect: %s", data.Username, err) @@ -2031,7 +2085,7 @@ func handleLogin(resp http.ResponseWriter, request *http.Request) { loginData = fmt.Sprintf(`{"success": true, "cookies": [{"key": "session_token", "value": "%s", "expiration": %d}]}`, Userdata.Session, expiration.Unix()) //log.Printf("SESSION LENGTH MORE THAN 0 IN LOGIN: %s", Userdata.Session) - err = SetSession(ctx, *Userdata, Userdata.Session) + err = SetSession(ctx, Userdata, Userdata.Session) if err != nil { log.Printf("Error adding session to database: %s", err) } @@ -2050,7 +2104,7 @@ func handleLogin(resp http.ResponseWriter, request *http.Request) { }) // ADD TO DATABASE - err = SetSession(ctx, *Userdata, sessionToken.String()) + err = SetSession(ctx, Userdata, sessionToken.String()) if err != nil { log.Printf("Error adding session to database: %s", err) } @@ -2088,8 +2142,8 @@ func getSession(ctx context.Context, thissession string) (*session, error) { } // ListBooks returns a list of books, ordered by title. -func getUser(ctx context.Context, Username string) (*User, error) { - key := datastore.NameKey("Users", strings.ToLower(Username), nil) +func getUser(ctx context.Context, id string) (*User, error) { + key := datastore.NameKey("Users", id, nil) curUser := &User{} if err := dbclient.Get(ctx, key, curUser); err != nil { return &User{}, err @@ -2133,7 +2187,7 @@ func SetApikey(ctx context.Context, Userdata User) error { func SetSession(ctx context.Context, Userdata User, value string) error { // Non indexed User data Userdata.Session = value - key1 := datastore.NameKey("Users", strings.ToLower(Userdata.Username), nil) + key1 := datastore.NameKey("Users", Userdata.Id, nil) // New struct, to not add body, author etc if _, err := dbclient.Put(ctx, key1, &Userdata); err != nil { @@ -2146,6 +2200,7 @@ func SetSession(ctx context.Context, Userdata User, value string) error { sessiondata := new(session) sessiondata.Username = Userdata.Username sessiondata.Session = Userdata.Session + sessiondata.Id = Userdata.Id key2 := datastore.NameKey("sessions", sessiondata.Session, nil) if _, err := dbclient.Put(ctx, key2, sessiondata); err != nil { @@ -2193,10 +2248,7 @@ func setEnvironment(ctx context.Context, data *Environment) error { // ListBooks returns a list of books, ordered by title. func setUser(ctx context.Context, data *User) error { // clear session_token and API_token for user - k := datastore.NameKey("Users", strings.ToLower(data.Username), nil) - - // New struct, to not add body, author etc - + k := datastore.NameKey("Users", data.Id, nil) if _, err := dbclient.Put(ctx, k, data); err != nil { log.Println(err) return err @@ -5881,6 +5933,41 @@ func runInit(ctx context.Context) { log.Printf("Failed increasing local stats: %s", err) } + // Fix active users etc + q := datastore.NewQuery("Users").Filter("active =", true) + var users []User + _, err = dbclient.GetAll(ctx, q, &users) + if err != nil { + log.Printf("Error getting users apikey: %s", err) + } else { + if len(users) == 0 { + log.Printf("No active users found - setting ALL to active") + q := datastore.NewQuery("Users") + var users []User + _, err := dbclient.GetAll(ctx, q, &users) + if err == nil { + for _, user := range users { + user.Active = true + if len(user.Username) == 0 { + DeleteKey(ctx, "Users", strings.ToLower(user.Username)) + continue + } + + err = setUser(ctx, &user) + if err != nil { + log.Printf("Failed to reset user") + } else { + log.Printf("Remade user %s with ID", user.Id) + err = DeleteKey(ctx, "Users", strings.ToLower(user.Username)) + if err != nil { + log.Printf("Failed to delete old user by username") + } + } + } + } + } + } + // Gets environments and inits if it doesn't exist count, err := getEnvironmentCount() if count == 0 && err == nil { @@ -6022,18 +6109,29 @@ func init() { r.HandleFunc("/functions/outlook/register", handleNewOutlookRegister).Methods("GET", "OPTIONS") r.HandleFunc("/functions/outlook/getFolders", handleGetOutlookFolders).Methods("GET", "OPTIONS") - // General + // Make user related locations + r.HandleFunc("/api/v1/users/login", handleLogin).Methods("POST", "OPTIONS") + r.HandleFunc("/api/v1/users/logout", handleLogout).Methods("POST", "OPTIONS") + r.HandleFunc("/api/v1/users/register", handleRegister).Methods("POST", "OPTIONS") + r.HandleFunc("/api/v1/users/checkusers", checkAdminLogin).Methods("GET", "OPTIONS") + r.HandleFunc("/api/v1/users/getusers", handleGetUsers).Methods("GET", "OPTIONS") + r.HandleFunc("/api/v1/users/getinfo", handleInfo).Methods("GET", "OPTIONS") + r.HandleFunc("/api/v1/users/getsettings", handleSettings).Methods("GET", "OPTIONS") + r.HandleFunc("/api/v1/users/generateapikey", handleApiGeneration).Methods("GET", "OPTIONS") + r.HandleFunc("/api/v1/users/{user}", deleteUser).Methods("DELETE", "OPTIONS") + + // General - duplicates and old. r.HandleFunc("/api/v1/login", handleLogin).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/logout", handleLogout).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/register", handleRegister).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/checkusers", checkAdminLogin).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/getusers", handleGetUsers).Methods("GET", "OPTIONS") - - r.HandleFunc("/api/v1/getenvironments", handleGetEnvironments).Methods("GET", "OPTIONS") - r.HandleFunc("/api/v1/setenvironments", handleSetEnvironments).Methods("PUT", "OPTIONS") r.HandleFunc("/api/v1/getinfo", handleInfo).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/getsettings", handleSettings).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/generateapikey", handleApiGeneration).Methods("GET", "OPTIONS") + + r.HandleFunc("/api/v1/getenvironments", handleGetEnvironments).Methods("GET", "OPTIONS") + r.HandleFunc("/api/v1/setenvironments", handleSetEnvironments).Methods("PUT", "OPTIONS") r.HandleFunc("/api/v1/passwordchange", handlePasswordChange).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/docs", getDocList).Methods("GET", "OPTIONS") @@ -6042,8 +6140,6 @@ func init() { // Queuebuilder and Workflow streams. First is to update a stream, second to get a stream // Changed from workflows/streams to streams, as appengine was messing up // This does not increase the API counter - r.HandleFunc("/api/v1/workflows/queue", handleGetWorkflowqueue).Methods("GET") - r.HandleFunc("/api/v1/workflows/queue/confirm", handleGetWorkflowqueueConfirm).Methods("POST") r.HandleFunc("/api/v1/streams", handleWorkflowQueue).Methods("POST") r.HandleFunc("/api/v1/streams/results", handleGetStreamResults).Methods("POST", "OPTIONS") @@ -6068,6 +6164,8 @@ func init() { /* Everything below here increases the counters*/ r.HandleFunc("/api/v1/workflows", getWorkflows).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/workflows", setNewWorkflow).Methods("POST", "OPTIONS") + r.HandleFunc("/api/v1/workflows/queue", handleGetWorkflowqueue).Methods("GET") + r.HandleFunc("/api/v1/workflows/queue/confirm", handleGetWorkflowqueueConfirm).Methods("POST") r.HandleFunc("/api/v1/workflows/schedules", handleGetSchedules).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/workflows/download_remote", loadSpecificWorkflows).Methods("POST", "OPTIONS") //r.HandleFunc("/api/v1/workflows/{key}/execute_fs", executeWorkflowFS) diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go index 87041fa5..2dc041bf 100644 --- a/backend/go-app/walkoff.go +++ b/backend/go-app/walkoff.go @@ -2642,6 +2642,84 @@ func setWorkflow(ctx context.Context, workflow Workflow, id string) error { return nil } +func deleteUser(resp http.ResponseWriter, request *http.Request) { + cors := handleCors(resp, request) + if cors { + return + } + + user, userErr := handleApiAuthentication(resp, request) + if userErr != nil { + log.Printf("Api authentication failed in edit workflow: %s", userErr) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + if user.Role != "admin" { + log.Printf("Wrong user (%s) when deleting - must be admin", user.Username) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false, "reason": "Must be admin"}`)) + return + } + + location := strings.Split(request.URL.String(), "/") + var userId string + if location[1] == "api" { + if len(location) <= 4 { + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + userId = location[4] + } + + if userId == user.Id { + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false, "reason": "Can't deactivate yourself"}`)) + return + } + + ctx := context.Background() + q := datastore.NewQuery("Users").Filter("id =", userId) + var users []User + _, err := dbclient.GetAll(ctx, q, &users) + if err != nil { + log.Printf("Error getting users apikey: %s", err) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false, "reason": "Failed getting users for verification"}`)) + return + } + + if len(users) != 1 { + log.Printf("Found too many users!") + resp.WriteHeader(500) + resp.Write([]byte(`{"success": false, "reason": "Backend error: too many users"}`)) + return + } + + // Invert. No user deletion. + if users[0].Active { + users[0].Active = false + } else { + users[0].Active = true + } + + err = setUser(ctx, &users[0]) + if err != nil { + log.Printf("Failed swapping active for user %s (%s)", users[0].Username, users[0].Id) + resp.WriteHeader(401) + resp.Write([]byte(fmt.Sprintf(`{"success": true"}`))) + return + } + + log.Printf("Successfully inverted %s", users[0].Username) + + resp.WriteHeader(200) + resp.Write([]byte(`{"success": true}`)) +} + func deleteWorkflowApp(resp http.ResponseWriter, request *http.Request) { cors := handleCors(resp, request) if cors { diff --git a/frontend/src/Admin.js b/frontend/src/Admin.js index c3700307..1790c87e 100644 --- a/frontend/src/Admin.js +++ b/frontend/src/Admin.js @@ -63,6 +63,36 @@ const Admin = (props) => { }); } + const deleteUser = (data) => { + // Just use this one? + const url = globalUrl+'/api/v1/users/'+data.id + fetch(url, { + method: 'DELETE', + credentials: "include", + headers: { + 'Content-Type': 'application/json', + }, + }) + .then(response => { + if (response.status === 200) { + getUsers() + } + + return response.json() + }) + .then((responseJson) => { + if (!responseJson.success && responseJson.reason !== undefined) { + alert.error("Failed to deactivate user: "+responseJson.reason) + } else { + alert.success("Deleted user "+data.id) + } + }) + + .catch(error => { + console.log("Error in userdata: ", error) + }); + } + const submitUser = (data) => { // FIXME - add some check here ROFL console.log("INPUT: ", data) @@ -244,8 +274,8 @@ const Admin = (props) => { } const paperStyle = { - minWidth: "100%", - maxWidth: "100%", + maxWidth: 1250, + margin: "auto", color: "white", backgroundColor: surfaceColor, marginBottom: 10, @@ -373,11 +403,67 @@ const Admin = (props) => { + + + + + + + + {users === undefined ? null : users.map(data => { - console.log(data) + console.log("USER: ", data) return ( - {data.Username} + + + + + console.log("Should set user to active")} + /> + + + ) })} @@ -472,7 +558,7 @@ const Admin = (props) => { } const data = -
+