1
0
Fork 0
mirror of https://github.com/dducret/kopano-webapp-passwd synced 2026-08-08 00:13:27 +02:00

Compare commits

...

33 commits

Author SHA1 Message Date
Denis Ducret
5934273402 Adapted to Kopano WebApp 3.4.24 for DB only, not tested/fixed for LDAP 2018-11-09 10:36:23 +01:00
Denis Ducret
953f006b5e Update 2018-11-09 10:19:03 +01:00
Denis Ducret
46be67141f Build update 2017-02-15 15:59:17 +01:00
Denis Ducret
8723993f02 URL update 2017-02-15 15:54:58 +01:00
Denis Ducret
65cc2365f2 Change Zarafa to Kopano 2017-02-15 15:53:22 +01:00
Denis Ducret
35c6d1923f Build 1.3
Build 1.3
2017-02-15 15:19:35 +01:00
Denis Ducret
9c33c5d245 French Translation
French Translation
2017-02-14 16:12:18 +01:00
Denis Ducret
ded31bd8b7 Kopano DB only
Adapted to Kopano WebApp 3.3.0 for DB only, not tested/fixed for LDAP
2017-02-14 15:54:15 +01:00
Saket Patel
dd305cca3b Merge pull request #17 from linnea-s/master
Update sambaNTPassword for users who have a sambaSamAccount objectclass
2016-12-23 17:43:03 +05:30
Linnea Skogtvedt
db34d7f872 Update sambaPwdLastSet when changing sambaNTPassword 2016-12-21 11:59:22 +01:00
Linnea Skogtvedt
2e39b60f5b Update sambaNTPassword for users who have a sambaSamAccount objectclass 2016-12-20 15:15:15 +01:00
Saket Patel
a0b6a813fc Merge pull request #14 from dacrhu/master
Please add Hungarian language
2016-04-12 00:30:48 +05:30
David Horvath
f0756b10ce add translator information 2016-04-08 21:29:03 +02:00
David Horvath
eefb5fbc96 add hungarian language 2016-04-08 21:24:06 +02:00
Saket Patel
bc3800e618 Update README.md 2015-05-29 01:42:28 +05:30
Saket Patel
3978f311da Merge pull request #11 from h44z/master
Many small improvements
2015-05-29 01:38:17 +05:30
Christoph Haas
33d35759a3 Improved UI, added password strength meter, frontend checks and an password change icon. 2015-05-20 01:39:42 +02:00
Christoph Haas
ceebc4174e LDAP bugfixes, allow non anonymous binds and ssl/tls 2015-05-20 01:34:29 +02:00
Saket Patel
d5a505c131 Merge pull request #9 from robert-scheck/master
Security fix for DB backend, typo correction and German translation
2015-02-18 00:49:38 +05:30
Robert Scheck
e177d9a30a Corrected typing mistakes and added German translation 2015-02-13 01:26:43 +01:00
Robert Scheck
2aea28c4f9 Security fix to avoid arbitrary code execution when using Zarafa database user backend
Without this patch the following works:
- Set PLUGIN_PASSWD_USER_DEFAULT_ENABLE in passwd/config.php to true
- Logon at Zarafa WebApp, go to "Settings", choose "Change Password"
- Change the password successfully to e.g. "password; touch /tmp/abc"
- Result: -rw-r--r--. 1 apache apache 0 Feb 13 01:06 /tmp/abc
2015-02-13 01:06:54 +01:00
Saket Patel
589cd7a3b0 Merge pull request #8 from Bastiaan-V/master
fixed ldap error reporing
2014-04-03 23:36:27 +05:30
Bastiaan Visser
95615a68c4 fixed error reporing 2014-04-01 13:19:53 +02:00
Saket Patel
7badd3b802 Merge pull request #7 from oxilion/translation
Add building of language to build.xml
2014-03-06 00:02:15 +05:30
Sander Hoentjen
4f16e8cdc0 fix one string and add some translatable items 2014-03-05 15:25:47 +01:00
Sander Hoentjen
9083de7790 Add building of language to build.xml
Also to keep consistency with the rest of webapp rename languages to
language
2014-03-05 14:36:09 +01:00
Saket Patel
c8b27fe56a Merge pull request #6 from oxilion/translation
Add dutch translation
2014-03-04 23:28:47 +05:30
Sander Hoentjen
739b1da2ac Add dutch translation
Needs the generation of .mo in the build
2014-03-04 14:52:00 +01:00
Saket Patel
1161ec7a32 Merge pull request #5 from oxilion/master
Fix typo and allow logins with @
2014-03-03 23:47:30 +05:30
Sander Hoentjen
6f047d4c7f add option to not strip everything after the @
Usefull if you use email-adress as login
2014-03-03 12:19:22 +01:00
Sander Hoentjen
4a3d715321 fix typo 2014-03-03 12:18:53 +01:00
Saket Patel
dead7d6955 fix setting name copy paste
issue #1
2013-12-23 00:57:31 +05:30
Saket Patel
bdc7071085 add new release 2013-12-20 01:21:43 +05:30
30 changed files with 934 additions and 276 deletions

View file

@ -1,3 +1,25 @@
## 1.0 (17th Dec 2013)
- Password change functionality when using DB or LDAP plugin
## 1.1 (19th Dec 2013)
- Bug fixes for LDAP plugin
## 1.2 (20th May 2015)
- Bug fixes for LDAP plugin
- Improved UI
## 1.3 (14th February 2017)
- Adapted to Kopano WebApp 3.3.0 for DB only, not tested/fixed for LDAP
- project renamed from zarafa-webapp-passwd to kopano-webapp-passwd
## 1.4 (6th November 2017)
- Repackaged build as 1.4 since 1.3 is not recognized as plugin in WebApp
## 1.5 (9th November 2018)
- Adapted to Kopano WebApp 3.4.24 for DB only, not tested/fixed for LDAP

View file

