diff --git a/app/commands.py b/app/commands.py index 1e02ec2..6d4b3a3 100644 --- a/app/commands.py +++ b/app/commands.py @@ -10,14 +10,15 @@ def seed_defaults(): "butterbox_logo": current_app.config["BUTTERBOX_LOGO"], "ssid": current_app.config["BUTTERBOX_SSID"], "wifi_password": current_app.config["BUTTERBOX_WIFI_PASSWORD"], - "disable_access_point": current_app.config["DISABLE_ACCESS_POINT"], + "enable_access_point": current_app.config["ENABLE_ACCESS_POINT"], "apply_changes": "false", "onboarding_complete": "false", "lock_root_password": "false", - "disable_file_viewer": current_app.config["DISABLE_FILE_VIEWER"], - "disable_map_viewer": current_app.config["DISABLE_MAP_VIEWER"], - "disable_chat": current_app.config["DISABLE_CHAT"], - "disable_app_store": current_app.config["DISABLE_APP_STORE"], + "enable_file_viewer": current_app.config["ENABLE_FILE_VIEWER"], + "enable_map_viewer": current_app.config["ENABLE_MAP_VIEWER"], + "enable_chat": current_app.config["ENABLE_CHAT"], + "enable_app_store": current_app.config["ENABLE_APP_STORE"], + "enable_deltachat": current_app.config["ENABLE_DELTACHAT"], "ssh_password": "", "admin_password": current_app.config["ADMIN_PASSWORD"], } diff --git a/app/forms.py b/app/forms.py index 43548bd..1dca64a 100644 --- a/app/forms.py +++ b/app/forms.py @@ -15,15 +15,16 @@ class SettingsForm(FlaskForm): # Access point settings ssid = StringField('SSID', validators=[DataRequired()]) wifi_password = PasswordField(_l('WiFi Password')) - disable_access_point = BooleanField(_l('Disable Access Point')) + enable_access_point = BooleanField(_l('Enable Access Point')) # Customisation settings butterbox_name = StringField(_l('Butterbox Name'), validators=[DataRequired()]) butterbox_logo = FileField((_l('Butterbox Logo')), validators=[FileAllowed(['jpg', 'png', 'svg'], 'Images only!')]) # Services settings - disable_file_viewer = BooleanField(_l('Disable File Viewer')) - disable_map_viewer = BooleanField(_l('Disable Map Viewer')) - disable_chat = BooleanField(_l('Disable Chat')) - disable_app_store = BooleanField(_l('Disable App Store')) + enable_file_viewer = BooleanField(_l('Enable File Viewer')) + enable_map_viewer = BooleanField(_l('Enable Map Viewer')) + enable_chat = BooleanField(_l('Enable Chat')) + enable_app_store = BooleanField(_l('Enable App Store')) + enable_deltachat = BooleanField(_l('Enable DeltaChat')) # Access Settings admin_password = PasswordField(_l('Admin Password')) ssh_password = PasswordField(_l('SSH Password')) diff --git a/app/routes.py b/app/routes.py index f715551..6fea7b8 100644 --- a/app/routes.py +++ b/app/routes.py @@ -13,6 +13,22 @@ from werkzeug.datastructures import FileStorage import json from flask_babel import _ import base64 +import random +from wordfreq import top_n_list +import secrets +import string + +def gen_username(): + words = top_n_list("en", 5000) + prefix = random.randint(1000, 9999) + return f"{random.choice(words)}{random.choice(words)}{prefix}" + +def gen_password(): + characters = string.ascii_letters + string.digits + password = ''.join(secrets.choice(characters) for i in range(20)) + return password + + def get_setting(name) -> str: setting = db.session.scalar(sa.select(Setting).where(Setting.key == name)) @@ -33,21 +49,24 @@ def dump_settings(filename: str) -> None: @app.route('/') @app.route('/index') def index(): - disable_chat = get_setting("disable_chat") - disable_app_store = get_setting("disable_app_store") - disable_map_viewer = get_setting("disable_map_viewer") - disable_file_viewer = get_setting("disable_file_viewer") + enable_chat = get_setting("enable_chat") + enable_app_store = get_setting("enable_app_store") + enable_map_viewer = get_setting("enable_map_viewer") + enable_file_viewer = get_setting("enable_file_viewer") + enable_deltachat = get_setting("enable_deltachat") service_array = [] usb_inserted = False # actual test of whether USB is inserted usb_has_maps = False # actual test of whether USB has maps folder usb_has_appstore = False # actual test of whether USB has an appstore - if disable_chat == 'false': + if enable_deltachat == 'true': + service_array.append({"name": "Secure Messaging", "image": url_for("static", filename="images/deltachat-icon.png"), "url": url_for("messaging") }) + if enable_chat == 'true': service_array.append({"name": "Message Board", "image": url_for("static", filename="images/chat-icon.png"), "url": app.config["CONVENE_INSTALL_PATH"] }) - if disable_app_store == 'false' and usb_has_appstore: + if enable_app_store == 'true' and usb_has_appstore: service_array.append({"name": "Apps", "image": url_for("static", filename="images/appstore-icon.svg")}) - if disable_map_viewer == 'false' and usb_has_maps: + if enable_map_viewer == 'true' and usb_has_maps: service_array.append({"name": "Offline Maps", "image": url_for("static", filename="images/maps-icon.png")}) - if disable_file_viewer == 'false': + if enable_file_viewer == 'true': name = "Files" if not usb_inserted: name = "Insert USB to browse files" @@ -85,9 +104,9 @@ def logout(): @login_required def admin(): form = SettingsForm() - populate_settings = ['butterbox_name', 'wifi_password', 'disable_access_point', 'ssid', 'disable_file_viewer', 'disable_map_viewer', 'disable_app_store', 'disable_chat' ] + populate_settings = ['butterbox_name', 'wifi_password', 'enable_access_point', 'ssid', 'enable_file_viewer', 'enable_map_viewer', 'enable_app_store', 'enable_chat', 'enable_deltachat' ] - bool_settings = ['disable_access_point','disable_file_viewer', 'disable_map_viewer', 'disable_app_store', 'disable_chat'] + bool_settings = ['enable_access_point','enable_file_viewer', 'enable_map_viewer', 'enable_app_store', 'enable_chat', 'enable_deltachat'] if not form.is_submitted(): for s in populate_settings: @@ -95,7 +114,7 @@ def admin(): getattr(form, s).data = (get_setting(s) == "true") else: getattr(form, s).data = get_setting(s) - + non_admin_settings_changed = False if form.validate_on_submit(): if form.submit.data: for s in populate_settings: @@ -106,7 +125,8 @@ def admin(): if new_value != existing_value: print(f"New value was changed for {s}. Existing value was {existing_value}, new value was {new_value}") set_setting(s, new_value) - if s in ['butterbox_name', 'wifi_password', 'ssid', 'disable_access_point']: + non_admin_settings_changed = True + if s in ['butterbox_name', 'wifi_password', 'ssid', 'enable_access_point', 'enable_chat', 'enable_delta_chat']: app.config['SETTINGS_CHANGED'] = True new_logo = form.butterbox_logo.data @@ -117,18 +137,21 @@ def admin(): new_value = f"data:{file_mimetype};base64,{b64_logo}" existing_value = get_setting('butterbox_logo') if new_value != existing_value: - print( f"New value was changed for logo") set_setting('butterbox_logo', new_value) + non_admin_settings_changed = True new_admin_password = form.admin_password.data if new_admin_password: existing_admin_password = get_setting('admin_password') if new_admin_password != existing_admin_password: - print( f"New value was changed for admin password") set_setting('admin_password', new_admin_password) - print(get_setting('admin_password')) + non_admin_settings_changed = True if app.config['SETTINGS_CHANGED']: - flash(_("⚠️ Some settings won't take effect until the Butter Box restarts. Click 'Apply Changes' to restart.")) + flash(_("⚠️ Some settings won't fully take effect until the Butter Box restarts. Click 'Apply Changes' to restart.")) + else: + if non_admin_settings_changed: + flash( + _("Settings successfully changed.")) db.session.commit() if form.apply_changes.data: @@ -138,3 +161,19 @@ def admin(): return render_template('admin.html', get_setting=get_setting, form=form) + + +@app.route('/messaging', methods=['GET', 'POST']) +def messaging(): + return render_template('messaging.html', get_setting=get_setting) + +@app.route("/deltachat_credentials", methods=["POST"]) +def generate_random_deltachat_credentials(): + ip = app.config['BUTTERBOX_DEFAULT_IP'] + username = gen_username() + password = gen_password() + + flash(f"Username: {username}") + flash(f"Password: {password}") + flash(f"IP: {ip}") + return redirect(url_for("messaging")) \ No newline at end of file diff --git a/app/static/images/deltachat-icon.png b/app/static/images/deltachat-icon.png new file mode 100644 index 0000000..0715643 Binary files /dev/null and b/app/static/images/deltachat-icon.png differ diff --git a/app/templates/admin.html b/app/templates/admin.html index 2ed362e..33a34b0 100644 --- a/app/templates/admin.html +++ b/app/templates/admin.html @@ -5,9 +5,6 @@ {% import "bulma_wtf.html" as wtf %}
{{ form.hidden_tag() }} - {% if config['SETTINGS_CHANGED'] %} -

