diff --git a/.prettierignore b/.prettierignore index 99de08e9e..a5e70dcfd 100644 --- a/.prettierignore +++ b/.prettierignore @@ -11,13 +11,6 @@ CODE_OF_CONDUCT.md LICENSE.md README.md SECURITY.md -tsparticles.bundle.min.js -flatpickr.* -src/ui/static/js/lottie-web.min.js -src/ui/static/js/editor/* -src/ui/static/js/utils/purify/* -src/ui/static/json/particles.json -src/ui/templates/* +src/ui/app/templates/* src/common/core/*/ui/* -datepicker-foundation.css examples/ diff --git a/src/ui/app/models/models.py b/src/ui/app/models/models.py index b313948ef..d7e1f68ff 100644 --- a/src/ui/app/models/models.py +++ b/src/ui/app/models/models.py @@ -23,8 +23,8 @@ class AnonymousUser(AnonymousUserMixin): method = "manual" admin = False totp_secret = None - creation_date = datetime.now() - update_date = datetime.now() + creation_date = datetime.now().astimezone() + update_date = datetime.now().astimezone() list_roles = [] list_permissions = [] list_recovery_codes = [] diff --git a/src/ui/app/models/ui_database.py b/src/ui/app/models/ui_database.py index a2508ba1c..8a0c92c23 100644 --- a/src/ui/app/models/ui_database.py +++ b/src/ui/app/models/ui_database.py @@ -47,7 +47,7 @@ def init_ui_tables(self, bunkerweb_version: str) -> Tuple[bool, str]: if db_version != bunkerweb_version: self.logger.warning(f"UI tables version ({db_version}) is different from BunkerWeb version ({bunkerweb_version}), migrating them ...") - current_time = datetime.now() + current_time = datetime.now().astimezone() error = True while error: try: @@ -55,7 +55,7 @@ def init_ui_tables(self, bunkerweb_version: str) -> Tuple[bool, str]: metadata.reflect(self.sql_engine) error = False except BaseException as e: - if (datetime.now() - current_time).total_seconds() > 10: + if (datetime.now().astimezone() - current_time).total_seconds() > 10: raise e sleep(1) @@ -201,7 +201,7 @@ def create_ui_user( return f"Role {role} doesn't exist" session.add(RolesUsers(user_name=username, role_name=role)) - current_time = datetime.now() + current_time = datetime.now().astimezone() session.add( Users( username=username, @@ -263,7 +263,7 @@ def update_ui_user( user.password = password.decode("utf-8") user.totp_secret = totp_secret user.method = method - user.update_date = datetime.now() + user.update_date = datetime.now().astimezone() try: session.commit() @@ -354,7 +354,7 @@ def create_ui_role(self, name: str, description: str, permissions: List[str]) -> if session.query(Roles).with_entities(Roles.name).filter_by(name=name).first(): return f"Role {name} already exists" - session.add(Roles(name=name, description=description, update_datetime=datetime.now())) + session.add(Roles(name=name, description=description, update_datetime=datetime.now().astimezone())) for permission in permissions: if not session.query(Permissions).with_entities(Permissions.name).filter_by(name=permission).first(): @@ -479,15 +479,10 @@ def use_ui_user_recovery_code(self, username: str, hashed_code: str) -> str: return "" - def get_ui_user_last_session(self, username: str) -> Optional[UserSessions]: - """Get ui user last session.""" - with self._db_session() as session: - return session.query(UserSessions).filter_by(user_name=username).order_by(UserSessions.creation_date.desc()).first() - def get_ui_user_sessions(self, username: str) -> List[UserSessions]: """Get ui user sessions.""" with self._db_session() as session: - return session.query(UserSessions).filter_by(user_name=username).order_by(UserSessions.creation_date.desc()).limit(10).all() + return session.query(UserSessions).filter_by(user_name=username).order_by(UserSessions.creation_date.desc()).all() def delete_ui_user_old_sessions(self, username: str) -> str: """Delete ui user old sessions.""" diff --git a/src/ui/app/routes/bans.py b/src/ui/app/routes/bans.py index 8d4c77d9c..8c65dfbcc 100644 --- a/src/ui/app/routes/bans.py +++ b/src/ui/app/routes/bans.py @@ -165,7 +165,8 @@ def get_load_data(): ban_end = float(ban["ban_end"]) except ValueError: continue - ban_end = (datetime.fromtimestamp(ban_end) - datetime.now()).total_seconds() + current_time = datetime.now().astimezone() + ban_end = (datetime.fromtimestamp(ban_end, tz=current_time.tzinfo) - current_time).total_seconds() if redis_client: ok = redis_client.set(f"bans_ip_{ban['ip']}", dumps({"reason": reason, "date": time()})) diff --git a/src/ui/app/routes/login.py b/src/ui/app/routes/login.py index 233821f4d..466782e18 100644 --- a/src/ui/app/routes/login.py +++ b/src/ui/app/routes/login.py @@ -25,15 +25,13 @@ def login_page(): ui_user = DB.get_ui_user(username=request.form["username"]) if ui_user and ui_user.username == request.form["username"] and ui_user.check_password(request.form["password"]): # log the user in + session["creation_date"] = datetime.now().astimezone() + session["ip"] = request.remote_addr + session["user_agent"] = request.headers.get("User-Agent") session["totp_validated"] = False session["flash_messages"] = [] - ret = DB.mark_ui_user_login( - ui_user.username, - datetime.now().astimezone(), - request.remote_addr, - request.headers.get("User-Agent"), - ) + ret = DB.mark_ui_user_login(ui_user.username, session["creation_date"], session["ip"], session["user_agent"]) if isinstance(ret, str): LOGGER.error(f"Couldn't mark the user login: {ret}") else: diff --git a/src/ui/app/routes/profile.py b/src/ui/app/routes/profile.py index 99606677e..6a220dd39 100644 --- a/src/ui/app/routes/profile.py +++ b/src/ui/app/routes/profile.py @@ -11,6 +11,25 @@ profile = Blueprint("profile", __name__) +BROWSERS = { + "Chrome": "bxl-chrome", + "Firefox": "bxl-firefox", + "Safari": "bx-compass", + "Edge": "bxl-edge", + "Opera": "bxl-opera", + "Internet Explorer": "bxl-internet-explorer", +} + +OS = { + "Windows": "bxl-windows", + "Mac": "bxl-apple", + "Linux": "bxl-tux", +} + +DEVICES = { + "PC": "bx-desktop", +} + @profile.route("/profile", methods=["GET"]) @login_required @@ -23,15 +42,32 @@ def profile_page(): last_sessions = [] for db_session in DB.get_ui_user_sessions(current_user.username): ua_data = parse(db_session.user_agent) - last_sessions.append( - { - "browser": ua_data.get_browser(), - "os": ua_data.get_os(), - "ip": db_session.ip, - "creation_date": db_session.creation_date.strftime("%Y-%m-%d %H:%M:%S %Z"), - "last_activity": db_session.last_activity.strftime("%Y-%m-%d %H:%M:%S %Z"), - } - ) + last_session = { + "current": db_session.id == session.get("session_id"), + "browser": ua_data.get_browser(), + "os": ua_data.get_os(), + "device": ua_data.get_device(), + "ip": db_session.ip, + "creation_date": db_session.creation_date.astimezone().strftime("%Y-%m-%d %H:%M:%S %Z"), + "last_activity": db_session.last_activity.astimezone().strftime("%Y-%m-%d %H:%M:%S %Z"), + } + + for browser, icon in BROWSERS.items(): + if browser in last_session["browser"]: + last_session["browser"] = f" {last_session['browser']}" + break + + for os, icon in OS.items(): + if os in last_session["os"]: + last_session["os"] = f" {last_session['os']}" + break + + last_session["device"] = f" {last_session['device']}" + + if last_session["current"] and last_sessions: + last_sessions.insert(0, last_session) + continue + last_sessions.append(last_session) return render_template( "profile.html", diff --git a/src/ui/app/routes/utils.py b/src/ui/app/routes/utils.py index 96ce6efde..4c2746bd2 100644 --- a/src/ui/app/routes/utils.py +++ b/src/ui/app/routes/utils.py @@ -23,9 +23,9 @@ def wait_applying(): - current_time = datetime.now() + current_time = datetime.now().astimezone() ready = False - while not ready and (datetime.now() - current_time).seconds < 120: + while not ready and (datetime.now().astimezone() - current_time).seconds < 120: db_metadata = DB.get_metadata() if isinstance(db_metadata, str): LOGGER.error(f"An error occurred when checking for changes in the database : {db_metadata}") @@ -112,7 +112,7 @@ def manage_bunkerweb(method: str, *args, operation: str = "reloads", is_draft: b flash(f["content"]) if "flash_messages" in session: - session["flash_messages"].append((f["content"], f["type"], datetime.now().strftime("%Y-%m-%d %H:%M:%S %Z"))) + session["flash_messages"].append((f["content"], f["type"], datetime.now().astimezone().strftime("%Y-%m-%d %H:%M:%S %Z"))) DATA["TO_FLASH"] = [] diff --git a/src/ui/app/static/img/avatar_profil_BW.png b/src/ui/app/static/img/avatar_profil_BW.png new file mode 100644 index 000000000..29dfc8ee6 Binary files /dev/null and b/src/ui/app/static/img/avatar_profil_BW.png differ diff --git a/src/ui/app/templates/base.html b/src/ui/app/templates/base.html index 0beb52b7b..45e8f4da6 100644 --- a/src/ui/app/templates/base.html +++ b/src/ui/app/templates/base.html @@ -1,127 +1,79 @@ {% set current_endpoint = url_for(request.endpoint).split("/")[-1] %} - - -
- - - - - - -