mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-22 09:00:10 +00:00
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.
This commit is contained in:
parent
fcedea110d
commit
68004e1d34
@ -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 {
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
}
|
||||
|
47
api-users.go
47
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 {
|
||||
|
2
auth.go
2
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)
|
||||
|
24
daemon.go
24
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
|
||||
|
16
discord.go
16
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
|
||||
}
|
||||
|
14
email.go
14
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 ""
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
366
package-lock.json
generated
366
package-lock.json
generated
@ -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": {
|
||||
|
@ -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",
|
||||
|
119
storage.go
119
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 {
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user