diff --git a/api-userpage.go b/api-userpage.go index f519524..ea7adb7 100644 --- a/api-userpage.go +++ b/api-userpage.go @@ -590,6 +590,9 @@ func (app *appContext) ResetMyPassword(gc *gin.Context) { cancel := time.AfterFunc(1*time.Second, func() { timerWait <- true }) + usernameAllowed := app.config.Section("user_page").Key("allow_pwr_username").MustBool(true) + emailAllowed := app.config.Section("user_page").Key("allow_pwr_email").MustBool(true) + contactMethodAllowed := app.config.Section("user_page").Key("allow_pwr_contact_method").MustBool(true) address := gc.Param("address") if address == "" { app.debug.Println("Ignoring empty request for PWR") @@ -600,7 +603,7 @@ func (app *appContext) ResetMyPassword(gc *gin.Context) { var pwr InternalPWR var err error - jfUser, ok := app.ReverseUserSearch(address) + jfUser, ok := app.ReverseUserSearch(address, usernameAllowed, emailAllowed, contactMethodAllowed) if !ok { app.debug.Printf("Ignoring PWR request: User not found") diff --git a/config.go b/config.go index b3189d1..aa9c214 100644 --- a/config.go +++ b/config.go @@ -122,6 +122,20 @@ func (app *appContext) loadConfig() error { app.MustSetValue("password_resets", "url_base", strings.TrimSuffix(url1, "/invite")) app.MustSetValue("invite_emails", "url_base", url2) + pwrMethods := []string{"allow_pwr_username", "allow_pwr_email", "allow_pwr_contact_method"} + allDisabled := true + for _, v := range pwrMethods { + if app.config.Section("user_page").Key(v).MustBool(true) { + allDisabled = false + } + } + if allDisabled { + fmt.Println("SETALLTRUE") + for _, v := range pwrMethods { + app.config.Section("user_page").Key(v).SetValue("true") + } + } + messagesEnabled = app.config.Section("messages").Key("enabled").MustBool(false) telegramEnabled = app.config.Section("telegram").Key("enabled").MustBool(false) discordEnabled = app.config.Section("discord").Key("enabled").MustBool(false) diff --git a/config/config-base.json b/config/config-base.json index 5099751..d45dadf 100644 --- a/config/config-base.json +++ b/config/config-base.json @@ -629,6 +629,7 @@ "name": "Show Link on Admin Login page", "required": false, "requires_restart": false, + "depends_true": "enabled", "type": "bool", "value": true, "description": "Whether or not to show a link to the \"My Account\" page on the admin login screen, to direct lost users." @@ -637,6 +638,7 @@ "name": "User Referrals", "required": false, "requires_restart": true, + "depends_true": "enabled", "type": "bool", "value": true, "description": "Users are given their own \"invite\" to send to others." @@ -648,6 +650,41 @@ "depends_true": "referrals", "required": "false", "description": "Create an invite with your desired settings, then either assign it to a user in the accounts tab, or to a profile in settings." + }, + "allow_pwr_username": { + "name": "Allow PWR with username", + "required": false, + "requires_restart": true, + "depends_true": "enabled", + "type": "bool", + "value": true, + "description": "Allow users to start a Password Reset by inputting their username." + }, + "allow_pwr_email": { + "name": "Allow PWR with email address", + "required": false, + "requires_restart": true, + "depends_true": "enabled", + "type": "bool", + "value": true, + "description": "Allow users to start a Password Reset by inputting their email address." + }, + "allow_pwr_contact_method": { + "name": "Allow PWR with Discord/Telegram/Matrix", + "required": false, + "requires_restart": true, + "depends_true": "enabled", + "type": "bool", + "value": true, + "description": "Allow users to start a Password Reset by inputting their Discord/Telegram/Matrix username/id." + }, + "pwr_note": { + "name": "PWR Methods", + "type": "note", + "depends_true": "enabled", + "value": "", + "required": "false", + "description": "Select at least one PWR initiation method. If none are selected, all will be enabled." } } }, diff --git a/email.go b/email.go index bab6eef..156e55e 100644 --- a/email.go +++ b/email.go @@ -899,55 +899,65 @@ func (app *appContext) getAddressOrName(jfID string) string { // ReverseUserSearch returns the jellyfin ID of the user with the given username, email, or contact method username. // returns "" if none found. returns only the first match, might be an issue if there are users with the same contact method usernames. -func (app *appContext) ReverseUserSearch(address string) (user mediabrowser.User, ok bool) { +func (app *appContext) ReverseUserSearch(address string, matchUsername, matchEmail, matchContactMethod bool) (user mediabrowser.User, ok bool) { ok = false - user, status, err := app.jf.UserByName(address, false) - if status == 200 && err == nil { - ok = true - return + var status int + var err error = nil + if matchUsername { + user, status, err = app.jf.UserByName(address, false) + if status == 200 && err == nil { + ok = true + return + } } - emailAddresses := []EmailAddress{} - err = app.storage.db.Find(&emailAddresses, badgerhold.Where("Addr").Eq(address)) - if err == nil && len(emailAddresses) > 0 { - for _, emailUser := range emailAddresses { - user, status, err = app.jf.UserByID(emailUser.JellyfinID, false) - if status == 200 && err == nil { - ok = true - return + + if matchEmail { + emailAddresses := []EmailAddress{} + err = app.storage.db.Find(&emailAddresses, badgerhold.Where("Addr").Eq(address)) + if err == nil && len(emailAddresses) > 0 { + for _, emailUser := range emailAddresses { + user, status, err = app.jf.UserByID(emailUser.JellyfinID, false) + if status == 200 && err == nil { + ok = true + return + } } } } + // Dont know how we'd use badgerhold when we need to render each username, // Apart from storing the rendered name in the db. - for _, dcUser := range app.storage.GetDiscord() { - if RenderDiscordUsername(dcUser) == strings.ToLower(address) { - user, status, err = app.jf.UserByID(dcUser.JellyfinID, false) - if status == 200 && err == nil { - ok = true - return + if matchContactMethod { + for _, dcUser := range app.storage.GetDiscord() { + if RenderDiscordUsername(dcUser) == strings.ToLower(address) { + user, status, err = app.jf.UserByID(dcUser.JellyfinID, false) + if status == 200 && err == nil { + ok = true + return + } } } - } - tgUsername := strings.TrimPrefix(address, "@") - telegramUsers := []TelegramUser{} - err = app.storage.db.Find(&telegramUsers, badgerhold.Where("Username").Eq(tgUsername)) - if err == nil && len(telegramUsers) > 0 { - for _, telegramUser := range telegramUsers { - user, status, err = app.jf.UserByID(telegramUser.JellyfinID, false) - if status == 200 && err == nil { - ok = true - return + tgUsername := strings.TrimPrefix(address, "@") + telegramUsers := []TelegramUser{} + err = app.storage.db.Find(&telegramUsers, badgerhold.Where("Username").Eq(tgUsername)) + if err == nil && len(telegramUsers) > 0 { + for _, telegramUser := range telegramUsers { + user, status, err = app.jf.UserByID(telegramUser.JellyfinID, false) + if status == 200 && err == nil { + ok = true + return + } } } - } - matrixUsers := []MatrixUser{} - err = app.storage.db.Find(&matrixUsers, badgerhold.Where("UserID").Eq(address)) - if err == nil && len(matrixUsers) > 0 { - for _, matrixUser := range matrixUsers { - user, status, err = app.jf.UserByID(matrixUser.JellyfinID, false) - if status == 200 && err == nil { - ok = true - return + matrixUsers := []MatrixUser{} + err = app.storage.db.Find(&matrixUsers, badgerhold.Where("UserID").Eq(address)) + if err == nil && len(matrixUsers) > 0 { + for _, matrixUser := range matrixUsers { + user, status, err = app.jf.UserByID(matrixUser.JellyfinID, false) + if status == 200 && err == nil { + ok = true + return + } } } } diff --git a/html/user.html b/html/user.html index ab142aa..cfbeb17 100644 --- a/html/user.html +++ b/html/user.html @@ -48,11 +48,17 @@ {{ if .pwrEnabled }}