Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Community] fix expired JWT token error #2854

Merged
merged 1 commit into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion octobot/community/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,8 @@ async def _initialize_account(self, minimal=False, fetch_private_data=True):
await self._ensure_init_community_feed()
except authentication.AuthenticationError as err:
self.logger.info(f"Login aborted: no authenticated session: {err}")
if await self.has_login_info():
await self.logout()
except authentication.UnavailableError as e:
self.logger.exception(e, True, f"Error when fetching community data, "
f"please check your internet connection.")
Expand Down Expand Up @@ -803,7 +805,8 @@ async def _auth_handler(self):
except authentication.FailedAuthentication as e:
if should_warn:
self.logger.warning(f"Invalid authentication details, please re-authenticate. {e}")
await self.logout()
if await self.has_login_info():
await self.logout()
except authentication.UnavailableError:
raise
except Exception as e:
Expand Down
5 changes: 3 additions & 2 deletions octobot/community/models/community_public_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ def __init__(self):
self.products = _DataElement({}, False)

def set_products(self, products):
self.products.value = {product[enums.ProductKeys.ID.value]: product for product in products}
self.products.fetched = True
if products:
self.products.value = {product[enums.ProductKeys.ID.value]: product for product in products}
self.products.fetched = True

def get_product_slug(self, product_id):
return self.products.value[product_id][enums.ProductKeys.SLUG.value]
Expand Down
67 changes: 43 additions & 24 deletions octobot/community/supabase_backend/community_supabase_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ async def sign_up(self, email: str, password: str) -> None:
async def sign_out(self, options: gotrue.types.SignOutOptions) -> None:
try:
await self.auth.sign_out(options)
except gotrue.errors.AuthApiError:
except (postgrest.exceptions.APIError, gotrue.errors.AuthApiError):
pass

def _requires_email_validation(self, user: gotrue.types.User) -> bool:
Expand All @@ -137,7 +137,7 @@ async def restore_session(self):
async def refresh_session(self, refresh_token: typing.Union[str, None] = None):
try:
await self.auth.refresh_session(refresh_token=refresh_token)
except gotrue.errors.AuthError as err:
except (postgrest.exceptions.APIError, gotrue.errors.AuthError) as err:
raise authentication.AuthenticationError(f"Community auth error: {err}") from err

async def sign_in_with_otp_token(self, token):
Expand Down Expand Up @@ -229,16 +229,21 @@ async def fetch_checkout_url(self, payment_method: str, redirect_url: str) -> di
return json.loads(json.loads(resp)["message"])

async def fetch_bot(self, bot_id) -> dict:
try:
# https://postgrest.org/en/stable/references/api/resource_embedding.html#hint-disambiguation
return (await self.table("bots").select("*,bot_deployment:bot_deployments!bots_current_deployment_id_fkey(*)").eq(
enums.BotKeys.ID.value, bot_id
).execute()).data[0]
except IndexError:
raise errors.BotNotFoundError(f"Can't find bot with id: {bot_id}")
with jwt_expired_auth_raiser():
try:
# https://postgrest.org/en/stable/references/api/resource_embedding.html#hint-disambiguation
return (await self.table("bots").select("*,bot_deployment:bot_deployments!bots_current_deployment_id_fkey(*)").eq(
enums.BotKeys.ID.value, bot_id
).execute()).data[0]
except IndexError:
raise errors.BotNotFoundError(f"Can't find bot with id: {bot_id}")

async def fetch_bots(self) -> list:
return (await self.table("bots").select("*,bot_deployment:bot_deployments!bots_current_deployment_id_fkey!inner(*)").execute()).data
with jwt_expired_auth_raiser():
return (
await self.table("bots").select(
"*,bot_deployment:bot_deployments!bots_current_deployment_id_fkey!inner(*)"
).execute()).data

async def create_bot(self, deployment_type: enums.DeploymentTypes) -> dict:
created_bot = (await self.table("bots").insert({
Expand Down Expand Up @@ -305,19 +310,23 @@ async def fetch_startup_info(self, bot_id) -> dict:
return resp.data[0]

async def fetch_products(self, category_types: list[str]) -> list:
return (
await self.table("products").select(
"*,"
"category:product_categories!inner(slug, name_translations, type, metadata),"
"results:product_results!products_current_result_id_fkey("
" profitability,"
" reference_market_profitability"
")"
).eq(
enums.ProductKeys.VISIBILITY.value, "public"
).in_("category.type", category_types)
.execute()
).data
try:
return (
await self.table("products").select(
"*,"
"category:product_categories!inner(slug, name_translations, type, metadata),"
"results:product_results!products_current_result_id_fkey("
" profitability,"
" reference_market_profitability"
")"
).eq(
enums.ProductKeys.VISIBILITY.value, "public"
).in_("category.type", category_types)
.execute()
).data
except postgrest.exceptions.APIError as err:
commons_logging.get_logger(__name__).error(f"Error when fetching products: {err}")
return []

async def fetch_subscribed_products_urls(self) -> list:
resp = await self.rpc("get_subscribed_products_urls").execute()
Expand Down Expand Up @@ -934,4 +943,14 @@ async def aclose(self):
except RuntimeError:
# happens when the event loop is closed already
pass
self.production_anon_client = None
self.production_anon_client = None


@contextlib.contextmanager
def jwt_expired_auth_raiser():
try:
yield
except postgrest.exceptions.APIError as err:
if "JWT expired" in str(err):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

raise authentication.AuthenticationError(f"Please re-login to your OctoBot account: {err}") from err
raise
Loading