import logging import os from typing import Any, Callable from descope import DescopeClient from nicegui import Client, app, ui descope_id = os.environ.get('DESCOPE_ID', '') try: descope_client = DescopeClient(project_id=descope_id) except Exception as error: print("failed to initialize. Error:") print(error) async def logout(): result = await ui.run_javascript('return await sdk.logout()', respond=True) if result['code'] != 200: logging.error('Logout failed: ' + result) ui.notify('Logout failed', type='negative') ui.open('/login') def _verify(token: str): try: jwt_response = descope_client.validate_session(session_token=token) ic(jwt_response) app.storage.user['user_id'] = jwt_response['userId'] return True except Exception: app.storage.user['user_id'] = None logging.exception("Could not validate user session.") ui.notify('Wrong username or password', type='negative') return False def login_form(): with ui.card().classes('w-96 mx-auto'): return ui.element('descope-wc').props(f'project-id="{descope_id}" flow-id="sign-up-or-in"') class page(ui.page): def __init__(self, path): super().__init__(path) def __call__(self, func: Callable[..., Any]) -> Callable[..., Any]: async def content(client: Client): ui.add_head_html('') ui.add_head_html('') ui.add_body_html(''' ''') await client.connected() token = await ui.run_javascript('return sessionToken && !sdk.isJwtExpired(sessionToken) ? sessionToken : null;') if token and _verify(token): if self.path == '/login': await ui.run_javascript('sdk.refresh()', respond=False) ui.open('/') else: func() else: if self.path != '/login': ui.open('/login') else: func() return super().__call__(content) def login_page(func: Callable[..., Any]) -> Callable[..., Any]: return page('/login')(func)