From 68004e1d34945300ca906e2bd490785afa496733 Mon Sep 17 00:00:00 2001 From: Harvey Tindall Date: Tue, 20 Jun 2023 12:19:24 +0100 Subject: [PATCH] storage: user set/get methods for contact method access Get/GetKey/SetKey/DeleteKey methods are used for access to email/discord/telegram/matrix, everywhere. Mutex added for each, avoids concurrent read/write issues. Will also make potential transition to database easier. --- api-invites.go | 2 +- api-messages.go | 52 +++---- api-ombi.go | 2 +- api-userpage.go | 29 ++-- api-users.go | 47 +++--- auth.go | 2 +- daemon.go | 24 ++- discord.go | 16 +- email.go | 14 +- matrix.go | 9 +- migrations.go | 8 +- package-lock.json | 366 +++++++++++++++++++++++----------------------- package.json | 2 +- storage.go | 119 ++++++++++++++- telegram.go | 6 +- 15 files changed, 397 insertions(+), 301 deletions(-) diff --git a/api-invites.go b/api-invites.go index 1102297..a41bd57 100644 --- a/api-invites.go +++ b/api-invites.go @@ -280,7 +280,7 @@ func (app *appContext) GetInvites(gc *gin.Context) { var address string if app.config.Section("ui").Key("jellyfin_login").MustBool(false) { app.storage.loadEmails() - if addr, ok := app.storage.emails[gc.GetString("jfId")]; ok && addr.Addr != "" { + if addr, ok := app.storage.GetEmailsKey(gc.GetString("jfId")); ok && addr.Addr != "" { address = addr.Addr } } else { diff --git a/api-messages.go b/api-messages.go index 8009adc..f971717 100644 --- a/api-messages.go +++ b/api-messages.go @@ -305,10 +305,10 @@ func (app *appContext) TelegramAddUser(gc *gin.Context) { if lang, ok := app.telegram.languages[tgToken.ChatID]; ok { tgUser.Lang = lang } - if app.storage.telegram == nil { - app.storage.telegram = map[string]TelegramUser{} + if app.storage.GetTelegram() == nil { + app.storage.telegram = telegramStore{} } - app.storage.telegram[req.ID] = tgUser + app.storage.SetTelegramKey(req.ID, tgUser) err := app.storage.storeTelegramUsers() if err != nil { app.err.Printf("Failed to store Telegram users: %v", err) @@ -340,15 +340,10 @@ func (app *appContext) SetContactMethods(gc *gin.Context) { } func (app *appContext) setContactMethods(req SetContactMethodsDTO, gc *gin.Context) { - if tgUser, ok := app.storage.telegram[req.ID]; ok { + if tgUser, ok := app.storage.GetTelegramKey(req.ID); ok { change := tgUser.Contact != req.Telegram tgUser.Contact = req.Telegram - app.storage.telegram[req.ID] = tgUser - if err := app.storage.storeTelegramUsers(); err != nil { - respondBool(500, false, gc) - app.err.Printf("Telegram: Failed to store users: %v", err) - return - } + app.storage.SetTelegramKey(req.ID, tgUser) if change { msg := "" if !req.Telegram { @@ -357,10 +352,10 @@ func (app *appContext) setContactMethods(req SetContactMethodsDTO, gc *gin.Conte app.debug.Printf("Telegram: User \"%s\" will%s be notified through Telegram.", tgUser.Username, msg) } } - if dcUser, ok := app.storage.discord[req.ID]; ok { + if dcUser, ok := app.storage.GetDiscordKey(req.ID); ok { change := dcUser.Contact != req.Discord dcUser.Contact = req.Discord - app.storage.discord[req.ID] = dcUser + app.storage.SetDiscordKey(req.ID, dcUser) if err := app.storage.storeDiscordUsers(); err != nil { respondBool(500, false, gc) app.err.Printf("Discord: Failed to store users: %v", err) @@ -374,10 +369,10 @@ func (app *appContext) setContactMethods(req SetContactMethodsDTO, gc *gin.Conte app.debug.Printf("Discord: User \"%s\" will%s be notified through Discord.", dcUser.Username, msg) } } - if mxUser, ok := app.storage.matrix[req.ID]; ok { + if mxUser, ok := app.storage.GetMatrixKey(req.ID); ok { change := mxUser.Contact != req.Matrix mxUser.Contact = req.Matrix - app.storage.matrix[req.ID] = mxUser + app.storage.SetMatrixKey(req.ID, mxUser) if err := app.storage.storeMatrixUsers(); err != nil { respondBool(500, false, gc) app.err.Printf("Matrix: Failed to store users: %v", err) @@ -391,10 +386,10 @@ func (app *appContext) setContactMethods(req SetContactMethodsDTO, gc *gin.Conte app.debug.Printf("Matrix: User \"%s\" will%s be notified through Matrix.", mxUser.UserID, msg) } } - if email, ok := app.storage.emails[req.ID]; ok { + if email, ok := app.storage.GetEmailsKey(req.ID); ok { change := email.Contact != req.Email email.Contact = req.Email - app.storage.emails[req.ID] = email + app.storage.SetEmailsKey(req.ID, email) if err := app.storage.storeEmails(); err != nil { respondBool(500, false, gc) app.err.Printf("Failed to store emails: %v", err) @@ -458,7 +453,7 @@ func (app *appContext) TelegramVerifiedInvite(gc *gin.Context) { } } if app.config.Section("telegram").Key("require_unique").MustBool(false) { - for _, u := range app.storage.telegram { + for _, u := range app.storage.GetTelegram() { if app.telegram.verifiedTokens[tokenIndex].Username == u.Username { respondBool(400, false, gc) return @@ -490,7 +485,7 @@ func (app *appContext) DiscordVerifiedInvite(gc *gin.Context) { pin := gc.Param("pin") _, ok := app.discord.verifiedTokens[pin] if app.config.Section("discord").Key("require_unique").MustBool(false) { - for _, u := range app.storage.discord { + for _, u := range app.storage.GetDiscord() { if app.discord.verifiedTokens[pin].ID == u.ID { delete(app.discord.verifiedTokens, pin) respondBool(400, false, gc) @@ -551,7 +546,7 @@ func (app *appContext) MatrixSendPIN(gc *gin.Context) { return } if app.config.Section("matrix").Key("require_unique").MustBool(false) { - for _, u := range app.storage.matrix { + for _, u := range app.storage.GetMatrix() { if req.UserID == u.UserID { respondBool(400, false, gc) return @@ -648,8 +643,8 @@ func (app *appContext) MatrixLogin(gc *gin.Context) { func (app *appContext) MatrixConnect(gc *gin.Context) { var req MatrixConnectUserDTO gc.BindJSON(&req) - if app.storage.matrix == nil { - app.storage.matrix = map[string]MatrixUser{} + if app.storage.GetMatrix() == nil { + app.storage.matrix = matrixStore{} } roomID, encrypted, err := app.matrix.CreateRoom(req.UserID) if err != nil { @@ -657,13 +652,13 @@ func (app *appContext) MatrixConnect(gc *gin.Context) { respondBool(500, false, gc) return } - app.storage.matrix[req.JellyfinID] = MatrixUser{ + app.storage.SetMatrixKey(req.JellyfinID, MatrixUser{ UserID: req.UserID, RoomID: string(roomID), Lang: "en-us", Contact: true, Encrypted: encrypted, - } + }) app.matrix.isEncrypted[roomID] = encrypted if err := app.storage.storeMatrixUsers(); err != nil { app.err.Printf("Failed to store Matrix users: %v", err) @@ -719,7 +714,7 @@ func (app *appContext) DiscordConnect(gc *gin.Context) { respondBool(500, false, gc) return } - app.storage.discord[req.JellyfinID] = user + app.storage.SetDiscordKey(req.JellyfinID, user) if err := app.storage.storeDiscordUsers(); err != nil { app.err.Printf("Failed to store Discord users: %v", err) respondBool(500, false, gc) @@ -743,8 +738,7 @@ func (app *appContext) UnlinkDiscord(gc *gin.Context) { respond(400, "User not found", gc) return } */ - delete(app.storage.discord, req.ID) - app.storage.storeDiscordUsers() + app.storage.DeleteDiscordKey(req.ID) respondBool(200, true, gc) } @@ -762,8 +756,7 @@ func (app *appContext) UnlinkTelegram(gc *gin.Context) { respond(400, "User not found", gc) return } */ - delete(app.storage.telegram, req.ID) - app.storage.storeTelegramUsers() + app.storage.DeleteTelegramKey(req.ID) respondBool(200, true, gc) } @@ -781,7 +774,6 @@ func (app *appContext) UnlinkMatrix(gc *gin.Context) { respond(400, "User not found", gc) return } */ - delete(app.storage.matrix, req.ID) - app.storage.storeMatrixUsers() + app.storage.DeleteMatrixKey(req.ID) respondBool(200, true, gc) } diff --git a/api-ombi.go b/api-ombi.go index 9bbb027..40a8f72 100644 --- a/api-ombi.go +++ b/api-ombi.go @@ -17,7 +17,7 @@ func (app *appContext) getOmbiUser(jfID string) (map[string]interface{}, int, er } username := jfUser.Name email := "" - if e, ok := app.storage.emails[jfID]; ok { + if e, ok := app.storage.GetEmailsKey(jfID); ok { email = e.Addr } for _, ombiUser := range ombiUsers { diff --git a/api-userpage.go b/api-userpage.go index 8c3f288..b63199d 100644 --- a/api-userpage.go +++ b/api-userpage.go @@ -41,7 +41,7 @@ func (app *appContext) MyDetails(gc *gin.Context) { if emailEnabled { resp.Email = &MyDetailsContactMethodsDTO{} - if email, ok := app.storage.emails[user.ID]; ok && email.Addr != "" { + if email, ok := app.storage.GetEmailsKey(user.ID); ok && email.Addr != "" { resp.Email.Value = email.Addr resp.Email.Enabled = email.Contact } @@ -49,7 +49,7 @@ func (app *appContext) MyDetails(gc *gin.Context) { if discordEnabled { resp.Discord = &MyDetailsContactMethodsDTO{} - if discord, ok := app.storage.discord[user.ID]; ok { + if discord, ok := app.storage.GetDiscordKey(user.ID); ok { resp.Discord.Value = RenderDiscordUsername(discord) resp.Discord.Enabled = discord.Contact } @@ -57,7 +57,7 @@ func (app *appContext) MyDetails(gc *gin.Context) { if telegramEnabled { resp.Telegram = &MyDetailsContactMethodsDTO{} - if telegram, ok := app.storage.telegram[user.ID]; ok { + if telegram, ok := app.storage.GetTelegramKey(user.ID); ok { resp.Telegram.Value = telegram.Username resp.Telegram.Enabled = telegram.Contact } @@ -65,7 +65,7 @@ func (app *appContext) MyDetails(gc *gin.Context) { if matrixEnabled { resp.Matrix = &MyDetailsContactMethodsDTO{} - if matrix, ok := app.storage.matrix[user.ID]; ok { + if matrix, ok := app.storage.GetMatrixKey(user.ID); ok { resp.Matrix.Value = matrix.UserID resp.Matrix.Enabled = matrix.Contact } @@ -172,14 +172,14 @@ func (app *appContext) confirmMyAction(gc *gin.Context, key string) { gc.Redirect(http.StatusSeeOther, "/my/account") return } else if target == UserEmailChange { - emailStore, ok := app.storage.emails[id] + emailStore, ok := app.storage.GetEmailsKey(id) if !ok { emailStore = EmailAddress{ Contact: true, } } emailStore.Addr = claims["email"].(string) - app.storage.emails[id] = emailStore + app.storage.SetEmailsKey(id, emailStore) if app.config.Section("ombi").Key("enabled").MustBool(false) { ombiUser, code, err := app.getOmbiUser(id) if code == 200 && err == nil { @@ -320,7 +320,7 @@ func (app *appContext) MyDiscordVerifiedInvite(gc *gin.Context) { return } if app.config.Section("discord").Key("require_unique").MustBool(false) { - for _, u := range app.storage.discord { + for _, u := range app.storage.GetDiscord() { if app.discord.verifiedTokens[pin].ID == u.ID { delete(app.discord.verifiedTokens, pin) respondBool(400, false, gc) @@ -328,15 +328,12 @@ func (app *appContext) MyDiscordVerifiedInvite(gc *gin.Context) { } } } - dc := app.storage.discord - existingUser, ok := app.storage.discord[gc.GetString("jfId")] + existingUser, ok := app.storage.GetDiscordKey(gc.GetString("jfId")) if ok { dcUser.Lang = existingUser.Lang dcUser.Contact = existingUser.Contact } - dc[gc.GetString("jfId")] = dcUser - app.storage.discord = dc - app.storage.storeDiscordUsers() + app.storage.SetDiscordKey(gc.GetString("jfId"), dcUser) respondBool(200, true, gc) } @@ -361,7 +358,7 @@ func (app *appContext) MyTelegramVerifiedInvite(gc *gin.Context) { return } if app.config.Section("telegram").Key("require_unique").MustBool(false) { - for _, u := range app.storage.telegram { + for _, u := range app.storage.GetTelegram() { if app.telegram.verifiedTokens[tokenIndex].Username == u.Username { respondBool(400, false, gc) return @@ -374,13 +371,11 @@ func (app *appContext) MyTelegramVerifiedInvite(gc *gin.Context) { Contact: true, } - tg := app.storage.telegram - existingUser, ok := app.storage.telegram[gc.GetString("jfId")] + existingUser, ok := app.storage.GetTelegramKey(gc.GetString("jfId")) if ok { tgUser.Lang = existingUser.Lang tgUser.Contact = existingUser.Contact } - tg[gc.GetString("jfId")] = tgUser - app.storage.storeTelegramUsers() + app.storage.SetTelegramKey(gc.GetString("jfId"), tgUser) respondBool(200, true, gc) } diff --git a/api-users.go b/api-users.go index 4452cac..343139d 100644 --- a/api-users.go +++ b/api-users.go @@ -61,7 +61,7 @@ func (app *appContext) NewUserAdmin(gc *gin.Context) { } app.jf.CacheExpiry = time.Now() if emailEnabled { - app.storage.emails[id] = EmailAddress{Addr: req.Email, Contact: true} + app.storage.SetEmailsKey(id, EmailAddress{Addr: req.Email, Contact: true}) app.storage.storeEmails() } if app.config.Section("ombi").Key("enabled").MustBool(false) { @@ -131,7 +131,7 @@ func (app *appContext) newUser(req newUserDTO, confirmed bool) (f errorFunc, suc return } if app.config.Section("discord").Key("require_unique").MustBool(false) { - for _, u := range app.storage.discord { + for _, u := range app.storage.GetDiscord() { if discordUser.ID == u.ID { f = func(gc *gin.Context) { app.debug.Printf("%s: New user failed: Discord user already linked", req.Code) @@ -177,7 +177,7 @@ func (app *appContext) newUser(req newUserDTO, confirmed bool) (f errorFunc, suc return } if app.config.Section("matrix").Key("require_unique").MustBool(false) { - for _, u := range app.storage.matrix { + for _, u := range app.storage.GetMatrix() { if user.User.UserID == u.UserID { f = func(gc *gin.Context) { app.debug.Printf("%s: New user failed: Matrix user already linked", req.Code) @@ -220,7 +220,7 @@ func (app *appContext) newUser(req newUserDTO, confirmed bool) (f errorFunc, suc return } if app.config.Section("telegram").Key("require_unique").MustBool(false) { - for _, u := range app.storage.telegram { + for _, u := range app.storage.GetTelegram() { if app.telegram.verifiedTokens[telegramTokenIndex].Username == u.Username { f = func(gc *gin.Context) { app.debug.Printf("%s: New user failed: Telegram user already linked", req.Code) @@ -339,7 +339,7 @@ func (app *appContext) newUser(req newUserDTO, confirmed bool) (f errorFunc, suc } // if app.config.Section("password_resets").Key("enabled").MustBool(false) { if req.Email != "" { - app.storage.emails[id] = EmailAddress{Addr: req.Email, Contact: true} + app.storage.SetEmailsKey(id, EmailAddress{Addr: req.Email, Contact: true}) app.storage.storeEmails() } expiry := time.Time{} @@ -355,9 +355,9 @@ func (app *appContext) newUser(req newUserDTO, confirmed bool) (f errorFunc, suc if discordEnabled && discordVerified { discordUser.Contact = req.DiscordContact if app.storage.discord == nil { - app.storage.discord = map[string]DiscordUser{} + app.storage.discord = discordStore{} } - app.storage.discord[user.ID] = discordUser + app.storage.SetDiscordKey(user.ID, discordUser) if err := app.storage.storeDiscordUsers(); err != nil { app.err.Printf("Failed to store Discord users: %v", err) } else { @@ -375,9 +375,9 @@ func (app *appContext) newUser(req newUserDTO, confirmed bool) (f errorFunc, suc tgUser.Lang = lang } if app.storage.telegram == nil { - app.storage.telegram = map[string]TelegramUser{} + app.storage.telegram = telegramStore{} } - app.storage.telegram[user.ID] = tgUser + app.storage.SetTelegramKey(user.ID, tgUser) if err := app.storage.storeTelegramUsers(); err != nil { app.err.Printf("Failed to store Telegram users: %v", err) } else { @@ -405,7 +405,8 @@ func (app *appContext) newUser(req newUserDTO, confirmed bool) (f errorFunc, suc dID = discordUser.ID } if telegramEnabled && telegramTokenIndex != -1 { - tUser = app.storage.telegram[user.ID].Username + u, _ := app.storage.GetTelegramKey(user.ID) + tUser = u.Username } resp, status, err := app.ombi.SetNotificationPrefs(ombiUser, dID, tUser) if !(status == 200 || status == 204) || err != nil { @@ -423,9 +424,9 @@ func (app *appContext) newUser(req newUserDTO, confirmed bool) (f errorFunc, suc matrixUser.Contact = req.MatrixContact delete(app.matrix.tokens, req.MatrixPIN) if app.storage.matrix == nil { - app.storage.matrix = map[string]MatrixUser{} + app.storage.matrix = matrixStore{} } - app.storage.matrix[user.ID] = matrixUser + app.storage.SetMatrixKey(user.ID, matrixUser) if err := app.storage.storeMatrixUsers(); err != nil { app.err.Printf("Failed to store Matrix users: %v", err) } @@ -488,7 +489,7 @@ func (app *appContext) NewUser(gc *gin.Context) { return } if app.config.Section("email").Key("require_unique").MustBool(false) && req.Email != "" { - for _, email := range app.storage.emails { + for _, email := range app.storage.GetEmails() { if req.Email == email.Addr { app.info.Printf("%s: New user failed: Email already in use", req.Code) respond(400, "errorEmailLinked", gc) @@ -897,7 +898,7 @@ func (app *appContext) GetUsers(gc *gin.Context) { if !jfUser.LastActivityDate.IsZero() { user.LastActive = jfUser.LastActivityDate.Unix() } - if email, ok := app.storage.emails[jfUser.ID]; ok { + if email, ok := app.storage.GetEmailsKey(jfUser.ID); ok { user.Email = email.Addr user.NotifyThroughEmail = email.Contact user.Label = email.Label @@ -907,15 +908,15 @@ func (app *appContext) GetUsers(gc *gin.Context) { if ok { user.Expiry = expiry.Unix() } - if tgUser, ok := app.storage.telegram[jfUser.ID]; ok { + if tgUser, ok := app.storage.GetTelegramKey(jfUser.ID); ok { user.Telegram = tgUser.Username user.NotifyThroughTelegram = tgUser.Contact } - if mxUser, ok := app.storage.matrix[jfUser.ID]; ok { + if mxUser, ok := app.storage.GetMatrixKey(jfUser.ID); ok { user.Matrix = mxUser.UserID user.NotifyThroughMatrix = mxUser.Contact } - if dcUser, ok := app.storage.discord[jfUser.ID]; ok { + if dcUser, ok := app.storage.GetDiscordKey(jfUser.ID); ok { user.Discord = RenderDiscordUsername(dcUser) // user.Discord = dcUser.Username + "#" + dcUser.Discriminator user.DiscordID = dcUser.ID @@ -949,11 +950,11 @@ func (app *appContext) SetAccountsAdmin(gc *gin.Context) { id := jfUser.ID if admin, ok := req[id]; ok { var emailStore = EmailAddress{} - if oldEmail, ok := app.storage.emails[id]; ok { + if oldEmail, ok := app.storage.GetEmailsKey(id); ok { emailStore = oldEmail } emailStore.Admin = admin - app.storage.emails[id] = emailStore + app.storage.SetEmailsKey(id, emailStore) } } if err := app.storage.storeEmails(); err != nil { @@ -986,11 +987,11 @@ func (app *appContext) ModifyLabels(gc *gin.Context) { id := jfUser.ID if label, ok := req[id]; ok { var emailStore = EmailAddress{} - if oldEmail, ok := app.storage.emails[id]; ok { + if oldEmail, ok := app.storage.GetEmailsKey(id); ok { emailStore = oldEmail } emailStore.Label = label - app.storage.emails[id] = emailStore + app.storage.SetEmailsKey(id, emailStore) } } if err := app.storage.storeEmails(); err != nil { @@ -1024,7 +1025,7 @@ func (app *appContext) ModifyEmails(gc *gin.Context) { id := jfUser.ID if address, ok := req[id]; ok { var emailStore = EmailAddress{} - oldEmail, ok := app.storage.emails[id] + oldEmail, ok := app.storage.GetEmailsKey(id) if ok { emailStore = oldEmail } @@ -1035,7 +1036,7 @@ func (app *appContext) ModifyEmails(gc *gin.Context) { } emailStore.Addr = address - app.storage.emails[id] = emailStore + app.storage.SetEmailsKey(id, emailStore) if ombiEnabled { ombiUser, code, err := app.getOmbiUser(id) if code == 200 && err == nil { diff --git a/auth.go b/auth.go index c1754e4..6ce4926 100644 --- a/auth.go +++ b/auth.go @@ -209,7 +209,7 @@ func (app *appContext) getTokenLogin(gc *gin.Context) { if !app.config.Section("ui").Key("allow_all").MustBool(false) { accountsAdmin := false adminOnly := app.config.Section("ui").Key("admin_only").MustBool(true) - if emailStore, ok := app.storage.emails[jfID]; ok { + if emailStore, ok := app.storage.GetEmailsKey(jfID); ok { accountsAdmin = emailStore.Admin } accountsAdmin = accountsAdmin || (adminOnly && user.Policy.IsAdministrator) diff --git a/daemon.go b/daemon.go index d7aeb57..8b3b465 100644 --- a/daemon.go +++ b/daemon.go @@ -13,14 +13,16 @@ func (app *appContext) clearEmails() { return } // Rebuild email storage to from existing users to reduce time complexity - emails := map[string]EmailAddress{} + emails := emailStore{} + app.storage.emailsLock.Lock() for _, user := range users { - if email, ok := app.storage.emails[user.ID]; ok { + if email, ok := app.storage.GetEmailsKey(user.ID); ok { emails[user.ID] = email } } app.storage.emails = emails app.storage.storeEmails() + app.storage.emailsLock.Unlock() } // clearDiscord does the same as clearEmails, but for Discord Users. @@ -32,14 +34,16 @@ func (app *appContext) clearDiscord() { return } // Rebuild discord storage to from existing users to reduce time complexity - dcUsers := map[string]DiscordUser{} + dcUsers := discordStore{} + app.storage.discordLock.Lock() for _, user := range users { - if dcUser, ok := app.storage.discord[user.ID]; ok { + if dcUser, ok := app.storage.GetDiscordKey(user.ID); ok { dcUsers[user.ID] = dcUser } } app.storage.discord = dcUsers app.storage.storeDiscordUsers() + app.storage.discordLock.Unlock() } // clearMatrix does the same as clearEmails, but for Matrix Users. @@ -51,14 +55,16 @@ func (app *appContext) clearMatrix() { return } // Rebuild matrix storage to from existing users to reduce time complexity - mxUsers := map[string]MatrixUser{} + mxUsers := matrixStore{} + app.storage.matrixLock.Lock() for _, user := range users { - if mxUser, ok := app.storage.matrix[user.ID]; ok { + if mxUser, ok := app.storage.GetMatrixKey(user.ID); ok { mxUsers[user.ID] = mxUser } } app.storage.matrix = mxUsers app.storage.storeMatrixUsers() + app.storage.matrixLock.Unlock() } // clearTelegram does the same as clearEmails, but for Telegram Users. @@ -70,14 +76,16 @@ func (app *appContext) clearTelegram() { return } // Rebuild telegram storage to from existing users to reduce time complexity - tgUsers := map[string]TelegramUser{} + tgUsers := telegramStore{} + app.storage.telegramLock.Lock() for _, user := range users { - if tgUser, ok := app.storage.telegram[user.ID]; ok { + if tgUser, ok := app.storage.GetTelegramKey(user.ID); ok { tgUsers[user.ID] = tgUser } } app.storage.telegram = tgUsers app.storage.storeTelegramUsers() + app.storage.telegramLock.Unlock() } // https://bbengfort.github.io/snippets/2016/06/26/background-work-goroutines-timer.html THANKS diff --git a/discord.go b/discord.go index f10e7c5..4fc98be 100644 --- a/discord.go +++ b/discord.go @@ -48,7 +48,7 @@ func newDiscordDaemon(app *appContext) (*DiscordDaemon, error) { dd.commandHandlers[app.config.Section("discord").Key("start_command").MustString("start")] = dd.cmdStart dd.commandHandlers["lang"] = dd.cmdLang dd.commandHandlers["pin"] = dd.cmdPIN - for _, user := range app.storage.discord { + for _, user := range app.storage.GetDiscord() { dd.users[user.ID] = user } @@ -472,14 +472,11 @@ func (d *DiscordDaemon) cmdLang(s *dg.Session, i *dg.InteractionCreate, lang str code := i.ApplicationCommandData().Options[0].StringValue() if _, ok := d.app.storage.lang.Telegram[code]; ok { var user DiscordUser - for jfID, u := range d.app.storage.discord { + for jfID, u := range d.app.storage.GetDiscord() { if u.ID == i.Interaction.Member.User.ID { u.Lang = code lang = code - d.app.storage.discord[jfID] = u - if err := d.app.storage.storeDiscordUsers(); err != nil { - d.app.err.Printf("Failed to store Discord users: %v", err) - } + d.app.storage.SetDiscordKey(jfID, u) user = u break } @@ -582,13 +579,10 @@ func (d *DiscordDaemon) msgLang(s *dg.Session, m *dg.MessageCreate, sects []stri } if _, ok := d.app.storage.lang.Telegram[sects[1]]; ok { var user DiscordUser - for jfID, u := range d.app.storage.discord { + for jfID, u := range d.app.storage.GetDiscord() { if u.ID == m.Author.ID { u.Lang = sects[1] - d.app.storage.discord[jfID] = u - if err := d.app.storage.storeDiscordUsers(); err != nil { - d.app.err.Printf("Failed to store Discord users: %v", err) - } + d.app.storage.SetDiscordKey(jfID, u) user = u break } diff --git a/email.go b/email.go index f31da18..808369c 100644 --- a/email.go +++ b/email.go @@ -838,25 +838,25 @@ func (emailer *Emailer) send(email *Message, address ...string) error { func (app *appContext) sendByID(email *Message, ID ...string) error { for _, id := range ID { var err error - if tgChat, ok := app.storage.telegram[id]; ok && tgChat.Contact && telegramEnabled { + if tgChat, ok := app.storage.GetTelegramKey(id); ok && tgChat.Contact && telegramEnabled { err = app.telegram.Send(email, tgChat.ChatID) if err != nil { return err } } - if dcChat, ok := app.storage.discord[id]; ok && dcChat.Contact && discordEnabled { + if dcChat, ok := app.storage.GetDiscordKey(id); ok && dcChat.Contact && discordEnabled { err = app.discord.Send(email, dcChat.ChannelID) if err != nil { return err } } - if mxChat, ok := app.storage.matrix[id]; ok && mxChat.Contact && matrixEnabled { + if mxChat, ok := app.storage.GetMatrixKey(id); ok && mxChat.Contact && matrixEnabled { err = app.matrix.Send(email, mxChat) if err != nil { return err } } - if address, ok := app.storage.emails[id]; ok && address.Contact && emailEnabled { + if address, ok := app.storage.GetEmailsKey(id); ok && address.Contact && emailEnabled { err = app.email.send(email, address.Addr) if err != nil { return err @@ -870,13 +870,13 @@ func (app *appContext) sendByID(email *Message, ID ...string) error { } func (app *appContext) getAddressOrName(jfID string) string { - if dcChat, ok := app.storage.discord[jfID]; ok && dcChat.Contact && discordEnabled { + if dcChat, ok := app.storage.GetDiscordKey(jfID); ok && dcChat.Contact && discordEnabled { return RenderDiscordUsername(dcChat) } - if tgChat, ok := app.storage.telegram[jfID]; ok && tgChat.Contact && telegramEnabled { + if tgChat, ok := app.storage.GetTelegramKey(jfID); ok && tgChat.Contact && telegramEnabled { return "@" + tgChat.Username } - if addr, ok := app.storage.emails[jfID]; ok { + if addr, ok := app.storage.GetEmailsKey(jfID); ok { return addr.Addr } return "" diff --git a/matrix.go b/matrix.go index ecd8268..932a6c0 100644 --- a/matrix.go +++ b/matrix.go @@ -83,7 +83,7 @@ func newMatrixDaemon(app *appContext) (d *MatrixDaemon, err error) { // return // } // d.bot.Store.SaveFilterID(d.userID, resp.FilterID) - for _, user := range app.storage.matrix { + for _, user := range app.storage.GetMatrix() { if user.Lang != "" { d.languages[id.RoomID(user.RoomID)] = user.Lang } @@ -176,12 +176,9 @@ func (d *MatrixDaemon) commandLang(evt *event.Event, code, lang string) { return } d.languages[evt.RoomID] = code - if u, ok := d.app.storage.matrix[string(evt.RoomID)]; ok { + if u, ok := d.app.storage.GetMatrixKey(string(evt.RoomID)); ok { u.Lang = code - d.app.storage.matrix[string(evt.RoomID)] = u - if err := d.app.storage.storeMatrixUsers(); err != nil { - d.app.err.Printf("Matrix: Failed to store Matrix users: %v", err) - } + d.app.storage.SetMatrixKey(string(evt.RoomID), u) } } diff --git a/migrations.go b/migrations.go index e09a0c7..95f69eb 100644 --- a/migrations.go +++ b/migrations.go @@ -139,7 +139,7 @@ func migrateNotificationMethods(app *appContext) error { if !strings.Contains(address, "@") { continue } - for id, email := range app.storage.emails { + for id, email := range app.storage.GetEmails() { if email.Addr == address { invite.Notify[id] = notifyPrefs delete(invite.Notify, address) @@ -168,10 +168,10 @@ func linkExistingOmbiDiscordTelegram(app *appContext) error { return nil } idList := map[string][2]string{} - for jfID, user := range app.storage.discord { + for jfID, user := range app.storage.GetDiscord() { idList[jfID] = [2]string{user.ID, ""} } - for jfID, user := range app.storage.telegram { + for jfID, user := range app.storage.GetTelegram() { vals, ok := idList[jfID] if !ok { vals = [2]string{"", ""} @@ -212,7 +212,7 @@ func linkExistingOmbiDiscordTelegram(app *appContext) error { // app.jf.GetUsers(false) // // noHyphens := true -// for id := range app.storage.emails { +// for id := range app.storage.GetEmails() { // if strings.Contains(id, "-") { // noHyphens = false // break diff --git a/package-lock.json b/package-lock.json index d53ad2c..17ac14d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "any-date-parser": "^1.5.4", "browserslist": "^4.21.7", "cheerio": "^1.0.0-rc.12", - "esbuild": "^0.18.4", + "esbuild": "^0.18.5", "fs-cheerio": "^3.0.0", "inline-source": "^8.0.2", "jsdom": "^22.1.0", @@ -57,9 +57,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.4.tgz", - "integrity": "sha512-yKmQC9IiuvHdsNEbPHSprnMHg6OhL1cSeQZLzPpgzJBJ9ppEg9GAZN8MKj1TcmB4tZZUrq5xjK7KCmhwZP8iDA==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.5.tgz", + "integrity": "sha512-+8GXQzuASxGg/rb47Z5zJe3vjOfL7RRce/DILuk6kbB/8HO0p3CPo72CbR349P2K8YP1h5NvNqU+2GDRbNJylw==", "cpu": [ "arm" ], @@ -72,9 +72,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.4.tgz", - "integrity": "sha512-yQVgO+V307hA2XhzELQ6F91CBGX7gSnlVGAj5YIqjQOxThDpM7fOcHT2YLJbE6gNdPtgRSafQrsK8rJ9xHCaZg==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.5.tgz", + "integrity": "sha512-410IPUj7ZOxZ2dwK0B7o7Nibu7YEyaLBvYOfYBpuA1TpY0fOkDM5r4bwn+hT8Uma06DBI4RnYNN09fn55PYInQ==", "cpu": [ "arm64" ], @@ -87,9 +87,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.4.tgz", - "integrity": "sha512-yLKXMxQg6sk1ntftxQ5uwyVgG4/S2E7UoOCc5N4YZW7fdkfRiYEXqm7CMuIfY2Vs3FTrNyKmSfNevIuIvJnMww==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.5.tgz", + "integrity": "sha512-+fdfceCYwcz9OReheSWYOGaAAt03n0BnG5/UW9tyGyo15PjSOF14ylxfjvz+0atDx0S/RxyezMsH/mbnWhnC8w==", "cpu": [ "x64" ], @@ -102,9 +102,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.4.tgz", - "integrity": "sha512-MVPEoZjZpk2xQ1zckZrb8eQuQib+QCzdmMs3YZAYEQPg+Rztk5pUxGyk8htZOC8Z38NMM29W+MqY9Sqo/sDGKw==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.5.tgz", + "integrity": "sha512-L7noeTaus5xEtgd5J7u/lGrZfSiYkvZb0gOD7rvKTuuWbdGM4bunz5DUFsWBbEIlloslpOO5PDy4Hnd6mZT20A==", "cpu": [ "arm64" ], @@ -117,9 +117,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.4.tgz", - "integrity": "sha512-uEsRtYRUDsz7i2tXg/t/SyF+5gU1cvi9B6B8i5ebJgtUUHJYWyIPIesmIOL4/+bywjxsDMA/XrNFMgMffLnh5A==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.5.tgz", + "integrity": "sha512-eA39B8SxbxRdSSILD4AsePzvJiVao6ZaYrcTOJqg89jnnMEGR/EAh+ehV7E4GOx4WXQoWeJRP1P9JQSzIrROeg==", "cpu": [ "x64" ], @@ -132,9 +132,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.4.tgz", - "integrity": "sha512-I8EOigqWnOHRin6Zp5Y1cfH3oT54bd7Sdz/VnpUNksbOtfp8IWRTH4pgkgO5jWaRQPjCpJcOpdRjYAMjPt8wXg==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.5.tgz", + "integrity": "sha512-Eg1UnkTZHfsphgcy1Wj/McNModSO/F+kqtWqvtvEZc9BAgvdwxAt11BESgBczU+Gti0G2dLvHs0Sfb3gavwhGg==", "cpu": [ "arm64" ], @@ -147,9 +147,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.4.tgz", - "integrity": "sha512-1bHfgMz/cNMjbpsYxjVgMJ1iwKq+NdDPlACBrWULD7ZdFmBQrhMicMaKb5CdmdVyvIwXmasOuF4r6Iq574kUTA==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.5.tgz", + "integrity": "sha512-GNTMSJ55gl7Tf5VUqVRkMJhRGzH6vI9vFBfZCj4Zjm7RgfXCWxLnTyjMgZZKT8pOzW40KD2KlrGbqwnnJWyGWw==", "cpu": [ "x64" ], @@ -162,9 +162,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.4.tgz", - "integrity": "sha512-4XCGqM/Ay1LCXUBH59bL4JbSbbTK1K22dWHymWMGaEh2sQCDOUw+OQxozYV/YdBb91leK2NbuSrE2BRamwgaYw==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.5.tgz", + "integrity": "sha512-6R+vEIyfEvp+gOWKSc+m6hdnhWKQYzicqONQYiDGT6qepc6OGsLEZcyFwoz6BvFx5j233CBWMcJ69eXFrwXw9A==", "cpu": [ "arm" ], @@ -177,9 +177,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.4.tgz", - "integrity": "sha512-J42vLHaYREyiBwH0eQE4/7H1DTfZx8FuxyWSictx4d7ezzuKE3XOkIvOg+SQzRz7T9HLVKzq2tvbAov4UfufBw==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.5.tgz", + "integrity": "sha512-r08LmhqyPRj6FtuNPBTu8BliKh6h+oNEhMkWmmR/aWs4DWjDOivyDfLGznPdgtSThL23fk1QgSBUEbuCIzjA2A==", "cpu": [ "arm64" ], @@ -192,9 +192,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.4.tgz", - "integrity": "sha512-4ksIqFwhq7OExty7Sl1n0vqQSCqTG4sU6i99G2yuMr28CEOUZ/60N+IO9hwI8sIxBqmKmDgncE1n5CMu/3m0IA==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.5.tgz", + "integrity": "sha512-ph6M9iEMc6BHgv2XuIE8qeQrQCH+2l116c8L9ysmmXYwpNXa3E7JNIu/O7hI0I9qDvh1P19AGbIh+/y0GAZijA==", "cpu": [ "ia32" ], @@ -207,9 +207,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.4.tgz", - "integrity": "sha512-bsWtoVHkGQgAsFXioDueXRiUIfSGrVkJjBBz4gcBJxXcD461cWFQFyu8Fxdj9TP+zEeqJ8C/O4LFFMBNi6Fscw==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.5.tgz", + "integrity": "sha512-s6Nup5FMQ8R8OKJG2rSxtV40s8LRdfC73XGHGaFlGiC+2SeCyq4dl3MMfLdzLowYzyDjfc4GRrXWUNMX3kNxYA==", "cpu": [ "loong64" ], @@ -222,9 +222,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.4.tgz", - "integrity": "sha512-LRD9Fu8wJQgIOOV1o3nRyzrheFYjxA0C1IVWZ93eNRRWBKgarYFejd5WBtrp43cE4y4D4t3qWWyklm73Mrsd/g==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.5.tgz", + "integrity": "sha512-DxW4nNDIGbivZxnJD01C5PlwKPpin8YgSwWtToCy4w4lNigT7Iaf5A+wcPT2laibdgbcgPKpPOXUg6RFGTt8xA==", "cpu": [ "mips64el" ], @@ -237,9 +237,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.4.tgz", - "integrity": "sha512-jtQgoZjM92gauVRxNaaG/TpL3Pr4WcL3Pwqi9QgdrBGrEXzB+twohQiWNSTycs6lUygakos4mm2h0B9/SHveng==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.5.tgz", + "integrity": "sha512-BksOs2uYTafS+u75QiN4RoLbEMNjE192adJCBalncI3E2PWyR2i1kEs9rEghHK7pw0SD0uWgV9otRmV7G5b2lQ==", "cpu": [ "ppc64" ], @@ -252,9 +252,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.4.tgz", - "integrity": "sha512-7WaU/kRZG0VCV09Xdlkg6LNAsfU9SAxo6XEdaZ8ffO4lh+DZoAhGTx7+vTMOXKxa+r2w1LYDGxfJa2rcgagMRA==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.5.tgz", + "integrity": "sha512-mGv8BOJXsV7bZyjyMdeDs55CDXZ5vrY3oKa58DNRz2vPn54dREyj4BhhyWuqSuzSURJhFg7pM/1fI2vnAHGkHw==", "cpu": [ "riscv64" ], @@ -267,9 +267,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.4.tgz", - "integrity": "sha512-D19ed0xreKQvC5t+ArE2njSnm18WPpE+1fhwaiJHf+Xwqsq+/SUaV8Mx0M27nszdU+Atq1HahrgCOZCNNEASUg==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.5.tgz", + "integrity": "sha512-m4uIYyrl5znGnNHgiM/Zsw6I9Se513NqdTxeUxZ66/VDWbuUp8ACe1KOSpwF4NNxfYy6Q3W8beZsIdF4F85q8Q==", "cpu": [ "s390x" ], @@ -282,9 +282,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.4.tgz", - "integrity": "sha512-Rx3AY1sxyiO/gvCGP00nL69L60dfmWyjKWY06ugpB8Ydpdsfi3BHW58HWC24K3CAjAPSwxcajozC2PzA9JBS1g==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.5.tgz", + "integrity": "sha512-R1C7X30YjXmOZYOzx4dJ/QvRNfrkK/sDCFfcGNhlHFX6B/iodJdk81h7EhnKVUQy+3BaARxF7udd91iSSzMlbQ==", "cpu": [ "x64" ], @@ -297,9 +297,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.4.tgz", - "integrity": "sha512-AaShPmN9c6w1mKRpliKFlaWcSkpBT4KOlk93UfFgeI3F3cbjzdDKGsbKnOZozmYbE1izZKLmNJiW0sFM+A5JPA==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.5.tgz", + "integrity": "sha512-MABnKzjMcXjO0NEYyexOhqjcrgM6dE8BXnm+lctm2x2aPpYg5iL0Ew3aABSTZyp9dS3Z4VzFu5PPoOYEw8akTQ==", "cpu": [ "x64" ], @@ -312,9 +312,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.4.tgz", - "integrity": "sha512-tRGvGwou3BrvHVvF8HxTqEiC5VtPzySudS9fh2jBIKpLX7HCW8jIkW+LunkFDNwhslx4xMAgh0jAHsx/iCymaQ==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.5.tgz", + "integrity": "sha512-aU7R0tLIUMaQuAgBjKrq02Z98rcY9Pxk76hynSqcGeld2C/ro1uBbS2i9rh7vdwBAY0rG08Og4wnDnlx5rU+fQ==", "cpu": [ "x64" ], @@ -327,9 +327,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.4.tgz", - "integrity": "sha512-acORFDI95GKhmAnlH8EarBeuqoy/j3yxIU+FDB91H3+ZON+8HhTadtT450YkaMzX6lEWbhi+mjVUCj00M5yyOQ==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.5.tgz", + "integrity": "sha512-ngm3fVv2VxufI8zH/Phk0mYkgvFjFGnS+l7uxxd20mmeLTNI/8OXDJpNqTUbvzJh3tqhI/Gof0N2+5xJbqEaxA==", "cpu": [ "x64" ], @@ -342,9 +342,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.4.tgz", - "integrity": "sha512-1NxP+iOk8KSvS1L9SSxEvBAJk39U0GiGZkiiJGbuDF9G4fG7DSDw6XLxZMecAgmvQrwwx7yVKdNN3GgNh0UfKg==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.5.tgz", + "integrity": "sha512-XqpS89+MGLzR8YtQQkBYsLCfAv1ySflMb+FEH99rOp6kOPv/ORO+ujEB5ICDBZZbvYqB75uFrNELo1BVEQbS3g==", "cpu": [ "arm64" ], @@ -357,9 +357,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.4.tgz", - "integrity": "sha512-OKr8jze93vbgqZ/r23woWciTixUwLa976C9W7yNBujtnVHyvsL/ocYG61tsktUfJOpyIz5TsohkBZ6Lo2+PCcQ==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.5.tgz", + "integrity": "sha512-V3xj/nb9uie0I4mn1f8nPZSgHldtNJrqTKYjTyMPMBnHbMYF5Loz8ZHsp7+La8kI6NxIF1ClQ9XBV+G3RtSkww==", "cpu": [ "ia32" ], @@ -372,9 +372,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.4.tgz", - "integrity": "sha512-qJr3wVvcLjPFcV4AMDS3iquhBfTef2zo/jlm8RMxmiRp3Vy2HY8WMxrykJlcbCnqLXZPA0YZxZGND6eug85ogg==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.5.tgz", + "integrity": "sha512-gMxWvQeTQWDpa8ExPP41al+Ho7HyK24h7y41JdGKqE24KzXXQPxESUtrCoIES+HwF+OGq2smtibU9UvZ8WH3JQ==", "cpu": [ "x64" ], @@ -1647,9 +1647,9 @@ } }, "node_modules/esbuild": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.4.tgz", - "integrity": "sha512-9rxWV/Cb2DMUXfe9aUsYtqg0KTlw146ElFH22kYeK9KVV1qT082X4lpmiKsa12ePiCcIcB686TQJxaGAa9TFvA==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.5.tgz", + "integrity": "sha512-ztF1Z53Mc8ijEo1ZWFduHZXIqRWufo76JHm1ikvhGjIzO1mj84LdKXSGmRzahfgvWSwky48MkT+o5yUIkQtDPA==", "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -1658,28 +1658,28 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.18.4", - "@esbuild/android-arm64": "0.18.4", - "@esbuild/android-x64": "0.18.4", - "@esbuild/darwin-arm64": "0.18.4", - "@esbuild/darwin-x64": "0.18.4", - "@esbuild/freebsd-arm64": "0.18.4", - "@esbuild/freebsd-x64": "0.18.4", - "@esbuild/linux-arm": "0.18.4", - "@esbuild/linux-arm64": "0.18.4", - "@esbuild/linux-ia32": "0.18.4", - "@esbuild/linux-loong64": "0.18.4", - "@esbuild/linux-mips64el": "0.18.4", - "@esbuild/linux-ppc64": "0.18.4", - "@esbuild/linux-riscv64": "0.18.4", - "@esbuild/linux-s390x": "0.18.4", - "@esbuild/linux-x64": "0.18.4", - "@esbuild/netbsd-x64": "0.18.4", - "@esbuild/openbsd-x64": "0.18.4", - "@esbuild/sunos-x64": "0.18.4", - "@esbuild/win32-arm64": "0.18.4", - "@esbuild/win32-ia32": "0.18.4", - "@esbuild/win32-x64": "0.18.4" + "@esbuild/android-arm": "0.18.5", + "@esbuild/android-arm64": "0.18.5", + "@esbuild/android-x64": "0.18.5", + "@esbuild/darwin-arm64": "0.18.5", + "@esbuild/darwin-x64": "0.18.5", + "@esbuild/freebsd-arm64": "0.18.5", + "@esbuild/freebsd-x64": "0.18.5", + "@esbuild/linux-arm": "0.18.5", + "@esbuild/linux-arm64": "0.18.5", + "@esbuild/linux-ia32": "0.18.5", + "@esbuild/linux-loong64": "0.18.5", + "@esbuild/linux-mips64el": "0.18.5", + "@esbuild/linux-ppc64": "0.18.5", + "@esbuild/linux-riscv64": "0.18.5", + "@esbuild/linux-s390x": "0.18.5", + "@esbuild/linux-x64": "0.18.5", + "@esbuild/netbsd-x64": "0.18.5", + "@esbuild/openbsd-x64": "0.18.5", + "@esbuild/sunos-x64": "0.18.5", + "@esbuild/win32-arm64": "0.18.5", + "@esbuild/win32-ia32": "0.18.5", + "@esbuild/win32-x64": "0.18.5" } }, "node_modules/escalade": { @@ -6797,135 +6797,135 @@ } }, "@esbuild/android-arm": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.4.tgz", - "integrity": "sha512-yKmQC9IiuvHdsNEbPHSprnMHg6OhL1cSeQZLzPpgzJBJ9ppEg9GAZN8MKj1TcmB4tZZUrq5xjK7KCmhwZP8iDA==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.5.tgz", + "integrity": "sha512-+8GXQzuASxGg/rb47Z5zJe3vjOfL7RRce/DILuk6kbB/8HO0p3CPo72CbR349P2K8YP1h5NvNqU+2GDRbNJylw==", "optional": true }, "@esbuild/android-arm64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.4.tgz", - "integrity": "sha512-yQVgO+V307hA2XhzELQ6F91CBGX7gSnlVGAj5YIqjQOxThDpM7fOcHT2YLJbE6gNdPtgRSafQrsK8rJ9xHCaZg==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.5.tgz", + "integrity": "sha512-410IPUj7ZOxZ2dwK0B7o7Nibu7YEyaLBvYOfYBpuA1TpY0fOkDM5r4bwn+hT8Uma06DBI4RnYNN09fn55PYInQ==", "optional": true }, "@esbuild/android-x64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.4.tgz", - "integrity": "sha512-yLKXMxQg6sk1ntftxQ5uwyVgG4/S2E7UoOCc5N4YZW7fdkfRiYEXqm7CMuIfY2Vs3FTrNyKmSfNevIuIvJnMww==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.5.tgz", + "integrity": "sha512-+fdfceCYwcz9OReheSWYOGaAAt03n0BnG5/UW9tyGyo15PjSOF14ylxfjvz+0atDx0S/RxyezMsH/mbnWhnC8w==", "optional": true }, "@esbuild/darwin-arm64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.4.tgz", - "integrity": "sha512-MVPEoZjZpk2xQ1zckZrb8eQuQib+QCzdmMs3YZAYEQPg+Rztk5pUxGyk8htZOC8Z38NMM29W+MqY9Sqo/sDGKw==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.5.tgz", + "integrity": "sha512-L7noeTaus5xEtgd5J7u/lGrZfSiYkvZb0gOD7rvKTuuWbdGM4bunz5DUFsWBbEIlloslpOO5PDy4Hnd6mZT20A==", "optional": true }, "@esbuild/darwin-x64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.4.tgz", - "integrity": "sha512-uEsRtYRUDsz7i2tXg/t/SyF+5gU1cvi9B6B8i5ebJgtUUHJYWyIPIesmIOL4/+bywjxsDMA/XrNFMgMffLnh5A==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.5.tgz", + "integrity": "sha512-eA39B8SxbxRdSSILD4AsePzvJiVao6ZaYrcTOJqg89jnnMEGR/EAh+ehV7E4GOx4WXQoWeJRP1P9JQSzIrROeg==", "optional": true }, "@esbuild/freebsd-arm64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.4.tgz", - "integrity": "sha512-I8EOigqWnOHRin6Zp5Y1cfH3oT54bd7Sdz/VnpUNksbOtfp8IWRTH4pgkgO5jWaRQPjCpJcOpdRjYAMjPt8wXg==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.5.tgz", + "integrity": "sha512-Eg1UnkTZHfsphgcy1Wj/McNModSO/F+kqtWqvtvEZc9BAgvdwxAt11BESgBczU+Gti0G2dLvHs0Sfb3gavwhGg==", "optional": true }, "@esbuild/freebsd-x64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.4.tgz", - "integrity": "sha512-1bHfgMz/cNMjbpsYxjVgMJ1iwKq+NdDPlACBrWULD7ZdFmBQrhMicMaKb5CdmdVyvIwXmasOuF4r6Iq574kUTA==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.5.tgz", + "integrity": "sha512-GNTMSJ55gl7Tf5VUqVRkMJhRGzH6vI9vFBfZCj4Zjm7RgfXCWxLnTyjMgZZKT8pOzW40KD2KlrGbqwnnJWyGWw==", "optional": true }, "@esbuild/linux-arm": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.4.tgz", - "integrity": "sha512-4XCGqM/Ay1LCXUBH59bL4JbSbbTK1K22dWHymWMGaEh2sQCDOUw+OQxozYV/YdBb91leK2NbuSrE2BRamwgaYw==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.5.tgz", + "integrity": "sha512-6R+vEIyfEvp+gOWKSc+m6hdnhWKQYzicqONQYiDGT6qepc6OGsLEZcyFwoz6BvFx5j233CBWMcJ69eXFrwXw9A==", "optional": true }, "@esbuild/linux-arm64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.4.tgz", - "integrity": "sha512-J42vLHaYREyiBwH0eQE4/7H1DTfZx8FuxyWSictx4d7ezzuKE3XOkIvOg+SQzRz7T9HLVKzq2tvbAov4UfufBw==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.5.tgz", + "integrity": "sha512-r08LmhqyPRj6FtuNPBTu8BliKh6h+oNEhMkWmmR/aWs4DWjDOivyDfLGznPdgtSThL23fk1QgSBUEbuCIzjA2A==", "optional": true }, "@esbuild/linux-ia32": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.4.tgz", - "integrity": "sha512-4ksIqFwhq7OExty7Sl1n0vqQSCqTG4sU6i99G2yuMr28CEOUZ/60N+IO9hwI8sIxBqmKmDgncE1n5CMu/3m0IA==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.5.tgz", + "integrity": "sha512-ph6M9iEMc6BHgv2XuIE8qeQrQCH+2l116c8L9ysmmXYwpNXa3E7JNIu/O7hI0I9qDvh1P19AGbIh+/y0GAZijA==", "optional": true }, "@esbuild/linux-loong64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.4.tgz", - "integrity": "sha512-bsWtoVHkGQgAsFXioDueXRiUIfSGrVkJjBBz4gcBJxXcD461cWFQFyu8Fxdj9TP+zEeqJ8C/O4LFFMBNi6Fscw==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.5.tgz", + "integrity": "sha512-s6Nup5FMQ8R8OKJG2rSxtV40s8LRdfC73XGHGaFlGiC+2SeCyq4dl3MMfLdzLowYzyDjfc4GRrXWUNMX3kNxYA==", "optional": true }, "@esbuild/linux-mips64el": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.4.tgz", - "integrity": "sha512-LRD9Fu8wJQgIOOV1o3nRyzrheFYjxA0C1IVWZ93eNRRWBKgarYFejd5WBtrp43cE4y4D4t3qWWyklm73Mrsd/g==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.5.tgz", + "integrity": "sha512-DxW4nNDIGbivZxnJD01C5PlwKPpin8YgSwWtToCy4w4lNigT7Iaf5A+wcPT2laibdgbcgPKpPOXUg6RFGTt8xA==", "optional": true }, "@esbuild/linux-ppc64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.4.tgz", - "integrity": "sha512-jtQgoZjM92gauVRxNaaG/TpL3Pr4WcL3Pwqi9QgdrBGrEXzB+twohQiWNSTycs6lUygakos4mm2h0B9/SHveng==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.5.tgz", + "integrity": "sha512-BksOs2uYTafS+u75QiN4RoLbEMNjE192adJCBalncI3E2PWyR2i1kEs9rEghHK7pw0SD0uWgV9otRmV7G5b2lQ==", "optional": true }, "@esbuild/linux-riscv64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.4.tgz", - "integrity": "sha512-7WaU/kRZG0VCV09Xdlkg6LNAsfU9SAxo6XEdaZ8ffO4lh+DZoAhGTx7+vTMOXKxa+r2w1LYDGxfJa2rcgagMRA==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.5.tgz", + "integrity": "sha512-mGv8BOJXsV7bZyjyMdeDs55CDXZ5vrY3oKa58DNRz2vPn54dREyj4BhhyWuqSuzSURJhFg7pM/1fI2vnAHGkHw==", "optional": true }, "@esbuild/linux-s390x": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.4.tgz", - "integrity": "sha512-D19ed0xreKQvC5t+ArE2njSnm18WPpE+1fhwaiJHf+Xwqsq+/SUaV8Mx0M27nszdU+Atq1HahrgCOZCNNEASUg==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.5.tgz", + "integrity": "sha512-m4uIYyrl5znGnNHgiM/Zsw6I9Se513NqdTxeUxZ66/VDWbuUp8ACe1KOSpwF4NNxfYy6Q3W8beZsIdF4F85q8Q==", "optional": true }, "@esbuild/linux-x64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.4.tgz", - "integrity": "sha512-Rx3AY1sxyiO/gvCGP00nL69L60dfmWyjKWY06ugpB8Ydpdsfi3BHW58HWC24K3CAjAPSwxcajozC2PzA9JBS1g==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.5.tgz", + "integrity": "sha512-R1C7X30YjXmOZYOzx4dJ/QvRNfrkK/sDCFfcGNhlHFX6B/iodJdk81h7EhnKVUQy+3BaARxF7udd91iSSzMlbQ==", "optional": true }, "@esbuild/netbsd-x64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.4.tgz", - "integrity": "sha512-AaShPmN9c6w1mKRpliKFlaWcSkpBT4KOlk93UfFgeI3F3cbjzdDKGsbKnOZozmYbE1izZKLmNJiW0sFM+A5JPA==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.5.tgz", + "integrity": "sha512-MABnKzjMcXjO0NEYyexOhqjcrgM6dE8BXnm+lctm2x2aPpYg5iL0Ew3aABSTZyp9dS3Z4VzFu5PPoOYEw8akTQ==", "optional": true }, "@esbuild/openbsd-x64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.4.tgz", - "integrity": "sha512-tRGvGwou3BrvHVvF8HxTqEiC5VtPzySudS9fh2jBIKpLX7HCW8jIkW+LunkFDNwhslx4xMAgh0jAHsx/iCymaQ==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.5.tgz", + "integrity": "sha512-aU7R0tLIUMaQuAgBjKrq02Z98rcY9Pxk76hynSqcGeld2C/ro1uBbS2i9rh7vdwBAY0rG08Og4wnDnlx5rU+fQ==", "optional": true }, "@esbuild/sunos-x64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.4.tgz", - "integrity": "sha512-acORFDI95GKhmAnlH8EarBeuqoy/j3yxIU+FDB91H3+ZON+8HhTadtT450YkaMzX6lEWbhi+mjVUCj00M5yyOQ==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.5.tgz", + "integrity": "sha512-ngm3fVv2VxufI8zH/Phk0mYkgvFjFGnS+l7uxxd20mmeLTNI/8OXDJpNqTUbvzJh3tqhI/Gof0N2+5xJbqEaxA==", "optional": true }, "@esbuild/win32-arm64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.4.tgz", - "integrity": "sha512-1NxP+iOk8KSvS1L9SSxEvBAJk39U0GiGZkiiJGbuDF9G4fG7DSDw6XLxZMecAgmvQrwwx7yVKdNN3GgNh0UfKg==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.5.tgz", + "integrity": "sha512-XqpS89+MGLzR8YtQQkBYsLCfAv1ySflMb+FEH99rOp6kOPv/ORO+ujEB5ICDBZZbvYqB75uFrNELo1BVEQbS3g==", "optional": true }, "@esbuild/win32-ia32": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.4.tgz", - "integrity": "sha512-OKr8jze93vbgqZ/r23woWciTixUwLa976C9W7yNBujtnVHyvsL/ocYG61tsktUfJOpyIz5TsohkBZ6Lo2+PCcQ==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.5.tgz", + "integrity": "sha512-V3xj/nb9uie0I4mn1f8nPZSgHldtNJrqTKYjTyMPMBnHbMYF5Loz8ZHsp7+La8kI6NxIF1ClQ9XBV+G3RtSkww==", "optional": true }, "@esbuild/win32-x64": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.4.tgz", - "integrity": "sha512-qJr3wVvcLjPFcV4AMDS3iquhBfTef2zo/jlm8RMxmiRp3Vy2HY8WMxrykJlcbCnqLXZPA0YZxZGND6eug85ogg==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.5.tgz", + "integrity": "sha512-gMxWvQeTQWDpa8ExPP41al+Ho7HyK24h7y41JdGKqE24KzXXQPxESUtrCoIES+HwF+OGq2smtibU9UvZ8WH3JQ==", "optional": true }, "@jridgewell/gen-mapping": { @@ -7896,32 +7896,32 @@ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" }, "esbuild": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.4.tgz", - "integrity": "sha512-9rxWV/Cb2DMUXfe9aUsYtqg0KTlw146ElFH22kYeK9KVV1qT082X4lpmiKsa12ePiCcIcB686TQJxaGAa9TFvA==", + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.5.tgz", + "integrity": "sha512-ztF1Z53Mc8ijEo1ZWFduHZXIqRWufo76JHm1ikvhGjIzO1mj84LdKXSGmRzahfgvWSwky48MkT+o5yUIkQtDPA==", "requires": { - "@esbuild/android-arm": "0.18.4", - "@esbuild/android-arm64": "0.18.4", - "@esbuild/android-x64": "0.18.4", - "@esbuild/darwin-arm64": "0.18.4", - "@esbuild/darwin-x64": "0.18.4", - "@esbuild/freebsd-arm64": "0.18.4", - "@esbuild/freebsd-x64": "0.18.4", - "@esbuild/linux-arm": "0.18.4", - "@esbuild/linux-arm64": "0.18.4", - "@esbuild/linux-ia32": "0.18.4", - "@esbuild/linux-loong64": "0.18.4", - "@esbuild/linux-mips64el": "0.18.4", - "@esbuild/linux-ppc64": "0.18.4", - "@esbuild/linux-riscv64": "0.18.4", - "@esbuild/linux-s390x": "0.18.4", - "@esbuild/linux-x64": "0.18.4", - "@esbuild/netbsd-x64": "0.18.4", - "@esbuild/openbsd-x64": "0.18.4", - "@esbuild/sunos-x64": "0.18.4", - "@esbuild/win32-arm64": "0.18.4", - "@esbuild/win32-ia32": "0.18.4", - "@esbuild/win32-x64": "0.18.4" + "@esbuild/android-arm": "0.18.5", + "@esbuild/android-arm64": "0.18.5", + "@esbuild/android-x64": "0.18.5", + "@esbuild/darwin-arm64": "0.18.5", + "@esbuild/darwin-x64": "0.18.5", + "@esbuild/freebsd-arm64": "0.18.5", + "@esbuild/freebsd-x64": "0.18.5", + "@esbuild/linux-arm": "0.18.5", + "@esbuild/linux-arm64": "0.18.5", + "@esbuild/linux-ia32": "0.18.5", + "@esbuild/linux-loong64": "0.18.5", + "@esbuild/linux-mips64el": "0.18.5", + "@esbuild/linux-ppc64": "0.18.5", + "@esbuild/linux-riscv64": "0.18.5", + "@esbuild/linux-s390x": "0.18.5", + "@esbuild/linux-x64": "0.18.5", + "@esbuild/netbsd-x64": "0.18.5", + "@esbuild/openbsd-x64": "0.18.5", + "@esbuild/sunos-x64": "0.18.5", + "@esbuild/win32-arm64": "0.18.5", + "@esbuild/win32-ia32": "0.18.5", + "@esbuild/win32-x64": "0.18.5" } }, "escalade": { diff --git a/package.json b/package.json index 3aa5eab..b2b0747 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "any-date-parser": "^1.5.4", "browserslist": "^4.21.7", "cheerio": "^1.0.0-rc.12", - "esbuild": "^0.18.4", + "esbuild": "^0.18.5", "fs-cheerio": "^3.0.0", "inline-source": "^8.0.2", "jsdom": "^22.1.0", diff --git a/storage.go b/storage.go index 38d76c7..605516e 100644 --- a/storage.go +++ b/storage.go @@ -15,6 +15,11 @@ import ( "github.com/steambap/captcha" ) +type discordStore map[string]DiscordUser +type telegramStore map[string]TelegramUser +type matrixStore map[string]MatrixUser +type emailStore map[string]EmailAddress + type Storage struct { timePattern string invite_path, emails_path, policy_path, configuration_path, displayprefs_path, ombi_path, profiles_path, customEmails_path, users_path, telegram_path, discord_path, matrix_path, announcements_path, matrix_sql_path string @@ -23,16 +28,120 @@ type Storage struct { profiles map[string]Profile defaultProfile string displayprefs, ombi_template map[string]interface{} - emails map[string]EmailAddress - telegram map[string]TelegramUser // Map of Jellyfin User IDs to telegram users. - discord map[string]DiscordUser // Map of Jellyfin user IDs to discord users. - matrix map[string]MatrixUser // Map of Jellyfin user IDs to Matrix users. + emails emailStore + telegram telegramStore // Map of Jellyfin User IDs to telegram users. + discord discordStore // Map of Jellyfin user IDs to discord users. + matrix matrixStore // Map of Jellyfin user IDs to Matrix users. customEmails customEmails policy mediabrowser.Policy configuration mediabrowser.Configuration lang Lang announcements map[string]announcementTemplate - invitesLock, usersLock sync.Mutex + invitesLock, usersLock, discordLock, telegramLock, matrixLock, emailsLock sync.Mutex +} + +// GetEmails returns a copy of the store. +func (st *Storage) GetEmails() emailStore { + return st.emails +} + +// GetEmailsKey returns the value stored in the store's key. +func (st *Storage) GetEmailsKey(k string) (EmailAddress, bool) { + v, ok := st.emails[k] + return v, ok +} + +// SetEmailsKey stores value v in key k. +func (st *Storage) SetEmailsKey(k string, v EmailAddress) { + st.emailsLock.Lock() + st.emails[k] = v + st.storeEmails() + st.emailsLock.Unlock() +} + +// DeleteEmailKey deletes value at key k. +func (st *Storage) DeleteEmailsKey(k string) { + st.emailsLock.Lock() + delete(st.emails, k) + st.emailsLock.Unlock() +} + +// GetDiscord returns a copy of the store. +func (st *Storage) GetDiscord() discordStore { + return st.discord +} + +// GetDiscordKey returns the value stored in the store's key. +func (st *Storage) GetDiscordKey(k string) (DiscordUser, bool) { + v, ok := st.discord[k] + return v, ok +} + +// SetDiscordKey stores value v in key k. +func (st *Storage) SetDiscordKey(k string, v DiscordUser) { + st.discordLock.Lock() + st.discord[k] = v + st.storeDiscordUsers() + st.discordLock.Unlock() +} + +// DeleteDiscordKey deletes value at key k. +func (st *Storage) DeleteDiscordKey(k string) { + st.discordLock.Lock() + delete(st.discord, k) + st.discordLock.Unlock() +} + +// GetTelegram returns a copy of the store. +func (st *Storage) GetTelegram() telegramStore { + return st.telegram +} + +// GetTelegramKey returns the value stored in the store's key. +func (st *Storage) GetTelegramKey(k string) (TelegramUser, bool) { + v, ok := st.telegram[k] + return v, ok +} + +// SetTelegramKey stores value v in key k. +func (st *Storage) SetTelegramKey(k string, v TelegramUser) { + st.telegramLock.Lock() + st.telegram[k] = v + st.storeTelegramUsers() + st.telegramLock.Unlock() +} + +// DeleteTelegramKey deletes value at key k. +func (st *Storage) DeleteTelegramKey(k string) { + st.telegramLock.Lock() + delete(st.telegram, k) + st.telegramLock.Unlock() +} + +// GetMatrix returns a copy of the store. +func (st *Storage) GetMatrix() matrixStore { + return st.matrix +} + +// GetMatrixKey returns the value stored in the store's key. +func (st *Storage) GetMatrixKey(k string) (MatrixUser, bool) { + v, ok := st.matrix[k] + return v, ok +} + +// SetMatrixKey stores value v in key k. +func (st *Storage) SetMatrixKey(k string, v MatrixUser) { + st.matrixLock.Lock() + st.matrix[k] = v + st.storeMatrixUsers() + st.matrixLock.Unlock() +} + +// DeleteMatrixKey deletes value at key k. +func (st *Storage) DeleteMatrixKey(k string) { + st.matrixLock.Lock() + delete(st.matrix, k) + st.matrixLock.Unlock() } type TelegramUser struct { diff --git a/telegram.go b/telegram.go index 654d05b..288d95d 100644 --- a/telegram.go +++ b/telegram.go @@ -46,7 +46,7 @@ func newTelegramDaemon(app *appContext) (*TelegramDaemon, error) { link: "https://t.me/" + bot.Self.UserName, app: app, } - for _, user := range app.storage.telegram { + for _, user := range app.storage.GetTelegram() { if user.Lang != "" { td.languages[user.ChatID] = user.Lang } @@ -198,10 +198,10 @@ func (t *TelegramDaemon) commandLang(upd *tg.Update, sects []string, lang string } if _, ok := t.app.storage.lang.Telegram[sects[1]]; ok { t.languages[upd.Message.Chat.ID] = sects[1] - for jfID, user := range t.app.storage.telegram { + for jfID, user := range t.app.storage.GetTelegram() { if user.ChatID == upd.Message.Chat.ID { user.Lang = sects[1] - t.app.storage.telegram[jfID] = user + t.app.storage.SetTelegramKey(jfID, user) if err := t.app.storage.storeTelegramUsers(); err != nil { t.app.err.Printf("Failed to store Telegram users: %v", err) }