Handle GrizzlyFlix signup mail and Seerr sync failures
This commit is contained in:
+25
-17
@@ -189,32 +189,40 @@ func (app *appContext) NewUserFromInvite(gc *gin.Context) {
|
|||||||
respond(500, "errorUnknown", gc)
|
respond(500, "errorUnknown", gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if app.ConfirmationKeys == nil {
|
|
||||||
app.ConfirmationKeys = map[string]map[string]ConfirmationKey{}
|
|
||||||
}
|
|
||||||
cKeys, ok := app.ConfirmationKeys[req.Code]
|
|
||||||
if !ok {
|
|
||||||
cKeys = map[string]ConfirmationKey{}
|
|
||||||
}
|
|
||||||
cKeys[key] = ConfirmationKey{
|
|
||||||
newUserDTO: req,
|
|
||||||
completeContactMethods: completeContactMethods,
|
|
||||||
}
|
|
||||||
app.confirmationKeysLock.Lock()
|
|
||||||
app.ConfirmationKeys[req.Code] = cKeys
|
|
||||||
app.confirmationKeysLock.Unlock()
|
|
||||||
|
|
||||||
app.debug.Printf(lm.EmailConfirmationRequired, req.Username)
|
|
||||||
respond(401, "confirmEmail", gc)
|
|
||||||
msg, err := app.email.constructConfirmation(req.Code, req.Username, key, false)
|
msg, err := app.email.constructConfirmation(req.Code, req.Username, key, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedConstructConfirmationEmail, req.Code, err)
|
app.err.Printf(lm.FailedConstructConfirmationEmail, req.Code, err)
|
||||||
|
respond(500, "errorUnknown", gc)
|
||||||
|
return
|
||||||
} else if err := app.email.send(msg, req.Email); err != nil {
|
} else if err := app.email.send(msg, req.Email); err != nil {
|
||||||
app.err.Printf(lm.FailedSendConfirmationEmail, req.Code, req.Email, err)
|
app.err.Printf(lm.FailedSendConfirmationEmail, req.Code, req.Email, err)
|
||||||
|
if !app.config.Section("email_confirmation").Key("allow_account_creation_on_send_failure").MustBool(false) {
|
||||||
|
respond(500, "errorUnknown", gc)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
app.debug.Printf("Email confirmation send failed for \"%s\"; continuing account creation because email_confirmation.allow_account_creation_on_send_failure is enabled", req.Username)
|
||||||
} else {
|
} else {
|
||||||
app.debug.Printf(lm.SentConfirmationEmail, req.Code, req.Email)
|
app.debug.Printf(lm.SentConfirmationEmail, req.Code, req.Email)
|
||||||
|
if app.ConfirmationKeys == nil {
|
||||||
|
app.ConfirmationKeys = map[string]map[string]ConfirmationKey{}
|
||||||
|
}
|
||||||
|
cKeys, ok := app.ConfirmationKeys[req.Code]
|
||||||
|
if !ok {
|
||||||
|
cKeys = map[string]ConfirmationKey{}
|
||||||
|
}
|
||||||
|
cKeys[key] = ConfirmationKey{
|
||||||
|
newUserDTO: req,
|
||||||
|
completeContactMethods: completeContactMethods,
|
||||||
|
}
|
||||||
|
app.confirmationKeysLock.Lock()
|
||||||
|
app.ConfirmationKeys[req.Code] = cKeys
|
||||||
|
app.confirmationKeysLock.Unlock()
|
||||||
|
|
||||||
|
app.debug.Printf(lm.EmailConfirmationRequired, req.Username)
|
||||||
|
respond(401, "confirmEmail", gc)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1436,6 +1436,15 @@ sections:
|
|||||||
description: Jellyseerr requires email addresses to be unique. If this is not
|
description: Jellyseerr requires email addresses to be unique. If this is not
|
||||||
the case, you may see errors in jfa-go's logs. You can require unique addresses
|
the case, you may see errors in jfa-go's logs. You can require unique addresses
|
||||||
in Settings > Email.
|
in Settings > Email.
|
||||||
|
- setting: ignore_csrf_email_update_errors
|
||||||
|
name: Ignore CSRF email update errors
|
||||||
|
advanced: true
|
||||||
|
type: bool
|
||||||
|
value: true
|
||||||
|
depends_true: enabled
|
||||||
|
description: Some Seerr builds allow API-key reads/imports but reject email or
|
||||||
|
notification writes with CSRF protection. If enabled, jfa-go logs those write
|
||||||
|
rejections at debug level while still importing/linking users.
|
||||||
- section: backups
|
- section: backups
|
||||||
meta:
|
meta:
|
||||||
name: Backups
|
name: Backups
|
||||||
@@ -1514,6 +1523,14 @@ sections:
|
|||||||
requires_restart: true
|
requires_restart: true
|
||||||
type: bool
|
type: bool
|
||||||
value: false
|
value: false
|
||||||
|
- setting: allow_account_creation_on_send_failure
|
||||||
|
name: Continue if confirmation email fails
|
||||||
|
advanced: true
|
||||||
|
type: bool
|
||||||
|
value: false
|
||||||
|
description: If enabled, account creation continues when the confirmation email
|
||||||
|
cannot be sent. Use this only when signups should keep working during temporary
|
||||||
|
mail relay failures.
|
||||||
- setting: subject
|
- setting: subject
|
||||||
name: Email subject
|
name: Email subject
|
||||||
type: text
|
type: text
|
||||||
|
|||||||
+12
-2
@@ -14,6 +14,10 @@ type JellyseerrInitialSyncStatus struct {
|
|||||||
Done bool
|
Done bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isJellyseerrCSRFFailure(err error) bool {
|
||||||
|
return err != nil && strings.Contains(strings.ToLower(err.Error()), "invalid csrf token")
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure the Jellyseerr cache is up to date before calling.
|
// Ensure the Jellyseerr cache is up to date before calling.
|
||||||
func (app *appContext) SynchronizeJellyseerrUser(jfID string) {
|
func (app *appContext) SynchronizeJellyseerrUser(jfID string) {
|
||||||
user, imported, err := app.js.GetOrImportUser(jfID, true)
|
user, imported, err := app.js.GetOrImportUser(jfID, true)
|
||||||
@@ -35,7 +39,9 @@ func (app *appContext) SynchronizeJellyseerrUser(jfID string) {
|
|||||||
if ok && email.Addr != "" && user.Email != email.Addr {
|
if ok && email.Addr != "" && user.Email != email.Addr {
|
||||||
err = app.js.ModifyMainUserSettings(jfID, jellyseerr.MainUserSettings{Email: email.Addr})
|
err = app.js.ModifyMainUserSettings(jfID, jellyseerr.MainUserSettings{Email: email.Addr})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(err.Error(), "INVALID_EMAIL") {
|
if isJellyseerrCSRFFailure(err) && app.config.Section("jellyseerr").Key("ignore_csrf_email_update_errors").MustBool(true) {
|
||||||
|
app.debug.Printf("Skipping Jellyseerr email update for user \"%s\": Jellyseerr rejected the API-key write with CSRF protection", jfID)
|
||||||
|
} else if strings.Contains(err.Error(), "INVALID_EMAIL") {
|
||||||
app.err.Printf(lm.FailedSetEmailAddress, lm.Jellyseerr, jfID, err.Error()+"\""+email.Addr+"\"")
|
app.err.Printf(lm.FailedSetEmailAddress, lm.Jellyseerr, jfID, err.Error()+"\""+email.Addr+"\"")
|
||||||
} else {
|
} else {
|
||||||
app.err.Printf(lm.FailedSetEmailAddress, lm.Jellyseerr, jfID, err)
|
app.err.Printf(lm.FailedSetEmailAddress, lm.Jellyseerr, jfID, err)
|
||||||
@@ -63,7 +69,11 @@ func (app *appContext) SynchronizeJellyseerrUser(jfID string) {
|
|||||||
if len(contactMethods) != 0 {
|
if len(contactMethods) != 0 {
|
||||||
err := app.js.ModifyNotifications(jfID, contactMethods)
|
err := app.js.ModifyNotifications(jfID, contactMethods)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedSyncContactMethods, lm.Jellyseerr, err)
|
if isJellyseerrCSRFFailure(err) && app.config.Section("jellyseerr").Key("ignore_csrf_email_update_errors").MustBool(true) {
|
||||||
|
app.debug.Printf("Skipping Jellyseerr notification update for user \"%s\": Jellyseerr rejected the API-key write with CSRF protection", jfID)
|
||||||
|
} else {
|
||||||
|
app.err.Printf(lm.FailedSyncContactMethods, lm.Jellyseerr, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -430,7 +430,7 @@ func (js *Jellyseerr) ModifyNotifications(jfID string, conf map[NotificationsFie
|
|||||||
switch v.(type) {
|
switch v.(type) {
|
||||||
case string:
|
case string:
|
||||||
conf[FieldDiscord] = []string{v.(string)}
|
conf[FieldDiscord] = []string{v.(string)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
u, err := js.getUser(jfID)
|
u, err := js.getUser(jfID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user