Compare commits
20
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c20a8a0b2c | ||
|
|
05821df546 | ||
|
|
3a88b7db3b | ||
|
|
a53f2aa274 | ||
|
|
92bc2bbdbf | ||
|
|
e2d0e7a95e | ||
|
|
9b4bd725da | ||
|
|
b783617335 | ||
|
|
4ea6831be2 | ||
|
|
b8645473a7 | ||
|
|
9cc6bf6290 | ||
|
|
4fe1bec588 | ||
|
|
f2ffabad3e | ||
|
|
7e7c599530 | ||
|
|
7a7edc1f92 | ||
|
|
078af33e77 | ||
|
|
94563bfefc | ||
|
|
da0114f2f8 | ||
|
|
cbb7ed4498 | ||
|
|
4d2cf64f19 |
@@ -6,3 +6,6 @@
|
|||||||
*~
|
*~
|
||||||
session
|
session
|
||||||
libs/__pycache__
|
libs/__pycache__
|
||||||
|
!static/tmp
|
||||||
|
static/tmp/*
|
||||||
|
!static/tmp/.gitkeep
|
||||||
|
|||||||
@@ -13,32 +13,34 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
<h1>2FA</h1>
|
<h1>{{ str['2fa-title'] }}</h1>
|
||||||
|
|
||||||
% if data['secureAuth'] == True:
|
% if data['secureAuth'] == True:
|
||||||
|
<div class="info">{{ str['2fa-info-1'] }}</div>
|
||||||
|
<div class="qr-code">
|
||||||
|
<img src="{{'static/tmp/'+data['authCode']+'.png'}}" />
|
||||||
|
</div>
|
||||||
<form name="disable2faForm" method="post" action="/disable_2fa">
|
<form name="disable2faForm" method="post" action="/disable_2fa">
|
||||||
|
|
||||||
<label for="2fa">2FA</label>
|
<label for="code">{{ str['code'] }}</label>
|
||||||
<input id="2fa" name="2fa" type="text" value="{{data['authCode']}}">
|
<input id="" name="code" type="text" value="{{data['authCode']}}" readonly>
|
||||||
|
|
||||||
<div class="form-buttons">
|
<div class="form-buttons">
|
||||||
<a href="/user"><button class="green" type="button">{{ str['back'] }}</button></a>
|
<a href="/user"><button class="green" type="button">{{ str['back'] }}</button></a>
|
||||||
<button class="green" type="submit">Disable</button>
|
<button class="green" type="submit">{{ str['disable'] }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
% else:
|
% else:
|
||||||
|
<div class="info">{{ str['2fa-info-2'] }}</div>
|
||||||
<form name="enable2faForm" method="post" action="/enable_2fa">
|
<form name="enable2faForm" method="post" action="/enable_2fa">
|
||||||
|
|
||||||
<label for="2fa">2FA</label>
|
<!--<input id="token" name="token" type="text" value="{{data['authCode']}}" readonly>-->
|
||||||
<input id="2fa" name="2fa" type="text" value="{{data['authCode']}}">
|
|
||||||
|
|
||||||
<div class="form-buttons">
|
<div class="form-buttons">
|
||||||
<a href="/user"><button class="green" type="button">{{ str['back'] }}</button></a>
|
<a href="/user"><button class="green" type="button">{{ str['back'] }}</button></a>
|
||||||
<button class="green" type="submit">Enable</button>
|
<button class="green" type="submit">{{ str['enable'] }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
import bottle
|
import bottle
|
||||||
from bottle import get, post, static_file, request, route, template
|
from bottle import get, post, static_file, request, route, template, error
|
||||||
from bottle import SimpleTemplate
|
from bottle import SimpleTemplate
|
||||||
from bottle.ext import beaker
|
from bottle.ext import beaker
|
||||||
from configparser import ConfigParser
|
from configparser import ConfigParser
|
||||||
@@ -27,20 +27,23 @@ from ldap3 import Server, Connection, ALL
|
|||||||
from ldap3 import SIMPLE, SUBTREE, MODIFY_REPLACE, MODIFY_ADD, MODIFY_DELETE, ALL_ATTRIBUTES
|
from ldap3 import SIMPLE, SUBTREE, MODIFY_REPLACE, MODIFY_ADD, MODIFY_DELETE, ALL_ATTRIBUTES
|
||||||
from ldap3.core.exceptions import LDAPBindError, LDAPConstraintViolationResult, \
|
from ldap3.core.exceptions import LDAPBindError, LDAPConstraintViolationResult, \
|
||||||
LDAPInvalidCredentialsResult, LDAPUserNameIsMandatoryError, \
|
LDAPInvalidCredentialsResult, LDAPUserNameIsMandatoryError, \
|
||||||
LDAPSocketOpenError, LDAPExceptionError, LDAPAttributeOrValueExistsResult
|
LDAPSocketOpenError, LDAPExceptionError, LDAPAttributeOrValueExistsResult, \
|
||||||
|
LDAPNoSuchAttributeResult
|
||||||
import logging
|
import logging
|
||||||
from os import getenv, environ, path
|
from os import getenv, environ, path, remove
|
||||||
from libs import flist, slist
|
from libs import flist, slist
|
||||||
from libs.localization import *
|
from libs.localization import *
|
||||||
from libs.helper import tools
|
from libs.helper import tools
|
||||||
import random
|
import random
|
||||||
from user_agents import parse as ua_parse
|
from user_agents import parse as ua_parse
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
import cryptocode
|
||||||
|
import base64
|
||||||
|
|
||||||
BASE_DIR = path.dirname(__file__)
|
BASE_DIR = path.dirname(__file__)
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
LOG_FORMAT = '%(asctime)s %(levelname)s: %(message)s'
|
LOG_FORMAT = '%(asctime)s %(levelname)s: %(message)s'
|
||||||
VERSION = '0.0.2'
|
VERSION = '0.0.3'
|
||||||
|
|
||||||
@get('/')
|
@get('/')
|
||||||
def get_index():
|
def get_index():
|
||||||
@@ -52,7 +55,7 @@ def get_index():
|
|||||||
@get('/user')
|
@get('/user')
|
||||||
def get_index():
|
def get_index():
|
||||||
try:
|
try:
|
||||||
print(newSession().get())
|
print('SESSION:',newSession().get())
|
||||||
return user_tpl(data=newSession().get(), str=i18n.str)
|
return user_tpl(data=newSession().get(), str=i18n.str)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return index_tpl(str=i18n.str)
|
return index_tpl(str=i18n.str)
|
||||||
@@ -119,17 +122,26 @@ def get_index():
|
|||||||
@get('/_2fa')
|
@get('/_2fa')
|
||||||
def get_index():
|
def get_index():
|
||||||
try:
|
try:
|
||||||
|
reload(newSession().get()['username'], None, None)
|
||||||
return _2fa_tpl(data=newSession().get(), str=i18n.str)
|
return _2fa_tpl(data=newSession().get(), str=i18n.str)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return index_tpl(str=i18n.str)
|
return index_tpl(str=i18n.str)
|
||||||
|
|
||||||
|
@get('/enable_2fa')
|
||||||
|
@get('/disable_2fa')
|
||||||
|
def get_index():
|
||||||
|
try:
|
||||||
|
return user_tpl(data=newSession().get(), str=i18n.str)
|
||||||
|
except Exception as e:
|
||||||
|
return index_tpl(str=i18n.str)
|
||||||
|
|
||||||
@post('/user')
|
@post('/user')
|
||||||
def post_user():
|
def post_user():
|
||||||
form = request.forms.getunicode
|
form = request.forms.getunicode
|
||||||
|
|
||||||
def error(msg):
|
def error(msg):
|
||||||
return index_tpl(alerts=[('error', msg, 'fadeOut')], str=i18n.str)
|
return index_tpl(alerts=[('error', msg, 'fadeOut')], str=i18n.str)
|
||||||
|
|
||||||
if len(form('username')) < 3:
|
if len(form('username')) < 3:
|
||||||
return error(i18n.msg[2])
|
return error(i18n.msg[2])
|
||||||
elif not tools.input_validation(form('username')):
|
elif not tools.input_validation(form('username')):
|
||||||
@@ -143,11 +155,58 @@ def post_user():
|
|||||||
except Error as e:
|
except Error as e:
|
||||||
LOG.warning("Unsuccessful attempt to login %s: %s" % (form('username'), e))
|
LOG.warning("Unsuccessful attempt to login %s: %s" % (form('username'), e))
|
||||||
return error(str(e))
|
return error(str(e))
|
||||||
|
|
||||||
#if 2fa not chekced || (2fa checked & success)
|
try:
|
||||||
|
#if(check_2fa_step1(form('username'))):
|
||||||
|
if(newSession().get()['secureAuth']):
|
||||||
|
# encrypt and store the credentials
|
||||||
|
sid = newSession().get()['id']
|
||||||
|
data = ';'.join([form('username'),form('password'),newSession().get()['authCode']])
|
||||||
|
data_enc = cryptocode.encrypt(data, newSession().get()['id'])
|
||||||
|
data_to_url = base64.urlsafe_b64encode(str.encode(data_enc))
|
||||||
|
memo.get(data_enc)
|
||||||
|
memo.sid=sid
|
||||||
|
logout(form('username'))
|
||||||
|
return index_tpl(two_factor_authentication=True, path=data_to_url, str=i18n.str)
|
||||||
|
except Error as e:
|
||||||
|
#On error force disable 2fa
|
||||||
|
add_auth_attribute_step1(form('username'), None, action='disable')
|
||||||
|
LOG.debug("Two factor authentication has been impossible.")
|
||||||
|
return error(i18n.msg[29])
|
||||||
return user_tpl(alerts=[('success', '%s %s' % (i18n.msg[1], form('username').capitalize()), 'fadeOut' )], data=newSession().get(), str=i18n.str)
|
return user_tpl(alerts=[('success', '%s %s' % (i18n.msg[1], form('username').capitalize()), 'fadeOut' )], data=newSession().get(), str=i18n.str)
|
||||||
#elif 2fa checked
|
|
||||||
#return _2fa_tpl(alerts=[('success', '%s %s' % (i18n.msg[1], form('username').capitalize()), 'fadeOut' )], data=newSession().get(), str=i18n.str)
|
@post('/user/<path>')
|
||||||
|
def post_user_step2(path):
|
||||||
|
form = request.forms.getunicode
|
||||||
|
|
||||||
|
def error(msg):
|
||||||
|
return index_tpl(alerts=[('error', msg, 'fadeOut')], str=i18n.str)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# decrypt url
|
||||||
|
path = base64.urlsafe_b64decode(path)
|
||||||
|
path = cryptocode.decrypt(path.decode('utf-8'), memo.sid)
|
||||||
|
data = path.split(';')
|
||||||
|
|
||||||
|
username = data[0]
|
||||||
|
password = data[1]
|
||||||
|
secret = data[2]
|
||||||
|
except:
|
||||||
|
newSession()
|
||||||
|
return error(i18n.msg[27])
|
||||||
|
|
||||||
|
#if not tools._2fa_validation(form('token'), newSession().get()['authCode']):
|
||||||
|
if not tools._2fa_validation(form('token'), secret):
|
||||||
|
return error(i18n.msg[6])
|
||||||
|
else:
|
||||||
|
|
||||||
|
try:
|
||||||
|
login(username, password)
|
||||||
|
except Error as e:
|
||||||
|
LOG.warning("Unsuccessful attempt to login %s: %s" % (username, e))
|
||||||
|
return error(str(e))
|
||||||
|
|
||||||
|
return user_tpl(alerts=[('success', '%s %s' % (i18n.msg[1], newSession().get()['username']), 'fadeOut' )], data=newSession().get(), str=i18n.str)
|
||||||
|
|
||||||
@post('/signup')
|
@post('/signup')
|
||||||
def post_signup():
|
def post_signup():
|
||||||
@@ -198,7 +257,7 @@ def post_signup():
|
|||||||
return error(i18n.msg[15])
|
return error(i18n.msg[15])
|
||||||
|
|
||||||
if not tools.pwd_validation(form('password')):
|
if not tools.pwd_validation(form('password')):
|
||||||
return error(i18n.msg[8]) #mezua ALDATU egin behar da
|
return error(i18n.msg[8])
|
||||||
elif form('password') != form('confirm-password'):
|
elif form('password') != form('confirm-password'):
|
||||||
return error(i18n.msg[7])
|
return error(i18n.msg[7])
|
||||||
|
|
||||||
@@ -276,33 +335,45 @@ def post_edit_email():
|
|||||||
|
|
||||||
@post('/enable_2fa')
|
@post('/enable_2fa')
|
||||||
def post_enable_2fa():
|
def post_enable_2fa():
|
||||||
try:
|
|
||||||
username=newSession().get()['username']
|
|
||||||
add_auth_attribute_step1(username, tools.generate_secret(), action='enable')
|
|
||||||
'''
|
|
||||||
add attribute authCode
|
|
||||||
set session data
|
|
||||||
'''
|
|
||||||
except Error as e:
|
|
||||||
LOG.warning("akatsa")
|
|
||||||
return error(str(e))
|
|
||||||
|
|
||||||
return _2fa_tpl(data=newSession().get(), str=i18n.str)
|
def error(msg):
|
||||||
|
return _2fa_tpl(alerts=[('error', msg, 'fadeOut')], data=newSession().get(), str=i18n.str)
|
||||||
|
|
||||||
|
try:
|
||||||
|
if(not newSession().get()['secureAuth']):
|
||||||
|
try:
|
||||||
|
username=newSession().get()['username']
|
||||||
|
add_auth_attribute_step1(username, tools.gen_secret(), action='enable')
|
||||||
|
except Error as e:
|
||||||
|
reload(newSession().get()['username'], None, None)
|
||||||
|
LOG.warning(e)
|
||||||
|
return error(i18n.msg[30])
|
||||||
|
except Error as e:
|
||||||
|
LOG.warning(e)
|
||||||
|
return index_tpl(alerts=[('error', e, 'fadeOut')], str=i18n.str)
|
||||||
|
|
||||||
|
return _2fa_tpl(alerts=[('success', i18n.msg[31], 'fadeOut')], data=newSession().get(), str=i18n.str)
|
||||||
|
|
||||||
@post('/disable_2fa')
|
@post('/disable_2fa')
|
||||||
def post_disable_2fa():
|
def post_disable_2fa():
|
||||||
try:
|
|
||||||
username=newSession().get()['username']
|
|
||||||
add_auth_attribute_step1(username, tools.generate_secret(), action='disable')
|
|
||||||
'''
|
|
||||||
add attribute authCode
|
|
||||||
set session data
|
|
||||||
'''
|
|
||||||
except Error as e:
|
|
||||||
LOG.warning("akatsa")
|
|
||||||
return error(str(e))
|
|
||||||
|
|
||||||
return _2fa_tpl(data=newSession().get(), str=i18n.str)
|
def error(msg):
|
||||||
|
return _2fa_tpl(alerts=[('error', msg, 'fadeOut')], data=newSession().get(), str=i18n.str)
|
||||||
|
|
||||||
|
try:
|
||||||
|
if(newSession().get()['secureAuth']):
|
||||||
|
try:
|
||||||
|
username=newSession().get()['username']
|
||||||
|
add_auth_attribute_step1(username, None, action='disable')
|
||||||
|
except Error as e:
|
||||||
|
reload(newSession().get()['username'], None, None)
|
||||||
|
LOG.warning(e)
|
||||||
|
return error(str(e))
|
||||||
|
except Error as e:
|
||||||
|
LOG.warning(e)
|
||||||
|
return index_tpl(alerts=[('error', e, 'fadeOut')], str=i18n.str)
|
||||||
|
|
||||||
|
return _2fa_tpl(alerts=[('error', i18n.msg[32], 'fadeOut')], data=newSession().get(), str=i18n.str)
|
||||||
|
|
||||||
@post('/change_pwd')
|
@post('/change_pwd')
|
||||||
def post_change_pwd():
|
def post_change_pwd():
|
||||||
@@ -366,6 +437,10 @@ def serve_static(filename):
|
|||||||
def font(filepath):
|
def font(filepath):
|
||||||
return static_file(filepath, root="static/fonts")
|
return static_file(filepath, root="static/fonts")
|
||||||
|
|
||||||
|
@get("/static/tmp/<filepath:re:.*\.(png|svg)>")
|
||||||
|
def font(filepath):
|
||||||
|
return static_file(filepath, root="static/tmp")
|
||||||
|
|
||||||
def index_tpl(**kwargs):
|
def index_tpl(**kwargs):
|
||||||
return template('index', **kwargs)
|
return template('index', **kwargs)
|
||||||
|
|
||||||
@@ -401,8 +476,14 @@ def connect_ldap(conf, **kwargs):
|
|||||||
|
|
||||||
return Connection(server, raise_exceptions=True, **kwargs)
|
return Connection(server, raise_exceptions=True, **kwargs)
|
||||||
|
|
||||||
|
@error(404)
|
||||||
|
@error(405)
|
||||||
|
def error40x(error):
|
||||||
|
return index_tpl(str=i18n.str)
|
||||||
|
|
||||||
#LOGIN
|
#LOGIN
|
||||||
def login(username, password):
|
def login(username, password):
|
||||||
|
|
||||||
n = N
|
n = N
|
||||||
for key in (key for key in CONF.sections()
|
for key in (key for key in CONF.sections()
|
||||||
if key == 'ldap' or key.startswith('ldap:')):
|
if key == 'ldap' or key.startswith('ldap:')):
|
||||||
@@ -417,7 +498,6 @@ def login(username, password):
|
|||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
def login_user(conf, *args):
|
def login_user(conf, *args):
|
||||||
@@ -447,9 +527,13 @@ def login_user_ldap(conf, username, password):
|
|||||||
c.bind()
|
c.bind()
|
||||||
if is_trusted_device(conf, user_dn):
|
if is_trusted_device(conf, user_dn):
|
||||||
newSession().set(get_user_data(user_dn, c))
|
newSession().set(get_user_data(user_dn, c))
|
||||||
|
newSession().data['id'] = tools.session_id()
|
||||||
#update timestamp + ip address
|
#update timestamp + ip address
|
||||||
update_login_info(conf, user_dn)
|
update_login_info(conf, user_dn)
|
||||||
LOG.debug("%s logged in to %s" % (username, conf['base']))
|
LOG.debug("%s logged in to %s" % (username, conf['base']))
|
||||||
|
#generate qr if it doenst exists when 2fa enable
|
||||||
|
if(newSession().get()['secureAuth']):
|
||||||
|
tools.gen_qr(newSession().get()['authCode'])
|
||||||
|
|
||||||
#LOGOUT
|
#LOGOUT
|
||||||
def logout(username):
|
def logout(username):
|
||||||
@@ -702,10 +786,10 @@ def add_auth_attribute_step1(username, code, action):
|
|||||||
try:
|
try:
|
||||||
add_auth_attribute_step2(CONF[key], username, code, action)
|
add_auth_attribute_step2(CONF[key], username, code, action)
|
||||||
changed.append(key)
|
changed.append(key)
|
||||||
LOG.debug("%s changed email address on %s" % (username, key))
|
LOG.debug("%s has activated 2FA authentication on %s" % (username, key))
|
||||||
except Error as e:
|
except Error as e:
|
||||||
for key in reversed(changed):
|
for key in reversed(changed):
|
||||||
LOG.info("Reverting email change in %s for %s" % (key, username))
|
LOG.info("Reverting 2FA activation in %s for %s due to errors" % (key, username))
|
||||||
try:
|
try:
|
||||||
new_email_address(CONF[key], username, new_email, old_email)
|
new_email_address(CONF[key], username, new_email, old_email)
|
||||||
except Error as e2:
|
except Error as e2:
|
||||||
@@ -728,16 +812,18 @@ def add_auth_attribute_step2(conf, *args):
|
|||||||
LOG.error('{}: {!s}'.format(e.__class__.__name__, e))
|
LOG.error('{}: {!s}'.format(e.__class__.__name__, e))
|
||||||
raise Error(i18n.msg[23])
|
raise Error(i18n.msg[23])
|
||||||
|
|
||||||
|
except LDAPNoSuchAttributeResult as e:
|
||||||
|
LOG.error('{}: {!s}'.format(e.__class__.__name__, e))
|
||||||
|
raise Error(i18n.msg[33])
|
||||||
|
|
||||||
except LDAPExceptionError as e:
|
except LDAPExceptionError as e:
|
||||||
LOG.error('{}: {!s}'.format(e.__class__.__name__, e))
|
LOG.error('{}: {!s}'.format(e.__class__.__name__, e))
|
||||||
raise Error(i18n.msg[23])
|
raise Error(i18n.msg[23])
|
||||||
|
|
||||||
def add_auth_attribute_step3(conf, username, code, action):
|
def add_auth_attribute_step3(conf, username, code, action):
|
||||||
|
|
||||||
#set current LDAP
|
#set current LDAP
|
||||||
superUser = SuperUsers(conf)
|
superUser = SuperUsers(conf)
|
||||||
|
|
||||||
print(action)
|
|
||||||
with connect_ldap(conf, user=superUser.admin_dn, password=superUser.admin_pwd) as c:
|
with connect_ldap(conf, user=superUser.admin_dn, password=superUser.admin_pwd) as c:
|
||||||
user_dn = find_user_dn(conf, c, username)
|
user_dn = find_user_dn(conf, c, username)
|
||||||
if(action == 'enable'):
|
if(action == 'enable'):
|
||||||
@@ -746,8 +832,18 @@ def add_auth_attribute_step3(conf, username, code, action):
|
|||||||
elif(action == 'disable'):
|
elif(action == 'disable'):
|
||||||
c.modify(user_dn,{'authCode': [(MODIFY_DELETE, [])]})
|
c.modify(user_dn,{'authCode': [(MODIFY_DELETE, [])]})
|
||||||
c.modify(user_dn,{'secureAuth': [MODIFY_REPLACE, [False]]})
|
c.modify(user_dn,{'secureAuth': [MODIFY_REPLACE, [False]]})
|
||||||
|
#remove file
|
||||||
|
try:
|
||||||
|
remove('static/tmp/'+newSession().get()['authCode']+'.png')
|
||||||
|
except OSError as e:
|
||||||
|
LOG.warning(str(e))
|
||||||
|
#raise Error(e)
|
||||||
|
pass
|
||||||
|
|
||||||
newSession().set(get_user_data(user_dn, c))
|
newSession().set(get_user_data(user_dn, c))
|
||||||
|
|
||||||
|
reload=add_auth_attribute_step1
|
||||||
|
|
||||||
#CHANGE PASSWORD
|
#CHANGE PASSWORD
|
||||||
def change_passwords(username, old_pass, new_pass):
|
def change_passwords(username, old_pass, new_pass):
|
||||||
changed = []
|
changed = []
|
||||||
@@ -908,6 +1004,12 @@ def get_user_email_array(user_dn, conn, old_email, new_email):
|
|||||||
emails[i] = new_email
|
emails[i] = new_email
|
||||||
return(emails)
|
return(emails)
|
||||||
|
|
||||||
|
def check_secure_auth(user_dn, conn):
|
||||||
|
search_filter = '(objectClass=*)'
|
||||||
|
conn.search(user_dn, search_filter, attributes=['secureAuth'])
|
||||||
|
status = conn.entries[0].secureAuth
|
||||||
|
return(status)
|
||||||
|
|
||||||
def get_user_data(user_dn, conn):
|
def get_user_data(user_dn, conn):
|
||||||
search_filter = '(objectClass=*)'
|
search_filter = '(objectClass=*)'
|
||||||
conn.search(user_dn, search_filter,
|
conn.search(user_dn, search_filter,
|
||||||
@@ -979,7 +1081,7 @@ def is_trusted_device(conf, user_dn):
|
|||||||
c.unbind()
|
c.unbind()
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
LOG.warning(e)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def update_login_info(conf, user_dn):
|
def update_login_info(conf, user_dn):
|
||||||
@@ -993,6 +1095,16 @@ def update_login_info(conf, user_dn):
|
|||||||
class Error(Exception):
|
class Error(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# TEMPORAL MEMORY
|
||||||
|
class tMemory(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.data = None
|
||||||
|
self.sid = None
|
||||||
|
def get(self, data):
|
||||||
|
self.data = data
|
||||||
|
|
||||||
|
memo = tMemory()
|
||||||
|
|
||||||
#SESSIONS MANAGEMENT
|
#SESSIONS MANAGEMENT
|
||||||
def newSession():
|
def newSession():
|
||||||
|
|
||||||
@@ -1001,11 +1113,10 @@ def newSession():
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(Session, self).__init__()
|
super(Session, self).__init__()
|
||||||
self.data = bottle.request.environ.get('beaker.session')
|
self.data = bottle.request.environ.get('beaker.session')
|
||||||
self.lang = self.get_lang()
|
|
||||||
#localization
|
#localization
|
||||||
self.lang = self.get_lang()
|
self.lang = self.get_lang()
|
||||||
global i18n
|
global i18n
|
||||||
i18n = LocalizeTo(self.lang, CONF)
|
i18n = LocalizeTo(self.lang, CONF)
|
||||||
|
|
||||||
def get_lang(self):
|
def get_lang(self):
|
||||||
if 'HTTP_ACCEPT_LANGUAGE' in bottle.request.environ:
|
if 'HTTP_ACCEPT_LANGUAGE' in bottle.request.environ:
|
||||||
|
|||||||
Binary file not shown.
@@ -14,13 +14,22 @@
|
|||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
<h1>{{ str['login'] }}</h1>
|
<h1>{{ str['login'] }}</h1>
|
||||||
|
|
||||||
|
%try:
|
||||||
|
%if two_factor_authentication:
|
||||||
|
<form method="post" action="/user/{{path}}">
|
||||||
|
<label for="token">{{ str['token'] }}</label>
|
||||||
|
<input id="token" name="token" value="" type="text" required autofocus>
|
||||||
|
%end
|
||||||
|
%except:
|
||||||
|
<form method="post" action="/user">
|
||||||
|
<label for="username">{{ str['usrn'] }}</label>
|
||||||
|
<input id="username" name="username" value="{{ get('username', '') }}" type="text" required autofocus>
|
||||||
|
|
||||||
<form method="post" action="/user">
|
<label for="password">{{ str['pwd'] }}</label>
|
||||||
<label for="username">{{ str['usrn'] }}</label>
|
<input id="password" name="password" type="password" pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*_=+-]).{8,24}$" oninvalid="setCustomValidity('{{ str['pwd-pattern'] }}')" oninput="setCustomValidity('')" required>
|
||||||
<input id="username" name="username" value="{{ get('username', '') }}" type="text" required autofocus>
|
|
||||||
|
%end
|
||||||
<label for="password">{{ str['pwd'] }}</label>
|
|
||||||
<input id="password" name="password" type="password" pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*_=+-]).{8,24}$" oninvalid="setCustomValidity('{{ str['pwd-pattern'] }}')" oninput="setCustomValidity('')" required>
|
|
||||||
|
|
||||||
<button class="green" type="submit">{{str['login']}}</button>
|
<button class="green" type="submit">{{str['login']}}</button>
|
||||||
<a href="/signup">{{ str['or-sign-up'] }}</a>
|
<a href="/signup">{{ str['or-sign-up'] }}</a>
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
from onetimepass import valid_totp
|
|
||||||
from secrets import choice
|
|
||||||
|
|
||||||
|
|
||||||
def generate_secret(): # Function to return a random string with length 16.
|
|
||||||
secret = ''
|
|
||||||
while len(secret) < 16:
|
|
||||||
secret += choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')
|
|
||||||
return secret
|
|
||||||
|
|
||||||
|
|
||||||
secret = generate_secret()
|
|
||||||
print('Enter the following secret in your authenticator app: ', secret)
|
|
||||||
print("""
|
|
||||||
Instructions for saving this secret it Google Authenticator:
|
|
||||||
1. Open Google Authenticator.
|
|
||||||
2. Click plus icon at the right bottom.
|
|
||||||
3. Click Enter a setup key.
|
|
||||||
4. Enter an Account name of your choice and enter the secret provided above.
|
|
||||||
5. Click Add.
|
|
||||||
""")
|
|
||||||
while True:
|
|
||||||
otp = int(input('Please enter the otp generated by your authenticator app: '))
|
|
||||||
authenticated = valid_totp(otp, secret)
|
|
||||||
if authenticated:
|
|
||||||
print('Correct otp, Authenticated!')
|
|
||||||
elif not authenticated:
|
|
||||||
print('Wrong otp, please try again.')
|
|
||||||
|
|
||||||
+22
-1
@@ -4,6 +4,9 @@ import sqlite3
|
|||||||
import re
|
import re
|
||||||
from onetimepass import valid_totp
|
from onetimepass import valid_totp
|
||||||
from secrets import choice
|
from secrets import choice
|
||||||
|
import segno
|
||||||
|
from os import path
|
||||||
|
import uuid
|
||||||
|
|
||||||
class Tools():
|
class Tools():
|
||||||
|
|
||||||
@@ -44,12 +47,30 @@ class Tools():
|
|||||||
def pwd_validation(self, e):
|
def pwd_validation(self, e):
|
||||||
regex = r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!#%*?&]{8,18}$'
|
regex = r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!#%*?&]{8,18}$'
|
||||||
return(bool(re.fullmatch(regex, e)))
|
return(bool(re.fullmatch(regex, e)))
|
||||||
|
|
||||||
|
# 2FA
|
||||||
|
def gen_qr(self, secret):
|
||||||
|
if(not path.isfile('static/tmp/'+secret+'.png')):
|
||||||
|
qrcode = segno.make(secret, micro=False)
|
||||||
|
qrcode.save('static/tmp/'+secret+'.png', scale=10)
|
||||||
|
|
||||||
def generate_secret(self): # Function to return a random string with length 16.
|
def gen_secret(self): # Function to return a random string with length 16.
|
||||||
secret = ''
|
secret = ''
|
||||||
while len(secret) < 16:
|
while len(secret) < 16:
|
||||||
secret += choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')
|
secret += choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')
|
||||||
|
self.gen_qr(secret)
|
||||||
return secret
|
return secret
|
||||||
|
|
||||||
|
def _2fa_validation(self, otp, secret):
|
||||||
|
authenticated = valid_totp(otp, secret)
|
||||||
|
if authenticated:
|
||||||
|
print('Correct otp, Authenticated!')
|
||||||
|
return True
|
||||||
|
elif not authenticated:
|
||||||
|
print('Wrong otp, please try again.')
|
||||||
|
return False
|
||||||
|
|
||||||
|
def session_id(self):
|
||||||
|
return uuid.uuid4().hex
|
||||||
|
|
||||||
tools = Tools()
|
tools = Tools()
|
||||||
|
|||||||
+17
-2
@@ -40,6 +40,13 @@ class LocalizeTo(object):
|
|||||||
str_25 = _("Last login")
|
str_25 = _("Last login")
|
||||||
str_26 = _("Devices")
|
str_26 = _("Devices")
|
||||||
str_27 = _("show")
|
str_27 = _("show")
|
||||||
|
str_28 = _("Two factor authentication")
|
||||||
|
str_29 = _("Token")
|
||||||
|
str_30 = _("Disable")
|
||||||
|
str_31 = _("Enable")
|
||||||
|
str_32 = _("You must then use the following code to log in. Using the key you will receive by reading the QR code via a OTP or 2FA mobile app.")
|
||||||
|
str_33 = _("Two factor authentication is additional security. By enabling this you will be asked at the login, in addition to the user and password, a key you will receive by QR.")
|
||||||
|
str_34 = _("Code")
|
||||||
|
|
||||||
#messages
|
#messages
|
||||||
msg_00 = _("The session was closed.")
|
msg_00 = _("The session was closed.")
|
||||||
@@ -71,11 +78,19 @@ class LocalizeTo(object):
|
|||||||
msg_26 = _("Forgot your password? Please try again.")
|
msg_26 = _("Forgot your password? Please try again.")
|
||||||
msg_27 = _("The session has expired.")
|
msg_27 = _("The session has expired.")
|
||||||
msg_28 = _("Registration is currently closed. We apologize for the inconvenience.")
|
msg_28 = _("Registration is currently closed. We apologize for the inconvenience.")
|
||||||
|
msg_29 = _("Two factor authentication has been impossible.")
|
||||||
|
msg_30 = _("Two factor authentication has been restored.")
|
||||||
|
msg_31 = _("Two factor authentication has been enabled.")
|
||||||
|
msg_32 = _("Two factor authentication has been disabled.")
|
||||||
|
msg_33 = _("Two factor authentication was already disabled.")
|
||||||
|
|
||||||
self.str = {'usr':str_00, 'usrn':str_01, 'fn':str_02, 'sn':str_03, 'pwd':str_04, 'old-pwd':str_05,
|
self.str = {'usr':str_00, 'usrn':str_01, 'fn':str_02, 'sn':str_03, 'pwd':str_04, 'old-pwd':str_05,
|
||||||
'new-pwd':str_06, 'conf-pwd':str_07, 'email':str_08, 'edit':str_09, 'login':str_10, 'log-out':str_11,
|
'new-pwd':str_06, 'conf-pwd':str_07, 'email':str_08, 'edit':str_09, 'login':str_10, 'log-out':str_11,
|
||||||
'del':str_12, 'sign-up':str_13, 'back':str_14, 'update':str_15, 'or-sign-in':str_16,
|
'del':str_12, 'sign-up':str_13, 'back':str_14, 'update':str_15, 'or-sign-in':str_16,
|
||||||
'or-sign-up':str_17, 'inv-code':str_18, 'edit-fn':str_19, 'edit-email':str_20, 'ch-pwd':str_21,
|
'or-sign-up':str_17, 'inv-code':str_18, 'edit-fn':str_19, 'edit-email':str_20, 'ch-pwd':str_21,
|
||||||
'del-account':str_22, 'welcome':str_23, 'logs':str_24, 'last-login':str_25, 'devices':str_26,
|
'del-account':str_22, 'welcome':str_23, 'logs':str_24, 'last-login':str_25, 'devices':str_26,
|
||||||
'show':str_27, 'pwd-pattern': msg_08}
|
'show':str_27, '2fa-title':str_28, 'token':str_29, 'disable':str_30, 'enable':str_31, '2fa-info-1':str_32,
|
||||||
self.msg = (msg_00, msg_01, msg_02, msg_03, msg_04, msg_05, msg_06, msg_07, msg_08, msg_09, msg_10, msg_11, msg_12, msg_13, msg_14, msg_15, msg_16, msg_17, msg_18, msg_19, msg_20, msg_21, msg_22, msg_23, msg_24, msg_25, msg_26, msg_27, msg_28)
|
'2fa-info-2':str_33, 'code':str_34, 'pwd-pattern': msg_08}
|
||||||
|
self.msg = (msg_00, msg_01, msg_02, msg_03, msg_04, msg_05, msg_06, msg_07, msg_08, msg_09, msg_10, msg_11,
|
||||||
|
msg_12, msg_13, msg_14, msg_15, msg_16, msg_17, msg_18, msg_19, msg_20, msg_21, msg_22, msg_23,
|
||||||
|
msg_24, msg_25, msg_26, msg_27, msg_28, msg_29, msg_30, msg_31, msg_32, msg_33)
|
||||||
|
|||||||
+76
-28
@@ -109,7 +109,7 @@ msgstr "Change your password"
|
|||||||
msgid "Delete your account"
|
msgid "Delete your account"
|
||||||
msgstr "Delete your account"
|
msgstr "Delete your account"
|
||||||
|
|
||||||
#: libs/localization.py:38 libs/localization.py:46
|
#: libs/localization.py:38 libs/localization.py:53
|
||||||
msgid "Welcome"
|
msgid "Welcome"
|
||||||
msgstr "Welcome"
|
msgstr "Welcome"
|
||||||
|
|
||||||
@@ -129,35 +129,63 @@ msgstr "Devices"
|
|||||||
msgid "show"
|
msgid "show"
|
||||||
msgstr "show"
|
msgstr "show"
|
||||||
|
|
||||||
|
#: libs/localization.py:43
|
||||||
|
msgid "Two factor authentication"
|
||||||
|
msgstr "Two factor authentication"
|
||||||
|
|
||||||
|
#: libs/localization.py:44
|
||||||
|
msgid "Token"
|
||||||
|
msgstr "Token"
|
||||||
|
|
||||||
#: libs/localization.py:45
|
#: libs/localization.py:45
|
||||||
|
msgid "Disable"
|
||||||
|
msgstr "Disable"
|
||||||
|
|
||||||
|
#: libs/localization.py:46
|
||||||
|
msgid "Enable"
|
||||||
|
msgstr "Enable"
|
||||||
|
|
||||||
|
#: libs/localization.py:47
|
||||||
|
msgid "You must then use the following code to log in. Using the key you will receive by reading the QR code via a OTP or 2FA mobile app."
|
||||||
|
msgstr "You must then use the following code to log in. Using the key you will receive by reading the QR code via a OTP or 2FA mobile app."
|
||||||
|
|
||||||
|
#: libs/localization.py:48
|
||||||
|
msgid "Two factor authentication is additional security. By enabling this you will be asked at the login, in addition to the user and password, a key you will receive by QR."
|
||||||
|
msgstr "Two factor authentication is additional security. By enabling this you will be asked at the login, in addition to the user and password, a key you will receive by QR."
|
||||||
|
|
||||||
|
#: libs/localization.py:49
|
||||||
|
msgid "Code"
|
||||||
|
msgstr "Code"
|
||||||
|
|
||||||
|
#: libs/localization.py:52
|
||||||
msgid "The session was closed."
|
msgid "The session was closed."
|
||||||
msgstr "The session was closed."
|
msgstr "The session was closed."
|
||||||
|
|
||||||
#: libs/localization.py:47
|
#: libs/localization.py:54
|
||||||
msgid "Username must be at least 3 characters long!"
|
msgid "Username must be at least 3 characters long!"
|
||||||
msgstr "Username must be at least 3 characters long!"
|
msgstr "Username must be at least 3 characters long!"
|
||||||
|
|
||||||
#: libs/localization.py:48
|
#: libs/localization.py:55
|
||||||
msgid "Not allowed characters for the username field."
|
msgid "Not allowed characters for the username field."
|
||||||
msgstr "Not allowed characters for the username field."
|
msgstr "Not allowed characters for the username field."
|
||||||
|
|
||||||
#: libs/localization.py:49
|
#: libs/localization.py:56
|
||||||
msgid "Not allowed characters for the firstname field."
|
msgid "Not allowed characters for the firstname field."
|
||||||
msgstr "Not allowed characters for the firstname field."
|
msgstr "Not allowed characters for the firstname field."
|
||||||
|
|
||||||
#: libs/localization.py:50
|
#: libs/localization.py:57
|
||||||
msgid "Not allowed characters for the surname field."
|
msgid "Not allowed characters for the surname field."
|
||||||
msgstr "Not allowed characters for the surname field."
|
msgstr "Not allowed characters for the surname field."
|
||||||
|
|
||||||
#: libs/localization.py:51
|
#: libs/localization.py:58
|
||||||
msgid "The code is invalid or has expired."
|
msgid "The code is invalid or has expired."
|
||||||
msgstr "The code is invalid or has expired."
|
msgstr "The code is invalid or has expired."
|
||||||
|
|
||||||
#: libs/localization.py:52
|
#: libs/localization.py:59
|
||||||
msgid "Passwords do not match!"
|
msgid "Passwords do not match!"
|
||||||
msgstr "Passwords do not match!"
|
msgstr "Passwords do not match!"
|
||||||
|
|
||||||
#: libs/localization.py:53
|
#: libs/localization.py:60
|
||||||
msgid ""
|
msgid ""
|
||||||
"The password must contain at least 8 characters, at least one number, "
|
"The password must contain at least 8 characters, at least one number, "
|
||||||
"a capital letter and a special character."
|
"a capital letter and a special character."
|
||||||
@@ -165,84 +193,104 @@ msgstr ""
|
|||||||
"The password must contain at least 8 characters, at least one number, "
|
"The password must contain at least 8 characters, at least one number, "
|
||||||
"a capital letter and a special character."
|
"a capital letter and a special character."
|
||||||
|
|
||||||
#: libs/localization.py:54
|
#: libs/localization.py:61
|
||||||
msgid "Congratulations, your account has been created!"
|
msgid "Congratulations, your account has been created!"
|
||||||
msgstr "Congratulations, your account has been created!"
|
msgstr "Congratulations, your account has been created!"
|
||||||
|
|
||||||
#: libs/localization.py:55
|
#: libs/localization.py:62
|
||||||
msgid "Your first and last name have not been changed."
|
msgid "Your first and last name have not been changed."
|
||||||
msgstr "Your first and last name have not been changed."
|
msgstr "Your first and last name have not been changed."
|
||||||
|
|
||||||
#: libs/localization.py:56
|
#: libs/localization.py:63
|
||||||
msgid "Your firstname is a bit short, don't you think?"
|
msgid "Your firstname is a bit short, don't you think?"
|
||||||
msgstr "Your firstname is a bit short, don't you think?"
|
msgstr "Your firstname is a bit short, don't you think?"
|
||||||
|
|
||||||
#: libs/localization.py:57
|
#: libs/localization.py:64
|
||||||
msgid "Your surname is a bit short, don't you think?"
|
msgid "Your surname is a bit short, don't you think?"
|
||||||
msgstr "Your surname is a bit short, don't you think?"
|
msgstr "Your surname is a bit short, don't you think?"
|
||||||
|
|
||||||
#: libs/localization.py:58
|
#: libs/localization.py:65
|
||||||
msgid "Your first and last name have been successfully updated."
|
msgid "Your first and last name have been successfully updated."
|
||||||
msgstr "Your first and last name have been successfully updated."
|
msgstr "Your first and last name have been successfully updated."
|
||||||
|
|
||||||
#: libs/localization.py:59
|
#: libs/localization.py:66
|
||||||
msgid "Invalid email address. Please try again."
|
msgid "Invalid email address. Please try again."
|
||||||
msgstr "Invalid email address. Please try again."
|
msgstr "Invalid email address. Please try again."
|
||||||
|
|
||||||
#: libs/localization.py:60
|
#: libs/localization.py:67
|
||||||
msgid "Email address has not been changed."
|
msgid "Email address has not been changed."
|
||||||
msgstr "Email address has not been changed."
|
msgstr "Email address has not been changed."
|
||||||
|
|
||||||
#: libs/localization.py:61
|
#: libs/localization.py:68
|
||||||
msgid "Your email has been successfully updated."
|
msgid "Your email has been successfully updated."
|
||||||
msgstr "Your email has been successfully updated."
|
msgstr "Your email has been successfully updated."
|
||||||
|
|
||||||
#: libs/localization.py:62
|
#: libs/localization.py:69
|
||||||
msgid "The password entered is the same as the current password."
|
msgid "The password entered is the same as the current password."
|
||||||
msgstr "The password entered is the same as the current password."
|
msgstr "The password entered is the same as the current password."
|
||||||
|
|
||||||
#: libs/localization.py:63
|
#: libs/localization.py:70
|
||||||
msgid "Password has been changed!"
|
msgid "Password has been changed!"
|
||||||
msgstr "Password has been changed!"
|
msgstr "Password has been changed!"
|
||||||
|
|
||||||
#: libs/localization.py:64
|
#: libs/localization.py:71
|
||||||
msgid "Please, type your username for account deletion."
|
msgid "Please, type your username for account deletion."
|
||||||
msgstr "Please, type your username for account deletion."
|
msgstr "Please, type your username for account deletion."
|
||||||
|
|
||||||
#: libs/localization.py:65
|
#: libs/localization.py:72
|
||||||
msgid "Account successfully deleted!"
|
msgid "Account successfully deleted!"
|
||||||
msgstr "Account successfully deleted!"
|
msgstr "Account successfully deleted!"
|
||||||
|
|
||||||
#: libs/localization.py:66
|
#: libs/localization.py:73
|
||||||
msgid "Username or password is incorrect!"
|
msgid "Username or password is incorrect!"
|
||||||
msgstr "Username or password is incorrect!"
|
msgstr "Username or password is incorrect!"
|
||||||
|
|
||||||
#: libs/localization.py:67
|
#: libs/localization.py:74
|
||||||
msgid "Unable to connect to the remote server."
|
msgid "Unable to connect to the remote server."
|
||||||
msgstr "Unable to connect to the remote server."
|
msgstr "Unable to connect to the remote server."
|
||||||
|
|
||||||
#: libs/localization.py:68
|
#: libs/localization.py:75
|
||||||
msgid ""
|
msgid ""
|
||||||
"Encountered an unexpected error while communicating with the remote server."
|
"Encountered an unexpected error while communicating with the remote server."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Encountered an unexpected error while communicating with the remote server."
|
"Encountered an unexpected error while communicating with the remote server."
|
||||||
|
|
||||||
#: libs/localization.py:69
|
#: libs/localization.py:76
|
||||||
msgid "User already exists."
|
msgid "User already exists."
|
||||||
msgstr "User already exists."
|
msgstr "User already exists."
|
||||||
|
|
||||||
#: libs/localization.py:70
|
#: libs/localization.py:77
|
||||||
msgid "Email already exists."
|
msgid "Email already exists."
|
||||||
msgstr "Email already exists."
|
msgstr "Email already exists."
|
||||||
|
|
||||||
#: libs/localization.py:71
|
#: libs/localization.py:78
|
||||||
msgid "Forgot your password? Please try again."
|
msgid "Forgot your password? Please try again."
|
||||||
msgstr "Forgot your password? Please try again."
|
msgstr "Forgot your password? Please try again."
|
||||||
|
|
||||||
#: libs/localization.py:72
|
#: libs/localization.py:79
|
||||||
msgid "The session has expired."
|
msgid "The session has expired."
|
||||||
msgstr "The session has expired."
|
msgstr "The session has expired."
|
||||||
|
|
||||||
#: libs/localization.py:73
|
#: libs/localization.py:80
|
||||||
msgid "Registration is currently closed. We apologize for the inconvenience."
|
msgid "Registration is currently closed. We apologize for the inconvenience."
|
||||||
msgstr "Registration is currently closed. We apologize for the inconvenience."
|
msgstr "Registration is currently closed. We apologize for the inconvenience."
|
||||||
|
|
||||||
|
#: libs/localization.py:81
|
||||||
|
msgid "Two factor authentication has been impossible."
|
||||||
|
msgstr "Two factor authentication has been impossible."
|
||||||
|
|
||||||
|
#: libs/localization.py:82
|
||||||
|
msgid "Two factor authentication has been restored."
|
||||||
|
msgstr "Two factor authentication has been restored."
|
||||||
|
|
||||||
|
#: libs/localization.py:83
|
||||||
|
msgid "Two factor authentication has been enabled."
|
||||||
|
msgstr "Two factor authentication has been enabled."
|
||||||
|
|
||||||
|
#: libs/localization.py:84
|
||||||
|
msgid "Two factor authentication has been disabled."
|
||||||
|
msgstr "Two factor authentication has been disabled."
|
||||||
|
|
||||||
|
#: libs/localization.py:85
|
||||||
|
msgid "Two factor authentication was already disabled."
|
||||||
|
msgstr "Two factor authentication was already disabled."
|
||||||
|
|||||||
Binary file not shown.
@@ -1,21 +1,21 @@
|
|||||||
# SOME DESCRIPTIVE TITLE.
|
# SOME DESCRIPTIVE TITLE.
|
||||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
# FIRST AUTHOR <aitzol@lainoa.eus>, 2022.
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
#
|
#
|
||||||
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: 0.0.1\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2022-04-07 17:20+0200\n"
|
"POT-Creation-Date: 2022-04-25 16:52+0200\n"
|
||||||
"PO-Revision-Date: 2023-04-07 13:28+0200\n"
|
"PO-Revision-Date: 2023-04-07 13:28+0200\n"
|
||||||
"Last-Translator: Aitzol Berasategi <aitzol@lainoa.eus>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <EN@en.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
"Language: en\n"
|
"Language: \n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=CHARSET\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"X-Generator: Poedit 2.3\n"
|
|
||||||
|
|
||||||
#: libs/localization.py:15
|
#: libs/localization.py:15
|
||||||
msgid "User"
|
msgid "User"
|
||||||
@@ -109,7 +109,7 @@ msgstr "Change your password"
|
|||||||
msgid "Delete your account"
|
msgid "Delete your account"
|
||||||
msgstr "Delete your account"
|
msgstr "Delete your account"
|
||||||
|
|
||||||
#: libs/localization.py:38 libs/localization.py:46
|
#: libs/localization.py:38 libs/localization.py:53
|
||||||
msgid "Welcome"
|
msgid "Welcome"
|
||||||
msgstr "Welcome"
|
msgstr "Welcome"
|
||||||
|
|
||||||
@@ -129,35 +129,63 @@ msgstr "Devices"
|
|||||||
msgid "show"
|
msgid "show"
|
||||||
msgstr "show"
|
msgstr "show"
|
||||||
|
|
||||||
|
#: libs/localization.py:43
|
||||||
|
msgid "Two factor authentication"
|
||||||
|
msgstr "Two factor authentication"
|
||||||
|
|
||||||
|
#: libs/localization.py:44
|
||||||
|
msgid "Token"
|
||||||
|
msgstr "Token"
|
||||||
|
|
||||||
#: libs/localization.py:45
|
#: libs/localization.py:45
|
||||||
|
msgid "Disable"
|
||||||
|
msgstr "Disable"
|
||||||
|
|
||||||
|
#: libs/localization.py:46
|
||||||
|
msgid "Enable"
|
||||||
|
msgstr "Enable"
|
||||||
|
|
||||||
|
#: libs/localization.py:47
|
||||||
|
msgid "You must then use the following code to log in. Using the key you will receive by reading the QR code via a OTP or 2FA mobile app."
|
||||||
|
msgstr "You must then use the following code to log in. Using the key you will receive by reading the QR code via a OTP or 2FA mobile app."
|
||||||
|
|
||||||
|
#: libs/localization.py:48
|
||||||
|
msgid "Two factor authentication is additional security. By enabling this you will be asked at the login, in addition to the user and password, a key you will receive by QR."
|
||||||
|
msgstr "Two factor authentication is additional security. By enabling this you will be asked at the login, in addition to the user and password, a key you will receive by QR."
|
||||||
|
|
||||||
|
#: libs/localization.py:49
|
||||||
|
msgid "Code"
|
||||||
|
msgstr "Code"
|
||||||
|
|
||||||
|
#: libs/localization.py:52
|
||||||
msgid "The session was closed."
|
msgid "The session was closed."
|
||||||
msgstr "The session was closed."
|
msgstr "The session was closed."
|
||||||
|
|
||||||
#: libs/localization.py:47
|
#: libs/localization.py:54
|
||||||
msgid "Username must be at least 3 characters long!"
|
msgid "Username must be at least 3 characters long!"
|
||||||
msgstr "Username must be at least 3 characters long!"
|
msgstr "Username must be at least 3 characters long!"
|
||||||
|
|
||||||
#: libs/localization.py:48
|
#: libs/localization.py:55
|
||||||
msgid "Not allowed characters for the username field."
|
msgid "Not allowed characters for the username field."
|
||||||
msgstr "Not allowed characters for the username field."
|
msgstr "Not allowed characters for the username field."
|
||||||
|
|
||||||
#: libs/localization.py:49
|
#: libs/localization.py:56
|
||||||
msgid "Not allowed characters for the firstname field."
|
msgid "Not allowed characters for the firstname field."
|
||||||
msgstr "Not allowed characters for the firstname field."
|
msgstr "Not allowed characters for the firstname field."
|
||||||
|
|
||||||
#: libs/localization.py:50
|
#: libs/localization.py:57
|
||||||
msgid "Not allowed characters for the surname field."
|
msgid "Not allowed characters for the surname field."
|
||||||
msgstr "Not allowed characters for the surname field."
|
msgstr "Not allowed characters for the surname field."
|
||||||
|
|
||||||
#: libs/localization.py:51
|
#: libs/localization.py:58
|
||||||
msgid "The code is invalid or has expired."
|
msgid "The code is invalid or has expired."
|
||||||
msgstr "The code is invalid or has expired."
|
msgstr "The code is invalid or has expired."
|
||||||
|
|
||||||
#: libs/localization.py:52
|
#: libs/localization.py:59
|
||||||
msgid "Passwords do not match!"
|
msgid "Passwords do not match!"
|
||||||
msgstr "Passwords do not match!"
|
msgstr "Passwords do not match!"
|
||||||
|
|
||||||
#: libs/localization.py:53
|
#: libs/localization.py:60
|
||||||
msgid ""
|
msgid ""
|
||||||
"The password must contain at least 8 characters, at least one number, "
|
"The password must contain at least 8 characters, at least one number, "
|
||||||
"a capital letter and a special character."
|
"a capital letter and a special character."
|
||||||
@@ -165,84 +193,104 @@ msgstr ""
|
|||||||
"The password must contain at least 8 characters, at least one number, "
|
"The password must contain at least 8 characters, at least one number, "
|
||||||
"a capital letter and a special character."
|
"a capital letter and a special character."
|
||||||
|
|
||||||
#: libs/localization.py:54
|
#: libs/localization.py:61
|
||||||
msgid "Congratulations, your account has been created!"
|
msgid "Congratulations, your account has been created!"
|
||||||
msgstr "Congratulations, your account has been created!"
|
msgstr "Congratulations, your account has been created!"
|
||||||
|
|
||||||
#: libs/localization.py:55
|
#: libs/localization.py:62
|
||||||
msgid "Your first and last name have not been changed."
|
msgid "Your first and last name have not been changed."
|
||||||
msgstr "Your first and last name have not been changed."
|
msgstr "Your first and last name have not been changed."
|
||||||
|
|
||||||
#: libs/localization.py:56
|
#: libs/localization.py:63
|
||||||
msgid "Your firstname is a bit short, don't you think?"
|
msgid "Your firstname is a bit short, don't you think?"
|
||||||
msgstr "Your firstname is a bit short, don't you think?"
|
msgstr "Your firstname is a bit short, don't you think?"
|
||||||
|
|
||||||
#: libs/localization.py:57
|
#: libs/localization.py:64
|
||||||
msgid "Your surname is a bit short, don't you think?"
|
msgid "Your surname is a bit short, don't you think?"
|
||||||
msgstr "Your surname is a bit short, don't you think?"
|
msgstr "Your surname is a bit short, don't you think?"
|
||||||
|
|
||||||
#: libs/localization.py:58
|
#: libs/localization.py:65
|
||||||
msgid "Your first and last name have been successfully updated."
|
msgid "Your first and last name have been successfully updated."
|
||||||
msgstr "Your first and last name have been successfully updated."
|
msgstr "Your first and last name have been successfully updated."
|
||||||
|
|
||||||
#: libs/localization.py:59
|
#: libs/localization.py:66
|
||||||
msgid "Invalid email address. Please try again."
|
msgid "Invalid email address. Please try again."
|
||||||
msgstr "Invalid email address. Please try again."
|
msgstr "Invalid email address. Please try again."
|
||||||
|
|
||||||
#: libs/localization.py:60
|
#: libs/localization.py:67
|
||||||
msgid "Email address has not been changed."
|
msgid "Email address has not been changed."
|
||||||
msgstr "Email address has not been changed."
|
msgstr "Email address has not been changed."
|
||||||
|
|
||||||
#: libs/localization.py:61
|
#: libs/localization.py:68
|
||||||
msgid "Your email has been successfully updated."
|
msgid "Your email has been successfully updated."
|
||||||
msgstr "Your email has been successfully updated."
|
msgstr "Your email has been successfully updated."
|
||||||
|
|
||||||
#: libs/localization.py:62
|
#: libs/localization.py:69
|
||||||
msgid "The password entered is the same as the current password."
|
msgid "The password entered is the same as the current password."
|
||||||
msgstr "The password entered is the same as the current password."
|
msgstr "The password entered is the same as the current password."
|
||||||
|
|
||||||
#: libs/localization.py:63
|
#: libs/localization.py:70
|
||||||
msgid "Password has been changed!"
|
msgid "Password has been changed!"
|
||||||
msgstr "Password has been changed!"
|
msgstr "Password has been changed!"
|
||||||
|
|
||||||
#: libs/localization.py:64
|
#: libs/localization.py:71
|
||||||
msgid "Please, type your username for account deletion."
|
msgid "Please, type your username for account deletion."
|
||||||
msgstr "Please, type your username for account deletion."
|
msgstr "Please, type your username for account deletion."
|
||||||
|
|
||||||
#: libs/localization.py:65
|
#: libs/localization.py:72
|
||||||
msgid "Account successfully deleted!"
|
msgid "Account successfully deleted!"
|
||||||
msgstr "Account successfully deleted!"
|
msgstr "Account successfully deleted!"
|
||||||
|
|
||||||
#: libs/localization.py:66
|
#: libs/localization.py:73
|
||||||
msgid "Username or password is incorrect!"
|
msgid "Username or password is incorrect!"
|
||||||
msgstr "Username or password is incorrect!"
|
msgstr "Username or password is incorrect!"
|
||||||
|
|
||||||
#: libs/localization.py:67
|
#: libs/localization.py:74
|
||||||
msgid "Unable to connect to the remote server."
|
msgid "Unable to connect to the remote server."
|
||||||
msgstr "Unable to connect to the remote server."
|
msgstr "Unable to connect to the remote server."
|
||||||
|
|
||||||
#: libs/localization.py:68
|
#: libs/localization.py:75
|
||||||
msgid ""
|
msgid ""
|
||||||
"Encountered an unexpected error while communicating with the remote server."
|
"Encountered an unexpected error while communicating with the remote server."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Encountered an unexpected error while communicating with the remote server."
|
"Encountered an unexpected error while communicating with the remote server."
|
||||||
|
|
||||||
#: libs/localization.py:69
|
#: libs/localization.py:76
|
||||||
msgid "User already exists."
|
msgid "User already exists."
|
||||||
msgstr "User already exists."
|
msgstr "User already exists."
|
||||||
|
|
||||||
#: libs/localization.py:70
|
#: libs/localization.py:77
|
||||||
msgid "Email already exists."
|
msgid "Email already exists."
|
||||||
msgstr "Email already exists."
|
msgstr "Email already exists."
|
||||||
|
|
||||||
#: libs/localization.py:71
|
#: libs/localization.py:78
|
||||||
msgid "Forgot your password? Please try again."
|
msgid "Forgot your password? Please try again."
|
||||||
msgstr "Forgot your password? Please try again."
|
msgstr "Forgot your password? Please try again."
|
||||||
|
|
||||||
#: libs/localization.py:72
|
#: libs/localization.py:79
|
||||||
msgid "The session has expired."
|
msgid "The session has expired."
|
||||||
msgstr "The session has expired."
|
msgstr "The session has expired."
|
||||||
|
|
||||||
#: libs/localization.py:73
|
#: libs/localization.py:80
|
||||||
msgid "Registration is currently closed. We apologize for the inconvenience."
|
msgid "Registration is currently closed. We apologize for the inconvenience."
|
||||||
msgstr "Registration is currently closed. We apologize for the inconvenience."
|
msgstr "Registration is currently closed. We apologize for the inconvenience."
|
||||||
|
|
||||||
|
#: libs/localization.py:81
|
||||||
|
msgid "Two factor authentication has been impossible."
|
||||||
|
msgstr "Two factor authentication has been impossible."
|
||||||
|
|
||||||
|
#: libs/localization.py:82
|
||||||
|
msgid "Two factor authentication has been restored."
|
||||||
|
msgstr "Two factor authentication has been restored."
|
||||||
|
|
||||||
|
#: libs/localization.py:83
|
||||||
|
msgid "Two factor authentication has been enabled."
|
||||||
|
msgstr "Two factor authentication has been enabled."
|
||||||
|
|
||||||
|
#: libs/localization.py:84
|
||||||
|
msgid "Two factor authentication has been disabled."
|
||||||
|
msgstr "Two factor authentication has been disabled."
|
||||||
|
|
||||||
|
#: libs/localization.py:85
|
||||||
|
msgid "Two factor authentication was already disabled."
|
||||||
|
msgstr "Two factor authentication was already disabled."
|
||||||
|
|||||||
Binary file not shown.
@@ -8,14 +8,14 @@ msgstr ""
|
|||||||
"Project-Id-Version: 0.0.1\n"
|
"Project-Id-Version: 0.0.1\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2022-04-07 17:23+0200\n"
|
"POT-Creation-Date: 2022-04-07 17:23+0200\n"
|
||||||
"PO-Revision-Date: 2023-04-07 13:27+0200\n"
|
"PO-Revision-Date: 2023-11-24 20:21+0100\n"
|
||||||
"Last-Translator: Aitzol Berasategi <aitzol@lainoa.eus>\n"
|
"Last-Translator: Aitzol Berasategi <aitzol@lainoa.eus>\n"
|
||||||
"Language-Team: LANGUAGE <EU@eu.org>\n"
|
"Language-Team: LANGUAGE <EU@eu.org>\n"
|
||||||
"Language: eu\n"
|
"Language: eu\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"X-Generator: Poedit 2.3\n"
|
"X-Generator: Poedit 3.2.2\n"
|
||||||
|
|
||||||
#: libs/localization.py:15
|
#: libs/localization.py:15
|
||||||
msgid "User"
|
msgid "User"
|
||||||
@@ -109,7 +109,7 @@ msgstr "Pasahitza eguneratu"
|
|||||||
msgid "Delete your account"
|
msgid "Delete your account"
|
||||||
msgstr "Kontua ezabatu"
|
msgstr "Kontua ezabatu"
|
||||||
|
|
||||||
#: libs/localization.py:38 libs/localization.py:46
|
#: libs/localization.py:38 libs/localization.py:53
|
||||||
msgid "Welcome"
|
msgid "Welcome"
|
||||||
msgstr "Ongi etorri"
|
msgstr "Ongi etorri"
|
||||||
|
|
||||||
@@ -129,119 +129,164 @@ msgstr "Gailuak"
|
|||||||
msgid "show"
|
msgid "show"
|
||||||
msgstr "ikusi"
|
msgstr "ikusi"
|
||||||
|
|
||||||
|
#: libs/localization.py:43
|
||||||
|
msgid "Two factor authentication"
|
||||||
|
msgstr "Bi urratseko autentifikazioa"
|
||||||
|
|
||||||
|
#: libs/localization.py:44
|
||||||
|
msgid "Token"
|
||||||
|
msgstr "Gakoa"
|
||||||
|
|
||||||
#: libs/localization.py:45
|
#: libs/localization.py:45
|
||||||
|
msgid "Disable"
|
||||||
|
msgstr "Desgaitu"
|
||||||
|
|
||||||
|
#: libs/localization.py:46
|
||||||
|
msgid "Enable"
|
||||||
|
msgstr "Gaitu"
|
||||||
|
|
||||||
|
#: libs/localization.py:47
|
||||||
|
msgid "You must then use the following code to log in. Using the key you will receive by reading the QR code via a OTP or 2FA mobile app."
|
||||||
|
msgstr ""
|
||||||
|
"Aurrerantzean ondorengo kodea erabili beharko duzu saioa hasteko. Mugikorrerako OTP edo 2FA aplikazio baten bidez QR kodea irakurtzean jasoko duzun gakoa baliatuz "
|
||||||
|
"horretarako."
|
||||||
|
|
||||||
|
#: libs/localization.py:48
|
||||||
|
msgid "Two factor authentication is additional security. By enabling this you will be asked at the login, in addition to the user and password, a key you will receive by QR."
|
||||||
|
msgstr "Bi urratseko autentifikazioa segurtasun gehigarri bat da. Hau gaituz saio hasieran erabiltzaile eta pasahitzaz gain QR bidez jasoko duzun gako bat eskatuko zaizu."
|
||||||
|
|
||||||
|
#: libs/localization.py:49
|
||||||
|
msgid "Code"
|
||||||
|
msgstr "Kodea"
|
||||||
|
|
||||||
|
#: libs/localization.py:52
|
||||||
msgid "The session was closed."
|
msgid "The session was closed."
|
||||||
msgstr "Saioa itxi da."
|
msgstr "Saioa itxi da."
|
||||||
|
|
||||||
#: libs/localization.py:47
|
#: libs/localization.py:54
|
||||||
msgid "Username must be at least 3 characters long!"
|
msgid "Username must be at least 3 characters long!"
|
||||||
msgstr "Erabiltzaile izenak gutxienez 3 karaktere izan behar ditu!"
|
msgstr "Erabiltzaile izenak gutxienez 3 karaktere izan behar ditu!"
|
||||||
|
|
||||||
#: libs/localization.py:48
|
#: libs/localization.py:55
|
||||||
msgid "Not allowed characters for the username field."
|
msgid "Not allowed characters for the username field."
|
||||||
msgstr "Erabiltzaile-izenaren eremurako onartzen ez diren karaktereak."
|
msgstr "Erabiltzaile-izenaren eremurako onartzen ez diren karaktereak."
|
||||||
|
|
||||||
#: libs/localization.py:49
|
#: libs/localization.py:56
|
||||||
msgid "Not allowed characters for the firstname field."
|
msgid "Not allowed characters for the firstname field."
|
||||||
msgstr "Izenaren eremurako onartzen ez diren karaktereak."
|
msgstr "Izenaren eremurako onartzen ez diren karaktereak."
|
||||||
|
|
||||||
#: libs/localization.py:50
|
#: libs/localization.py:57
|
||||||
msgid "Not allowed characters for the surname field."
|
msgid "Not allowed characters for the surname field."
|
||||||
msgstr "Abizenaren eremurako onartzen ez diren karaktereak."
|
msgstr "Abizenaren eremurako onartzen ez diren karaktereak."
|
||||||
|
|
||||||
#: libs/localization.py:51
|
#: libs/localization.py:58
|
||||||
msgid "The code is invalid or has expired."
|
msgid "The code is invalid or has expired."
|
||||||
msgstr "Kodea baliogabea da edo iraungi egin da."
|
msgstr "Kodea baliogabea da edo iraungi egin da."
|
||||||
|
|
||||||
#: libs/localization.py:52
|
#: libs/localization.py:59
|
||||||
msgid "Passwords do not match!"
|
msgid "Passwords do not match!"
|
||||||
msgstr "Pasahitzak ez datoz bat!"
|
msgstr "Pasahitzak ez datoz bat!"
|
||||||
|
|
||||||
#: libs/localization.py:53
|
#: libs/localization.py:60
|
||||||
msgid ""
|
msgid "The password must contain at least 8 characters, at least one number, a capital letter and a special character."
|
||||||
"The password must contain at least 8 characters, at least one number, "
|
msgstr "Pasahitzak gutxienez 8 karaktere izan behar ditu, zenbaki bat, hizki larri bat eta karaktere berezi bat."
|
||||||
"a capital letter and a special character."
|
|
||||||
msgstr ""
|
|
||||||
"Pasahitzak gutxienez 8 karaktere izan behar ditu, zenbaki bat, hizki larri bat "
|
|
||||||
"eta karaktere berezi bat."
|
|
||||||
|
|
||||||
#: libs/localization.py:54
|
#: libs/localization.py:61
|
||||||
msgid "Congratulations, your account has been created!"
|
msgid "Congratulations, your account has been created!"
|
||||||
msgstr "Zorionak, zure kontua sortu da!"
|
msgstr "Zorionak, zure kontua sortu da!"
|
||||||
|
|
||||||
#: libs/localization.py:55
|
#: libs/localization.py:62
|
||||||
msgid "Your first and last name have not been changed."
|
msgid "Your first and last name have not been changed."
|
||||||
msgstr "Zure izen-abizenak ez dira aldatu."
|
msgstr "Zure izen-abizenak ez dira aldatu."
|
||||||
|
|
||||||
#: libs/localization.py:56
|
#: libs/localization.py:63
|
||||||
msgid "Your firstname is a bit short, don't you think?"
|
msgid "Your firstname is a bit short, don't you think?"
|
||||||
msgstr "Zure izena labur-xamarra da, ez duzu uste?"
|
msgstr "Zure izena labur-xamarra da, ez duzu uste?"
|
||||||
|
|
||||||
#: libs/localization.py:57
|
#: libs/localization.py:64
|
||||||
msgid "Your surname is a bit short, don't you think?"
|
msgid "Your surname is a bit short, don't you think?"
|
||||||
msgstr "Zure abizena labur-xamarra da, ez duzu uste?"
|
msgstr "Zure abizena labur-xamarra da, ez duzu uste?"
|
||||||
|
|
||||||
#: libs/localization.py:58
|
#: libs/localization.py:65
|
||||||
msgid "Your first and last name have been successfully updated."
|
msgid "Your first and last name have been successfully updated."
|
||||||
msgstr "Zure izen-abizenak ongi eguneratu dira."
|
msgstr "Zure izen-abizenak ongi eguneratu dira."
|
||||||
|
|
||||||
#: libs/localization.py:59
|
#: libs/localization.py:66
|
||||||
msgid "Invalid email address. Please try again."
|
msgid "Invalid email address. Please try again."
|
||||||
msgstr "Baliogabeko email helbidea. Saia zaitez berriz, mesedez."
|
msgstr "Baliogabeko email helbidea. Saia zaitez berriz, mesedez."
|
||||||
|
|
||||||
#: libs/localization.py:60
|
#: libs/localization.py:67
|
||||||
msgid "Email address has not been changed."
|
msgid "Email address has not been changed."
|
||||||
msgstr "Email helbidea ez da aldatu."
|
msgstr "Email helbidea ez da aldatu."
|
||||||
|
|
||||||
#: libs/localization.py:61
|
#: libs/localization.py:68
|
||||||
msgid "Your email has been successfully updated."
|
msgid "Your email has been successfully updated."
|
||||||
msgstr "Zure emaila ongi eguneratu da."
|
msgstr "Zure emaila ongi eguneratu da."
|
||||||
|
|
||||||
#: libs/localization.py:62
|
#: libs/localization.py:69
|
||||||
msgid "The password entered is the same as the current password."
|
msgid "The password entered is the same as the current password."
|
||||||
msgstr "Sartutako pasahitza egungo pasahitzaren berdina da."
|
msgstr "Sartutako pasahitza egungo pasahitzaren berdina da."
|
||||||
|
|
||||||
#: libs/localization.py:63
|
#: libs/localization.py:70
|
||||||
msgid "Password has been changed!"
|
msgid "Password has been changed!"
|
||||||
msgstr "Pasahitza eguneratua izan da!"
|
msgstr "Pasahitza eguneratua izan da!"
|
||||||
|
|
||||||
#: libs/localization.py:64
|
#: libs/localization.py:71
|
||||||
msgid "Please, type your username for account deletion."
|
msgid "Please, type your username for account deletion."
|
||||||
msgstr "Kontua ezabatzeko idatzi zure erabiltzaile izena, mesedez."
|
msgstr "Kontua ezabatzeko idatzi zure erabiltzaile izena, mesedez."
|
||||||
|
|
||||||
#: libs/localization.py:65
|
#: libs/localization.py:72
|
||||||
msgid "Account successfully deleted!"
|
msgid "Account successfully deleted!"
|
||||||
msgstr "Kontua ongi ezabatu da!"
|
msgstr "Kontua ongi ezabatu da!"
|
||||||
|
|
||||||
#: libs/localization.py:66
|
#: libs/localization.py:73
|
||||||
msgid "Username or password is incorrect!"
|
msgid "Username or password is incorrect!"
|
||||||
msgstr "Erabiltzaile izena edo pasahitza okerrak dira!"
|
msgstr "Erabiltzaile izena edo pasahitza okerrak dira!"
|
||||||
|
|
||||||
#: libs/localization.py:67
|
#: libs/localization.py:74
|
||||||
msgid "Unable to connect to the remote server."
|
msgid "Unable to connect to the remote server."
|
||||||
msgstr "Ezinezkoa urruneko zerbitzara konektatzea."
|
msgstr "Ezinezkoa urruneko zerbitzara konektatzea."
|
||||||
|
|
||||||
#: libs/localization.py:68
|
#: libs/localization.py:75
|
||||||
msgid ""
|
msgid "Encountered an unexpected error while communicating with the remote server."
|
||||||
"Encountered an unexpected error while communicating with the remote server."
|
|
||||||
msgstr "Ezusteko errore bat gertatu da urruneko zerbitzariarekin komunikatzean."
|
msgstr "Ezusteko errore bat gertatu da urruneko zerbitzariarekin komunikatzean."
|
||||||
|
|
||||||
#: libs/localization.py:69
|
#: libs/localization.py:76
|
||||||
msgid "User already exists."
|
msgid "User already exists."
|
||||||
msgstr "Erabiltzaile hori existitzen da."
|
msgstr "Erabiltzaile hori existitzen da."
|
||||||
|
|
||||||
#: libs/localization.py:70
|
#: libs/localization.py:77
|
||||||
msgid "Email already exists."
|
msgid "Email already exists."
|
||||||
msgstr "Email hori existitzen da."
|
msgstr "Email hori existitzen da."
|
||||||
|
|
||||||
#: libs/localization.py:71
|
#: libs/localization.py:78
|
||||||
msgid "Forgot your password? Please try again."
|
msgid "Forgot your password? Please try again."
|
||||||
msgstr "Zure pasahitza ahaztu duzu? Saia zeitez berriz, mesedez."
|
msgstr "Zure pasahitza ahaztu duzu? Saia zeitez berriz, mesedez."
|
||||||
|
|
||||||
#: libs/localization.py:72
|
#: libs/localization.py:79
|
||||||
msgid "The session has expired."
|
msgid "The session has expired."
|
||||||
msgstr "Saioa iraungi egin da."
|
msgstr "Saioa iraungi egin da."
|
||||||
|
|
||||||
#: libs/localization.py:73
|
#: libs/localization.py:80
|
||||||
msgid "Registration is currently closed. We apologize for the inconvenience."
|
msgid "Registration is currently closed. We apologize for the inconvenience."
|
||||||
msgstr "Izen-ematea itxita dago une honetan. Barkatu eragozpenak."
|
msgstr "Izen-ematea itxita dago une honetan. Barkatu eragozpenak."
|
||||||
|
|
||||||
|
#: libs/localization.py:81
|
||||||
|
msgid "Two factor authentication has been impossible."
|
||||||
|
msgstr "Ezinezkoa izan da bi urratseko autentifikazioa burutzea."
|
||||||
|
|
||||||
|
#: libs/localization.py:82
|
||||||
|
msgid "Two factor authentication has been restored."
|
||||||
|
msgstr "Bi urratseko autentifikazioa birgaitua izan da."
|
||||||
|
|
||||||
|
#: libs/localization.py:83
|
||||||
|
msgid "Two factor authentication has been enabled."
|
||||||
|
msgstr "Bi urratseko autentifikazioa gaitua izan da."
|
||||||
|
|
||||||
|
#: libs/localization.py:84
|
||||||
|
msgid "Two factor authentication has been disabled."
|
||||||
|
msgstr "Bi urratseko autentifikazioa desgaitua izan da."
|
||||||
|
|
||||||
|
#: libs/localization.py:85
|
||||||
|
msgid "Two factor authentication was already disabled."
|
||||||
|
msgstr "Bi urratseko autentifikazioa desgaiturik zegoen."
|
||||||
|
|||||||
@@ -194,6 +194,22 @@ button.red:hover{
|
|||||||
animation-name: fadeOut;
|
animation-name: fadeOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
.qr-code {
|
||||||
|
margin: 0 auto;
|
||||||
|
width: max-content;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
|
||||||
|
.info {
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: 24rem;
|
||||||
|
padding: 0 2.5rem 0 2.5rem;
|
||||||
|
text-align: justify;
|
||||||
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
.grid-container {
|
.grid-container {
|
||||||
display: grid;
|
display: grid;
|
||||||
@@ -226,7 +242,16 @@ button.red:hover{
|
|||||||
form {
|
form {
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
max-width: 16rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media only screen and (min-width: 481px) and (max-width: 760px) {
|
||||||
|
|
||||||
|
.info {
|
||||||
|
max-width: 22rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
<div class="grid-item">
|
<div class="grid-item">
|
||||||
<div class="account">
|
<div class="account">
|
||||||
<h5>2FA</h5>
|
<h5>2FA</h5>
|
||||||
<p>Bi urratseko autentifikazioa</p>
|
<p>{{ str['2fa-title'] }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -4,5 +4,6 @@
|
|||||||
http = :8080
|
http = :8080
|
||||||
chdir = %v
|
chdir = %v
|
||||||
wsgi-file = %v/app.py
|
wsgi-file = %v/app.py
|
||||||
|
enable-thread = true
|
||||||
processes = 1
|
processes = 1
|
||||||
threads = 2
|
threads = 2
|
||||||
|
|||||||
Reference in New Issue
Block a user