from __future__ import annotations
from typing import List, Literal, Optional
from typing_extensions import TypedDict
ErrorCode = Literal[
"unexpected_failure",
"validation_failed",
"bad_json",
"email_exists",
"phone_exists",
"bad_jwt",
"not_admin",
"no_authorization",
"user_not_found",
"session_not_found",
"flow_state_not_found",
"flow_state_expired",
"signup_disabled",
"user_banned",
"provider_email_needs_verification",
"invite_not_found",
"bad_oauth_state",
"bad_oauth_callback",
"oauth_provider_not_supported",
"unexpected_audience",
"single_identity_not_deletable",
"email_conflict_identity_not_deletable",
"identity_already_exists",
"email_provider_disabled",
"phone_provider_disabled",
"too_many_enrolled_mfa_factors",
"mfa_factor_name_conflict",
"mfa_factor_not_found",
"mfa_ip_address_mismatch",
"mfa_challenge_expired",
"mfa_verification_failed",
"mfa_verification_rejected",
"insufficient_aal",
"captcha_failed",
"saml_provider_disabled",
"manual_linking_disabled",
"sms_send_failed",
"email_not_confirmed",
"phone_not_confirmed",
"reauth_nonce_missing",
"saml_relay_state_not_found",
"saml_relay_state_expired",
"saml_idp_not_found",
"saml_assertion_no_user_id",
"saml_assertion_no_email",
"user_already_exists",
"sso_provider_not_found",
"saml_metadata_fetch_failed",
"saml_idp_already_exists",
"sso_domain_already_exists",
"saml_entity_id_mismatch",
"conflict",
"provider_disabled",
"user_sso_managed",
"reauthentication_needed",
"same_password",
"reauthentication_not_valid",
"otp_expired",
"otp_disabled",
"identity_not_found",
"weak_password",
"over_request_rate_limit",
"over_email_send_rate_limit",
"over_sms_send_rate_limit",
"bad_code_verifier",
"anonymous_provider_disabled",
"hook_timeout",
"hook_timeout_after_retry",
"hook_payload_over_size_limit",
"hook_payload_invalid_content_type",
"request_timeout",
"mfa_phone_enroll_not_enabled",
"mfa_phone_verify_not_enabled",
"mfa_totp_enroll_not_enabled",
"mfa_totp_verify_not_enabled",
"mfa_webauthn_enroll_not_enabled",
"mfa_webauthn_verify_not_enabled",
"mfa_verified_factor_exists",
"invalid_credentials",
"email_address_not_authorized",
"email_address_invalid",
]
class AuthError(Exception):
def __init__(self, message: str, code: ErrorCode) -> None:
Exception.__init__(self, message)
self.message = message
self.name = "AuthError"
self.code = code
class AuthApiErrorDict(TypedDict):
name: str
message: str
status: int
code: ErrorCode
class AuthApiError(AuthError):
def __init__(self, message: str, status: int, code: ErrorCode) -> None:
AuthError.__init__(self, message, code)
self.name = "AuthApiError"
self.status = status
self.code = code
def to_dict(self) -> AuthApiErrorDict:
return {
"name": self.name,
"message": self.message,
"status": self.status,
"code": self.code,
}
class AuthUnknownError(AuthError):
def __init__(self, message: str, original_error: Exception) -> None:
AuthError.__init__(self, message, None)
self.name = "AuthUnknownError"
self.original_error = original_error
class CustomAuthError(AuthError):
def __init__(self, message: str, name: str, status: int, code: ErrorCode) -> None:
AuthError.__init__(self, message, code)
self.name = name
self.status = status
def to_dict(self) -> AuthApiErrorDict:
return {
"name": self.name,
"message": self.message,
"status": self.status,
}
class AuthSessionMissingError(CustomAuthError):
def __init__(self) -> None:
CustomAuthError.__init__(
self,
"Auth session missing!",
"AuthSessionMissingError",
400,
None,
)
class AuthInvalidCredentialsError(CustomAuthError):
def __init__(self, message: str) -> None:
CustomAuthError.__init__(
self,
message,
"AuthInvalidCredentialsError",
400,
None,
)
class AuthImplicitGrantRedirectErrorDetails(TypedDict):
error: str
code: str
class AuthImplicitGrantRedirectErrorDict(AuthApiErrorDict):
details: Optional[AuthImplicitGrantRedirectErrorDetails]
class AuthImplicitGrantRedirectError(CustomAuthError):
def __init__(
self,
message: str,
details: Optional[AuthImplicitGrantRedirectErrorDetails] = None,
) -> None:
CustomAuthError.__init__(
self,
message,
"AuthImplicitGrantRedirectError",
500,
None,
)
self.details = details
def to_dict(self) -> AuthImplicitGrantRedirectErrorDict:
return {
"name": self.name,
"message": self.message,
"status": self.status,
"details": self.details,
}
class AuthRetryableError(CustomAuthError):
def __init__(self, message: str, status: int) -> None:
CustomAuthError.__init__(
self,
message,
"AuthRetryableError",
status,
None,
)
class AuthWeakPasswordError(CustomAuthError):
def __init__(self, message: str, status: int, reasons: List[str]) -> None:
CustomAuthError.__init__(
self,
message,
"AuthWeakPasswordError",
status,
"weak_password",
)
self.reasons = reasons
def to_dict(self) -> AuthApiErrorDict:
return {
"name": self.name,
"message": self.message,
"status": self.status,
"reasons": self.reasons,
}