Commit 3da20641 by taufikyu

fix base, update template schema

1 parent 3becdae6
...@@ -101,16 +101,16 @@ class Password(colander.Schema): ...@@ -101,16 +101,16 @@ class Password(colander.Schema):
old_password = colander.SchemaNode( old_password = colander.SchemaNode(
colander.String(), widget=widget.PasswordWidget()) colander.String(), widget=widget.PasswordWidget())
new_password = colander.SchemaNode( new_password = colander.SchemaNode(
colander.String(), widget=widget.PasswordWidget()) colander.String(), widget=widget.CheckedPasswordWidget())
retype_password = colander.SchemaNode( # retype_password = colander.SchemaNode(
colander.String(), widget=widget.PasswordWidget()) # colander.String(), widget=widget.PasswordWidget())
def password_validator(form, value): def password_validator(form, value):
if not UserService.check_password(form.request.user, value['old_password']): if not UserService.check_password(form.request.user, value['old_password']):
raise colander.Invalid(form, 'Invalid old password.') raise colander.Invalid(form, 'Invalid old password.')
if value['new_password'] != value['retype_password']: # if value['new_password'] != value['retype_password']:
raise colander.Invalid(form, 'Retype mismatch.') # raise colander.Invalid(form, 'Retype mismatch.')
@view_config( @view_config(
......
...@@ -317,30 +317,33 @@ class Logout(BaseView): ...@@ -317,30 +317,33 @@ class Logout(BaseView):
class ChangePassword(colander.Schema): class ChangePassword(colander.Schema):
new_password = colander.SchemaNode( new_password = colander.SchemaNode(
colander.String(), widget=widget.PasswordWidget()) colander.String(), widget=widget.CheckedPasswordWidget())
retype_password = colander.SchemaNode( # retype_password = colander.SchemaNode(
colander.String(), widget=widget.PasswordWidget()) # colander.String(), widget=widget.PasswordWidget())
password = colander.SchemaNode(colander.String(), # password = colander.SchemaNode(colander.String(),
widget=widget.PasswordWidget(), # widget=widget.PasswordWidget(),
title=_("Old Password")) # title=_("Old Password"))
def change_password_validator(form, value): def change_password_validator(form, value):
exc = colander.Invalid(form, '') exc = colander.Invalid(form, '')
user = form.request.user user = form.request.user
if not UserService.check_password(user, value["password"]): # if not UserService.check_password(user, value["password"]):
exc["password"] = 'Login Failed' # exc["password"] = 'Login Failed'
raise exc # raise exc
if value['new_password'] != value['retype_password']: # if value['new_password'] != value['retype_password']:
exc["new_password"] = 'Retype mismatch.' # exc["new_password"] = 'Retype mismatch.'
exc["retype_password"] = 'Retype mismatch.' # exc["retype_password"] = 'Retype mismatch.'
raise exc # raise exc
@view_config(route_name='change-password', @view_config(route_name='change-password',
renderer='templates/change-password.pt') renderer='templates/change-password.pt')
def view_change_password(request): def view_change_password(request):
"""
Digunakan untuk change password url dari email (register, reset password)
"""
if request.authenticated_userid: if request.authenticated_userid:
request.session.flash('Anda sudah login', 'error') request.session.flash('Anda sudah login', 'error')
return HTTPFound(location=get_urls(f"{request.route_url('home')}")) return HTTPFound(location=get_urls(f"{request.route_url('home')}"))
......
...@@ -4,9 +4,10 @@ ...@@ -4,9 +4,10 @@
css_class css_class|field.widget.css_class; css_class css_class|field.widget.css_class;
style style|field.widget.style"> style style|field.widget.style">
${field.start_mapping()} ${field.start_mapping()}
<div> <div class="input">
<input type="password" <input type="password"
name="${name}" name="${name}"
onkeyup="checkPasswordStrength();"
value="${field.widget.redisplay and cstruct or ''}" value="${field.widget.redisplay and cstruct or ''}"
tal:attributes="class string: form-control ${css_class or ''}; tal:attributes="class string: form-control ${css_class or ''};
style style; style style;
...@@ -14,10 +15,17 @@ ${field.start_mapping()} ...@@ -14,10 +15,17 @@ ${field.start_mapping()}
id="${oid}" id="${oid}"
i18n:attributes="placeholder" i18n:attributes="placeholder"
placeholder="Password"/> placeholder="Password"/>
<div class="checkbox">
<label>
<input type="checkbox" id="view${field.oid}">
<span>Show Password</span>
</label>
</div>
</div> </div>
<div> <div class="input">
<input type="password" <input type="password"
name="${name}-confirm" name="${name}-confirm"
onkeyup="checkPasswordStrength${oid}();"
value="${field.widget.redisplay and confirm or ''}" value="${field.widget.redisplay and confirm or ''}"
tal:attributes="class string: form-control ${css_class or ''}; tal:attributes="class string: form-control ${css_class or ''};
style style; style style;
...@@ -25,6 +33,70 @@ ${field.start_mapping()} ...@@ -25,6 +33,70 @@ ${field.start_mapping()}
id="${oid}-confirm" id="${oid}-confirm"
i18n:attributes="placeholder" i18n:attributes="placeholder"
placeholder="Confirm Password"/> placeholder="Confirm Password"/>
<div class="checkbox">
<label>
<input type="checkbox" id="view${field.oid}-confirm">
<span>Show Password</span>
</label>
</div>
<div id="${oid}-confirm-password-strength-status"></div>
</div> </div>
${field.end_mapping()} ${field.end_mapping()}
<style>
#password-strength-status {
padding: 5px 10px;
border-radius: 4px;
margin-top: 5px;
}
</style>
<script type="text/javascript">
$('#view${oid}').change(function(){
if ($(this).prop('checked')==true){
$('#${oid}').attr('type','text');
}
else {
$('#${oid}').attr('type','password');
}
});
$('#view${oid}-confirm').change(function(){
if ($(this).prop('checked')==true){
$('#${oid}-confirm').attr('type','text');
}
else {
$('#${oid}-confirm').attr('type','password');
}
});
function checkPasswordStrength${oid}() {
var number = /([0-9])/;
var alphabets = /([a-zA-Z])/;
var special_characters = /([~,!,@,#,$,%,^,&,*,-,_,+,=,?,>,<,\),\(,{,},\[,\]])/;
var passworda = $('#${oid}').val().trim();
var password = $('#${oid}-confirm').val().trim();
if (password.length <= 8) {
$('#${oid}-confirm-password-strength-status').removeClass();
$('#${oid}-confirm-password-strength-status').addClass('label label-danger');
$('#${oid}-confirm-password-strength-status').html("Weak (should be atleast 8 characters.)");
} else {
if (passworda != password){
$('#${oid}-confirm-password-strength-status').removeClass();
$('#${oid}-confirm-password-strength-status').addClass('label label-danger');
$('#${oid}-confirm-password-strength-status').html("Password do not match.");
}
else if (password.match(number) && password.match(alphabets) && password.match(special_characters)) {
$('#${oid}-confirm-password-strength-status').removeClass();
$('#${oid}-confirm-password-strength-status').addClass('label label-success');
$('#${oid}-confirm-password-strength-status').html("Strong");
}
else {
$('#${oid}-confirm-password-strength-status').removeClass();
$('#${oid}-confirm-password-strength-status').addClass('label label-warning');
$('#${oid}-confirm-password-strength-status').html("Medium (should include alphabets, numbers and special characters.)");
}
}
}
</script>
</div> </div>
...@@ -2,23 +2,37 @@ ...@@ -2,23 +2,37 @@
css_class css_class|field.widget.css_class; css_class css_class|field.widget.css_class;
style style|field.widget.style; style style|field.widget.style;
preview_url cstruct.get('preview_url')|cstruct.get('base64')|''; preview_url cstruct.get('preview_url')|cstruct.get('base64')|'';
ext str(cstruct.get('filename').split('.')[-1:][0]).lower()|[];"> ext str(cstruct.get('filename').split('.')[-1:][0]).lower()|[];
fname str(cstruct.get('filename'))|'';
delete cstruct.get('delete')|'';">
${field.start_mapping()} ${field.start_mapping()}
<tal:block tal:condition="preview_url and ext in ['jpg','jpeg','png','bmp','gif']"> <tal:block tal:condition="preview_url and ext in ['jpg','jpeg','png','bmp','gif']">
<img id="preview-${oid}" alt="" src="${structure: preview_url}" style="width:100px;height:auto;"></img> <img id="preview-${oid}" alt="" src="${structure: preview_url}" style="width:100px;height:auto;"
onload="window.URL.revokeObjectURL(this.src)"></img>
<br> <br>
</tal:block> </tal:block>
<tal:block tal:condition="not preview_url or ext not in ['jpg','jpeg','png','bmp','gif']"> <tal:block tal:condition="not preview_url or ext not in ['jpg','jpeg','png','bmp','gif']">
<img id="preview-${oid}" alt="" src="" style="width:100px;height:auto;"></img> <img id="preview-${oid}" alt="" src="" style="width:100px;height:auto;"
onload="window.URL.revokeObjectURL(this.src)"></img>
<br> <br>
</tal:block> </tal:block>
<a id="label-${oid}" tal:condition="preview_url" class="label label-default" href="${structure: preview_url}" <a id="label-${oid}" tal:condition="preview_url" class="label label-default" href="${structure: preview_url}"
target="_blank"><i class="fa fa-search"></i> View</a> target="_blank"><i class="fa fa-search"></i> View</a>
<button id="labeldelete-${oid}" type="button" tal:condition="delete" class="label label-danger" href="#"
target="_blank"
onclick="var daft = document.getElementById('daftar_file_hapus').value.replace(/\[|\]/g,'').split(',');
daft.push('${fname}');
document.getElementById('daftar_file_hapus').value=daft;
document.getElementById('${oid}-close').click();">
<i class="fa fa-remove"></i> Delete</button>
<input type="file" name="upload" id="${oid}" <input type="file" name="upload" id="${oid}"
tal:attributes="style style; tal:attributes="style style;
accept accept|field.widget.accept; accept accept|field.widget.accept;
data-filename cstruct.get('filename'); data-filename fname;
attributes|field.widget.attributes|{};"/> attributes|field.widget.attributes|{};"
onchange="document.getElementById('preview-'+this.id).src = window.URL.createObjectURL(this.files[0]);
document.getElementById('labeldelete-'+this.id).remove();
document.getElementById('label-'+this.id).remove();"/>
<input tal:define="uid cstruct.get('uid')" <input tal:define="uid cstruct.get('uid')"
tal:condition="uid" tal:condition="uid"
type="hidden" name="uid" value="${uid}"/> type="hidden" name="uid" value="${uid}"/>
...@@ -27,13 +41,6 @@ ...@@ -27,13 +41,6 @@
deform.addCallback('${oid}', function (oid) { deform.addCallback('${oid}', function (oid) {
$('#' + oid).upload(); $('#' + oid).upload();
}); });
document.getElementById('${oid}').addEventListener('change', function () {
var output = document.getElementById('preview-${oid}');
output.src = URL.createObjectURL(this.files[0]);
document.getElementById('label-${oid}').remove();
output.onload = function() {
URL.revokeObjectURL(output.src) // free memory
}
});
</script> </script>
</tal:block> </tal:block>
<input <tal:block tal:define="name name|field.name;
tal:define="autofocus autofocus|field.autofocus" oid oid|field.oid;">
<div class="input">
<input
type="password" type="password"
name="${name|field.name}" name="${name}"
onkeyup="checkPasswordStrength${oid}();"
value="${field.widget.redisplay and cstruct or ''}" value="${field.widget.redisplay and cstruct or ''}"
tal:attributes="style style|field.widget.style; tal:attributes="style style|field.widget.style;
class string: form-control ${css_class|field.widget.css_class or ''}; class string: form-control ${css_class|field.widget.css_class or ''};
autofocus autofocus;
attributes|field.widget.attributes|{};" attributes|field.widget.attributes|{};"
id="${oid|field.oid}"/> id="${oid}"/>
<div class="checkbox">
<label>
<input type="checkbox" id="view${oid}">
<span>Show Password</span>
</label>
</div>
<div id="${oid}-password-strength-status"></div>
</div>
<style>
#password-strength-status {
padding: 5px 10px;
border-radius: 4px;
margin-top: 5px;
}
</style>
<script type="text/javascript">
$('#view${oid}').change(function(){
if ($(this).prop('checked')==true){
$('#${oid}').attr('type','text');
}
else {
$('#${oid}').attr('type','password');
}
});
function checkPasswordStrength${oid}() {
var number = /([0-9])/;
var alphabets = /([a-zA-Z])/;
var special_characters = /([~,!,@,#,$,%,^,&,*,-,_,+,=,?,>,<,\),\(,{,},\[,\]])/;
var password = $('#${oid}').val().trim();
if (password.length <= 8) {
$('#${oid}-password-strength-status').removeClass();
$('#${oid}-password-strength-status').addClass('label label-danger');
$('#${oid}-password-strength-status').html("Weak (should be atleast 8 characters.)");
} else {
if (password.match(number) && password.match(alphabets) && password.match(special_characters)) {
$('#${oid}-password-strength-status').removeClass();
$('#${oid}-password-strength-status').addClass('label label-success');
$('#${oid}-password-strength-status').html("Strong");
}
else {
$('#${oid}-password-strength-status').removeClass();
$('#${oid}-password-strength-status').addClass('label label-warning');
$('#${oid}-password-strength-status').html("Medium (should include alphabets, numbers and special characters.)");
}
}
}
</script>
</tal:block>
<p tal:define="preview_url cstruct.get('preview_url')"> <p tal:define="preview_url cstruct.get('preview_url');
<a tal:condition="preview_url" href="${structure: preview_url}" ext str(cstruct.get('filename').split('.')[-1:][0]).lower()|[];">
target="_blank">Show</a> <tal:block tal:condition="preview_url and ext in ['jpg','jpeg','png','bmp','gif']">
<p tal:condition="not preview_url" id="${oid|field.oid}" <img src="${structure: preview_url}" style="width:100px;height:auto;"></img>
class="form-control-static deform-readonly-text" <br>
tal:content="cstruct.get('filename') or ''"></p> </tal:block>
<a class="label label-default" href="${structure: preview_url}"
target="_blank"><i class="fa fa-search"></i> View</a>
</p> </p>
...@@ -99,6 +99,7 @@ ...@@ -99,6 +99,7 @@
<input type="hidden" name="__end__" value="${field.name}:sequence"/> <input type="hidden" name="__end__" value="${field.name}:sequence"/>
<!-- /sequence --> <!-- /sequence -->
<input tal:define="templates subfields[0][1].widget.template|''" tal:condition="templates=='file_upload'" id="daftar_file_hapus" name="daftar_file_hapus" type="hidden">
</div> </div>
</div> </div>
......
...@@ -20,12 +20,12 @@ ...@@ -20,12 +20,12 @@
</div> </div>
<div class="col-xs-1" style="padding:0"> <div class="col-xs-1" style="padding:0">
<!-- sequence_item --> <!-- sequence_item -->
<span class="deform-order-button close glyphicon glyphicon-resize-vertical" <span class="deform-order-button close glyphicon glyphicon-resize-vertical ${field.widget.template=='file_upload' and 'hide' or ''}"
id="${oid}-order" id="${oid}-order"
tal:condition="not hidden" tal:condition="not hidden"
title="Reorder (via drag and drop)" title="Reorder (via drag and drop)"
i18n:attributes="title"></span> i18n:attributes="title"></span>
<a class="deform-close-button close" <a class="deform-close-button close ${field.widget.template=='file_upload' and 'hide' or ''}"
id="${oid}-close" id="${oid}-close"
tal:condition="not field.widget.hidden" tal:condition="not field.widget.hidden"
title="Remove" title="Remove"
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!