Proper context.Context usage
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
package backend
|
||||
|
||||
import "net/http"
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// An application interface. Both LogTable and CrashTable are optional, if they return nil then requests will be forbidden.
|
||||
type App interface {
|
||||
@@ -18,7 +21,7 @@ type CallbackApp interface {
|
||||
// Allows for an App to filter crashes before they get added to the DB, such as making sure the crash is from the correct version.
|
||||
type CrashFilterApp interface {
|
||||
App
|
||||
AddCrash(IndividualCrash) bool
|
||||
ShouldAddCrash(context.Context, IndividualCrash) bool
|
||||
}
|
||||
|
||||
// Allows an app more flexibility by directly interfacing with the backend's mux
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package backend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
@@ -53,15 +54,15 @@ func (b *Backend) countLog(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
curDate := getDate(time.Now())
|
||||
if req.ID == "" {
|
||||
err = addToCountTable(w, count, req.Platform, curDate)
|
||||
err = addToCountTable(r.Context(), w, count, req.Platform, curDate)
|
||||
if err != nil {
|
||||
log.Println("error adding to count table:", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
l, err := count.Get(req.ID)
|
||||
l, err := count.Get(r.Context(), req.ID)
|
||||
if err == ErrNotFound {
|
||||
err = addToCountTable(w, count, req.Platform, curDate)
|
||||
err = addToCountTable(r.Context(), w, count, req.Platform, curDate)
|
||||
if err != nil {
|
||||
log.Println("error adding to count table:", err)
|
||||
}
|
||||
@@ -72,7 +73,7 @@ func (b *Backend) countLog(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
return
|
||||
}
|
||||
err = count.PartUpdate(req.ID, map[string]any{"date": curDate})
|
||||
err = count.PartUpdate(r.Context(), req.ID, map[string]any{"date": curDate})
|
||||
if err != nil {
|
||||
log.Println("error updating count log:", err)
|
||||
ReturnError(w, http.StatusInternalServerError, "internal", "Server error")
|
||||
@@ -82,14 +83,14 @@ func (b *Backend) countLog(w http.ResponseWriter, r *http.Request) {
|
||||
json.NewEncoder(w).Encode(map[string]string{"id": req.ID})
|
||||
}
|
||||
|
||||
func addToCountTable(w http.ResponseWriter, c CountTable, platform string, curDate int) error {
|
||||
func addToCountTable(ctx context.Context, w http.ResponseWriter, c CountTable, platform string, curDate int) error {
|
||||
id, err := uuid.NewV7()
|
||||
if err != nil {
|
||||
log.Println("error generating new log UUID:", err)
|
||||
ReturnError(w, http.StatusInternalServerError, "internal", "Server error")
|
||||
return err
|
||||
}
|
||||
err = c.Insert(CountLog{
|
||||
err = c.Insert(ctx, CountLog{
|
||||
ID: id.String(),
|
||||
Platform: platform,
|
||||
Date: curDate,
|
||||
@@ -127,7 +128,7 @@ func (b *Backend) getCount(w http.ResponseWriter, r *http.Request) {
|
||||
ReturnError(w, http.StatusBadRequest, "badRequest", "Trying to get user count on app that doesn't have a count table")
|
||||
return
|
||||
}
|
||||
out, err := count.Count(r.URL.Query().Get("platform"))
|
||||
out, err := count.Count(r.Context(), r.URL.Query().Get("platform"))
|
||||
if err != nil {
|
||||
log.Println("error getting count:", err)
|
||||
ReturnError(w, http.StatusInternalServerError, "internal", "Server error")
|
||||
|
||||
+15
-14
@@ -1,6 +1,7 @@
|
||||
package backend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
@@ -49,7 +50,7 @@ func (b *Backend) reportCrash(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
if filter, ok := ap.(CrashFilterApp); ok {
|
||||
if !filter.AddCrash(crash) {
|
||||
if !filter.ShouldAddCrash(r.Context(), crash) {
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -59,8 +60,8 @@ func (b *Backend) reportCrash(w http.ResponseWriter, r *http.Request) {
|
||||
ReturnError(w, http.StatusInternalServerError, "misconfigured", "Server misconfigured")
|
||||
return
|
||||
}
|
||||
if !tab.IsArchived(crash) {
|
||||
err = tab.InsertCrash(crash)
|
||||
if !tab.IsArchived(r.Context(), crash) {
|
||||
err = tab.InsertCrash(r.Context(), crash)
|
||||
if err != nil {
|
||||
log.Println("crash insertion error:", err)
|
||||
ReturnError(w, http.StatusInternalServerError, "internal", "Server error")
|
||||
@@ -83,7 +84,7 @@ func (b *Backend) deleteCrash(w http.ResponseWriter, r *http.Request) {
|
||||
ReturnError(w, http.StatusBadRequest, "badRequest", "Bad request")
|
||||
return
|
||||
}
|
||||
b.actualCrashDelete(w, b.GetApp(hdr.Key), crashID)
|
||||
b.actualCrashDelete(r.Context(), w, b.GetApp(hdr.Key), crashID)
|
||||
}
|
||||
|
||||
func (b *Backend) managementDeleteCrash(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -105,16 +106,16 @@ func (b *Backend) managementDeleteCrash(w http.ResponseWriter, r *http.Request)
|
||||
ReturnError(w, http.StatusBadRequest, "badRequest", "Bad request")
|
||||
return
|
||||
}
|
||||
b.actualCrashDelete(w, ap, crashID)
|
||||
b.actualCrashDelete(r.Context(), w, ap, crashID)
|
||||
}
|
||||
|
||||
func (b *Backend) actualCrashDelete(w http.ResponseWriter, ap App, crashID string) {
|
||||
func (b *Backend) actualCrashDelete(ctx context.Context, w http.ResponseWriter, ap App, crashID string) {
|
||||
crash := ap.CrashTable()
|
||||
if crash == nil {
|
||||
ReturnError(w, http.StatusInternalServerError, "misconfigured", "Server Misconfigured")
|
||||
return
|
||||
}
|
||||
err := crash.Remove(crashID)
|
||||
err := crash.Remove(ctx, crashID)
|
||||
if err != nil && err != ErrNotFound {
|
||||
log.Println("error when deleting crash:", err)
|
||||
}
|
||||
@@ -135,7 +136,7 @@ func (b *Backend) archiveCrash(w http.ResponseWriter, r *http.Request) {
|
||||
ReturnError(w, http.StatusBadRequest, "invalidBody", "Bad request")
|
||||
return
|
||||
}
|
||||
b.actualCrashArchive(w, b.GetApp(hdr.Key), toArchive)
|
||||
b.actualCrashArchive(r.Context(), w, b.GetApp(hdr.Key), toArchive)
|
||||
}
|
||||
|
||||
func (b *Backend) managementArchiveCrash(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -159,22 +160,22 @@ func (b *Backend) managementArchiveCrash(w http.ResponseWriter, r *http.Request)
|
||||
ReturnError(w, http.StatusBadRequest, "invalidBody", "Bad request")
|
||||
return
|
||||
}
|
||||
b.actualCrashArchive(w, ap, toArchive)
|
||||
b.actualCrashArchive(r.Context(), w, ap, toArchive)
|
||||
}
|
||||
|
||||
func (b *Backend) actualCrashArchive(w http.ResponseWriter, ap App, toArchive ArchivedCrash) {
|
||||
func (b *Backend) actualCrashArchive(ctx context.Context, w http.ResponseWriter, ap App, toArchive ArchivedCrash) {
|
||||
crash := ap.CrashTable()
|
||||
if crash == nil {
|
||||
ReturnError(w, http.StatusInternalServerError, "misconfigured", "Server Misconfigured")
|
||||
return
|
||||
}
|
||||
err := crash.Archive(toArchive)
|
||||
err := crash.Archive(ctx, toArchive)
|
||||
if err != nil {
|
||||
log.Println("error archive crash:", err)
|
||||
return
|
||||
}
|
||||
first, _, _ := strings.Cut(toArchive.Stack, "\n")
|
||||
crashes, err := crash.Find(map[string]any{"error": toArchive.Error, "firstLine": first})
|
||||
crashes, err := crash.Find(ctx, map[string]any{"error": toArchive.Error, "firstLine": first})
|
||||
if err == ErrNotFound {
|
||||
return
|
||||
} else if err != nil {
|
||||
@@ -194,12 +195,12 @@ func (b *Backend) actualCrashArchive(w http.ResponseWriter, ap App, toArchive Ar
|
||||
}
|
||||
}
|
||||
if len(c.Individual) == 0 {
|
||||
err = crash.Remove(c.ID)
|
||||
err = crash.Remove(ctx, c.ID)
|
||||
if err != nil {
|
||||
log.Println("error removing empty crash report:", err)
|
||||
}
|
||||
} else if len(c.Individual) < ogLen {
|
||||
err = crash.PartUpdate(c.ID, map[string]any{"individual": c.Individual})
|
||||
err = crash.PartUpdate(ctx, c.ID, map[string]any{"individual": c.Individual})
|
||||
if err != nil {
|
||||
log.Println("error updating individual crash reports:", err)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package backend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ed25519"
|
||||
"embed"
|
||||
"encoding/json"
|
||||
@@ -83,7 +84,7 @@ func (b *Backend) cleanupLoop() {
|
||||
if tab == nil {
|
||||
continue
|
||||
}
|
||||
err = tab.RemoveOldLogs(old)
|
||||
err = tab.RemoveOldLogs(context.Background(), old)
|
||||
if err != nil {
|
||||
log.Printf("error removing old logs for %v: %v\n", a.AppID(), err)
|
||||
}
|
||||
|
||||
+15
-12
@@ -1,6 +1,9 @@
|
||||
package backend
|
||||
|
||||
import "errors"
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNotFound = errors.New("no matches found in table")
|
||||
@@ -11,28 +14,28 @@ type IDStruct interface {
|
||||
}
|
||||
|
||||
type Table[T IDStruct] interface {
|
||||
Get(ID string) (data *T, err error)
|
||||
Find(values map[string]any) ([]T, error)
|
||||
Insert(data T) error
|
||||
Remove(ID string) error
|
||||
FullUpdate(ID string, data T) error
|
||||
PartUpdate(ID string, update map[string]any) error
|
||||
Get(ctx context.Context, ID string) (data *T, err error)
|
||||
Find(ctx context.Context, values map[string]any) ([]T, error)
|
||||
Insert(ctx context.Context, data T) error
|
||||
Remove(ctx context.Context, ID string) error
|
||||
FullUpdate(ctx context.Context, ID string, data T) error
|
||||
PartUpdate(ctx context.Context, ID string, update map[string]any) error
|
||||
}
|
||||
|
||||
type CountTable interface {
|
||||
Table[CountLog]
|
||||
// Remove all Log items that have a CountLog.Date value less then the given value.
|
||||
RemoveOldLogs(date int) error
|
||||
RemoveOldLogs(ctx context.Context, date int) error
|
||||
// Get count. If platform is an empty string or "all", the full count should be given
|
||||
Count(platform string) (int, error)
|
||||
Count(ctx context.Context, platform string) (int, error)
|
||||
}
|
||||
|
||||
type CrashTable interface {
|
||||
Table[CrashReport]
|
||||
// Move a crash type to archive. Crashes that match the archived crash will be automatically removed from the CrashTable.
|
||||
Archive(ArchivedCrash) error
|
||||
IsArchived(IndividualCrash) bool
|
||||
Archive(context.Context, ArchivedCrash) error
|
||||
IsArchived(context.Context, IndividualCrash) bool
|
||||
// Add the IndividualCrash report to the crash table. If a CrashReport exists that matches, then it gets added to CrashReport.Individual.
|
||||
// If an IndividualCrash exists that is a perfect match, Count is incremented instead of adding it to the array.
|
||||
InsertCrash(IndividualCrash) error
|
||||
InsertCrash(context.Context, IndividualCrash) error
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@ func NewMongoTable[T backend.IDStruct](col *mongo.Collection) *MongoTable[T] {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MongoTable[T]) Get(ID string) (data *T, err error) {
|
||||
res := m.col.FindOne(context.Background(), bson.M{"_id": ID})
|
||||
func (m *MongoTable[T]) Get(ctx context.Context, ID string) (data *T, err error) {
|
||||
res := m.col.FindOne(ctx, bson.M{"_id": ID})
|
||||
if res.Err() == mongo.ErrNoDocuments {
|
||||
return nil, backend.ErrNotFound
|
||||
} else if res.Err() != nil {
|
||||
@@ -30,58 +30,58 @@ func (m *MongoTable[T]) Get(ID string) (data *T, err error) {
|
||||
return &out, err
|
||||
}
|
||||
|
||||
func (m *MongoTable[T]) Find(values map[string]any) ([]T, error) {
|
||||
res, err := m.col.Find(context.Background(), values)
|
||||
func (m *MongoTable[T]) Find(ctx context.Context, values map[string]any) ([]T, error) {
|
||||
res, err := m.col.Find(ctx, values)
|
||||
if err == mongo.ErrNoDocuments {
|
||||
return nil, backend.ErrNotFound
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var out []T
|
||||
err = res.All(context.Background(), &out)
|
||||
err = res.All(ctx, &out)
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (m *MongoTable[T]) Insert(data T) error {
|
||||
_, err := m.col.InsertOne(context.Background(), data)
|
||||
func (m *MongoTable[T]) Insert(ctx context.Context, data T) error {
|
||||
_, err := m.col.InsertOne(ctx, data)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *MongoTable[T]) Remove(ID string) error {
|
||||
res := m.col.FindOneAndDelete(context.Background(), bson.M{"_id": ID})
|
||||
func (m *MongoTable[T]) Remove(ctx context.Context, ID string) error {
|
||||
res := m.col.FindOneAndDelete(ctx, bson.M{"_id": ID})
|
||||
return res.Err()
|
||||
}
|
||||
|
||||
func (m *MongoTable[T]) FullUpdate(ID string, data T) error {
|
||||
res := m.col.FindOneAndReplace(context.Background(), bson.M{"_id": ID}, data)
|
||||
func (m *MongoTable[T]) FullUpdate(ctx context.Context, ID string, data T) error {
|
||||
res := m.col.FindOneAndReplace(ctx, bson.M{"_id": ID}, data)
|
||||
if res.Err() == mongo.ErrNoDocuments {
|
||||
return backend.ErrNotFound
|
||||
}
|
||||
return res.Err()
|
||||
}
|
||||
|
||||
func (m *MongoTable[T]) PartUpdate(ID string, update map[string]any) error {
|
||||
res := m.col.FindOneAndUpdate(context.Background(), bson.M{"_id": ID}, bson.M{"$set": update})
|
||||
func (m *MongoTable[T]) PartUpdate(ctx context.Context, ID string, update map[string]any) error {
|
||||
res := m.col.FindOneAndUpdate(ctx, bson.M{"_id": ID}, bson.M{"$set": update})
|
||||
if res.Err() == mongo.ErrNoDocuments {
|
||||
return backend.ErrNotFound
|
||||
}
|
||||
return res.Err()
|
||||
}
|
||||
|
||||
func (m *MongoTable[CountLog]) RemoveOldLogs(date int) error {
|
||||
_, err := m.col.DeleteMany(context.Background(), bson.M{"date": bson.M{"$lt": date}})
|
||||
func (m *MongoTable[CountLog]) RemoveOldLogs(ctx context.Context, date int) error {
|
||||
_, err := m.col.DeleteMany(ctx, bson.M{"date": bson.M{"$lt": date}})
|
||||
if err == mongo.ErrNoDocuments {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
func (m *MongoTable[CountLog]) Count(platform string) (int, error) {
|
||||
func (m *MongoTable[CountLog]) Count(ctx context.Context, platform string) (int, error) {
|
||||
var filter bson.M
|
||||
if platform == "" || platform == "all" {
|
||||
filter = bson.M{}
|
||||
} else {
|
||||
filter = bson.M{"platform": platform}
|
||||
}
|
||||
out, err := m.col.CountDocuments(context.Background(), filter)
|
||||
out, err := m.col.CountDocuments(ctx, filter)
|
||||
return int(out), err
|
||||
}
|
||||
|
||||
@@ -22,24 +22,24 @@ func NewMongoCrashTable(crashCol *mongo.Collection, archiveCol *mongo.Collection
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MongoCrashTable) Archive(toArchive backend.ArchivedCrash) error {
|
||||
func (m *MongoCrashTable) Archive(ctx context.Context, toArchive backend.ArchivedCrash) error {
|
||||
if toArchive.Platform == "" {
|
||||
toArchive.Platform = "all"
|
||||
}
|
||||
_, err := m.archiveCol.InsertOne(context.Background(), toArchive)
|
||||
_, err := m.archiveCol.InsertOne(ctx, toArchive)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *MongoCrashTable) IsArchived(ind backend.IndividualCrash) bool {
|
||||
res := m.archiveCol.FindOne(context.Background(),
|
||||
func (m *MongoCrashTable) IsArchived(ctx context.Context, ind backend.IndividualCrash) bool {
|
||||
res := m.archiveCol.FindOne(ctx,
|
||||
bson.M{"error": ind.Error, "stack": ind.Stack, "platform": bson.M{"$in": []string{ind.Platform, "all"}}},
|
||||
)
|
||||
return res.Err() == nil
|
||||
}
|
||||
|
||||
func (m *MongoCrashTable) InsertCrash(ind backend.IndividualCrash) error {
|
||||
func (m *MongoCrashTable) InsertCrash(ctx context.Context, ind backend.IndividualCrash) error {
|
||||
first, _, _ := strings.Cut(ind.Stack, "\n")
|
||||
res, err := m.col.UpdateOne(context.Background(),
|
||||
res, err := m.col.UpdateOne(ctx,
|
||||
bson.M{"error": ind.Error, "firstLine": first, //filter main report
|
||||
"individual": bson.M{"$elemMatch": bson.M{"stack": ind.Stack, "platform": ind.Platform}}}, //filter individual
|
||||
bson.M{"$inc": bson.M{"individual.$.count": 1}}, //increment count
|
||||
@@ -49,7 +49,7 @@ func (m *MongoCrashTable) InsertCrash(ind backend.IndividualCrash) error {
|
||||
}
|
||||
if err == mongo.ErrNoDocuments || res.MatchedCount == 0 {
|
||||
ind.Count = 1
|
||||
res, err = m.col.UpdateMany(context.Background(),
|
||||
res, err = m.col.UpdateMany(ctx,
|
||||
bson.M{"error": ind.Error, "firstLine": first}, //filter
|
||||
bson.M{"$push": bson.M{"individual": ind}}, //Add new individual report
|
||||
)
|
||||
@@ -63,7 +63,7 @@ func (m *MongoCrashTable) InsertCrash(ind backend.IndividualCrash) error {
|
||||
return err
|
||||
}
|
||||
ind.Count = 1
|
||||
_, err = m.col.InsertOne(context.Background(),
|
||||
_, err = m.col.InsertOne(ctx,
|
||||
backend.CrashReport{
|
||||
ID: id.String(),
|
||||
Error: ind.Error,
|
||||
|
||||
@@ -45,7 +45,7 @@ func (b *Backend) ParseHeader(r *http.Request) (*ParsedHeader, error) {
|
||||
|
||||
token := strings.TrimPrefix(r.Header.Get("Authorization"), "Bearer ")
|
||||
if key != "" {
|
||||
apiKey, err := b.keyTable.Get(key)
|
||||
apiKey, err := b.keyTable.Get(r.Context(), key)
|
||||
if err == ErrNotFound {
|
||||
return nil, ErrApiKeyUnauthorized
|
||||
} else if err != nil {
|
||||
@@ -73,7 +73,7 @@ func (b *Backend) ParseHeader(r *http.Request) (*ParsedHeader, error) {
|
||||
} else if err != nil {
|
||||
return out, errors.Join(ErrTokenUnauthorized, err)
|
||||
}
|
||||
usr, err := b.userTable.Get(sub)
|
||||
usr, err := b.userTable.Get(r.Context(), sub)
|
||||
if err == jwt.ErrInvalidKey {
|
||||
return out, ErrTokenUnauthorized
|
||||
} else if err != nil {
|
||||
|
||||
@@ -139,7 +139,7 @@ func (b *Backend) createUser(w http.ResponseWriter, r *http.Request) {
|
||||
// TODO: filter offensive words/phrases
|
||||
b.userMutex.Lock()
|
||||
defer b.userMutex.Unlock()
|
||||
matchUsername, err := b.userTable.Find(map[string]any{"username": req.Username})
|
||||
matchUsername, err := b.userTable.Find(r.Context(), map[string]any{"username": req.Username})
|
||||
if err != nil && !errors.Is(err, ErrNotFound) {
|
||||
log.Println("error when checking for username collisions:", err)
|
||||
ReturnError(w, http.StatusInternalServerError, "internal", "Server error")
|
||||
@@ -148,7 +148,7 @@ func (b *Backend) createUser(w http.ResponseWriter, r *http.Request) {
|
||||
ReturnError(w, http.StatusUnauthorized, "taken", "Username or email already used")
|
||||
return
|
||||
}
|
||||
matchEmail, err := b.userTable.Find(map[string]any{"email": req.Email})
|
||||
matchEmail, err := b.userTable.Find(r.Context(), map[string]any{"email": req.Email})
|
||||
if err != nil && !errors.Is(err, ErrNotFound) {
|
||||
log.Println("error when checking for email collisions:", err)
|
||||
ReturnError(w, http.StatusInternalServerError, "internal", "Server error")
|
||||
@@ -163,7 +163,7 @@ func (b *Backend) createUser(w http.ResponseWriter, r *http.Request) {
|
||||
ReturnError(w, http.StatusInternalServerError, "internal", "Server error")
|
||||
return
|
||||
}
|
||||
err = b.userTable.Insert(u)
|
||||
err = b.userTable.Insert(r.Context(), u)
|
||||
if err != nil {
|
||||
log.Println("error inserting new user:", err)
|
||||
ReturnError(w, http.StatusInternalServerError, "internal", "Server error")
|
||||
@@ -196,7 +196,7 @@ func (b *Backend) deleteUser(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
b.userMutex.Lock()
|
||||
defer b.userMutex.Unlock()
|
||||
err = b.userTable.Remove(userID)
|
||||
err = b.userTable.Remove(r.Context(), userID)
|
||||
if err != nil && err != ErrNotFound {
|
||||
log.Println("error deleting user:", err)
|
||||
}
|
||||
@@ -231,7 +231,7 @@ func (b *Backend) login(w http.ResponseWriter, r *http.Request) {
|
||||
b.userMutex.RLock()
|
||||
defer b.userMutex.RUnlock()
|
||||
var ret loginReturn
|
||||
users, err := b.userTable.Find(map[string]any{"username": req.Username})
|
||||
users, err := b.userTable.Find(r.Context(), map[string]any{"username": req.Username})
|
||||
if errors.Is(err, ErrNotFound) || len(users) != 1 {
|
||||
ret.Error = "invalid"
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
@@ -269,7 +269,7 @@ func (b *Backend) login(w http.ResponseWriter, r *http.Request) {
|
||||
upd["timeout"] = timeout
|
||||
ret.Timeout = timeout - time.Now().Unix()
|
||||
}
|
||||
b.userTable.PartUpdate(u.ID, upd)
|
||||
b.userTable.PartUpdate(r.Context(), u.ID, upd)
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
json.NewEncoder(w).Encode(ret)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user