{{ form.apply_changes(class="button is-warning") }}

- {% endif %}
{{ wtf.form_input_field(form.ssid) }}

This is the name of the advertised Wi-Fi network. Current SSID: {{ get_setting('ssid') }}

@@ -23,23 +20,27 @@ Current name: {{ get_setting('butterbox_name') }}, accessed at {{ get_setting('butterbox_name') }}.local.

- {{ wtf.form_bool_field(form.disable_access_point) }} + {{ wtf.form_bool_field(form.enable_access_point) }}

Whether this box will advertise a WiFi network.

- {{ wtf.form_bool_field(form.disable_map_viewer) }} + {{ wtf.form_bool_field(form.enable_map_viewer) }}

Whether map services are enabled.

- {{ wtf.form_bool_field(form.disable_chat) }} + {{ wtf.form_bool_field(form.enable_chat) }}

Whether chat services are enabled.

- {{ wtf.form_bool_field(form.disable_file_viewer) }} + {{ wtf.form_bool_field(form.enable_deltachat) }} +

Whether secure messaging using DeltaChat is enabled.

+
+
+ {{ wtf.form_bool_field(form.enable_file_viewer) }}

Whether files services via USB are enabled.

- {{ wtf.form_bool_field(form.disable_app_store) }} + {{ wtf.form_bool_field(form.enable_app_store) }}

Whether app store services are enabled.

@@ -55,7 +56,11 @@

This is the logo shown in the UI. Current logo:

-

{{ form.submit( class="button is-link") }}

+

