mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-22 09:00:10 +00:00
Invites: unique email/ID requirement
"Require unique ..." Settings (`require_unique` in relevant sections of config.ini) are now available for email/discord/telegram/matrix. An error is shown on the invite form if a non-unique address/ID is used. This was on my kanban without a link to an issue, so i'm guessing it was requested on Discord.
This commit is contained in:
parent
895dcf5a30
commit
2722e8482d
@ -453,6 +453,14 @@ func (app *appContext) TelegramVerifiedInvite(gc *gin.Context) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if app.config.Section("telegram").Key("require_unique").MustBool(false) {
|
||||||
|
for _, u := range app.storage.telegram {
|
||||||
|
if app.telegram.verifiedTokens[tokenIndex].Username == u.Username {
|
||||||
|
respondBool(400, false, gc)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// if tokenIndex != -1 {
|
// if tokenIndex != -1 {
|
||||||
// length := len(app.telegram.verifiedTokens)
|
// length := len(app.telegram.verifiedTokens)
|
||||||
// app.telegram.verifiedTokens[length-1], app.telegram.verifiedTokens[tokenIndex] = app.telegram.verifiedTokens[tokenIndex], app.telegram.verifiedTokens[length-1]
|
// app.telegram.verifiedTokens[length-1], app.telegram.verifiedTokens[tokenIndex] = app.telegram.verifiedTokens[tokenIndex], app.telegram.verifiedTokens[length-1]
|
||||||
@ -477,6 +485,15 @@ func (app *appContext) DiscordVerifiedInvite(gc *gin.Context) {
|
|||||||
}
|
}
|
||||||
pin := gc.Param("pin")
|
pin := gc.Param("pin")
|
||||||
_, ok := app.discord.verifiedTokens[pin]
|
_, ok := app.discord.verifiedTokens[pin]
|
||||||
|
if app.config.Section("discord").Key("require_unique").MustBool(false) {
|
||||||
|
for _, u := range app.storage.discord {
|
||||||
|
if app.discord.verifiedTokens[pin].ID == u.ID {
|
||||||
|
delete(app.discord.verifiedTokens, pin)
|
||||||
|
respondBool(400, false, gc)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
respondBool(200, ok, gc)
|
respondBool(200, ok, gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,7 +527,7 @@ func (app *appContext) DiscordServerInvite(gc *gin.Context) {
|
|||||||
// @Summary Generate and send a new PIN to a specified Matrix user.
|
// @Summary Generate and send a new PIN to a specified Matrix user.
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} boolResponse
|
// @Success 200 {object} boolResponse
|
||||||
// @Failure 400 {object} boolResponse
|
// @Failure 400 {object} stringResponse
|
||||||
// @Failure 401 {object} boolResponse
|
// @Failure 401 {object} boolResponse
|
||||||
// @Failure 500 {object} boolResponse
|
// @Failure 500 {object} boolResponse
|
||||||
// @Param invCode path string true "invite Code"
|
// @Param invCode path string true "invite Code"
|
||||||
@ -526,9 +543,18 @@ func (app *appContext) MatrixSendPIN(gc *gin.Context) {
|
|||||||
var req MatrixSendPINDTO
|
var req MatrixSendPINDTO
|
||||||
gc.BindJSON(&req)
|
gc.BindJSON(&req)
|
||||||
if req.UserID == "" {
|
if req.UserID == "" {
|
||||||
respondBool(400, false, gc)
|
respond(400, "errorNoUserID", gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if app.config.Section("matrix").Key("require_unique").MustBool(false) {
|
||||||
|
for _, u := range app.storage.matrix {
|
||||||
|
if req.UserID == u.UserID {
|
||||||
|
respondBool(400, false, gc)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ok := app.matrix.SendStart(req.UserID)
|
ok := app.matrix.SendStart(req.UserID)
|
||||||
if !ok {
|
if !ok {
|
||||||
respondBool(500, false, gc)
|
respondBool(500, false, gc)
|
||||||
|
55
api-users.go
55
api-users.go
@ -130,6 +130,18 @@ func (app *appContext) newUser(req newUserDTO, confirmed bool) (f errorFunc, suc
|
|||||||
success = false
|
success = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if app.config.Section("discord").Key("require_unique").MustBool(false) {
|
||||||
|
for _, u := range app.storage.discord {
|
||||||
|
if discordUser.ID == u.ID {
|
||||||
|
f = func(gc *gin.Context) {
|
||||||
|
app.debug.Printf("%s: New user failed: Discord user already linked", req.Code)
|
||||||
|
respond(400, "errorAccountLinked", gc)
|
||||||
|
}
|
||||||
|
success = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
err := app.discord.ApplyRole(discordUser.ID)
|
err := app.discord.ApplyRole(discordUser.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f = func(gc *gin.Context) {
|
f = func(gc *gin.Context) {
|
||||||
@ -164,6 +176,18 @@ func (app *appContext) newUser(req newUserDTO, confirmed bool) (f errorFunc, suc
|
|||||||
success = false
|
success = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if app.config.Section("matrix").Key("require_unique").MustBool(false) {
|
||||||
|
for _, u := range app.storage.matrix {
|
||||||
|
if user.User.UserID == u.UserID {
|
||||||
|
f = func(gc *gin.Context) {
|
||||||
|
app.debug.Printf("%s: New user failed: Matrix user already linked", req.Code)
|
||||||
|
respond(400, "errorAccountLinked", gc)
|
||||||
|
}
|
||||||
|
success = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
matrixVerified = user.Verified
|
matrixVerified = user.Verified
|
||||||
matrixUser = *user.User
|
matrixUser = *user.User
|
||||||
|
|
||||||
@ -195,6 +219,18 @@ func (app *appContext) newUser(req newUserDTO, confirmed bool) (f errorFunc, suc
|
|||||||
success = false
|
success = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if app.config.Section("telegram").Key("require_unique").MustBool(false) {
|
||||||
|
for _, u := range app.storage.telegram {
|
||||||
|
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)
|
||||||
|
respond(400, "errorAccountLinked", gc)
|
||||||
|
}
|
||||||
|
success = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if emailEnabled && app.config.Section("email_confirmation").Key("enabled").MustBool(false) && !confirmed {
|
if emailEnabled && app.config.Section("email_confirmation").Key("enabled").MustBool(false) && !confirmed {
|
||||||
@ -445,10 +481,21 @@ func (app *appContext) NewUser(gc *gin.Context) {
|
|||||||
gc.JSON(200, validation)
|
gc.JSON(200, validation)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if emailEnabled && app.config.Section("email").Key("required").MustBool(false) && !strings.Contains(req.Email, "@") {
|
if emailEnabled {
|
||||||
app.info.Printf("%s: New user failed: Email Required", req.Code)
|
if app.config.Section("email").Key("required").MustBool(false) && !strings.Contains(req.Email, "@") {
|
||||||
respond(400, "errorNoEmail", gc)
|
app.info.Printf("%s: New user failed: Email Required", req.Code)
|
||||||
return
|
respond(400, "errorNoEmail", gc)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if app.config.Section("email").Key("require_unique").MustBool(false) && req.Email != "" {
|
||||||
|
for _, email := range app.storage.emails {
|
||||||
|
if req.Email == email.Addr {
|
||||||
|
app.info.Printf("%s: New user failed: Email already in use", req.Code)
|
||||||
|
respond(400, "errorEmailLinked", gc)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
f, success := app.newUser(req, false)
|
f, success := app.newUser(req, false)
|
||||||
if !success {
|
if !success {
|
||||||
|
@ -502,6 +502,14 @@
|
|||||||
"type": "bool",
|
"type": "bool",
|
||||||
"value": false,
|
"value": false,
|
||||||
"description": "Require an email address on sign-up."
|
"description": "Require an email address on sign-up."
|
||||||
|
},
|
||||||
|
"require_unique": {
|
||||||
|
"name": "Require unique address",
|
||||||
|
"required": false,
|
||||||
|
"requires_restart": true,
|
||||||
|
"type": "bool",
|
||||||
|
"value": false,
|
||||||
|
"description": "Disables using the same address on multiple accounts."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -641,6 +649,14 @@
|
|||||||
"value": false,
|
"value": false,
|
||||||
"description": "Require Discord connection on sign-up. See the jfa-go wiki for info on setting this up."
|
"description": "Require Discord connection on sign-up. See the jfa-go wiki for info on setting this up."
|
||||||
},
|
},
|
||||||
|
"require_unique": {
|
||||||
|
"name": "Require unique user",
|
||||||
|
"required": false,
|
||||||
|
"requires_restart": true,
|
||||||
|
"type": "bool",
|
||||||
|
"value": false,
|
||||||
|
"description": "Disables using the same user on multiple Jellyfin accounts."
|
||||||
|
},
|
||||||
"token": {
|
"token": {
|
||||||
"name": "API Token",
|
"name": "API Token",
|
||||||
"required": false,
|
"required": false,
|
||||||
@ -745,6 +761,14 @@
|
|||||||
"value": false,
|
"value": false,
|
||||||
"description": "Require telegram connection on sign-up."
|
"description": "Require telegram connection on sign-up."
|
||||||
},
|
},
|
||||||
|
"require_unique": {
|
||||||
|
"name": "Require unique user",
|
||||||
|
"required": false,
|
||||||
|
"requires_restart": true,
|
||||||
|
"type": "bool",
|
||||||
|
"value": false,
|
||||||
|
"description": "Disables using the same user on multiple Jellyfin accounts."
|
||||||
|
},
|
||||||
"token": {
|
"token": {
|
||||||
"name": "API Token",
|
"name": "API Token",
|
||||||
"required": false,
|
"required": false,
|
||||||
@ -801,6 +825,14 @@
|
|||||||
"value": false,
|
"value": false,
|
||||||
"description": "Require Matrix connection on sign-up."
|
"description": "Require Matrix connection on sign-up."
|
||||||
},
|
},
|
||||||
|
"require_unique": {
|
||||||
|
"name": "Require unique user",
|
||||||
|
"required": false,
|
||||||
|
"requires_restart": true,
|
||||||
|
"type": "bool",
|
||||||
|
"value": false,
|
||||||
|
"description": "Disables using the same user on multiple Jellyfin accounts."
|
||||||
|
},
|
||||||
"homeserver": {
|
"homeserver": {
|
||||||
"name": "Home Server URL",
|
"name": "Home Server URL",
|
||||||
"required": false,
|
"required": false,
|
||||||
|
160
daemon.go
Normal file
160
daemon.go
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
// clearEmails removes stored emails for users which no longer exist.
|
||||||
|
// meant to be called with other such housekeeping functions, so assumes
|
||||||
|
// the user cache is fresh.
|
||||||
|
func (app *appContext) clearEmails() {
|
||||||
|
app.debug.Println("Housekeeping: removing unused email addresses")
|
||||||
|
users, status, err := app.jf.GetUsers(false)
|
||||||
|
if status != 200 || err != nil || len(users) == 0 {
|
||||||
|
app.err.Printf("Failed to get users from Jellyfin (%d): %v", status, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Rebuild email storage to from existing users to reduce time complexity
|
||||||
|
emails := map[string]EmailAddress{}
|
||||||
|
for _, user := range users {
|
||||||
|
if email, ok := app.storage.emails[user.ID]; ok {
|
||||||
|
emails[user.ID] = email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
app.storage.emails = emails
|
||||||
|
app.storage.storeEmails()
|
||||||
|
}
|
||||||
|
|
||||||
|
// clearDiscord does the same as clearEmails, but for Discord Users.
|
||||||
|
func (app *appContext) clearDiscord() {
|
||||||
|
app.debug.Println("Housekeeping: removing unused Discord IDs")
|
||||||
|
users, status, err := app.jf.GetUsers(false)
|
||||||
|
if status != 200 || err != nil || len(users) == 0 {
|
||||||
|
app.err.Printf("Failed to get users from Jellyfin (%d): %v", status, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Rebuild discord storage to from existing users to reduce time complexity
|
||||||
|
dcUsers := map[string]DiscordUser{}
|
||||||
|
for _, user := range users {
|
||||||
|
if dcUser, ok := app.storage.discord[user.ID]; ok {
|
||||||
|
dcUsers[user.ID] = dcUser
|
||||||
|
}
|
||||||
|
}
|
||||||
|
app.storage.discord = dcUsers
|
||||||
|
app.storage.storeDiscordUsers()
|
||||||
|
}
|
||||||
|
|
||||||
|
// clearMatrix does the same as clearEmails, but for Matrix Users.
|
||||||
|
func (app *appContext) clearMatrix() {
|
||||||
|
app.debug.Println("Housekeeping: removing unused Matrix IDs")
|
||||||
|
users, status, err := app.jf.GetUsers(false)
|
||||||
|
if status != 200 || err != nil || len(users) == 0 {
|
||||||
|
app.err.Printf("Failed to get users from Jellyfin (%d): %v", status, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Rebuild matrix storage to from existing users to reduce time complexity
|
||||||
|
mxUsers := map[string]MatrixUser{}
|
||||||
|
for _, user := range users {
|
||||||
|
if mxUser, ok := app.storage.matrix[user.ID]; ok {
|
||||||
|
mxUsers[user.ID] = mxUser
|
||||||
|
}
|
||||||
|
}
|
||||||
|
app.storage.matrix = mxUsers
|
||||||
|
app.storage.storeMatrixUsers()
|
||||||
|
}
|
||||||
|
|
||||||
|
// clearTelegram does the same as clearEmails, but for Telegram Users.
|
||||||
|
func (app *appContext) clearTelegram() {
|
||||||
|
app.debug.Println("Housekeeping: removing unused Telegram IDs")
|
||||||
|
users, status, err := app.jf.GetUsers(false)
|
||||||
|
if status != 200 || err != nil || len(users) == 0 {
|
||||||
|
app.err.Printf("Failed to get users from Jellyfin (%d): %v", status, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Rebuild telegram storage to from existing users to reduce time complexity
|
||||||
|
tgUsers := map[string]TelegramUser{}
|
||||||
|
for _, user := range users {
|
||||||
|
if tgUser, ok := app.storage.telegram[user.ID]; ok {
|
||||||
|
tgUsers[user.ID] = tgUser
|
||||||
|
}
|
||||||
|
}
|
||||||
|
app.storage.telegram = tgUsers
|
||||||
|
app.storage.storeTelegramUsers()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://bbengfort.github.io/snippets/2016/06/26/background-work-goroutines-timer.html THANKS
|
||||||
|
|
||||||
|
type housekeepingDaemon struct {
|
||||||
|
Stopped bool
|
||||||
|
ShutdownChannel chan string
|
||||||
|
Interval time.Duration
|
||||||
|
period time.Duration
|
||||||
|
jobs []func(app *appContext)
|
||||||
|
app *appContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func newInviteDaemon(interval time.Duration, app *appContext) *housekeepingDaemon {
|
||||||
|
daemon := housekeepingDaemon{
|
||||||
|
Stopped: false,
|
||||||
|
ShutdownChannel: make(chan string),
|
||||||
|
Interval: interval,
|
||||||
|
period: interval,
|
||||||
|
app: app,
|
||||||
|
}
|
||||||
|
daemon.jobs = []func(app *appContext){func(app *appContext) {
|
||||||
|
app.debug.Println("Housekeeping: Checking for expired invites")
|
||||||
|
app.checkInvites()
|
||||||
|
}}
|
||||||
|
|
||||||
|
clearEmail := app.config.Section("email").Key("require_unique").MustBool(false)
|
||||||
|
clearDiscord := app.config.Section("discord").Key("require_unique").MustBool(false)
|
||||||
|
clearTelegram := app.config.Section("telegram").Key("require_unique").MustBool(false)
|
||||||
|
clearMatrix := app.config.Section("matrix").Key("require_unique").MustBool(false)
|
||||||
|
|
||||||
|
if clearEmail || clearDiscord || clearTelegram || clearMatrix {
|
||||||
|
daemon.jobs = append(daemon.jobs, func(app *appContext) { app.jf.CacheExpiry = time.Now() })
|
||||||
|
}
|
||||||
|
|
||||||
|
if clearEmail {
|
||||||
|
daemon.jobs = append(daemon.jobs, func(app *appContext) { app.clearEmails() })
|
||||||
|
}
|
||||||
|
if clearDiscord {
|
||||||
|
daemon.jobs = append(daemon.jobs, func(app *appContext) { app.clearDiscord() })
|
||||||
|
}
|
||||||
|
if clearTelegram {
|
||||||
|
daemon.jobs = append(daemon.jobs, func(app *appContext) { app.clearTelegram() })
|
||||||
|
}
|
||||||
|
if clearMatrix {
|
||||||
|
daemon.jobs = append(daemon.jobs, func(app *appContext) { app.clearMatrix() })
|
||||||
|
}
|
||||||
|
|
||||||
|
return &daemon
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rt *housekeepingDaemon) run() {
|
||||||
|
rt.app.info.Println("Invite daemon started")
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-rt.ShutdownChannel:
|
||||||
|
rt.ShutdownChannel <- "Down"
|
||||||
|
return
|
||||||
|
case <-time.After(rt.period):
|
||||||
|
break
|
||||||
|
}
|
||||||
|
started := time.Now()
|
||||||
|
rt.app.storage.loadInvites()
|
||||||
|
|
||||||
|
for _, job := range rt.jobs {
|
||||||
|
job(rt.app)
|
||||||
|
}
|
||||||
|
|
||||||
|
finished := time.Now()
|
||||||
|
duration := finished.Sub(started)
|
||||||
|
rt.period = rt.Interval - duration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rt *housekeepingDaemon) Shutdown() {
|
||||||
|
rt.Stopped = true
|
||||||
|
rt.ShutdownChannel <- "Down"
|
||||||
|
<-rt.ShutdownChannel
|
||||||
|
close(rt.ShutdownChannel)
|
||||||
|
}
|
50
invdaemon.go
50
invdaemon.go
@ -1,50 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
// https://bbengfort.github.io/snippets/2016/06/26/background-work-goroutines-timer.html THANKS
|
|
||||||
|
|
||||||
type inviteDaemon struct {
|
|
||||||
Stopped bool
|
|
||||||
ShutdownChannel chan string
|
|
||||||
Interval time.Duration
|
|
||||||
period time.Duration
|
|
||||||
app *appContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func newInviteDaemon(interval time.Duration, app *appContext) *inviteDaemon {
|
|
||||||
return &inviteDaemon{
|
|
||||||
Stopped: false,
|
|
||||||
ShutdownChannel: make(chan string),
|
|
||||||
Interval: interval,
|
|
||||||
period: interval,
|
|
||||||
app: app,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rt *inviteDaemon) run() {
|
|
||||||
rt.app.info.Println("Invite daemon started")
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-rt.ShutdownChannel:
|
|
||||||
rt.ShutdownChannel <- "Down"
|
|
||||||
return
|
|
||||||
case <-time.After(rt.period):
|
|
||||||
break
|
|
||||||
}
|
|
||||||
started := time.Now()
|
|
||||||
rt.app.storage.loadInvites()
|
|
||||||
rt.app.debug.Println("Daemon: Checking invites")
|
|
||||||
rt.app.checkInvites()
|
|
||||||
finished := time.Now()
|
|
||||||
duration := finished.Sub(started)
|
|
||||||
rt.period = rt.Interval - duration
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rt *inviteDaemon) Shutdown() {
|
|
||||||
rt.Stopped = true
|
|
||||||
rt.ShutdownChannel <- "Down"
|
|
||||||
<-rt.ShutdownChannel
|
|
||||||
close(rt.ShutdownChannel)
|
|
||||||
}
|
|
@ -24,6 +24,8 @@
|
|||||||
"notifications": {
|
"notifications": {
|
||||||
"errorUserExists": "User already exists.",
|
"errorUserExists": "User already exists.",
|
||||||
"errorInvalidCode": "Invalid invite code.",
|
"errorInvalidCode": "Invalid invite code.",
|
||||||
|
"errorAccountLinked": "Account already in use.",
|
||||||
|
"errorEmailLinked": "Email already in use.",
|
||||||
"errorTelegramVerification": "Telegram verification required.",
|
"errorTelegramVerification": "Telegram verification required.",
|
||||||
"errorDiscordVerification": "Discord verification required.",
|
"errorDiscordVerification": "Discord verification required.",
|
||||||
"errorMatrixVerification": "Matrix verification required.",
|
"errorMatrixVerification": "Matrix verification required.",
|
||||||
|
@ -18,7 +18,7 @@ import (
|
|||||||
type Storage struct {
|
type Storage struct {
|
||||||
timePattern string
|
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
|
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
|
||||||
users map[string]time.Time
|
users map[string]time.Time // Map of Jellyfin User IDs to their expiry times.
|
||||||
invites Invites
|
invites Invites
|
||||||
profiles map[string]Profile
|
profiles map[string]Profile
|
||||||
defaultProfile string
|
defaultProfile string
|
||||||
|
10
ts/form.ts
10
ts/form.ts
@ -61,6 +61,9 @@ if (window.telegramEnabled) {
|
|||||||
window.telegramModal.close();
|
window.telegramModal.close();
|
||||||
window.notifications.customError("invalidCodeError", window.messages["errorInvalidCode"]);
|
window.notifications.customError("invalidCodeError", window.messages["errorInvalidCode"]);
|
||||||
return;
|
return;
|
||||||
|
} else if (req.status == 400) {
|
||||||
|
window.telegramModal.close();
|
||||||
|
window.notifications.customError("accountLinkedError", window.messages["errorAccountLinked"]);
|
||||||
} else if (req.status == 200) {
|
} else if (req.status == 200) {
|
||||||
if (req.response["success"] as boolean) {
|
if (req.response["success"] as boolean) {
|
||||||
telegramVerified = true;
|
telegramVerified = true;
|
||||||
@ -124,6 +127,9 @@ if (window.discordEnabled) {
|
|||||||
window.discordModal.close();
|
window.discordModal.close();
|
||||||
window.notifications.customError("invalidCodeError", window.messages["errorInvalidCode"]);
|
window.notifications.customError("invalidCodeError", window.messages["errorInvalidCode"]);
|
||||||
return;
|
return;
|
||||||
|
} else if (req.status == 400) {
|
||||||
|
window.discordModal.close();
|
||||||
|
window.notifications.customError("accountLinkedError", window.messages["errorAccountLinked"]);
|
||||||
} else if (req.status == 200) {
|
} else if (req.status == 200) {
|
||||||
if (req.response["success"] as boolean) {
|
if (req.response["success"] as boolean) {
|
||||||
discordVerified = true;
|
discordVerified = true;
|
||||||
@ -165,6 +171,10 @@ if (window.matrixEnabled) {
|
|||||||
};
|
};
|
||||||
_post("/invite/" + window.code + "/matrix/user", send, (req: XMLHttpRequest) => {
|
_post("/invite/" + window.code + "/matrix/user", send, (req: XMLHttpRequest) => {
|
||||||
if (req.readyState == 4) {
|
if (req.readyState == 4) {
|
||||||
|
if (req.status == 400 && req.response["error"] == "errorAccountLinked") {
|
||||||
|
window.matrixModal.close();
|
||||||
|
window.notifications.customError("accountLinkedError", window.messages["errorAccountLinked"]);
|
||||||
|
}
|
||||||
removeLoader(submitButton);
|
removeLoader(submitButton);
|
||||||
userID = input.value;
|
userID = input.value;
|
||||||
if (req.status != 200) {
|
if (req.status != 200) {
|
||||||
|
Loading…
Reference in New Issue
Block a user