minor tweaks on otp_force
This commit is contained in:
parent
8d76ff2e29
commit
60b84162fa
|
@ -23,6 +23,7 @@ css_login = Bundle('node_modules/bootstrap/dist/css/bootstrap.css',
|
||||||
js_login = Bundle('node_modules/jquery/dist/jquery.js',
|
js_login = Bundle('node_modules/jquery/dist/jquery.js',
|
||||||
'node_modules/bootstrap/dist/js/bootstrap.js',
|
'node_modules/bootstrap/dist/js/bootstrap.js',
|
||||||
'node_modules/icheck/icheck.js',
|
'node_modules/icheck/icheck.js',
|
||||||
|
'custom/js/custom.js',
|
||||||
filters=(ConcatFilter, 'jsmin'),
|
filters=(ConcatFilter, 'jsmin'),
|
||||||
output='generated/login.js')
|
output='generated/login.js')
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,9 @@ import ldap.filter
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
from flask_login import AnonymousUserMixin
|
from flask_login import AnonymousUserMixin
|
||||||
from sqlalchemy import orm
|
from sqlalchemy import orm
|
||||||
|
import qrcode as qrc
|
||||||
|
import qrcode.image.svg as qrc_svg
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
from .base import db
|
from .base import db
|
||||||
from .role import Role
|
from .role import Role
|
||||||
|
@ -633,6 +636,13 @@ class User(db.Model):
|
||||||
for q in query:
|
for q in query:
|
||||||
accounts.append(q[1])
|
accounts.append(q[1])
|
||||||
return accounts
|
return accounts
|
||||||
|
|
||||||
|
def get_qrcode_value(self):
|
||||||
|
img = qrc.make(self.get_totp_uri(),
|
||||||
|
image_factory=qrc_svg.SvgPathImage)
|
||||||
|
stream = BytesIO()
|
||||||
|
img.save(stream)
|
||||||
|
return stream.getvalue()
|
||||||
|
|
||||||
|
|
||||||
def read_entitlements(self, key):
|
def read_entitlements(self, key):
|
||||||
|
@ -794,7 +804,4 @@ def getUserInfo(DomainsOrAccounts):
|
||||||
current=[]
|
current=[]
|
||||||
for DomainOrAccount in DomainsOrAccounts:
|
for DomainOrAccount in DomainsOrAccounts:
|
||||||
current.append(DomainOrAccount.name)
|
current.append(DomainOrAccount.name)
|
||||||
return current
|
return current
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -591,8 +591,7 @@ def authenticate_user(user, authenticator, remember=False):
|
||||||
# Prepare user to enter /welcome screen, otherwise they won't have permission to do so
|
# Prepare user to enter /welcome screen, otherwise they won't have permission to do so
|
||||||
def prepare_welcome_user(user_id):
|
def prepare_welcome_user(user_id):
|
||||||
logout_user()
|
logout_user()
|
||||||
session['user_id'] = user_id
|
session['welcome_user_id'] = user_id
|
||||||
session['welcome'] = True
|
|
||||||
|
|
||||||
@index_bp.route('/logout')
|
@index_bp.route('/logout')
|
||||||
def logout():
|
def logout():
|
||||||
|
@ -684,10 +683,8 @@ def register():
|
||||||
if Setting().get('verify_user_email'):
|
if Setting().get('verify_user_email'):
|
||||||
send_account_verification(email)
|
send_account_verification(email)
|
||||||
if Setting().get('otp_force') and Setting().get('otp_field_enabled'):
|
if Setting().get('otp_force') and Setting().get('otp_field_enabled'):
|
||||||
login_user(user)
|
user.update_profile(enable_otp=True)
|
||||||
current_user.update_profile(enable_otp=True)
|
prepare_welcome_user(user.id)
|
||||||
user_id = current_user.id
|
|
||||||
prepare_welcome_user(user_id)
|
|
||||||
return redirect(url_for('index.welcome'))
|
return redirect(url_for('index.welcome'))
|
||||||
else:
|
else:
|
||||||
return redirect(url_for('index.login'))
|
return redirect(url_for('index.login'))
|
||||||
|
@ -703,14 +700,11 @@ def register():
|
||||||
# Show welcome page on first login if otp_force is enabled
|
# Show welcome page on first login if otp_force is enabled
|
||||||
@index_bp.route('/welcome', methods=['GET', 'POST'])
|
@index_bp.route('/welcome', methods=['GET', 'POST'])
|
||||||
def welcome():
|
def welcome():
|
||||||
if 'welcome' not in session:
|
if 'welcome_user_id' not in session:
|
||||||
return redirect(url_for('index.index'))
|
return redirect(url_for('index.index'))
|
||||||
|
|
||||||
user_id = session['user_id']
|
user = User(id = session['welcome_user_id'])
|
||||||
user = User(id = user_id)
|
encoded_img_data = base64.b64encode(user.get_qrcode_value())
|
||||||
login_user(user)
|
|
||||||
encoded_img_data = base64.b64encode(qrcode()[0])
|
|
||||||
prepare_welcome_user(user_id)
|
|
||||||
|
|
||||||
if request.method == 'GET':
|
if request.method == 'GET':
|
||||||
return render_template('register_otp.html', qrcode_image=encoded_img_data.decode(), user=user)
|
return render_template('register_otp.html', qrcode_image=encoded_img_data.decode(), user=user)
|
||||||
|
@ -722,7 +716,7 @@ def welcome():
|
||||||
return render_template('register_otp.html', qrcode_image=encoded_img_data.decode(), user=user, error="Invalid token")
|
return render_template('register_otp.html', qrcode_image=encoded_img_data.decode(), user=user, error="Invalid token")
|
||||||
else:
|
else:
|
||||||
return render_template('register_otp.html', qrcode_image=encoded_img_data.decode(), user=user, error="Token required")
|
return render_template('register_otp.html', qrcode_image=encoded_img_data.decode(), user=user, error="Token required")
|
||||||
session.pop('welcome')
|
session.pop('welcome_user_id')
|
||||||
return redirect(url_for('index.index'))
|
return redirect(url_for('index.index'))
|
||||||
|
|
||||||
@index_bp.route('/confirm/<token>', methods=['GET'])
|
@index_bp.route('/confirm/<token>', methods=['GET'])
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
import datetime
|
import datetime
|
||||||
import qrcode as qrc
|
|
||||||
import qrcode.image.svg as qrc_svg
|
|
||||||
from io import BytesIO
|
|
||||||
from flask import Blueprint, request, render_template, make_response, jsonify, redirect, url_for, g, session, current_app
|
from flask import Blueprint, request, render_template, make_response, jsonify, redirect, url_for, g, session, current_app
|
||||||
from flask_login import current_user, login_required, login_manager
|
from flask_login import current_user, login_required, login_manager
|
||||||
|
|
||||||
|
@ -94,13 +91,9 @@ def qrcode():
|
||||||
if not current_user:
|
if not current_user:
|
||||||
return redirect(url_for('index'))
|
return redirect(url_for('index'))
|
||||||
|
|
||||||
img = qrc.make(current_user.get_totp_uri(),
|
return current_user.get_qrcode_value(), 200, {
|
||||||
image_factory=qrc_svg.SvgPathImage)
|
|
||||||
stream = BytesIO()
|
|
||||||
img.save(stream)
|
|
||||||
return stream.getvalue(), 200, {
|
|
||||||
'Content-Type': 'image/svg+xml',
|
'Content-Type': 'image/svg+xml',
|
||||||
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
||||||
'Pragma': 'no-cache',
|
'Pragma': 'no-cache',
|
||||||
'Expires': '0'
|
'Expires': '0'
|
||||||
}
|
}
|
|
@ -285,4 +285,14 @@ function timer(elToUpdate, maxTime) {
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
return interval;
|
return interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// copy otp secret code to clipboard
|
||||||
|
function copy_otp_secret_to_clipboard() {
|
||||||
|
var copyBox = document.getElementById("otp_secret");
|
||||||
|
copyBox.select();
|
||||||
|
copyBox.setSelectionRange(0, 99999); /* For mobile devices */
|
||||||
|
navigator.clipboard.writeText(copyBox.value);
|
||||||
|
$("#copy_tooltip").css("visibility", "visible");
|
||||||
|
setTimeout(function(){ $("#copy_tooltip").css("visibility", "collapse"); }, 2000);
|
||||||
|
}
|
|
@ -41,7 +41,7 @@
|
||||||
Your secret key is: <br />
|
Your secret key is: <br />
|
||||||
<form>
|
<form>
|
||||||
<input type=text id="otp_secret" value={{user.otp_secret}} readonly>
|
<input type=text id="otp_secret" value={{user.otp_secret}} readonly>
|
||||||
<button type=button style="position:relative; right:28px" onclick="copy_to_clickboard()"> <i class="fa fa-clipboard"></i> </button>
|
<button type=button style="position:relative; right:28px" onclick="copy_otp_secret_to_clipboard()"> <i class="fa fa-clipboard"></i> </button>
|
||||||
<br /><font color="red" id="copy_tooltip" style="visibility:collapse">Copied.</font>
|
<br /><font color="red" id="copy_tooltip" style="visibility:collapse">Copied.</font>
|
||||||
</form>
|
</form>
|
||||||
</p>
|
</p>
|
||||||
|
@ -87,15 +87,4 @@
|
||||||
{% assets "js_validation" -%}
|
{% assets "js_validation" -%}
|
||||||
<script type="text/javascript" src="{{ ASSET_URL }}"></script>
|
<script type="text/javascript" src="{{ ASSET_URL }}"></script>
|
||||||
{%- endassets %}
|
{%- endassets %}
|
||||||
<script>
|
|
||||||
// copy otp secret code to clipboard
|
|
||||||
function copy_to_clickboard() {
|
|
||||||
var copyBox = document.getElementById("otp_secret");
|
|
||||||
copyBox.select();
|
|
||||||
copyBox.setSelectionRange(0, 99999); /* For mobile devices */
|
|
||||||
navigator.clipboard.writeText(copyBox.value);
|
|
||||||
$("#copy_tooltip").css("visibility", "visible");
|
|
||||||
setTimeout(function(){ $("#copy_tooltip").css("visibility", "collapse"); }, 2000);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</html>
|
</html>
|
|
@ -97,7 +97,7 @@
|
||||||
Your secret key is: <br />
|
Your secret key is: <br />
|
||||||
<form>
|
<form>
|
||||||
<input type=text id="otp_secret" value={{current_user.otp_secret}} readonly>
|
<input type=text id="otp_secret" value={{current_user.otp_secret}} readonly>
|
||||||
<button type=button style="position:relative; right:28px" onclick="copy_to_clickboard()"> <i class="fa fa-clipboard"></i> </button>
|
<button type=button style="position:relative; right:28px" onclick="copy_otp_secret_to_clipboard()"> <i class="fa fa-clipboard"></i> </button>
|
||||||
<br /><font color="red" id="copy_tooltip" style="visibility:collapse">Copied.</font>
|
<br /><font color="red" id="copy_tooltip" style="visibility:collapse">Copied.</font>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -160,15 +160,5 @@
|
||||||
};
|
};
|
||||||
applyChanges(postdata, $SCRIPT_ROOT + '/user/profile', false, true);
|
applyChanges(postdata, $SCRIPT_ROOT + '/user/profile', false, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
// copy otp secret code to clipboard
|
|
||||||
function copy_to_clickboard() {
|
|
||||||
var copyBox = document.getElementById("otp_secret");
|
|
||||||
copyBox.select();
|
|
||||||
copyBox.setSelectionRange(0, 99999); /* For mobile devices */
|
|
||||||
navigator.clipboard.writeText(copyBox.value);
|
|
||||||
$("#copy_tooltip").css("visibility", "visible");
|
|
||||||
setTimeout(function(){ $("#copy_tooltip").css("visibility", "collapse"); }, 2000);
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
Loading…
Reference in a new issue