Browse Source

Handle invalid_nonce errors in 2fa login API

Tulir Asokan 2 years ago
parent
commit
e91b7dbf27

+ 1 - 0
mauigpapi/errors/__init__.py

@@ -7,6 +7,7 @@ from .mqtt import (
     MQTTNotLoggedIn,
 )
 from .response import (
+    IG2FACodeExpiredError,
     IGActionSpamError,
     IGBad2FACodeError,
     IGChallengeError,

+ 4 - 0
mauigpapi/errors/response.py

@@ -156,6 +156,10 @@ class IGBad2FACodeError(IGResponseError):
     pass
 
 
+class IG2FACodeExpiredError(IGResponseError):
+    pass
+
+
 class IGFBNoContactPointFoundError(IGLoginError):
     pass
 

+ 3 - 0
mauigpapi/http/base.py

@@ -28,6 +28,7 @@ from mautrix.types import JSON, Serializable
 from mautrix.util.logging import TraceLogger
 
 from ..errors import (
+    IG2FACodeExpiredError,
     IGActionSpamError,
     IGBad2FACodeError,
     IGChallengeError,
@@ -274,6 +275,8 @@ class BaseAndroidAPI:
             raise IGLoginInvalidUserError(resp, data)
         elif error_type == "sms_code_validation_code_invalid":
             raise IGBad2FACodeError(resp, data)
+        elif error_type == "invalid_nonce":
+            raise IG2FACodeExpiredError(resp, data)
         elif error_type == "fb_no_contact_point_found":
             raise IGFBNoContactPointFoundError(resp, data)
         elif error_type == "fb_email_taken":

+ 13 - 0
mautrix_instagram/web/provisioning_api.py

@@ -28,6 +28,7 @@ from yarl import URL
 
 from mauigpapi import AndroidAPI, AndroidState
 from mauigpapi.errors import (
+    IG2FACodeExpiredError,
     IGBad2FACodeError,
     IGChallengeError,
     IGChallengeWrongCodeError,
@@ -448,6 +449,18 @@ class ProvisioningAPI:
                 status=403,
                 headers=self._acao_headers,
             )
+        except IG2FACodeExpiredError as e:
+            self.log.debug("%s submitted an expired 2-factor auth code", user.mxid)
+            self.log.debug("Login error body: %s", e.body.serialize())
+            track(user, "$login_failed", {"error": "expired-2fa-code"})
+            return web.json_response(
+                data={
+                    "error": e.body.get("message") or str(e),
+                    "status": "expired-2fa-code",
+                },
+                status=403,
+                headers=self._acao_headers,
+            )
         except IGChallengeError as e:
             self.log.debug("%s submitted a 2-factor auth code, but got a challenge", user.mxid)
             return await self.start_checkpoint(user, state, api, e, after="2fa")