mirror of
				https://github.com/DarkflameUniverse/NexusDashboard.git
				synced 2025-10-31 12:31:54 +00:00 
			
		
		
		
	feat: add recaptcha support
This commit is contained in:
		| @@ -204,19 +204,23 @@ def register_settings(app): | |||||||
|     # Load environment specific settings |     # Load environment specific settings | ||||||
|     app.config['TESTING'] = False |     app.config['TESTING'] = False | ||||||
|     app.config['DEBUG'] = False |     app.config['DEBUG'] = False | ||||||
|  |     app.config['SQLALCHEMY_ENGINE_OPTIONS'] = { | ||||||
|  |         "pool_pre_ping": True, | ||||||
|  |         "pool_size": 10, | ||||||
|  |         "max_overflow": 2, | ||||||
|  |         "pool_recycle": 300, | ||||||
|  |         "pool_pre_ping": True, | ||||||
|  |         "pool_use_lifo": True | ||||||
|  |     } | ||||||
|  |  | ||||||
|     # always pull these two from the env |  | ||||||
|     app.config['SECRET_KEY'] = os.getenv( |     app.config['SECRET_KEY'] = os.getenv( | ||||||
|         'APP_SECRET_KEY', |         'APP_SECRET_KEY', | ||||||
|         app.config['APP_SECRET_KEY'] |         app.config['APP_SECRET_KEY'] | ||||||
|  |  | ||||||
|     ) |     ) | ||||||
|     app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv( |     app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv( | ||||||
|         'APP_DATABASE_URI', |         'APP_DATABASE_URI', | ||||||
|         app.config['APP_DATABASE_URI'] |         app.config['APP_DATABASE_URI'] | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     # try to get overides, otherwise just use what we have already |  | ||||||
|     app.config['USER_ENABLE_REGISTER'] = os.getenv( |     app.config['USER_ENABLE_REGISTER'] = os.getenv( | ||||||
|         'USER_ENABLE_REGISTER', |         'USER_ENABLE_REGISTER', | ||||||
|         app.config['USER_ENABLE_REGISTER'] |         app.config['USER_ENABLE_REGISTER'] | ||||||
| @@ -241,14 +245,6 @@ def register_settings(app): | |||||||
|         'USER_REQUIRE_INVITATION', |         'USER_REQUIRE_INVITATION', | ||||||
|         app.config['USER_REQUIRE_INVITATION'] |         app.config['USER_REQUIRE_INVITATION'] | ||||||
|     ) |     ) | ||||||
|     app.config['SQLALCHEMY_ENGINE_OPTIONS'] = { |  | ||||||
|         "pool_pre_ping": True, |  | ||||||
|         "pool_size": 10, |  | ||||||
|         "max_overflow": 2, |  | ||||||
|         "pool_recycle": 300, |  | ||||||
|         "pool_pre_ping": True, |  | ||||||
|         "pool_use_lifo": True |  | ||||||
|     } |  | ||||||
|     app.config['MAIL_SERVER'] = os.getenv( |     app.config['MAIL_SERVER'] = os.getenv( | ||||||
|         'MAIL_SERVER', |         'MAIL_SERVER', | ||||||
|         app.config['MAIL_SERVER'] |         app.config['MAIL_SERVER'] | ||||||
| @@ -312,6 +308,41 @@ def register_settings(app): | |||||||
|         app.config['CACHE_LOCATION'] |         app.config['CACHE_LOCATION'] | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|  |     # Recaptcha settings | ||||||
|  |     if "RECAPTCHA_ENABLE" not in app.config: | ||||||
|  |         app.config['RECAPTCHA_ENABLE'] = False | ||||||
|  |     app.config['RECAPTCHA_ENABLE'] = os.getenv( | ||||||
|  |         'RECAPTCHA_ENABLE', | ||||||
|  |         app.config['RECAPTCHA_ENABLE'] | ||||||
|  |     ) | ||||||
|  |     if "RECAPTCHA_PUBLIC_KEY" not in app.config: | ||||||
|  |         app.config['RECAPTCHA_PUBLIC_KEY'] = '' | ||||||
|  |     app.config['RECAPTCHA_PUBLIC_KEY'] = os.getenv( | ||||||
|  |         'RECAPTCHA_PUBLIC_KEY', | ||||||
|  |         app.config['RECAPTCHA_PUBLIC_KEY'] | ||||||
|  |     ) | ||||||
|  |     if "RECAPTCHA_PRIVATE_KEY" not in app.config: | ||||||
|  |         app.config['RECAPTCHA_PRIVATE_KEY'] = '' | ||||||
|  |     app.config['RECAPTCHA_PRIVATE_KEY'] = os.getenv( | ||||||
|  |         'RECAPTCHA_PRIVATE_KEY', | ||||||
|  |         app.config['RECAPTCHA_PRIVATE_KEY'] | ||||||
|  |     ) | ||||||
|  |     # Optional | ||||||
|  |     app.config['RECAPTCHA_API_SERVER'] = os.getenv( | ||||||
|  |         'RECAPTCHA_API_SERVER', | ||||||
|  |         app.config['RECAPTCHA_API_SERVER'] | ||||||
|  |     ) | ||||||
|  |     app.config['RECAPTCHA_PARAMETERS'] = os.getenv( | ||||||
|  |         'RECAPTCHA_PARAMETERS', | ||||||
|  |         app.config['RECAPTCHA_PARAMETERS'] | ||||||
|  |     ) | ||||||
|  |     if "RECAPTCHA_DATA_ATTRS" not in app.config: | ||||||
|  |         app.config['RECAPTCHA_DATA_ATTRS'] = {'theme': 'white', 'size': 'invisible'} | ||||||
|  |     app.config['RECAPTCHA_DATA_ATTRS'] = os.getenv( | ||||||
|  |         'RECAPTCHA_DATA_ATTRS', | ||||||
|  |         app.config['RECAPTCHA_DATA_ATTRS'] | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def gm_level(gm_level): | def gm_level(gm_level): | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| from flask_wtf import FlaskForm | from flask_wtf import FlaskForm | ||||||
|  | from flask_wtf.recaptcha import RecaptchaField | ||||||
| from flask import current_app | from flask import current_app | ||||||
|  |  | ||||||
| from flask_user.forms import ( | from flask_user.forms import ( | ||||||
| @@ -85,6 +86,10 @@ class CustomRegisterForm(FlaskForm): | |||||||
|  |  | ||||||
|     invite_token = HiddenField('Token') |     invite_token = HiddenField('Token') | ||||||
|      |      | ||||||
|  |     # Use recaptcha if config enables recaptcha | ||||||
|  |     if current_app.config["ENABLE_RECAPTCHA"]: | ||||||
|  |         recaptcha = RecaptchaField() | ||||||
|  |  | ||||||
|     submit = SubmitField('Register') |     submit = SubmitField('Register') | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -61,3 +61,13 @@ USER_AFTER_LOGOUT_ENDPOINT = "main.index" | |||||||
|  |  | ||||||
| # Option will be removed once this feature is full implemeted | # Option will be removed once this feature is full implemeted | ||||||
| ENABLE_CHAR_XML_UPLOAD = False | ENABLE_CHAR_XML_UPLOAD = False | ||||||
|  |  | ||||||
|  | # Recaptcha settings | ||||||
|  | # See: https://flask-wtf.readthedocs.io/en/1.2.x/form/#recaptcha | ||||||
|  | RECAPTCHA_ENABLE = False | ||||||
|  | RECAPTCHA_PUBLIC_KEY = '' | ||||||
|  | RECAPTCHA_PRIVATE_KEY = '' | ||||||
|  | # Optional | ||||||
|  | # RECAPTCHA_API_SERVER = '' | ||||||
|  | # RECAPTCHA_PARAMETERS = '' | ||||||
|  | RECAPTCHA_DATA_ATTRS = {'theme': 'white', 'size': 'invisible'} | ||||||
|   | |||||||
| @@ -1,188 +0,0 @@ | |||||||
| {% extends "bootstrap/base.html" %} |  | ||||||
| {% block title %}Key Creation{% endblock %} |  | ||||||
|  |  | ||||||
| {% block navbar %} |  | ||||||
| <nav class="navbar navbar-default"> |  | ||||||
|   <div class="container-fluid"> |  | ||||||
|     <div class="navbar-header"> |  | ||||||
|       <a class="navbar-brand" href="{{ url_for('dashboard') }}">Dashboard</a> |  | ||||||
|     </div> |  | ||||||
|     <ul class="nav navbar-nav"> |  | ||||||
|     </ul> |  | ||||||
|     <ul class="nav navbar-nav" style="float: right"> |  | ||||||
|       <li class="active"><a href="#">Welcome {{ current_user.username }}!</a></li> |  | ||||||
|       <li><a href="{{ url_for('logout') }}">Logout</a></li> |  | ||||||
|     </ul> |  | ||||||
|   </div> |  | ||||||
| </nav> |  | ||||||
| {% endblock navbar %}} |  | ||||||
|  |  | ||||||
| {% block content %} |  | ||||||
| {# LOGO #} |  | ||||||
| <div class="container" style="margin-top: 50px"> |  | ||||||
|  |  | ||||||
|     {# Display logo #} |  | ||||||
|     <div style="margin-bottom: 50px"> |  | ||||||
|         <img |  | ||||||
|                 src="{{ url_for('static', filename=resources.LOGO) }}" |  | ||||||
|                 class="center-block img-responsive mx-auto d-block" |  | ||||||
|                 alt="Logo" |  | ||||||
|                 width="100" |  | ||||||
|                 height="100" |  | ||||||
|         > |  | ||||||
|     </div> |  | ||||||
|  |  | ||||||
| </div> |  | ||||||
|  |  | ||||||
| {# Key creation #} |  | ||||||
| <div class="container"> |  | ||||||
|     <div class="text-center"> |  | ||||||
|         <h3>Key Creation</h3> |  | ||||||
|     </div> |  | ||||||
|  |  | ||||||
|     <div class="col-lg-3"> |  | ||||||
|     </div> |  | ||||||
|     <div class="col-lg-6"> |  | ||||||
|  |  | ||||||
|     {# If the error value is set, display the error in red text #} |  | ||||||
|     {% if error %} |  | ||||||
|         <div class="alert alert-danger"> |  | ||||||
|             {{ error }} |  | ||||||
|         </div> |  | ||||||
|     {% endif %} |  | ||||||
|  |  | ||||||
|     {# If the message value is set, display the message in green text #} |  | ||||||
|     {% if message %} |  | ||||||
|         <div class="alert alert-success"> |  | ||||||
|             {{ message }} |  | ||||||
|         </div> |  | ||||||
|     {% endif %} |  | ||||||
|  |  | ||||||
|     {# Form which takes in Admin Username, Admin Password, and the amount of keys to create. #} |  | ||||||
|     <form action="{{ url_for('dashboard') }}" method="post"> |  | ||||||
|         {# Key count input #} |  | ||||||
|         <div class="form-group"> |  | ||||||
|             <label for="key_count">Generate keys</label> |  | ||||||
|             <input type="number" class="form-control" name="key_count" placeholder="Enter number of keys..."> |  | ||||||
|             <small class="form-text text-muted">Number of keys to create.</small> |  | ||||||
|         </div> |  | ||||||
|          |  | ||||||
|         {# Submit button #} |  | ||||||
|         <div class="form-group"> |  | ||||||
|             <button type="submit" class="btn btn-primary">Generate Keys</button> |  | ||||||
|         </div> |  | ||||||
|     </form> |  | ||||||
|  |  | ||||||
|     {# If the keys value is set, create a list for each key in keys #} |  | ||||||
|     {% if keys %} |  | ||||||
|         <div class="alert alert-success"> |  | ||||||
|             <ul> |  | ||||||
|                 {% for key in keys %} |  | ||||||
|                     <li>{{ key }}</li> |  | ||||||
|                 {% endfor %} |  | ||||||
|             </ul> |  | ||||||
|         </div> |  | ||||||
|     {% endif %} |  | ||||||
|     </div> |  | ||||||
|     <div class="col-lg-3"> |  | ||||||
|     </div> |  | ||||||
|     </div> |  | ||||||
| </div> |  | ||||||
|  |  | ||||||
| {# Activity graphs #} |  | ||||||
| <div class="container"> |  | ||||||
|  |  | ||||||
|     <div class="text-center"> |  | ||||||
|         <h3>Activity</h3> |  | ||||||
|     </div> |  | ||||||
|  |  | ||||||
|     <div class="col-lg-3"> |  | ||||||
|     </div> |  | ||||||
|  |  | ||||||
|     <div class="col-lg-6"> |  | ||||||
|  |  | ||||||
|     <canvas id="sessions_graph" width="400" height="400"></canvas> |  | ||||||
|     <canvas id="play_time_graph" width="400" height="400"></canvas> |  | ||||||
|     <canvas id="zone_play_time_graph" width="400" height="400"></canvas> |  | ||||||
|  |  | ||||||
|     </div> |  | ||||||
|  |  | ||||||
|     <div class="col-lg-3"> |  | ||||||
|     </div> |  | ||||||
| </div> |  | ||||||
| {% endblock %} |  | ||||||
|  |  | ||||||
| {% block scripts %} |  | ||||||
| <script src="https://cdn.jsdelivr.net/npm/chart.js@3.5.1/dist/chart.min.js"></script> |  | ||||||
| <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| // Make a get request to the server to load the activity data |  | ||||||
| $.get("{{ url_for('load_activities') }}", function(data) { |  | ||||||
|  |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| // Make a get request to the server to get the activity data for "sessions" |  | ||||||
| $.get("{{ url_for('activity_data', name='sessions') }}", function(data) { |  | ||||||
|     // Load data as a json object |  | ||||||
|     data = JSON.parse(data); |  | ||||||
|     var ctx = document.getElementById('sessions_graph').getContext('2d'); |  | ||||||
|     var myChart = new Chart(ctx, { |  | ||||||
|         type: 'line', |  | ||||||
|         data: { |  | ||||||
|             labels: data.labels, |  | ||||||
|             datasets: data.datasets |  | ||||||
|         }, |  | ||||||
|         options: { |  | ||||||
|             scales: { |  | ||||||
|                 y: { |  | ||||||
|                     beginAtZero: true |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     }); |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| // Make a get request to the server to get the activity data for "play_time" |  | ||||||
| $.get("{{ url_for('activity_data', name='play_time') }}", function(data) { |  | ||||||
|     // Load data as a json object |  | ||||||
|     data = JSON.parse(data); |  | ||||||
|     var ctx = document.getElementById('play_time_graph').getContext('2d'); |  | ||||||
|     var myChart = new Chart(ctx, { |  | ||||||
|         type: 'line', |  | ||||||
|         data: { |  | ||||||
|             labels: data.labels, |  | ||||||
|             datasets: data.datasets |  | ||||||
|         }, |  | ||||||
|         options: { |  | ||||||
|             scales: { |  | ||||||
|                 y: { |  | ||||||
|                     beginAtZero: true |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     }); |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| // Make a get request to the server to get the activity data for "zone_play_time" |  | ||||||
| $.get("{{ url_for('activity_data', name='zone_play_time') }}", function(data) { |  | ||||||
|     // Load data as a json object |  | ||||||
|     data = JSON.parse(data); |  | ||||||
|     var ctx = document.getElementById('zone_play_time_graph').getContext('2d'); |  | ||||||
|     var myChart = new Chart(ctx, { |  | ||||||
|         type: 'line', |  | ||||||
|         data: { |  | ||||||
|             labels: data.labels, |  | ||||||
|             datasets: data.datasets |  | ||||||
|         }, |  | ||||||
|         options: { |  | ||||||
|             scales: { |  | ||||||
|                 y: { |  | ||||||
|                     beginAtZero: true |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     }); |  | ||||||
| }); |  | ||||||
| </script> |  | ||||||
| {% endblock scripts %}} |  | ||||||
| @@ -82,7 +82,6 @@ | |||||||
|         </div> |         </div> | ||||||
|       {% endif %} |       {% endif %} | ||||||
|  |  | ||||||
|  |  | ||||||
|       <div class="row"> |       <div class="row"> | ||||||
|         <div class="col text-right"> |         <div class="col text-right"> | ||||||
|           Source |           Source | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 aronwk-aaron
					aronwk-aaron