{{ form.submit( class="button is-link") }} + {% if config['SETTINGS_CHANGED'] %} + {{ form.apply_changes(class="button is-warning") }} + {% endif %} +

Logout diff --git a/app/templates/messaging.html b/app/templates/messaging.html new file mode 100644 index 0000000..dac504f --- /dev/null +++ b/app/templates/messaging.html @@ -0,0 +1,18 @@ +{% extends "base.html" %} + +{% block content %} + +
+

To use secure messaging, install Delta Chat and then return to this page to create your local offline account

+
+ + +
+
+ +
+{% endblock %} \ No newline at end of file diff --git a/config.py b/config.py index 1b77d7e..4aa92df 100644 --- a/config.py +++ b/config.py @@ -9,14 +9,16 @@ class Config: BUTTERBOX_SSID= "butterbox" BUTTERBOX_WIFI_PASSWORD= "" LANGUAGES = ['en', 'ro'] + BUTTERBOX_DEFAULT_IP = "10.0.1.37" BUTTERBOX_NAME = "Butter Box" BUTTERBOX_LOGO = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjc5IiBoZWlnaHQ9IjIzNiIgdmlld0JveD0iMCAwIDI3OSAyMzYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIG9wYWNpdHk9IjAuOSI+CjxwYXRoIG9wYWNpdHk9IjAuOSIgZD0iTTEzOS4zODggMTk3LjYzNkMxNzIuMjg0IDE5Ny42MzYgMTk4Ljk1MiAxNzAuOTY4IDE5OC45NTIgMTM4LjA3MkMxOTguOTUyIDEwNS4xNzUgMTcyLjI4NCA3OC41MDcgMTM5LjM4OCA3OC41MDdDMTA2LjQ5MSA3OC41MDcgNzkuODIzIDEwNS4xNzUgNzkuODIzIDEzOC4wNzJDNzkuODIzIDE3MC45NjggMTA2LjQ5MSAxOTcuNjM2IDEzOS4zODggMTk3LjYzNloiIGZpbGw9IiNGRUY1QjgiIHN0cm9rZT0iI0ZFRjVCOCIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggb3BhY2l0eT0iMC45IiBkPSJNMTM5LjYxMiA0LjAzMjU5VjYwLjM3NTRDMTM0LjgxNyA1Ny40NTM0IDEzMS4xNDYgNDUuOTE1MSAxMzEuMTQ2IDMyLjIwNEMxMzEuMjIxIDE4LjQ5MjkgMTM0LjgxNyA2Ljk1NDYzIDEzOS42MTIgNC4wMzI1OVoiIGZpbGw9IiNGRUY1QjgiIHN0cm9rZT0iI0ZFRjVCOCIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggb3BhY2l0eT0iMC45IiBkPSJNNjAuNDE3OCAxMzkuNDJINEM2LjkyMjA0IDE0NC4yMTUgMTguNDYwMyAxNDcuODg3IDMyLjE3MTQgMTQ3Ljg4N0M0NS45NTc0IDE0Ny44ODcgNTcuNDk1NyAxNDQuMjE1IDYwLjQxNzggMTM5LjQyWiIgZmlsbD0iI0ZFRjVCOCIgc3Ryb2tlPSIjRkVGNUI4IiBzdHJva2Utd2lkdGg9IjQiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBvcGFjaXR5PSIwLjkiIGQ9Ik0yNzUgMTM5LjY0NUgyMTguNjU3QzIyMS41NzkgMTM0Ljg1IDIzMy4xMTggMTMxLjE3OSAyNDYuODI5IDEzMS4xNzlDMjYwLjU0IDEzMS4yNTQgMjcyLjA3OCAxMzQuODUgMjc1IDEzOS42NDVaIiBmaWxsPSIjRkVGNUI4IiBzdHJva2U9IiNGRUY1QjgiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIG9wYWNpdHk9IjAuOSIgZD0iTTIzNS4zNjUgNDMuODE3M0wxOTUuNTA2IDgzLjY3NjlDMTk0LjE1NyA3OC4yMDc0IDE5OS43NzYgNjcuNDkzMyAyMDkuNDQyIDU3LjgyODFDMjE5LjI1NyA0OC4wODggMjI5Ljg5NiA0Mi40Njg3IDIzNS4zNjUgNDMuODE3M1oiIGZpbGw9IiNGRUY1QjgiIHN0cm9rZT0iI0ZFRjVCOCIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggb3BhY2l0eT0iMC45IiBkPSJNODMuNjQ0MiA4My41MjY5TDQzLjc4NDcgNDMuNjY3NEM0Mi40MzYxIDQ5LjEzNjggNDguMDU1NCA1OS44NTA5IDU3LjcyMDUgNjkuNTE2MUM2Ny40NjA3IDc5LjI1NjIgNzguMTc0OCA4NC44NzU1IDgzLjY0NDIgODMuNTI2OVoiIGZpbGw9IiNGRUY1QjgiIHN0cm9rZT0iI0ZFRjVCOCIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggb3BhY2l0eT0iMC45IiBkPSJNMTgyLjkxOCAzNC45MDEyTDE2Ny41NTkgNzIuMTM4NUMxNjUuMTYxIDY4LjkxNjcgMTY1LjkxMSA2MC4zMDA1IDE2OS42NTcgNTEuMjM0N0MxNzMuNDAzIDQyLjE2ODkgMTc4Ljk0NyAzNS41MDA2IDE4Mi45MTggMzQuOTAxMloiIGZpbGw9IiNGRUY1QjgiIHN0cm9rZT0iI0ZFRjVCOCIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggb3BhY2l0eT0iMC45IiBkPSJNNzMuMDA1MSAxMTQuMDIxTDM1Ljg0MjggOTguNjYxNkMzNi40NDIyIDEwMi42MzMgNDMuMTEwNCAxMDguMTc3IDUyLjE3NjIgMTExLjkyM0M2MS4yNDIgMTE1LjY2OSA2OS43ODMzIDExNi40MTkgNzMuMDA1MSAxMTQuMDIxWiIgZmlsbD0iI0ZFRjVCOCIgc3Ryb2tlPSIjRkVGNUI4IiBzdHJva2Utd2lkdGg9IjQiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBvcGFjaXR5PSIwLjkiIGQ9Ik0yNDcuNjUzIDE4NC41MjRMMjEwLjQxNiAxNjkuMjRDMjEzLjYzNyAxNjYuODQyIDIyMi4yNTQgMTY3LjU5MiAyMzEuMzE5IDE3MS4zMzhDMjQwLjM4NSAxNzUuMDg0IDI0Ny4wNTMgMTgwLjU1MyAyNDcuNjUzIDE4NC41MjRaIiBmaWxsPSIjRkVGNUI4IiBzdHJva2U9IiNGRUY1QjgiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIG9wYWNpdHk9IjAuOSIgZD0iTTY3LjIzNTkgMTcwLjg4OEwzMC4wNzM2IDE4Ni4zMjNDMzMuMjk1MyAxODguNzIgNDEuODM2NyAxODcuOTcxIDUwLjkwMjUgMTg0LjIyNUM2MC4wNDMyIDE4MC40MDQgNjYuNjM2NSAxNzQuODU5IDY3LjIzNTkgMTcwLjg4OFoiIGZpbGw9IiNGRUY1QjgiIHN0cm9rZT0iI0ZFRjVCOCIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggb3BhY2l0eT0iMC45IiBkPSJNMjQ1LjEwNSA5NS4yODk5TDIwNy45NDMgMTEwLjc5OUMyMDguNTQyIDEwNi44MjggMjE1LjEzNiAxMDEuMjg0IDIyNC4yMDIgOTcuNTM3NkMyMzMuMjY3IDkzLjcxNjUgMjQxLjgwOSA5Mi44OTI0IDI0NS4xMDUgOTUuMjg5OVoiIGZpbGw9IiNGRUY1QjgiIHN0cm9rZT0iI0ZFRjVCOCIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggb3BhY2l0eT0iMC45IiBkPSJNMTEwLjA5MiA3My4wMzc3TDk0LjY1OCAzNS44NzU0QzkyLjI2MDQgMzkuMDk3MSA5My4wODQ2IDQ3LjcxMzQgOTYuODMwOCA1Ni43NzkyQzEwMC41NzcgNjUuODQ1IDEwNi4xMjEgNzIuNDM4MyAxMTAuMDkyIDczLjAzNzdaIiBmaWxsPSIjRkVGNUI4IiBzdHJva2U9IiNGRUY1QjgiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjwvZz4KPHBhdGggZD0iTTIwMy4xMyAxNzguOTM2QzE5OC4xMTkgMTc4LjIyIDE5Mi4zOTMgMTc3Ljc5MSAxOTAuMjQ2IDE3NS41NzJDMTg4LjQ1NyAxNzMuNzExIDE5Mi44OTQgMTY3LjYyNyAxODguNzQzIDE2MS44M0MxODcuODg0IDE2MC42ODUgMTg2LjUyNCAxNTkuNTM5IDE4NC45NSAxNTguNjA5VjEzOS43MTNDMTg0Ljk1IDEzNi4xMzUgMTgzLjE2IDEzMi44NDIgMTgwLjE1NCAxMzAuODM4TDE0NC40MzkgMTA4LjA3OEMxNDAuOTMyIDEwNS43ODcgMTM2LjQyMyAxMDUuNzg3IDEzMi45MTUgMTA4LjA3OEw5Ny4xMjg1IDEzMC45MUM5NC4xMjI0IDEzMi44NDIgOTIuMzMzIDEzNi4yMDYgOTIuMzMzIDEzOS43MTNWMTU4Ljc1MkM5MS4yNTk0IDE1OS4zOTYgOTAuMzI5IDE1OS45NjkgODkuNzU2NCAxNjAuMzk4QzgzLjk1ODkgMTY0LjMzNSA4OC4wMzg2IDE3MS40OTIgODUuODE5OCAxNzUuMjg2QzgzLjAyODQgMTc5Ljg2NiA4MC40NTE3IDE3OC44NjQgNzMuMDA4IDE4MC45NEM2Ni40OTQ4IDE4Mi42NTggNjMuNDE3MSAxOTQuMTgxIDg2LjUzNTUgMTg4LjQ1NUM4OS4xMTIyIDE4Ny44MTEgOTAuNTQzNiAxODcuNTI1IDkzLjQ3ODIgMTg5LjQ1N0MxMDAuNTY0IDE5My45NjYgOTMuMzM1MSAyMDguMjEgOTkuOTkxNCAyMTAuNDI4QzEwOS44NjkgMjEzLjcyMSAxMDIuNDI1IDE4OS40NTcgMTA4LjE1MSAxOTEuMDMyQzExMC44NzEgMTkyLjM5MiAxMTMuMzA0IDE5NC4zOTYgMTE0LjMwNiAxOTcuNjE3QzExNy4xNjkgMjA1LjIwNCAxMTIuNzMyIDIzMy4yNjEgMTIwLjAzMiAyMzQuNDc3QzEyOC40NzggMjM1Ljc2NiAxMjQuMTEyIDIwMy43IDEyOC4wNDggMjAyLjI2OUMxMzAuNDEgMjAxLjQxIDEzMi43MDEgMjA1LjU2MSAxMzguNDk4IDIwNi4yMDZDMTQzLjE1MSAyMDYuNzA3IDE0Ny45NDYgMjAzLjcgMTQ5LjY2NCAyMDIuMjY5QzE1NC41MzEgMTk4LjExOCAxNTcuODk1IDE5Ni41NDMgMTYxLjgzMSAxOTYuMTE0QzE3Mi4zNTMgMTk0Ljg5NyAxNjMuMTkxIDIyMC45NSAxNzIuOTk3IDIxOS44MDVDMTgxLjY1NyAyMTYuOTQyIDE3MS4yMDggMTk1LjA0IDE4Ni44MTEgMTg5LjI0M0MxOTIuODk0IDE4Ny4wOTUgMjA1LjA2MiAxOTAuMDMgMjA5LjI4NSAxODguMzEyQzIxMy4zNjUgMTg2LjUyMyAyMTEuNjQ3IDE3OS43OTUgMjAzLjEzIDE3OC45MzZaIiBmaWxsPSIjRkNFMzYzIi8+CjxwYXRoIGQ9Ik0xMjAuNTMzIDIzNS45MDlDMTIwLjMxOCAyMzUuOTA5IDEyMC4wMzIgMjM1LjkwOSAxMTkuODE3IDIzNS44MzdDMTE0LjE2MyAyMzQuOTA3IDExNC4wOTIgMjI0LjA5OSAxMTQuMDIgMjEyLjY0N0MxMTQuMDIgMjA2Ljc3OCAxMTMuOTQ4IDIwMC42OTQgMTEyLjk0NiAxOTguMDQ2VjE5Ny45NzVDMTEyLjIzMSAxOTUuNjg0IDExMC41MTMgMTkzLjgyMyAxMDcuNzIxIDE5Mi4zMkMxMDcuMTQ5IDE5My4xMDggMTA3LjA3NyAxOTYuODI5IDEwNy4wNzcgMTk5LjEyQzEwNy4wNzcgMjA0LjEzIDEwNy4wMDYgMjA5LjM1NSAxMDQuMjE0IDIxMS4zNTlDMTAyLjk5OCAyMTIuMjE4IDEwMS40MjMgMjEyLjM2MSA5OS41NjIgMjExLjc4OEM5NS4yNjc2IDIxMC4zNTcgOTUuMzM5MiAyMDUuNTYxIDk1LjQ4MjMgMjAwLjk4MUM5NS41NTM5IDE5Ni44MjkgOTUuNjI1NCAxOTIuNTM1IDkyLjc2MjUgMTkwLjY3NEM5MC4yNTc0IDE4OS4wMjggODkuMjU1NCAxODkuMjQzIDg2Ljk2NSAxODkuODg3QzcwLjcxNzcgMTkzLjg5NSA2Ny42NCAxODkuMzg2IDY3LjEzOSAxODcuMjM5QzY2LjM1MTcgMTg0LjE2MSA2OC45OTk5IDE4MC41ODIgNzIuNzkzMyAxNzkuNThDNzQuODY5IDE3OS4wMDggNzYuNTg2OCAxNzguNzIxIDc3Ljk0NjcgMTc4LjQzNUM4MS42Njg1IDE3Ny43MTkgODMuMDI4NCAxNzcuNDMzIDg0Ljc0NjIgMTc0LjY0MUM4NS4zOTA0IDE3My41NjggODUuMzE4OCAxNzEuNzc5IDg1LjI0NzIgMTY5LjkxOEM4NS4xMDQgMTY2LjQ4MiA4NC44ODkzIDE2Mi4xODggODkuMTEyMiAxNTkuMzI1Qzg5LjU0MTYgMTU4Ljk2NyA5MC4xODU4IDE1OC41MzcgOTEuMDQ0NyAxNTguMDM2VjEzOS43ODVDOTEuMDQ0NyAxMzUuNzc3IDkzLjEyMDMgMTMxLjkxMiA5Ni40ODQzIDEyOS43NjVMMTMyLjI3MSAxMDYuOTMyQzEzNi4yMDggMTA0LjM1NiAxNDEuMzYxIDEwNC4zNTYgMTQ1LjM2OSAxMDYuOTMyTDE4MS4wODUgMTI5LjY5M0MxODQuNTIgMTMxLjk4MyAxODYuNTI0IDEzNS43MDUgMTg2LjUyNCAxMzkuNzg1VjE1Ny44OTNDMTg3Ljk1NiAxNTguODI0IDE4OS4xNzMgMTU5Ljk2OSAxOTAuMDMyIDE2MS4wNDJDMTkyLjk2NiAxNjUuMTIyIDE5Mi4xNzkgMTY5LjI3MyAxOTEuNjc4IDE3Mi4wNjVDMTkxLjUzNSAxNzIuOTk1IDE5MS4yNDggMTc0LjM1NSAxOTEuNDYzIDE3NC42NDFDMTkyLjk2NiAxNzYuMjE2IDE5Ny40MDQgMTc2Ljc4OSAyMDEuMzQgMTc3LjI5QzIwMi4wNTYgMTc3LjM2MSAyMDIuNzcyIDE3Ny41MDQgMjAzLjQxNiAxNzcuNTc2QzIwOS43ODYgMTc4LjI5MiAyMTIuNTA2IDE4MS43MjcgMjEyLjkzNSAxODQuNDQ3QzIxMy4yOTMgMTg2LjY2NiAyMTIuMTQ4IDE4OC43NDIgMjEwLjAwMSAxODkuNjcyQzIwNy43MSAxOTAuNjAyIDIwMy45MTcgMTkwLjM4OCAxOTkuNjIyIDE5MC4xMDFDMTk1LjMyOCAxODkuODg3IDE5MC4zODkgMTg5LjYgMTg3LjQ1NSAxOTAuNjAyQzE3OS40MzkgMTkzLjYwOSAxNzkuMDgxIDIwMS4xOTUgMTc4Ljc5NCAyMDguNTY4QzE3OC41MDggMjE0LjI5MyAxNzguMjkzIDIxOS42NjIgMTczLjY0MSAyMjEuMjM2TDE3My4zNTUgMjIxLjMwOEMxNzEuNzggMjIxLjUyMiAxNzAuNDIgMjIxLjE2NSAxNjkuMzQ3IDIyMC4yMzRDMTY2Ljc3IDIxOC4wODcgMTY2LjYyNyAyMTMuMzYzIDE2Ni40MTIgMjA4LjQyNEMxNjYuMjY5IDIwNC4zNDUgMTY2LjA1NCAxOTkuNjkyIDE2NC4zMzYgMTk4LjE4OUMxNjMuOTc5IDE5Ny45MDMgMTYzLjQwNiAxOTcuNTQ1IDE2Mi4xODkgMTk3LjY4OEMxNTguMzk2IDE5OC4xMTggMTU1LjI0NyAxOTkuNjkyIDE1MC44MDkgMjAzLjQ4NkMxNTAuNTIzIDIwMy43MDEgMTQ0Ljc5NyAyMDguNDI0IDEzOC41NyAyMDcuNzhDMTM1LjEzNCAyMDcuNDIyIDEzMi44NDQgMjA1LjkxOSAxMzEuMTI2IDIwNC44NDZDMTMwLjEyNCAyMDQuMjAyIDEyOS4yNjUgMjAzLjcwMSAxMjguODM2IDIwMy43NzJDMTI4LjA0OCAyMDQuODQ2IDEyNy43NjIgMjEwLjcxNSAxMjcuNjE5IDIxNS4wMDlDMTI3LjI2MSAyMjMuNTI3IDEyNi45MDMgMjMyLjMzIDEyMy4zOTYgMjM1LjE5M0MxMjIuMzk0IDIzNS41NTEgMTIxLjQ2NCAyMzUuOTA5IDEyMC41MzMgMjM1LjkwOVpNMTE1LjY2NiAxOTcuMTE2QzExNi44MTEgMjAwLjI2NSAxMTYuODgzIDIwNi4yNzcgMTE2Ljg4MyAyMTIuNjQ3QzExNi44ODMgMjIwLjUyIDExNi45NTQgMjMyLjQ3MyAxMjAuMjQ3IDIzMy4wNDZDMTIwLjY3NiAyMzMuMTE3IDEyMS4wMzQgMjMzLjA0NiAxMjEuMzIxIDIzMi43NkMxMjMuODI2IDIzMC43NTYgMTI0LjE4MyAyMjEuNDUxIDEyNC40NyAyMTQuNjUxQzEyNC44MjggMjA1Ljk5MSAxMjUuMTE0IDIwMS43NjggMTI3LjQ3NiAyMDAuOTA5QzEyOS4yNjUgMjAwLjI2NSAxMzAuNzY4IDIwMS4yNjcgMTMyLjQxNCAyMDIuMjY5QzEzNC4wNjEgMjAzLjI3MSAxMzUuODUgMjA0LjQ4OCAxMzguNTcgMjA0Ljc3NEMxNDIuNzkzIDIwNS4yMDQgMTQ3LjMwMiAyMDIuMzQxIDE0OC42NjIgMjAxLjE5NUMxNTMuNTI5IDE5Ny4wNDQgMTU3LjE3OSAxOTUuMTgzIDE2MS42MTcgMTk0LjY4MkMxNjMuMzM0IDE5NC40NjcgMTY0LjgzOCAxOTQuODk3IDE2NS45ODMgMTk1LjgyN0MxNjguNzAzIDE5OC4xMTggMTY4LjkxNyAyMDIuOTg1IDE2OS4wNiAyMDguMTM4QzE2OS4yMDQgMjEyLjA3NSAxNjkuNDE4IDIxNi41ODQgMTcwLjk5MyAyMTcuOTQ0QzE3MS4yNzkgMjE4LjE1OCAxNzEuNzA5IDIxOC40NDUgMTcyLjYzOSAyMTguMzczQzE3NS4xNDQgMjE3LjQ0MyAxNzUuNDMgMjEzLjkzNiAxNzUuNjQ1IDIwOC4zNTNDMTc2LjAwMyAyMDAuODM4IDE3Ni4zNjEgMTkxLjUzMyAxODYuMjM4IDE4Ny44ODNDMTg5Ljc0NSAxODYuNjY2IDE5NC43NTUgMTg2Ljk1MiAxOTkuNTUxIDE4Ny4yMzlDMjAzLjIwMSAxODcuNDUzIDIwNi45OTUgMTg3LjY2OCAyMDguNjQxIDE4Ny4wMjRDMjA5LjU3MSAxODYuNjY2IDIxMC4wMDEgMTg1Ljg3OSAyMDkuODU4IDE4NC44NzdDMjA5LjU3MSAxODMuMDg3IDIwNy4yODEgMTgwLjg2OCAyMDIuODQzIDE4MC40MzlIMjAyLjc3MkMyMDIuMDU2IDE4MC4zNjcgMjAxLjQxMiAxODAuMjI0IDIwMC42OTYgMTgwLjE1M0MxOTUuODI5IDE3OS41MDkgMTkxLjMyIDE3OC45MzYgMTg5LjEwMSAxNzYuNjQ2QzE4Ny44ODQgMTc1LjM1NyAxODguMjQyIDE3My40OTYgMTg4LjYgMTcxLjU2NEMxODkuMTAxIDE2OC45ODcgMTg5LjY3NCAxNjUuNzY2IDE4Ny40NTUgMTYyLjc2QzE4Ni43MzkgMTYxLjgzIDE4NS41MjIgMTYwLjc1NiAxODQuMDkxIDE1OS45NjlMMTgzLjM3NSAxNTkuNTM5VjEzOS44NTdDMTgzLjM3NSAxMzYuNzc5IDE4MS44MDEgMTMzLjkxNiAxNzkuMjI0IDEzMi4xOThMMTQzLjY1MiAxMDkuMjIzQzE0MC42NDUgMTA3LjIxOSAxMzYuNzA5IDEwNy4yMTkgMTMzLjcwMyAxMDkuMjIzTDk3LjkxNTggMTMyLjA1NUM5NS4zMzkxIDEzMy43MDEgOTMuNzY0NSAxMzYuNjM2IDkzLjc2NDUgMTM5LjY0MlYxNTkuNDY4TDkzLjA0ODggMTU5Ljg5N0M5Mi4xMTgzIDE2MC40NyA5MS4xMTYzIDE2MS4wNDIgOTAuNjE1MiAxNjEuNDcyQzg3LjY4MDcgMTYzLjQ3NiA4Ny44MjM5IDE2Ni40ODIgODcuOTY3IDE2OS42MzFDODguMDM4NiAxNzEuODUgODguMTgxOCAxNzQuMTQgODcuMTA4MSAxNzYuMDAxQzg0Ljc0NjIgMTc5LjkzOCA4Mi4yNDExIDE4MC40MzkgNzguNDQ3NyAxODEuMTU1Qzc3LjAxNjIgMTgxLjQ0MSA3NS40NDE2IDE4MS43MjcgNzMuNTA5MSAxODIuM0M3MS4wNzU2IDE4Mi45NDQgNjkuNTcyNSAxODUuMDkxIDY5LjkzMDQgMTg2LjQ1MUM3MC4zNTk4IDE4OC4wOTcgNzQuMjk2NCAxOTAuMDMgODYuMzIwOCAxODcuMDk1Qzg5LjExMjIgMTg2LjM4IDkxLjA0NDcgMTg2LjA5MyA5NC40MDg3IDE4OC4zMTJDOTguNzAzMSAxOTEuMDMyIDk4LjU2IDE5Ni40IDk4LjQ4ODQgMjAxLjEyNEM5OC40MTY4IDIwNS42MzMgOTguNDg4NCAyMDguNDk2IDEwMC42MzYgMjA5LjIxMkMxMDIuMDY3IDIwOS43MTMgMTAyLjU2OCAyMDkuMzU1IDEwMi43MTEgMjA5LjIxMkMxMDQuMzU3IDIwOC4wNjcgMTA0LjM1NyAyMDIuOTg1IDEwNC4zNTcgMTk5LjMzNUMxMDQuMzU3IDE5NC45NjggMTA0LjQyOSAxOTEuNjA1IDEwNi4yMTggMTkwLjI0NUMxMDYuNzE5IDE4OS44ODcgMTA3LjUwNyAxODkuNTI5IDEwOC43MjMgMTg5LjgxNUwxMDkuMDEgMTg5Ljg4N0MxMTIuNDQ1IDE5MS41MzMgMTE0LjczNiAxOTMuOTY2IDExNS42NjYgMTk3LjExNloiIGZpbGw9IiMwMTAwMDQiLz4KPHBhdGggZD0iTTE1MC4wMjIgMTY2LjEyNEMxNTIuODEzIDE3MC4zNDcgMTQ2LjA4NSAxOTQuMTEgMTM4LjI4NCAxOTQuMTFDMTI4LjY5MyAxOTQuMTEgMTIzLjg5NyAxNjkuODQ2IDEyNi40NzQgMTY2LjEyNEMxMjcuOTA1IDE2NC4wNDkgMTMxLjQxMyAxNjguMzQzIDEzOC42NDEgMTY4LjM0M0MxNDUuMzY5IDE2OC4zNDMgMTQ4LjU5IDE2My45MDUgMTUwLjAyMiAxNjYuMTI0WiIgZmlsbD0iIzAxMDAwNCIvPgo8cGF0aCBkPSJNMTc1LjIxNiAxNTkuNjgzQzE3Ni45MzQgMTYwLjExMiAxNzguMjkzIDE1OC4zMjMgMTc3LjA3NyAxNTcuMTc4QzE3NS4yODcgMTU1LjYwMyAxNzIuMTM4IDE1My4xNjkgMTY2LjU1NSAxNTMuMTY5QzE2MS4xMTYgMTUzLjE2OSAxNTcuNzUyIDE1NS42MDMgMTU1LjY3NiAxNTcuMjQ5QzE1NC4yNDUgMTU4LjM5NCAxNTUuNjc2IDE2MC4zMjcgMTU3LjUzNyAxNTkuODI2QzE2MC4wNDIgMTU5LjE4MiAxNjMuMjYzIDE1Ny42MDcgMTY2LjY5OCAxNTcuNjA3QzE3MC4xMzQgMTU3Ljc1IDE3My4wNjkgMTU5LjE4MiAxNzUuMjE2IDE1OS42ODNaIiBmaWxsPSIjMDEwMDA0Ii8+CjxwYXRoIGQ9Ik0xMTkuMTAyIDE1OS42ODNDMTIwLjgxOSAxNjAuMTEyIDEyMi4xNzkgMTU4LjMyMyAxMjAuOTYzIDE1Ny4xNzhDMTE5LjE3MyAxNTUuNjAzIDExNi4wMjQgMTUzLjE2OSAxMTAuNDQxIDE1My4xNjlDMTA1LjAwMiAxNTMuMTY5IDEwMS42MzggMTU1LjYwMyA5OS41NjIgMTU3LjI0OUM5OC4xMzA1IDE1OC4zOTQgOTkuNTYyIDE2MC4zMjcgMTAxLjQyMyAxNTkuODI2QzEwMy45MjggMTU5LjE4MiAxMDcuMTQ5IDE1Ny42MDcgMTEwLjU4NCAxNTcuNjA3QzExNC4wOTIgMTU3Ljc1IDExNi45NTUgMTU5LjE4MiAxMTkuMTAyIDE1OS42ODNaIiBmaWxsPSIjMDEwMDA0Ii8+CjxwYXRoIGQ9Ik0xMDkuODY5IDE4Mi41ODZDMTE2LjE1NCAxODIuNTg2IDEyMS4yNDkgMTc4LjUxNyAxMjEuMjQ5IDE3My40OTZDMTIxLjI0OSAxNjguNDc2IDExNi4xNTQgMTY0LjQwNiAxMDkuODY5IDE2NC40MDZDMTAzLjU4MyAxNjQuNDA2IDk4LjQ4ODMgMTY4LjQ3NiA5OC40ODgzIDE3My40OTZDOTguNDg4MyAxNzguNTE3IDEwMy41ODMgMTgyLjU4NiAxMDkuODY5IDE4Mi41ODZaIiBmaWxsPSIjRkVGNUI4Ii8+CjxwYXRoIGQ9Ik0xNjYuNjk4IDE4Mi41ODZDMTcyLjk4MyAxODIuNTg2IDE3OC4wNzkgMTc4LjUxNyAxNzguMDc5IDE3My40OTZDMTc4LjA3OSAxNjguNDc2IDE3Mi45ODMgMTY0LjQwNiAxNjYuNjk4IDE2NC40MDZDMTYwLjQxMyAxNjQuNDA2IDE1NS4zMTggMTY4LjQ3NiAxNTUuMzE4IDE3My40OTZDMTU1LjMxOCAxNzguNTE3IDE2MC40MTMgMTgyLjU4NiAxNjYuNjk4IDE4Mi41ODZaIiBmaWxsPSIjRkVGNUI4Ii8+CjxwYXRoIGQ9Ik0xMzMuMjAyIDE1Mi4wOTZMMTA3LjQzNSAxMzYuMjA2QzEwNS45MzIgMTM1LjI3NiAxMDUuOTMyIDEzMy4wNTcgMTA3LjQzNSAxMzIuMTI3TDEzMy4yMDIgMTE2LjIzN0MxMzYuMzUxIDExNC4zMDUgMTQwLjI4OCAxMTQuMzA1IDE0My40MzcgMTE2LjIzN0wxNjkuMjAzIDEzMi4xMjdDMTcwLjcwNiAxMzMuMDU3IDE3MC43MDYgMTM1LjI3NiAxNjkuMjAzIDEzNi4yMDZMMTQzLjQzNyAxNTIuMDk2QzE0MC4yODggMTU0LjAyOCAxMzYuMjc5IDE1NC4wMjggMTMzLjIwMiAxNTIuMDk2WiIgZmlsbD0iI0ZFRjVCOCIvPgo8cGF0aCBkPSJNMTM1LjYzNSAxOTAuMzg4QzEzMi4yNzEgMTg3LjgxMSAxMzMuMjAyIDE3OC41NzggMTM5LjE0MiAxNzcuNTA0QzE0NC4xNTMgMTc2LjU3NCAxNDYuNTE1IDE3OC4yMiAxNDMuMzY1IDE4NC45NDhDMTQwLjIxNiAxOTEuODkxIDEzNy4yMSAxOTEuNTMzIDEzNS42MzUgMTkwLjM4OFoiIGZpbGw9IiNGRUY1QjgiLz4KPC9zdmc+Cg==" ADMIN_PASSWORD = "admin" - DISABLE_ACCESS_POINT = "false" - DISABLE_CHAT = "false" - DISABLE_APP_STORE = "false" - DISABLE_MAP_VIEWER = "false" - DISABLE_FILE_VIEWER = "false" + ENABLE_ACCESS_POINT = "true" + ENABLE_CHAT = "true" + ENABLE_APP_STORE = "true" + ENABLE_MAP_VIEWER = "true" + ENABLE_FILE_VIEWER = "true" + ENABLE_DELTACHAT = "true" CONVENE_INSTALL_PATH = "/chat" \ No newline at end of file