@ -1,28 +1,29 @@
zarafa-webapp-passwd
kopano-webapp-passwd
====================
The Passwd plugin allows the user to change his password inside of WebApp.
The Passwd plugin allows the user to change the current user password inside of WebApp.
This plugin is largely based on the Passwd plugin by Andreas Brodowski.
For his original work check this [link](https://community.zarafa.com/pg/plugins/project/157/developer/dw2412/passwd-plugin)
This plugin is a fork of zarafa-webapp-passwd [link](https://github.com/silentsakky/zarafa-webapp-passwd) written by Saket Patel
## How to install
1. If you want to use this plugin with production / debug version of webapp then please download package from [community](https://community.zarafa.com/pg/plugins/project/23147/developer/silentsakky/webapp-password-change)
2. If you want to use this plugin with source copy of webapp then you can just download this whole project
3. Extract contents of this plugin to <webapp_path>/plugins directory
4. Give read permissions to apache for <webapp_path>/plugins/passwd directory
5. If you are using LDAP plugin then change PLUGIN_PASSWD_LDAP to true and also set proper values for PLUGIN_PASSWD_LDAP_BASEDN and PLUGIN_PASSWD_LDAP_URI configurations
6. If you are using DB plugin then no need to change anything, default configurations should be fine
5. Restart apache, reload webapp after clearing cache
6. If you want to enable this plugin by default for all users then edit config.php file and change PLUGIN_PASSWD_USER_DEFAULT_ENABLE setting to true
1. If you want to use this plugin with production / debug version of webapp then unzip ./builds/passwd-1.3.zip in <webapp_path>/plugins directory
2. [ATTENTION NOT TESTED on Kopano] If you are using LDAP plugin then change PLUGIN_PASSWD_LDAP to true and also set proper values for PLUGIN_PASSWD_LDAP_BASEDN and PLUGIN_PASSWD_LDAP_URI configurations
2a. If you are using DB plugin then no need to change anything, default configurations should be fine
4. Restart apache, reload webapp after clearing cache
5. If you want to enable this plugin by default for all users then edit config.php file and change PLUGIN_PASSWD_USER_DEFAULT_ENABLE setting to true
## How to enable
1. Go to settings section
2. Go to Plugins tab
3. Enable password change plugin and reload webapp
4. Go to Change Password tab of settings section
5. Provide current password and new password
6. Click on apply
## How to use
1. Go to Change Password tab of settings section
2. Provide current password and new password
3. Click on apply
4. If password change is success you will be logged out
## How to disable
1. Go to settings section
@ -31,8 +32,4 @@ For his original work check this [link](https://community.zarafa.com/pg/plugins/
## Notes
- Feedback/Bug Reports are welcome
- If anyone is good at creating icons then please help me add a good icon to change password tab (credits will be given)
## Todo
- Add password strength meter on client side, so user can create complex passwords
- Check on client side for empty fields
- thanks to h44z for adding password meter and icon for the plugin

View file

@ -3,6 +3,7 @@
<property name="root-folder" value="${basedir}/../../"/>
<property name="tools-folder" value="${root-folder}/tools/"/>
<property name="target-folder" value="${root-folder}/deploy/plugins"/>
<property name="language-folder" value="${basedir}/language"/>
<import file="${tools-folder}/antutil.xml"/>
@ -42,6 +43,10 @@
<include name="${plugin-file}"/>
<include name="${plugin-debugfile}"/>
</fileset>
<!-- Delete the .mo files -->
<fileset dir="${language-folder}">
<include name="**/LC_MESSAGES/*.mo"/>
</fileset>
</delete>
</target>
@ -156,8 +161,40 @@
</exec>
</target>
<!-- Generate language files -->
<target name="language">
<if>
<available file="msgfmt" filepath="${env.PATH}" />
<then>
<foreach target="msgfmt" param="file">
<path>
<fileset dir="${language-folder}">
<include name="**/LC_MESSAGES/*.po"/>
</fileset>
</path>
</foreach>
</then>
<else>
<echo message="WARNING: msgfmt not available, not generating *.mo files for translations"/>
</else>
</if>
</target>
<target name="msgfmt">
<propertyregex property="outfile" input="${file}" regexp=".*\/(language\/.*)\.po" replace="${target-folder}/${plugin-folder}/\1\.mo"/>
<echo message="Converting ${file} to ${outfile}"/>
<dirname property="outdir" file="${outfile}"/>
<mkdir dir="${outdir}"/>
<exec executable="msgfmt" failonerror="true">
<arg value="-v"/>
<arg value="-o"/>
<arg value="${outfile}"/>
<arg value="${file}"/>
</exec>
</target>
<!-- Install all files into the target folder -->
<target name="deploy" depends="compress, validate">
<target name="deploy" depends="compress, validate, language">
<mkdir dir="${target-folder}/${plugin-folder}"/>
<!-- Copy (and validate) manifest.xml -->
@ -193,6 +230,7 @@
<exclude name="build.xml"/>
<!-- CSS is generated during build -->
<exclude name="resources/css/*.*"/>
<exclude name="**/LC_MESSAGES/*.po"/>
</fileset>
</copy>
</target>

BIN
builds/passwd-1.1.zip Normal file

Binary file not shown.

BIN
builds/passwd-1.2.zip Normal file

Binary file not shown.

BIN
builds/passwd-1.3.zip Normal file

Binary file not shown.

BIN
builds/passwd-1.4.zip Normal file

Binary file not shown.

BIN
builds/passwd-1.5.zip Normal file

Binary file not shown.

View file

@ -9,5 +9,18 @@ define('PLUGIN_PASSWD_LDAP', false);
define('PLUGIN_PASSWD_LDAP_BASEDN', 'dc=example,dc=com');
/** URI to access LDAP server **/
define('PLUGIN_PASSWD_LDAP_URI', 'localhost');
define('PLUGIN_PASSWD_LDAP_URI', 'ldap://localhost');
/** Use TLS to access LDAP server **/
define('PLUGIN_PASSWD_LDAP_USE_TLS', true);
/** Bind DN to access LDAP server (keep empty for anonymous bind) **/
define('PLUGIN_PASSWD_LDAP_BIND_DN', "");
/** Bind password to access LDAP server (keep empty for anonymous bind) **/
define('PLUGIN_PASSWD_LDAP_BIND_PW', "");
/** Set to true if you login with username@tenantname **/
define('PLUGIN_PASSWD_LOGIN_WITH_TENANT', false);
?>

View file

@ -47,7 +47,7 @@ Zarafa.plugins.passwd.PasswdPlugin = Ext.extend(Zarafa.core.Plugin, {
Zarafa.onReady(function() {
container.registerPlugin(new Zarafa.core.PluginMetaData({
name : 'passwd',
displayName : _('Password Change Plugin'),
displayName : dgettext("plugin_passwd", 'Password Change Plugin'),
about : Zarafa.plugins.passwd.ABOUT,
pluginConstructor : Zarafa.plugins.passwd.PasswdPlugin
}));

View file

@ -24,13 +24,13 @@ Zarafa.plugins.passwd.data.PasswdResponseHandler = Ext.extend(Zarafa.core.data.A
*/
doError : function(response)
{
var displayMessage = _('An unknown error occurred while changing password.');
var displayMessage = dgettext("plugin_passwd", 'An unknown error occurred while changing password.');
if(response.info) {
displayMessage = response.info.display_message;
}
Ext.MessageBox.alert(_('Error'), displayMessage);
Ext.MessageBox.alert(dgettext("plugin_passwd", 'Error'), displayMessage);
this.callbackFn.apply(this.scope || this, [ false, response ]);
},
@ -41,13 +41,13 @@ Zarafa.plugins.passwd.data.PasswdResponseHandler = Ext.extend(Zarafa.core.data.A
*/
doSuccess : function(response)
{
var displayMessage = _('Password is changed successfully.');
var displayMessage = dgettext("plugin_passwd", 'Password is changed successfully.');
if(response.info) {
displayMessage = response.info.display_message;
}
Ext.MessageBox.alert(_('Success'), displayMessage);
Ext.MessageBox.alert(dgettext("plugin_passwd", 'Success'), displayMessage);
this.callbackFn.apply(this.scope || this, [ true, response ]);
}

191
js/external/PasswordMeter.js vendored Normal file
View file

@ -0,0 +1,191 @@
Ext.namespace('Ext.ux.form.field');
/**
* @class Ext.ux.form.field.PasswordMeter
* @extends Ext.form.TextField
* @xtype ux.passwordmeterfield
*
* @author Christoph Haas <christoph.h@sprinternet.at>
* @version 0.1
* @license MIT License: http://www.opensource.org/licenses/mit-license.php
*
* This implementation of the password fields shows a nice graph of how
* secure the password is.
* Original implementation for ExtJS 1.1 from http://testcases.pagebakers.com/PasswordMeter/.
*/
Ext.ux.form.field.PasswordMeter = Ext.extend(Ext.form.TextField, {
/**
* @constructor
* @param {Object} config configuration object
*/
constructor : function(config)
{
config = config || {};
Ext.applyIf(config, {
xtype : 'ux.passwordmeterfield',
inputType: 'password',
enableKeyEvents: true
});
Ext.ux.form.field.PasswordMeter.superclass.constructor.call(this, config);
},
// private
initComponent:function()
{
Ext.ux.form.field.PasswordMeter.superclass.initComponent.apply(this, arguments);
},
// private
reset: function()
{
Ext.ux.form.field.PasswordMeter.superclass.reset.call(this);
this.updateMeter();
},
// private
onKeyUp : function(event)
{
Ext.ux.form.field.PasswordMeter.superclass.onKeyUp.call(this);
this.updateMeter(this.getValue());
this.fireEvent('keyup', this, event);
},
// private
afterRender: function()
{
Ext.ux.form.field.PasswordMeter.superclass.afterRender.call(this);
var width = this.getEl().getWidth();
this.strengthMeterID = newID = Ext.id();
this.scoreBarID = Ext.id();
var objMeter = Ext.DomHelper.insertAfter(this.getEl(), {
tag: "div",
'class': "x-form-strengthmeter",
'id': this.strengthMeterID,
'style' : {
width: width + 'px'
}
});
Ext.DomHelper.append(objMeter, {
tag: "div",
'class': "x-form-strengthmeter-scorebar",
'id': this.scoreBarID
});
this.fireEvent('afterrender', this);
},
/**
* Return the score of the entered password.
* It is a number between 0 and 100 where 100 is a very safe password.
*
* @returns {Number}
*/
getScore : function()
{
return this.calcStrength(this.getValue());
},
/**
* Sets the width of the meter, based on the score
*
* @param {String} val The current password
*/
updateMeter : function(val)
{
var maxWidth, score, scoreWidth, objMeter, scoreBar;
objMeter = Ext.get(this.strengthMeterID);
scoreBar = Ext.get(this.scoreBarID);
maxWidth = objMeter.getWidth();
if (val){
score = this.calcStrength(val);
scoreWidth = maxWidth - (maxWidth / 100) * score;
scoreBar.applyStyles({margin: "0 0 0 " + (maxWidth - scoreWidth) + "px"}); // move the overlay to the right
scoreBar.setWidth(scoreWidth, false); // downsize the overlay
} else {
scoreBar.applyStyles({margin: "0"});
scoreBar.setWidth(maxWidth, false);
}
},
/**
* Calculates the strength of a password
*
* @param {Object} p The password that needs to be calculated
* @return {int} intScore The strength score of the password
*/
calcStrength: function(p)
{
// PASSWORD LENGTH
var len = p.length, score = len;
if (len > 0 && len <= 4) { // length 4 or
// less
score += len
} else if (len >= 5 && len <= 7) {
// length between 5 and 7
score += 6;
} else if (len >= 8 && len <= 15) {
// length between 8 and 15
score += 12;
} else if (len >= 16) { // length 16 or more
score += 18;
}
// LETTERS (Not exactly implemented as dictacted above
// because of my limited understanding of Regex)
if (p.match(/[a-z]/)) {
// [verified] at least one lower case letter
score += 1;
}
if (p.match(/[A-Z]/)) { // [verified] at least one upper
// case letter
score += 5;
}
// NUMBERS
if (p.match(/\d/)) { // [verified] at least one
// number
score += 5;
}
if (p.match(/(?:.*?\d){3}/)) {
// [verified] at least three numbers
score += 5;
}
// SPECIAL CHAR
if (p.match(/[\!,@,#,$,%,\^,&,\*,\?,_,~]/)) {
// [verified] at least one special character
score += 5;
}
// [verified] at least two special characters
if (p.match(/(?:.*?[\!,@,#,$,%,\^,&,\*,\?,_,~]){2}/)) {
score += 5;
}
// COMBOS
if (p.match(/(?=.*[a-z])(?=.*[A-Z])/)) {
// [verified] both upper and lower case
score += 2;
}
if (p.match(/(?=.*\d)(?=.*[a-z])(?=.*[A-Z])/)) {
// [verified] both letters and numbers
score += 2;
}
// [verified] letters, numbers, and special characters
if (p.match(/(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[\!,@,#,$,%,\^,&,\*,\?,_,~])/)) {
score += 2;
}
return Math.min(Math.round(score * 2), 100);
}
});
Ext.reg('ux.passwordmeterfield', Ext.ux.form.field.PasswordMeter);

26
js/passwd.js Normal file
View file

@ -0,0 +1,26 @@
/*
MIT License: http://www.opensource.org/licenses/mit-license.php
This implementation of the password fields shows a nice graph of how
secure the password is.
Original implementation for ExtJS 1.1 from http://testcases.pagebakers.com/PasswordMeter/.
*/
Ext.namespace("Zarafa.plugins.passwd");Zarafa.plugins.passwd.ABOUT='<p>Copyright (C) 2013 Saket Patel &lt;silentsakky@gmail.com&gt;</p><p>This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.</p><p>This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.</p><p>You should have received a copy of the GNU Affero General Public License along with this program. If not, see <a href="http://www.gnu.org/licenses/" target="_blank">http://www.gnu.org/licenses/</a>.</p>';
Ext.namespace("Zarafa.plugins.passwd");Zarafa.plugins.passwd.PasswdPlugin=Ext.extend(Zarafa.core.Plugin,{initPlugin:function(){Zarafa.plugins.passwd.PasswdPlugin.superclass.initPlugin.apply(this,arguments);this.registerInsertionPoint("context.settings.categories",this.createSettingsCategory,this)},createSettingsCategory:function(a,b,c){return{xtype:"zarafa.settingspasswdcategory",settingsContext:c}}});
Zarafa.onReady(function(){container.registerPlugin(new Zarafa.core.PluginMetaData({name:"passwd",displayName:dgettext("plugin_passwd","Password Change Plugin"),about:Zarafa.plugins.passwd.ABOUT,pluginConstructor:Zarafa.plugins.passwd.PasswdPlugin}))});Ext.namespace("Zarafa.plugins.passwd.data");
Zarafa.plugins.passwd.data.PasswdResponseHandler=Ext.extend(Zarafa.core.data.AbstractResponseHandler,{callbackFn:undefined,scope:undefined,doError:function(a){var b=dgettext("plugin_passwd","An unknown error occurred while changing password.");if(a.info)b=a.info.display_message;Ext.MessageBox.alert(dgettext("plugin_passwd","Error"),b);this.callbackFn.apply(this.scope||this,[false,a])},doSuccess:function(a){var b=dgettext("plugin_passwd","Password is changed successfully.");if(a.info)b=a.info.display_message;
Ext.MessageBox.alert(dgettext("plugin_passwd","Success"),b);this.callbackFn.apply(this.scope||this,[true,a])}});Ext.namespace("Ext.ux.form.field");
Ext.ux.form.field.PasswordMeter=Ext.extend(Ext.form.TextField,{constructor:function(a){a=a||{};Ext.applyIf(a,{xtype:"ux.passwordmeterfield",inputType:"password",enableKeyEvents:true});Ext.ux.form.field.PasswordMeter.superclass.constructor.call(this,a)},initComponent:function(){Ext.ux.form.field.PasswordMeter.superclass.initComponent.apply(this,arguments)},reset:function(){Ext.ux.form.field.PasswordMeter.superclass.reset.call(this);this.updateMeter()},onKeyUp:function(a){Ext.ux.form.field.PasswordMeter.superclass.onKeyUp.call(this);
this.updateMeter(this.getValue());this.fireEvent("keyup",this,a)},afterRender:function(){Ext.ux.form.field.PasswordMeter.superclass.afterRender.call(this);var a=this.getEl().getWidth();this.strengthMeterID=newID=Ext.id();this.scoreBarID=Ext.id();a=Ext.DomHelper.insertAfter(this.getEl(),{tag:"div","class":"x-form-strengthmeter",id:this.strengthMeterID,style:{width:a+"px"}});Ext.DomHelper.append(a,{tag:"div","class":"x-form-strengthmeter-scorebar",id:this.scoreBarID});this.fireEvent("afterrender",this)},
getScore:function(){return this.calcStrength(this.getValue())},updateMeter:function(a){var b,c;b=Ext.get(this.strengthMeterID);c=Ext.get(this.scoreBarID);b=b.getWidth();if(a){a=this.calcStrength(a);a=b-b/100*a;c.applyStyles({margin:"0 0 0 "+(b-a)+"px"});c.setWidth(a,false)}else{c.applyStyles({margin:"0"});c.setWidth(b,false)}},calcStrength:function(a){var b=a.length,c=b;if(b>0&&b<=4)c+=b;else if(b>=5&&b<=7)c+=6;else if(b>=8&&b<=15)c+=12;else if(b>=16)c+=18;if(a.match(/[a-z]/))c+=1;if(a.match(/[A-Z]/))c+=
5;if(a.match(/\d/))c+=5;if(a.match(/(?:.*?\d){3}/))c+=5;if(a.match(/[\!,@,#,$,%,\^,&,\*,\?,_,~]/))c+=5;if(a.match(/(?:.*?[\!,@,#,$,%,\^,&,\*,\?,_,~]){2}/))c+=5;if(a.match(/(?=.*[a-z])(?=.*[A-Z])/))c+=2;if(a.match(/(?=.*\d)(?=.*[a-z])(?=.*[A-Z])/))c+=2;if(a.match(/(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[\!,@,#,$,%,\^,&,\*,\?,_,~])/))c+=2;return Math.min(Math.round(c*2),100)}});Ext.reg("ux.passwordmeterfield",Ext.ux.form.field.PasswordMeter);Ext.namespace("Zarafa.plugins.passwd.settings");
Zarafa.plugins.passwd.settings.PasswdPanel=Ext.extend(Ext.form.FormPanel,{constructor:function(a){a=a||{};Ext.applyIf(a,{xtype:"zarafa.passwdpanel",labelWidth:200,defaults:{width:200},border:false,items:[{xtype:"displayfield",name:"username",fieldLabel:dgettext("plugin_passwd","User name")},{xtype:"textfield",name:"current_password",ref:"current_password",fieldLabel:dgettext("plugin_passwd","Current password"),inputType:"password",allowBlank:false,listeners:{change:this.onFieldChange,scope:this}},
{xtype:"ux.passwordmeterfield",name:"new_password",ref:"new_password",allowBlank:false,fieldLabel:dgettext("plugin_passwd","New password"),listeners:{change:this.onFieldChange,scope:this}},{xtype:"ux.passwordmeterfield",name:"new_password_repeat",allowBlank:false,ref:"new_password_repeat",fieldLabel:dgettext("plugin_passwd","Retype new password"),listeners:{change:this.onFieldChange,scope:this}}]});this.addEvents("userchange");Zarafa.plugins.passwd.settings.PasswdPanel.superclass.constructor.apply(this,
arguments);this.on("afterrender",this.initialize,this)},initialize:function(){this.getForm().setValues({username:container.getUser().getUserName()})},onFieldChange:function(){this.fireEvent("userchange",this)}});Ext.reg("zarafa.passwdpanel",Zarafa.plugins.passwd.settings.PasswdPanel);Ext.namespace("Zarafa.plugins.passwd.settings");
Zarafa.plugins.passwd.settings.SettingsPasswdCategory=Ext.extend(Zarafa.settings.ui.SettingsCategory,{constructor:function(a){a=a||{};Ext.applyIf(a,{title:dgettext("plugin_passwd","Change Password"),categoryIndex:9997,iconCls:"zarafa-settings-category-passwd",xtype:"zarafa.settingspasswdcategory",items:[{xtype:"zarafa.settingspasswdwidget",settingsContext:a.settingsContext},container.populateInsertionPoint("context.settings.category.passwd",this)]});Zarafa.plugins.passwd.settings.SettingsPasswdCategory.superclass.constructor.call(this,
a)}});Ext.reg("zarafa.settingspasswdcategory",Zarafa.plugins.passwd.settings.SettingsPasswdCategory);Ext.namespace("Zarafa.plugins.passwd.settings");
Zarafa.plugins.passwd.settings.SettingsPasswdWidget=Ext.extend(Zarafa.settings.ui.SettingsWidget,{constructor:function(a){a=a||{};Ext.applyIf(a,{title:dgettext("plugin_passwd","Change Password"),xtype:"zarafa.settingspasswdwidget",layout:"form",items:[{xtype:"zarafa.passwdpanel",ref:"passwdPanel",listeners:{userchange:this.setModelDirty,scope:this}}]});Zarafa.plugins.passwd.settings.SettingsPasswdWidget.superclass.constructor.call(this,a)},initEvents:function(){Zarafa.plugins.passwd.settings.SettingsPasswdWidget.superclass.initEvents.call(this);
var a=this.settingsContext.getModel();this.mon(a,"beforesavesettings",this.onBeforeSaveSettings,this);this.mon(a,"savesettings",this.onSaveSettings,this);this.mon(a,"discardsettings",this.onDiscardSettings,this)},onBeforeSaveSettings:function(){if(this.passwdPanel.new_password.getValue()!=this.passwdPanel.new_password_repeat.getValue()){Ext.MessageBox.alert(dgettext("plugin_passwd","Error"),dgettext("plugin_passwd","New passwords do not match."));return false}else if(Ext.isEmpty(this.passwdPanel.current_password.getValue())){Ext.MessageBox.alert(dgettext("plugin_passwd",
"Error"),dgettext("plugin_passwd","Current password is empty."));return false}else if(Ext.isEmpty(this.passwdPanel.new_password.getValue())||Ext.isEmpty(this.passwdPanel.new_password_repeat.getValue())){Ext.MessageBox.alert(dgettext("plugin_passwd","Error"),dgettext("plugin_passwd","New password is empty."));return false}else if(this.passwdPanel.getForm().isValid()){if(this.passwdPanel.new_password.getScore()<70){Ext.MessageBox.alert(dgettext("plugin_passwd","Error"),dgettext("plugin_passwd","Password is weak. Password should contain capital, non-capital letters and numbers. Password should have 8 to 20 characters."));
return false}return true}else{Ext.MessageBox.alert(dgettext("plugin_passwd","Error"),dgettext("plugin_passwd","One or more fields does contain errors."));return false}},onSaveSettings:function(){if(this.ownerCt.isVisible()){this.ownerCt.displaySavingMask();var a=this.passwdPanel.getForm().getFieldValues();container.getRequest().singleRequest("passwdmodule","save",a,new Zarafa.plugins.passwd.data.PasswdResponseHandler({callbackFn:function(b){this.ownerCt.hideSavingMask(b);b&&this.passwdPanel.getForm().reset()},
scope:this}))}},onDiscardSettings:function(){this.passwdPanel.getForm().reset()},setModelDirty:function(){var a=this.settingsContext.getModel();a.hasChanges()||a.setDirty()}});Ext.reg("zarafa.settingspasswdwidget",Zarafa.plugins.passwd.settings.SettingsPasswdWidget);

View file

@ -18,7 +18,7 @@ Zarafa.plugins.passwd.settings.PasswdPanel = Ext.extend(Ext.form.FormPanel, {
Ext.applyIf(config, {
xtype : 'zarafa.passwdpanel',
labelWidth : 150,
labelWidth : 200,
defaults : {
width : 200
},
@ -26,30 +26,34 @@ Zarafa.plugins.passwd.settings.PasswdPanel = Ext.extend(Ext.form.FormPanel, {
items : [{
xtype : 'displayfield',
name : 'username',
fieldLabel : 'User name'
fieldLabel : dgettext("plugin_passwd", 'User name')
}, {
xtype : 'textfield',
name : 'current_password',
fieldLabel : 'Current password',
ref : 'current_password',
fieldLabel : dgettext("plugin_passwd", 'Current password'),
inputType : 'password',
allowBlank : false,
listeners : {
change : this.onFieldChange,
scope : this
}
}, {
xtype : 'textfield',
xtype : 'ux.passwordmeterfield',
name : 'new_password',
fieldLabel : 'New password',
inputType : 'password',
ref : 'new_password',
allowBlank : false,
fieldLabel : dgettext("plugin_passwd", 'New password'),
listeners : {
change : this.onFieldChange,
scope : this
}
}, {
xtype : 'textfield',
xtype : 'ux.passwordmeterfield',
name : 'new_password_repeat',
fieldLabel : 'Retype new password',
inputType : 'password',
allowBlank : false,
ref : 'new_password_repeat',
fieldLabel : dgettext("plugin_passwd", 'Retype new password'),
listeners : {
change : this.onFieldChange,
scope : this

View file

@ -17,13 +17,16 @@ Zarafa.plugins.passwd.settings.SettingsPasswdCategory = Ext.extend(Zarafa.settin
config = config || {};
Ext.applyIf(config, {
title : _('Change Password'),
title : dgettext("plugin_passwd", 'Change Password'),
categoryIndex : 9997,
iconCls : 'zarafa-settings-category-passwd',
xtype : 'zarafa.settingspasswdcategory',
items : [{
xtype : 'zarafa.settingspasswdwidget',
settingsContext : config.settingsContext
}]
},
container.populateInsertionPoint('context.settings.category.passwd', this)
]
});
Zarafa.plugins.passwd.settings.SettingsPasswdCategory.superclass.constructor.call(this, config);

View file

@ -19,14 +19,9 @@ Zarafa.plugins.passwd.settings.SettingsPasswdWidget = Ext.extend(Zarafa.settings
config = config || {};
Ext.applyIf(config, {
height : 175,
width : 400,
title : _('Change Password'),
title : dgettext("plugin_passwd", 'Change Password'),
xtype : 'zarafa.settingspasswdwidget',
layout : {
// override from SettingsWidget
type : 'fit'
},
layout: 'form',
items : [{
xtype : 'zarafa.passwdpanel',
ref : 'passwdPanel',
@ -51,10 +46,42 @@ Zarafa.plugins.passwd.settings.SettingsPasswdWidget = Ext.extend(Zarafa.settings
// listen to savesettings and discardsettings to save/discard delegation data
var contextModel = this.settingsContext.getModel();
this.mon(contextModel, 'beforesavesettings', this.onBeforeSaveSettings, this);
this.mon(contextModel, 'savesettings', this.onSaveSettings, this);
this.mon(contextModel, 'discardsettings', this.onDiscardSettings, this);
},
/**
* Event handler will be called when {@link Zarafa.settings.SettingsContextModel#beforesavesettings} event is fired.
* This function will validate the formdata.
*
* @private
*/
onBeforeSaveSettings : function()
{
// do some quick checks before submitting
if(this.passwdPanel.new_password.getValue() != this.passwdPanel.new_password_repeat.getValue()) {
Ext.MessageBox.alert(dgettext("plugin_passwd", 'Error'), dgettext("plugin_passwd", 'New passwords do not match.'));
return false;
} else if(Ext.isEmpty(this.passwdPanel.current_password.getValue())) {
Ext.MessageBox.alert(dgettext("plugin_passwd", 'Error'), dgettext("plugin_passwd", 'Current password is empty.'));
return false;
} else if(Ext.isEmpty(this.passwdPanel.new_password.getValue()) || Ext.isEmpty(this.passwdPanel.new_password_repeat.getValue())) {
Ext.MessageBox.alert(dgettext("plugin_passwd", 'Error'), dgettext("plugin_passwd", 'New password is empty.'));
return false;
} else if(!this.passwdPanel.getForm().isValid()) {
Ext.MessageBox.alert(dgettext("plugin_passwd", 'Error'), dgettext("plugin_passwd", 'One or more fields does contain errors.'));
return false;
} else {
// do a quick score check:
if(this.passwdPanel.new_password.getScore() < 70) {
Ext.MessageBox.alert(dgettext("plugin_passwd", 'Error'), dgettext("plugin_passwd", 'Password is weak. Password should contain capital, non-capital letters and numbers. Password should have 8 to 20 characters.'));
return false;
}
return true;
}
},
/**
* Event handler will be called when {@link Zarafa.settings.SettingsContextModel#savesettings} event is fired.
* This will relay this event to {@link Zarafa.plugins.passwd.settings.PasswdPanel PasswdPanel} so it can
@ -71,8 +98,11 @@ Zarafa.plugins.passwd.settings.SettingsPasswdWidget = Ext.extend(Zarafa.settings
// send request
container.getRequest().singleRequest('passwdmodule', 'save', data, new Zarafa.plugins.passwd.data.PasswdResponseHandler({
callbackFn : function(success, response) {
callbackFn: function (success, response) {
this.ownerCt.hideSavingMask(success);
if(success) {
this.passwdPanel.getForm().reset();
}
},
scope : this
}));

View file

@ -0,0 +1,93 @@
msgid ""
msgstr ""
"Project-Id-Version: zarafa-webapp-plugin-passwd\n"
"POT-Creation-Date: 2014-03-04 13:53+0100\n"
"PO-Revision-Date: 2014-03-04 14:34+0100\n"
"Last-Translator: Robert Scheck <zarafa@robert-scheck.de>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Language: de\n"
# php/class.passwdmodule.php:44:
msgid "No data received."
msgstr "Keine Daten empfangen!"
# php/class.passwdmodule.php:48:
msgid "User name is empty."
msgstr "Benutzername ist leer!"
# php/class.passwdmodule.php:52:
msgid "Current password is empty."
msgstr "Aktuelles Passwort ist leer!"
# php/class.passwdmodule.php:56:
msgid "New password is empty."
msgstr "Neues Passwort ist leer!"
# php/class.passwdmodule.php:60:
msgid "New passwords do not match."
msgstr "Neue Passwörter stimmen nicht überein!"
# php/class.passwdmodule.php:137:
# php/class.passwdmodule.php:196:
# js/data/PasswdResponseHandler.js:44:
msgid "Password is changed successfully."
msgstr "Passwort wurde erfolgreich geändert!"
# php/class.passwdmodule.php:141:
# php/class.passwdmodule.php:200:
msgid "Password is not changed."
msgstr "Passwort wurde nicht geändert!"
# php/class.passwdmodule.php:144:
# php/class.passwdmodule.php:203:
msgid ""
"Password is weak. Password should contain capital, non-capital letters and "
"numbers. Password should have 8 to 20 characters."
msgstr ""
"Das eingegebene Passwort ist schwach; es sollte große und kleine Buchstaben "
"sowie Ziffern enthalten und zwischen 8 und 20 Zeichen lang sein!"
# php/class.passwdmodule.php:147:
msgid "Current password does not match."
msgstr "Aktuelles Passwort ist falsch!"
# js/data/PasswdResponseHandler.js:27:
msgid "An unknown error occurred while changing password."
msgstr "Beim Ändern des Passworts ist ein unbekannter Fehler aufgetreten!"
# js/data/PasswdResponseHandler.js:33:
msgid "Error"
msgstr "Fehler"
# js/data/PasswdResponseHandler.js:50:
msgid "Success"
msgstr "Erfolg"
# js/settings/SettingsPasswdWidget.js:24:
# js/settings/SettingsPasswdCategory.js:20:
msgid "Change Password"
msgstr "Passwort ändern"
# js/PasswdPlugin.js:50:
msgid "Password Change Plugin"
msgstr "Passwortänderungsplugin"
# js/settings/PasswdPanel.js:29:
msgid "User name"
msgstr "Benutzername"
# js/settings/PasswdPanel.js:33:
msgid "Current password"
msgstr "Aktuelles Passwort"
# js/settings/PasswdPanel.js:42:
msgid "New password"
msgstr "Neues Passwort"
#js/settings/PasswdPanel.js:51:
msgid "Retype new password"
msgstr "Wiederholung"

Binary file not shown.

View file

@ -0,0 +1,94 @@
msgid ""
msgstr ""
"Project-Id-Version: zarafa-webapp-plugin-passwd\n"
"POT-Creation-Date: 2014-03-04 13:53+0100\n"
"PO-Revision-Date: 2017-02-14 16:11+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Language: de\n"
"X-Generator: Poedit 1.6.4\n"
# php/class.passwdmodule.php:44:
msgid "No data received."
msgstr "Aucune donnée reçue"
# php/class.passwdmodule.php:48:
msgid "User name is empty."
msgstr "Le nom d'utilisateur est vide"
# php/class.passwdmodule.php:52:
msgid "Current password is empty."
msgstr "Le mot de passe est vide"
# php/class.passwdmodule.php:56:
msgid "New password is empty."
msgstr "Le nouveau mot de passe est vide"
# php/class.passwdmodule.php:60:
msgid "New passwords do not match."
msgstr "Le nouveau mot de passe n'est pas identique"
# php/class.passwdmodule.php:137:
# php/class.passwdmodule.php:196:
# js/data/PasswdResponseHandler.js:44:
msgid "Password is changed successfully."
msgstr "Le mot de passe a été changé avec succès"
# php/class.passwdmodule.php:141:
# php/class.passwdmodule.php:200:
msgid "Password is not changed."
msgstr "Le mot de passe n'a pas changé!"
# php/class.passwdmodule.php:144:
# php/class.passwdmodule.php:203:
msgid ""
"Password is weak. Password should contain capital, non-capital letters and "
"numbers. Password should have 8 to 20 characters."
msgstr ""
"La complexité du mot de passe n'est pas suffisante, il faut au minimum 8 "
"caractères."
# php/class.passwdmodule.php:147:
msgid "Current password does not match."
msgstr "Le mot de passe est faux."
# js/data/PasswdResponseHandler.js:27:
msgid "An unknown error occurred while changing password."
msgstr "Une erreur inconnue est survenue lors du changement de mot de passe."
# js/data/PasswdResponseHandler.js:33:
msgid "Error"
msgstr "Erreur"
# js/data/PasswdResponseHandler.js:50:
msgid "Success"
msgstr "Réussi"
# js/settings/SettingsPasswdWidget.js:24:
# js/settings/SettingsPasswdCategory.js:20:
msgid "Change Password"
msgstr "Changer le mot de passe"
# js/PasswdPlugin.js:50:
msgid "Password Change Plugin"
msgstr "Plugin pour changer son mot de passe"
# js/settings/PasswdPanel.js:29:
msgid "User name"
msgstr "Nom d'utilisateur"
# js/settings/PasswdPanel.js:33:
msgid "Current password"
msgstr "Mot de passe"
# js/settings/PasswdPanel.js:42:
msgid "New password"
msgstr "Nouveau mot de passe"
# js/settings/PasswdPanel.js:51:
msgid "Retype new password"
msgstr "Retaper le nouveau mot de passe"

Binary file not shown.

View file

@ -0,0 +1,94 @@
msgid ""
msgstr ""
"Project-Id-Version: zarafa-webapp-plugin-passwd\n"
"POT-Creation-Date: 2014-03-04 13:53+0100\n"
"PO-Revision-Date: 2016-04-08 21:28+0200\n"
"Last-Translator: David Horvath <dacr@dacr.hu>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Language: hu\n"
"X-Generator: Poedit 1.8.7.1\n"
# php/class.passwdmodule.php:44:
msgid "No data received."
msgstr "Nem érkezett adat."
# php/class.passwdmodule.php:48:
msgid "User name is empty."
msgstr "Felhasználónév mező üres."
# php/class.passwdmodule.php:52:
msgid "Current password is empty."
msgstr "Jelenlegi jelszó mező üres."
# php/class.passwdmodule.php:56:
msgid "New password is empty."
msgstr "Új jelszó mező üres."
# php/class.passwdmodule.php:60:
msgid "New passwords do not match."
msgstr "Az új jelszavak nem egyeznek."
# php/class.passwdmodule.php:137:
# php/class.passwdmodule.php:196:
# js/data/PasswdResponseHandler.js:44:
msgid "Password is changed successfully."
msgstr "A jelszót sikeresen módosította."
# php/class.passwdmodule.php:141:
# php/class.passwdmodule.php:200:
msgid "Password is not changed."
msgstr "A jelszó nem módosult."
# php/class.passwdmodule.php:144:
# php/class.passwdmodule.php:203:
msgid ""
"Password is weak. Password should contain capital, non-capital letters and "
"numbers. Password should have 8 to 20 characters."
msgstr ""
"A jelszó gyenge. Tartalmaznia kell számot, nagy- és kisbetűt. A jelszó "
"minimum 8, maximum 20 karakter legyen."
# php/class.passwdmodule.php:147:
msgid "Current password does not match."
msgstr "A jelenlegi jelszó nem megfelelő."
# js/data/PasswdResponseHandler.js:27:
msgid "An unknown error occurred while changing password."
msgstr "Ismeretlen hiba történt a jelszó megváltoztatásakor."
# js/data/PasswdResponseHandler.js:33:
msgid "Error"
msgstr "Hiba"
# js/data/PasswdResponseHandler.js:50:
msgid "Success"
msgstr "Sikeres"
# js/settings/SettingsPasswdWidget.js:24:
# js/settings/SettingsPasswdCategory.js:20:
msgid "Change Password"
msgstr "Jelszó megváltoztatása"
# js/PasswdPlugin.js:50:
msgid "Password Change Plugin"
msgstr "Jelszóváltoztatás kiegészítő"
# js/settings/PasswdPanel.js:29:
msgid "User name"
msgstr "Felhasználónév"
# js/settings/PasswdPanel.js:33:
msgid "Current password"
msgstr "Jelenlegi jelszó"
# js/settings/PasswdPanel.js:42:
msgid "New password"
msgstr "Új jelszó"
# js/settings/PasswdPanel.js:51:
msgid "Retype new password"
msgstr "Új jelszó mégegyszer"

View file

@ -0,0 +1,95 @@
msgid ""
msgstr ""
"Project-Id-Version: zarafa-webapp-plugin-passwd\n"
"POT-Creation-Date: 2014-03-04 13:53+0100\n"
"PO-Revision-Date: 2014-03-04 14:34+0100\n"
"Last-Translator: Sander Hoentjen <sander@hoentjen.eu>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.5.4\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Language: nl\n"
# php/class.passwdmodule.php:44:
msgid "No data received."
msgstr "Geen data ontvangen."
# php/class.passwdmodule.php:48:
msgid "User name is empty."
msgstr "Gebruikersnaam is leeg."
# php/class.passwdmodule.php:52:
msgid "Current password is empty."
msgstr "Huidig wachtwoord is leeg."
# php/class.passwdmodule.php:56:
msgid "New password is empty."
msgstr "Nieuw wachtwoord is leeg."
# php/class.passwdmodule.php:60:
msgid "New passwords do not match."
msgstr "Nieuwe wachtwoorden zijn niet gelijk."
# php/class.passwdmodule.php:137:
# php/class.passwdmodule.php:196:
# js/data/PasswdResponseHandler.js:44:
msgid "Password is changed successfully."
msgstr "Wachtwoord succesvol gewijzigd."
# php/class.passwdmodule.php:141:
# php/class.passwdmodule.php:200:
msgid "Password is not changed."
msgstr "Wachtwoord is niet aangepast."
# php/class.passwdmodule.php:144:
# php/class.passwdmodule.php:203:
msgid ""
"Password is weak. Password should contain capital, non-capital letters and "
"numbers. Password should have 8 to 20 characters."
msgstr ""
"Wachtwoord is zwak. Een wachtwoord moet hoofdletters, kleine letters en "
"cijfers bevatten. Een wachtwoord moet 8 tot 20 karakters bevatten."
# php/class.passwdmodule.php:147:
msgid "Current password does not match."
msgstr "Huidig wachtwoord klopt niet."
# js/data/PasswdResponseHandler.js:27:
msgid "An unknown error occurred while changing password."
msgstr "Er is een onbekende fout opgetreden tijdens de wachtwoord wijziging."
# js/data/PasswdResponseHandler.js:33:
msgid "Error"
msgstr "Fout"
# js/data/PasswdResponseHandler.js:50:
msgid "Success"
msgstr "Succes"
# js/settings/SettingsPasswdWidget.js:24:
# js/settings/SettingsPasswdCategory.js:20:
msgid "Change Password"
msgstr "Wijzig wachtwoord"
# js/PasswdPlugin.js:50:
msgid "Password Change Plugin"
msgstr "Wachtwoord wijzigen plugin"
# js/settings/PasswdPanel.js:29:
msgid "User name"
msgstr "Gebruikersnaam"
# js/settings/PasswdPanel.js:33:
msgid "Current password"
msgstr "Huidig wachtwoord"
# js/settings/PasswdPanel.js:42:
msgid "New password"
msgstr "Nieuw wachtwoord"
#js/settings/PasswdPanel.js:51:
msgid "Retype new password"
msgstr "Herhaal nieuw wachtwoord"

View file

@ -1,158 +0,0 @@
// Create user extensions namespace (Ext.ux)
Ext.namespace('Ext.ux');
/**
* Ext.ux.PasswordMeter Extension Class
*
* @author Eelco Wiersma
* @version 0.2
*
* Algorithm based on code of Tane
* http://digitalspaghetti.me.uk/index.php?q=jquery-pstrength
* and Steve Moitozo
* http://www.geekwisdom.com/dyn/passwdmeter
*
* @license MIT License: http://www.opensource.org/licenses/mit-license.php
*
* @class Ext.ux.PasswordMeter
* @extends Ext.form.TextField
* @constructor
* Creates new Ext.ux.PasswordMeter
*/
Ext.ux.PasswordMeter = function(config) {
// call parent constructor
Ext.ux.PasswordMeter.superclass.constructor.call(this, config);
};
Ext.extend(Ext.ux.PasswordMeter, Ext.form.TextField, {
/**
* @cfg {String} inputType The type attribute for input fields -- e.g. text, password (defaults to "password").
*/
inputType: 'text',
// private
onRender: function(ct, position) {
Ext.ux.PasswordMeter.superclass.onRender.call(this, ct, position);
var elp = this.el.findParent('.x-form-element', 5, true);
this.objMeter = ct.createChild({tag: "div", 'class': "strengthMeter"});
this.objMeter.setWidth(elp.getWidth(true)-17);
this.scoreBar = this.objMeter.createChild({tag: "div", 'class': "scoreBar"});
if(Ext.isIE && !Ext.isIE7) { // Fix style for IE6
this.objMeter.setStyle('margin-left', '3px');
}
},
// private
initEvents: function() {
Ext.ux.PasswordMeter.superclass.initEvents.call(this);
this.el.on('keyup', this.updateMeter, this);
},
/**
* Sets the width of the meter, based on the score
* @param {Object} e
* Private function
*/
updateMeter: function(e) {
var score = 0
var p = e.target.value;
var maxWidth = this.objMeter.getWidth() - 2;
var nScore = this.calcStrength(p);
// Set new width
var nRound = Math.round(nScore * 2);
if (nRound > 100) {
nRound = 100;
}
var scoreWidth = (maxWidth / 100) * nRound;
this.scoreBar.setWidth(scoreWidth, true);
},
/**
* Calculates the strength of a password
* @param {Object} p The password that needs to be calculated
* @return {int} intScore The strength score of the password
*/
calcStrength: function(p) {
var intScore = 0;
// PASSWORD LENGTH
intScore += p.length;
if(p.length > 0 && p.length <= 4) { // length 4 or less
intScore += p.length;
}
else if (p.length >= 5 && p.length <= 7) { // length between 5 and 7
intScore += 6;
}
else if (p.length >= 8 && p.length <= 15) { // length between 8 and 15
intScore += 12;
//alert(intScore);
}
else if (p.length >= 16) { // length 16 or more
intScore += 18;
//alert(intScore);
}
// LETTERS (Not exactly implemented as dictacted above because of my limited understanding of Regex)
if (p.match(/[a-z]/)) { // [verified] at least one lower case letter
intScore += 1;
}
if (p.match(/[A-Z]/)) { // [verified] at least one upper case letter
intScore += 5;
}
// NUMBERS
if (p.match(/\d/)) { // [verified] at least one number
intScore += 5;
}
if (p.match(/.*\d.*\d.*\d/)) { // [verified] at least three numbers
intScore += 5;
}
// SPECIAL CHAR
if (p.match(/[!,@,#,$,%,^,&,*,?,_,~]/)) { // [verified] at least one special character
intScore += 5;
}
// [verified] at least two special characters
if (p.match(/.*[!,@,#,$,%,^,&,*,?,_,~].*[!,@,#,$,%,^,&,*,?,_,~]/)) {
intScore += 5;
}
// COMBOS
if (p.match(/(?=.*[a-z])(?=.*[A-Z])/)) { // [verified] both upper and lower case
intScore += 2;
}
if (p.match(/(?=.*\d)(?=.*[a-z])(?=.*[A-Z])/)) { // [verified] both letters and numbers
intScore += 2;
}
// [verified] letters, numbers, and special characters
if (p.match(/(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!,@,#,$,%,^,&,*,?,_,~])/)) {
intScore += 2;
}
return intScore;
},
// private
onFocus: function() {
Ext.ux.PasswordMeter.superclass.onFocus.call(this);
if(!Ext.isOpera) { // don't touch in Opera
this.objMeter.addClass('strengthMeter-focus');
}
},
// private
onBlur: function() {
Ext.ux.PasswordMeter.superclass.onBlur.call(this);
if(!Ext.isOpera) { // don't touch in Opera
this.objMeter.removeClass('strengthMeter-focus');
}
}
});

View file

@ -2,30 +2,22 @@
<!DOCTYPE plugin SYSTEM "manifest.dtd">
<plugin version="2">
<info>
<version>1.0</version>
<name>Passwd</name>
<version>1.5</version>
<Name>Passwd</Name>
<title>Password Change Plugin</title>
<author>Saket Patel</author>
<authorURL>https://github.com/silentsakky</authorURL>
<description>Change your password from zarafa webapp</description>
<author>Saket Patel - Denis Ducret</author>
<authorURL>https://github.com/dducret</authorURL>
<description>Change your password from Kopano WebApp</description>
</info>
<config>
<configfile>config.php</configfile>
</config>
<translations>
<translationsdir>language</translationsdir>
</translations>
<components>
<!-- <component>
<info>
<name>passwordmeter</name>
<title>PasswordMeter</title>
<author>Eelco Wiersma</author>
<description>Ext user extension to check password strength</description>
</info>
<files>
<client>
<clientfile>lib/PasswordMeter.js</clientfile>
</client>
</files>
</component> -->
<component>
<files>
<server>
@ -35,13 +27,20 @@
<client>
<clientfile load="release">js/passwd.js</clientfile>
<clientfile load="debug">js/passwd-debug.js</clientfile>
<clientfile load="source">js/PasswdPlugin.js</clientfile>
<clientfile load="source">js/settings/SettingsPasswdCategory.js</clientfile>
<clientfile load="source">js/settings/SettingsPasswdWidget.js</clientfile>
<clientfile load="source">js/settings/PasswdPanel.js</clientfile>
<clientfile load="source">js/data/PasswdResponseHandler.js</clientfile>
<clientfile load="source">js/ABOUT.js</clientfile>
<clientfile load="source">js/external/PasswordMeter.js</clientfile>
</client>
<resources>
<resourcefile load="release">resources/css/passwd.css</resourcefile>
<resourcefile load="debug">resources/css/passwd.css</resourcefile>
<resourcefile load="source">resources/css/passwd-main.css</resourcefile>
</resources>
</files>
</component>
</components>

View file

@ -41,23 +41,23 @@ class PasswdModule extends Module
// some sanity checks
if(empty($data)) {
$errorMessage = _('No data received.');
$errorMessage = dgettext("plugin_passwd", 'No data received.');
}
if(empty($data['username'])) {
$errorMessage = _('User name is empty.');
$errorMessage = dgettext("plugin_passwd", 'User name is empty.');
}
if(empty($data['current_password'])) {
$errorMessage = _('Current password is empty.');
$errorMessage = dgettext("plugin_passwd", 'Current password is empty.');
}
if(empty($data['new_password']) || empty($data['new_password_repeat'])) {
$errorMessage = _('New password is empty.');
$errorMessage = dgettext("plugin_passwd", 'New password is empty.');
}
if($data['new_password'] !== $data['new_password_repeat']) {
$errorMessage = _('New passwords does not match.');
$errorMessage = dgettext("plugin_passwd", 'New passwords do not match.');
}
if(empty($errorMessage)) {
@ -90,57 +90,87 @@ class PasswdModule extends Module
// check connection is successfull
if(ldap_errno($ldapconn) === 0) {
// get the users uid, if we have a multi tenant installation then remove company name from user name
$parts = explode('@', $data['username']);
$uid = $parts[0];
if (PLUGIN_PASSWD_LOGIN_WITH_TENANT){
$parts = explode('@', $data['username']);
$uid = $parts[0];
} else {
$uid = $data['username'];
}
// check if we should use tls!
if(strrpos(PLUGIN_PASSWD_LDAP_URI, "ldaps://", -strlen(PLUGIN_PASSWD_LDAP_URI)) === FALSE && PLUGIN_PASSWD_LDAP_USE_TLS === true) {
ldap_start_tls($ldapconn);
}
// set connection parametes
ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldapconn, LDAP_OPT_REFERRALS, 0);
// now bind to the ldap server to search the user dn
ldap_bind($ldapconn, PLUGIN_PASSWD_LDAP_BIND_DN, PLUGIN_PASSWD_LDAP_BIND_PW);
// search for the user dn that will be used to do login into LDAP
$userdn = ldap_search (
$ldapconn, // connection-identify
PLUGIN_PASSWD_LDAP_BASEDN, // basedn
'uid=' . $uid, // search filter
array('dn') // needed attributes. we need the dn
'uid=' . $uid, // search filter
array('dn', 'objectClass') // needed attributes. we need dn and objectclass
);
if ($userdn) {
$userdn = ldap_get_entries($ldapconn, $userdn);
$userdn = $userdn[0]['dn'];
$entries = ldap_get_entries($ldapconn, $userdn);
$userdn = $entries[0]['dn'];
// bind to ldap directory
ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
// login with current password if that fails then current password is wrong
$bind = ldap_bind($ladpconn, $userdn, $data['current_password']);
ldap_bind($ldapconn, $userdn, $data['current_password']);
if(ldap_errno($ldapconn) === 0) {
$passwd = $data['new_password'];
$passwdRepeat = $data['new_password_repeat'];
if($this->checkPasswordStrenth($passwd)) {
$passwd = $data['new_password'];
if ($this->checkPasswordStrenth($passwd)) {
$password_hash = $this->sshaEncode($passwd);
$entry = array('userPassword' => $password_hash);
$return_mod = ldap_modify($ldapconn, $userdn, $entry);
if (in_array('sambaSamAccount', $entries[0]['objectclass'])) {
$nthash = strtoupper(bin2hex(mhash(MHASH_MD4, iconv("UTF-8","UTF-16LE", $passwd))));
$entry['sambaNTPassword'] = $nthash;
$entry['sambaPwdLastSet'] = strval(time());
}
ldap_modify($ldapconn, $userdn, $entry);
if (ldap_errno($ldapconn) === 0) {
// password changed successfully
// write new password to session because we don't want user to re-authenticate
session_start();
$_SESSION['password'] = $passwd;
// if user has openssl module installed
if(function_exists("openssl_encrypt")) {
// In PHP 5.3.3 the iv parameter was added
if(version_compare(phpversion(), "5.3.3", "<")) {
$_SESSION['password'] = openssl_encrypt($passwd,"des-ede3-cbc",PASSWORD_KEY,0);
} else {
$_SESSION['password'] = openssl_encrypt($passwd,"des-ede3-cbc",PASSWORD_KEY,0,PASSWORD_IV);
}
}
else {
$_SESSION['password'] = $passwd;
}
session_write_close();
// send feedback to client
$this->sendFeedback(true, array(
'info' => array(
'display_message' => _('Password is changed successfully.')
'display_message' => dgettext("plugin_passwd", 'Password is changed successfully.')
)
));
} else {
$errorMessage = _('Password is not changed.');
$errorMessage = dgettext("plugin_passwd", 'Password is not changed.');
}
} else {
$errorMessage = _('Password is weak. Password should contain capital, non capital letters and numbers. Password shuold have 8 to 20 characters.');
$errorMessage = dgettext("plugin_passwd", 'Password is weak. Password should contain capital, non-capital letters and numbers. Password should have 8 to 20 characters.');
}
} else {
$errorMessage = _('Current password does not match.');
$errorMessage = dgettext("plugin_passwd", 'Current password does not match.');
}
// release ldap-bind
@ -152,8 +182,8 @@ class PasswdModule extends Module
$this->sendFeedback(false, array(
'type' => ERROR_ZARAFA,
'info' => array(
'ldap_error' => ldap_errno(),
'ldap_error_name' => ldap_error(),
'ldap_error' => ldap_errno($ldapconn),
'ldap_error_name' => ldap_error($ldapconn),
'display_message' => $errorMessage
)
));
@ -161,42 +191,76 @@ class PasswdModule extends Module
}
/**
* Function will execute zarafa-passwd command and will try to change user's password,
* this method is unsecure and unreliable.
* Function will try to change user's password via MAPI in SOAP connection.
* @param {Array} $data data sent by client.
*/
public function saveInDB($data)
{
$errorMessage = '';
$passwd = $data['new_password'];
$passwdRepeat = $data['new_password_repeat'];
if($this->checkPasswordStrenth($passwd)) {
$passwd_cmd = '/usr/bin/zarafa-passwd -u %s -o %s -p %s';
// all information correct, change password
$cmd = sprintf($passwd_cmd, $data['username'], $data['current_password'], $passwd);
exec($cmd, $arrayout, $retval);
if ($retval === 0) {
// password changed successfully
// write new password to session because we don't want user to re-authenticate
session_start();
$_SESSION['password'] = $passwd;
session_write_close();
// send feedback to client
$this->sendFeedback(true, array(
'info' => array(
'display_message' => _('Password is changed successfully.')
)
));
/*
// get current session password
$sessionPass = $_SESSION['password'];
// if user has openssl module installed
if (function_exists("openssl_decrypt")) {
if (version_compare(phpversion(), "5.3.3", "<")) {
$sessionPass = openssl_decrypt($sessionPass, "des-ede3-cbc", PASSWORD_KEY, 0);
} else {
$errorMessage = _('Password is not changed.');
$sessionPass = openssl_decrypt($sessionPass, "des-ede3-cbc", PASSWORD_KEY, 0, PASSWORD_IV);
}
if (!$sessionPass) {
$sessionPass = $_SESSION['password'];
}
}
*/
// Get current user password
$encryptionStore = EncryptionStore::getInstance();
$sessionPass = $encryptionStore->get('password');
if($data['current_password'] === $sessionPass) {
if ($this->checkPasswordStrenth($passwd)) {
// all information correct, change password
$store = $GLOBALS['mapisession']->getDefaultMessageStore();
$userinfo = mapi_zarafa_getuser_by_name($store, $data['username']);
if (mapi_zarafa_setuser($store, $userinfo['userid'], $data['username'], $userinfo['fullname'], $userinfo['emailaddress'], $passwd, 0, $userinfo['admin'])) {
// password changed successfully
/* Not able to find a way, session is discarded and user should log in again
// write new password to session because we don't want user to re-authenticate
session_start();
// if user has openssl module installed
if (function_exists("openssl_encrypt")) {
// In PHP 5.3.3 the iv parameter was added
if (version_compare(phpversion(), "5.3.3", "<")) {
$_SESSION['password'] = openssl_encrypt($passwd, "des-ede3-cbc", PASSWORD_KEY, 0);
} else {
$_SESSION['password'] = openssl_encrypt($passwd, "des-ede3-cbc", PASSWORD_KEY, 0, PASSWORD_IV);
}
} else {
$_SESSION['password'] = $passwd;
}
session_write_close();
// send feedback to client
$this->sendFeedback(true, array(
'info' => array(
'display_message' => dgettext("plugin_passwd", 'Password is changed successfully.')
)
));
*/
// Give the session a new id
session_regenerate_id();
} else {
$errorMessage = dgettext("plugin_passwd", 'Password is not changed.');
}
} else {
$errorMessage = dgettext("plugin_passwd", 'Password is weak. Password should contain capital, non-capital letters and numbers. Password should have 8 to 20 characters.');
}
} else {
$errorMessage = _('Password is weak. Password should contain capital, non capital letters and numbers. Password shuold have 8 to 20 characters.');
$errorMessage = dgettext("plugin_passwd", 'Current password does not match.');
}
if(!empty($errorMessage)) {
@ -221,7 +285,6 @@ class PasswdModule extends Module
*/
public function checkPasswordStrenth($password)
{
// @FIXME should be moved to client side
if (preg_match("#.*^(?=.{8,20})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).*$#", $password)) {
return true;
} else {

View file

@ -42,7 +42,7 @@ class Pluginpasswd extends Plugin {
'zarafa' => Array(
'v1' => Array(
'plugins' => Array(
'sugarcrm' => Array(
'passwd' => Array(
'enable' => PLUGIN_PASSWD_USER_DEFAULT_ENABLE,
)

View file

@ -0,0 +1,27 @@
.zarafa-settings-category-passwd {
background-image: url(../images/icon_lock.png) !important;
}
/* STYLES FOR THE PASSWORD METER */
.x-form-strengthmeter {
width : 100%;
height: 5px;
/*float: right;*/
background: #ff4c00; /* Old browsers */
/* IE9 SVG, needs conditional override of 'filter' to 'none' */
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmNGMwMCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjUwJSIgc3RvcC1jb2xvcj0iI2VkZDcxMiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMxYWZmMDAiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
background: -moz-linear-gradient(left, #ff4c00 0%, #edd712 50%, #1aff00 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, right top, color-stop(0%,#ff4c00), color-stop(50%,#edd712), color-stop(100%,#1aff00)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(left, #ff4c00 0%,#edd712 50%,#1aff00 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(left, #ff4c00 0%,#edd712 50%,#1aff00 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(left, #ff4c00 0%,#edd712 50%,#1aff00 100%); /* IE10+ */
background: linear-gradient(left, #ff4c00 0%,#edd712 50%,#1aff00 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff4c00', endColorstr='#1aff00',GradientType=1 ); /* IE6-8 */
}
.x-form-strengthmeter-scorebar {
background-color: white;
opacity: 0.7;
height: 5px;
width: 100%;
}

27
resources/css/passwd.css Normal file
View file

@ -0,0 +1,27 @@
.zarafa-settings-category-passwd {
background-image: url(../images/icon_lock.png) !important;
}
/* STYLES FOR THE PASSWORD METER */
.x-form-strengthmeter {
width : 100%;
height: 5px;
/*float: right;*/
background: #ff4c00; /* Old browsers */
/* IE9 SVG, needs conditional override of 'filter' to 'none' */
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmNGMwMCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjUwJSIgc3RvcC1jb2xvcj0iI2VkZDcxMiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMxYWZmMDAiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
background: -moz-linear-gradient(left, #ff4c00 0%, #edd712 50%, #1aff00 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, right top, color-stop(0%,#ff4c00), color-stop(50%,#edd712), color-stop(100%,#1aff00)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(left, #ff4c00 0%,#edd712 50%,#1aff00 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(left, #ff4c00 0%,#edd712 50%,#1aff00 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(left, #ff4c00 0%,#edd712 50%,#1aff00 100%); /* IE10+ */
background: linear-gradient(left, #ff4c00 0%,#edd712 50%,#1aff00 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff4c00', endColorstr='#1aff00',GradientType=1 ); /* IE6-8 */
}
.x-form-strengthmeter-scorebar {
background-color: white;
opacity: 0.7;
height: 5px;
width: 100%;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 B

Binary file not shown.