mirror of
https://github.com/dducret/kopano-webapp-passwd
synced 2026-08-10 09:24:07 +02:00
Compare commits
No commits in common. "master" and "1.1" have entirely different histories.
30 changed files with 276 additions and 934 deletions
22
CHANGELOG.md
22
CHANGELOG.md
|
|
@ -1,25 +1,3 @@
|
||||||
## 1.0 (17th Dec 2013)
|
## 1.0 (17th Dec 2013)
|
||||||
|
|
||||||
- Password change functionality when using DB or LDAP plugin
|
- 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
|
|
||||||
33
README.md
33
README.md
|
|
@ -1,29 +1,28 @@
|
||||||
kopano-webapp-passwd
|
zarafa-webapp-passwd
|
||||||
====================
|
====================
|
||||||
|
|
||||||
The Passwd plugin allows the user to change the current user password inside of WebApp.
|
The Passwd plugin allows the user to change his password inside of WebApp.
|
||||||
|
|
||||||
This plugin is largely based on the Passwd plugin by Andreas Brodowski.
|
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)
|
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
|
## How to install
|
||||||
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
|
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. [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
|
2. If you want to use this plugin with source copy of webapp then you can just download this whole project
|
||||||
2a. If you are using DB plugin then no need to change anything, default configurations should be fine
|
3. Extract contents of this plugin to <webapp_path>/plugins directory
|
||||||
4. Restart apache, reload webapp after clearing cache
|
4. Give read permissions to apache for <webapp_path>/plugins/passwd directory
|
||||||
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
|
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
|
||||||
|
|
||||||
## How to enable
|
## How to enable
|
||||||
1. Go to settings section
|
1. Go to settings section
|
||||||
2. Go to Plugins tab
|
2. Go to Plugins tab
|
||||||
3. Enable password change plugin and reload webapp
|
3. Enable password change plugin and reload webapp
|
||||||
|
4. Go to Change Password tab of settings section
|
||||||
## How to use
|
5. Provide current password and new password
|
||||||
1. Go to Change Password tab of settings section
|
6. Click on apply
|
||||||
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
|
## How to disable
|
||||||
1. Go to settings section
|
1. Go to settings section
|
||||||
|
|
@ -32,4 +31,8 @@ This plugin is a fork of zarafa-webapp-passwd [link](https://github.com/silentsa
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
- Feedback/Bug Reports are welcome
|
- Feedback/Bug Reports are welcome
|
||||||
- thanks to h44z for adding password meter and icon for the plugin
|
- 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
|
||||||
40
build.xml
40
build.xml
|
|
@ -3,7 +3,6 @@
|
||||||
<property name="root-folder" value="${basedir}/../../"/>
|
<property name="root-folder" value="${basedir}/../../"/>
|
||||||
<property name="tools-folder" value="${root-folder}/tools/"/>
|
<property name="tools-folder" value="${root-folder}/tools/"/>
|
||||||
<property name="target-folder" value="${root-folder}/deploy/plugins"/>
|
<property name="target-folder" value="${root-folder}/deploy/plugins"/>
|
||||||
<property name="language-folder" value="${basedir}/language"/>
|
|
||||||
|
|
||||||
<import file="${tools-folder}/antutil.xml"/>
|
<import file="${tools-folder}/antutil.xml"/>
|
||||||
|
|
||||||
|
|
@ -43,10 +42,6 @@
|
||||||
<include name="${plugin-file}"/>
|
<include name="${plugin-file}"/>
|
||||||
<include name="${plugin-debugfile}"/>
|
<include name="${plugin-debugfile}"/>
|
||||||
</fileset>
|
</fileset>
|
||||||
<!-- Delete the .mo files -->
|
|
||||||
<fileset dir="${language-folder}">
|
|
||||||
<include name="**/LC_MESSAGES/*.mo"/>
|
|
||||||
</fileset>
|
|
||||||
</delete>
|
</delete>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
|
@ -161,40 +156,8 @@
|
||||||
</exec>
|
</exec>
|
||||||
</target>
|
</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 -->
|
<!-- Install all files into the target folder -->
|
||||||
<target name="deploy" depends="compress, validate, language">
|
<target name="deploy" depends="compress, validate">
|
||||||
<mkdir dir="${target-folder}/${plugin-folder}"/>
|
<mkdir dir="${target-folder}/${plugin-folder}"/>
|
||||||
|
|
||||||
<!-- Copy (and validate) manifest.xml -->
|
<!-- Copy (and validate) manifest.xml -->
|
||||||
|
|
@ -230,7 +193,6 @@
|
||||||
<exclude name="build.xml"/>
|
<exclude name="build.xml"/>
|
||||||
<!-- CSS is generated during build -->
|
<!-- CSS is generated during build -->
|
||||||
<exclude name="resources/css/*.*"/>
|
<exclude name="resources/css/*.*"/>
|
||||||
<exclude name="**/LC_MESSAGES/*.po"/>
|
|
||||||
</fileset>
|
</fileset>
|
||||||
</copy>
|
</copy>
|
||||||
</target>
|
</target>
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
15
config.php
15
config.php
|
|
@ -9,18 +9,5 @@ define('PLUGIN_PASSWD_LDAP', false);
|
||||||
define('PLUGIN_PASSWD_LDAP_BASEDN', 'dc=example,dc=com');
|
define('PLUGIN_PASSWD_LDAP_BASEDN', 'dc=example,dc=com');
|
||||||
|
|
||||||
/** URI to access LDAP server **/
|
/** URI to access LDAP server **/
|
||||||
define('PLUGIN_PASSWD_LDAP_URI', 'ldap://localhost');
|
define('PLUGIN_PASSWD_LDAP_URI', '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);
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
@ -47,7 +47,7 @@ Zarafa.plugins.passwd.PasswdPlugin = Ext.extend(Zarafa.core.Plugin, {
|
||||||
Zarafa.onReady(function() {
|
Zarafa.onReady(function() {
|
||||||
container.registerPlugin(new Zarafa.core.PluginMetaData({
|
container.registerPlugin(new Zarafa.core.PluginMetaData({
|
||||||
name : 'passwd',
|
name : 'passwd',
|
||||||
displayName : dgettext("plugin_passwd", 'Password Change Plugin'),
|
displayName : _('Password Change Plugin'),
|
||||||
about : Zarafa.plugins.passwd.ABOUT,
|
about : Zarafa.plugins.passwd.ABOUT,
|
||||||
pluginConstructor : Zarafa.plugins.passwd.PasswdPlugin
|
pluginConstructor : Zarafa.plugins.passwd.PasswdPlugin
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,13 @@ Zarafa.plugins.passwd.data.PasswdResponseHandler = Ext.extend(Zarafa.core.data.A
|
||||||
*/
|
*/
|
||||||
doError : function(response)
|
doError : function(response)
|
||||||
{
|
{
|
||||||
var displayMessage = dgettext("plugin_passwd", 'An unknown error occurred while changing password.');
|
var displayMessage = _('An unknown error occurred while changing password.');
|
||||||
|
|
||||||
if(response.info) {
|
if(response.info) {
|
||||||
displayMessage = response.info.display_message;
|
displayMessage = response.info.display_message;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ext.MessageBox.alert(dgettext("plugin_passwd", 'Error'), displayMessage);
|
Ext.MessageBox.alert(_('Error'), displayMessage);
|
||||||
|
|
||||||
this.callbackFn.apply(this.scope || this, [ false, response ]);
|
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)
|
doSuccess : function(response)
|
||||||
{
|
{
|
||||||
var displayMessage = dgettext("plugin_passwd", 'Password is changed successfully.');
|
var displayMessage = _('Password is changed successfully.');
|
||||||
|
|
||||||
if(response.info) {
|
if(response.info) {
|
||||||
displayMessage = response.info.display_message;
|
displayMessage = response.info.display_message;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ext.MessageBox.alert(dgettext("plugin_passwd", 'Success'), displayMessage);
|
Ext.MessageBox.alert(_('Success'), displayMessage);
|
||||||
|
|
||||||
this.callbackFn.apply(this.scope || this, [ true, response ]);
|
this.callbackFn.apply(this.scope || this, [ true, response ]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
191
js/external/PasswordMeter.js
vendored
191
js/external/PasswordMeter.js
vendored
|
|
@ -1,191 +0,0 @@
|
||||||
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
26
js/passwd.js
|
|
@ -1,26 +0,0 @@
|
||||||
/*
|
|
||||||
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 <silentsakky@gmail.com></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);
|
|
||||||
|
|
@ -18,7 +18,7 @@ Zarafa.plugins.passwd.settings.PasswdPanel = Ext.extend(Ext.form.FormPanel, {
|
||||||
|
|
||||||
Ext.applyIf(config, {
|
Ext.applyIf(config, {
|
||||||
xtype : 'zarafa.passwdpanel',
|
xtype : 'zarafa.passwdpanel',
|
||||||
labelWidth : 200,
|
labelWidth : 150,
|
||||||
defaults : {
|
defaults : {
|
||||||
width : 200
|
width : 200
|
||||||
},
|
},
|
||||||
|
|
@ -26,34 +26,30 @@ Zarafa.plugins.passwd.settings.PasswdPanel = Ext.extend(Ext.form.FormPanel, {
|
||||||
items : [{
|
items : [{
|
||||||
xtype : 'displayfield',
|
xtype : 'displayfield',
|
||||||
name : 'username',
|
name : 'username',
|
||||||
fieldLabel : dgettext("plugin_passwd", 'User name')
|
fieldLabel : 'User name'
|
||||||
}, {
|
}, {
|
||||||
xtype : 'textfield',
|
xtype : 'textfield',
|
||||||
name : 'current_password',
|
name : 'current_password',
|
||||||
ref : 'current_password',
|
fieldLabel : 'Current password',
|
||||||
fieldLabel : dgettext("plugin_passwd", 'Current password'),
|
|
||||||
inputType : 'password',
|
inputType : 'password',
|
||||||
allowBlank : false,
|
|
||||||
listeners : {
|
listeners : {
|
||||||
change : this.onFieldChange,
|
change : this.onFieldChange,
|
||||||
scope : this
|
scope : this
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
xtype : 'ux.passwordmeterfield',
|
xtype : 'textfield',
|
||||||
name : 'new_password',
|
name : 'new_password',
|
||||||
ref : 'new_password',
|
fieldLabel : 'New password',
|
||||||
allowBlank : false,
|
inputType : 'password',
|
||||||
fieldLabel : dgettext("plugin_passwd", 'New password'),
|
|
||||||
listeners : {
|
listeners : {
|
||||||
change : this.onFieldChange,
|
change : this.onFieldChange,
|
||||||
scope : this
|
scope : this
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
xtype : 'ux.passwordmeterfield',
|
xtype : 'textfield',
|
||||||
name : 'new_password_repeat',
|
name : 'new_password_repeat',
|
||||||
allowBlank : false,
|
fieldLabel : 'Retype new password',
|
||||||
ref : 'new_password_repeat',
|
inputType : 'password',
|
||||||
fieldLabel : dgettext("plugin_passwd", 'Retype new password'),
|
|
||||||
listeners : {
|
listeners : {
|
||||||
change : this.onFieldChange,
|
change : this.onFieldChange,
|
||||||
scope : this
|
scope : this
|
||||||
|
|
|
||||||
|
|
@ -17,16 +17,13 @@ Zarafa.plugins.passwd.settings.SettingsPasswdCategory = Ext.extend(Zarafa.settin
|
||||||
config = config || {};
|
config = config || {};
|
||||||
|
|
||||||
Ext.applyIf(config, {
|
Ext.applyIf(config, {
|
||||||
title : dgettext("plugin_passwd", 'Change Password'),
|
title : _('Change Password'),
|
||||||
categoryIndex : 9997,
|
categoryIndex : 9997,
|
||||||
iconCls : 'zarafa-settings-category-passwd',
|
|
||||||
xtype : 'zarafa.settingspasswdcategory',
|
xtype : 'zarafa.settingspasswdcategory',
|
||||||
items : [{
|
items : [{
|
||||||
xtype : 'zarafa.settingspasswdwidget',
|
xtype : 'zarafa.settingspasswdwidget',
|
||||||
settingsContext : config.settingsContext
|
settingsContext : config.settingsContext
|
||||||
},
|
}]
|
||||||
container.populateInsertionPoint('context.settings.category.passwd', this)
|
|
||||||
]
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Zarafa.plugins.passwd.settings.SettingsPasswdCategory.superclass.constructor.call(this, config);
|
Zarafa.plugins.passwd.settings.SettingsPasswdCategory.superclass.constructor.call(this, config);
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,14 @@ Zarafa.plugins.passwd.settings.SettingsPasswdWidget = Ext.extend(Zarafa.settings
|
||||||
config = config || {};
|
config = config || {};
|
||||||
|
|
||||||
Ext.applyIf(config, {
|
Ext.applyIf(config, {
|
||||||
title : dgettext("plugin_passwd", 'Change Password'),
|
height : 175,
|
||||||
|
width : 400,
|
||||||
|
title : _('Change Password'),
|
||||||
xtype : 'zarafa.settingspasswdwidget',
|
xtype : 'zarafa.settingspasswdwidget',
|
||||||
layout: 'form',
|
layout : {
|
||||||
|
// override from SettingsWidget
|
||||||
|
type : 'fit'
|
||||||
|
},
|
||||||
items : [{
|
items : [{
|
||||||
xtype : 'zarafa.passwdpanel',
|
xtype : 'zarafa.passwdpanel',
|
||||||
ref : 'passwdPanel',
|
ref : 'passwdPanel',
|
||||||
|
|
@ -46,42 +51,10 @@ Zarafa.plugins.passwd.settings.SettingsPasswdWidget = Ext.extend(Zarafa.settings
|
||||||
// listen to savesettings and discardsettings to save/discard delegation data
|
// listen to savesettings and discardsettings to save/discard delegation data
|
||||||
var contextModel = this.settingsContext.getModel();
|
var contextModel = this.settingsContext.getModel();
|
||||||
|
|
||||||
this.mon(contextModel, 'beforesavesettings', this.onBeforeSaveSettings, this);
|
|
||||||
this.mon(contextModel, 'savesettings', this.onSaveSettings, this);
|
this.mon(contextModel, 'savesettings', this.onSaveSettings, this);
|
||||||
this.mon(contextModel, 'discardsettings', this.onDiscardSettings, 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.
|
* 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
|
* This will relay this event to {@link Zarafa.plugins.passwd.settings.PasswdPanel PasswdPanel} so it can
|
||||||
|
|
@ -98,11 +71,8 @@ Zarafa.plugins.passwd.settings.SettingsPasswdWidget = Ext.extend(Zarafa.settings
|
||||||
|
|
||||||
// send request
|
// send request
|
||||||
container.getRequest().singleRequest('passwdmodule', 'save', data, new Zarafa.plugins.passwd.data.PasswdResponseHandler({
|
container.getRequest().singleRequest('passwdmodule', 'save', data, new Zarafa.plugins.passwd.data.PasswdResponseHandler({
|
||||||
callbackFn: function (success, response) {
|
callbackFn : function(success, response) {
|
||||||
this.ownerCt.hideSavingMask(success);
|
this.ownerCt.hideSavingMask(success);
|
||||||
if(success) {
|
|
||||||
this.passwdPanel.getForm().reset();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
scope : this
|
scope : this
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
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.
|
|
@ -1,94 +0,0 @@
|
||||||
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.
|
|
@ -1,94 +0,0 @@
|
||||||
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"
|
|
||||||
|
|
@ -1,95 +0,0 @@
|
||||||
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"
|
|
||||||
|
|
||||||
158
lib/PasswordMeter.js
Normal file
158
lib/PasswordMeter.js
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
// 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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
35
manifest.xml
35
manifest.xml
|
|
@ -2,22 +2,30 @@
|
||||||
<!DOCTYPE plugin SYSTEM "manifest.dtd">
|
<!DOCTYPE plugin SYSTEM "manifest.dtd">
|
||||||
<plugin version="2">
|
<plugin version="2">
|
||||||
<info>
|
<info>
|
||||||
<version>1.5</version>
|
<version>1.0</version>
|
||||||
<Name>Passwd</Name>
|
<name>Passwd</name>
|
||||||
<title>Password Change Plugin</title>
|
<title>Password Change Plugin</title>
|
||||||
<author>Saket Patel - Denis Ducret</author>
|
<author>Saket Patel</author>
|
||||||
<authorURL>https://github.com/dducret</authorURL>
|
<authorURL>https://github.com/silentsakky</authorURL>
|
||||||
<description>Change your password from Kopano WebApp</description>
|
<description>Change your password from zarafa webapp</description>
|
||||||
</info>
|
</info>
|
||||||
<config>
|
<config>
|
||||||
<configfile>config.php</configfile>
|
<configfile>config.php</configfile>
|
||||||
</config>
|
</config>
|
||||||
<translations>
|
|
||||||
<translationsdir>language</translationsdir>
|
|
||||||
</translations>
|
|
||||||
|
|
||||||
|
|
||||||
<components>
|
<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>
|
<component>
|
||||||
<files>
|
<files>
|
||||||
<server>
|
<server>
|
||||||
|
|
@ -27,20 +35,13 @@
|
||||||
<client>
|
<client>
|
||||||
<clientfile load="release">js/passwd.js</clientfile>
|
<clientfile load="release">js/passwd.js</clientfile>
|
||||||
<clientfile load="debug">js/passwd-debug.js</clientfile>
|
<clientfile load="debug">js/passwd-debug.js</clientfile>
|
||||||
|
|
||||||
<clientfile load="source">js/PasswdPlugin.js</clientfile>
|
<clientfile load="source">js/PasswdPlugin.js</clientfile>
|
||||||
<clientfile load="source">js/settings/SettingsPasswdCategory.js</clientfile>
|
<clientfile load="source">js/settings/SettingsPasswdCategory.js</clientfile>
|
||||||
<clientfile load="source">js/settings/SettingsPasswdWidget.js</clientfile>
|
<clientfile load="source">js/settings/SettingsPasswdWidget.js</clientfile>
|
||||||
<clientfile load="source">js/settings/PasswdPanel.js</clientfile>
|
<clientfile load="source">js/settings/PasswdPanel.js</clientfile>
|
||||||
<clientfile load="source">js/data/PasswdResponseHandler.js</clientfile>
|
<clientfile load="source">js/data/PasswdResponseHandler.js</clientfile>
|
||||||
<clientfile load="source">js/ABOUT.js</clientfile>
|
<clientfile load="source">js/ABOUT.js</clientfile>
|
||||||
<clientfile load="source">js/external/PasswordMeter.js</clientfile>
|
|
||||||
</client>
|
</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>
|
</files>
|
||||||
</component>
|
</component>
|
||||||
</components>
|
</components>
|
||||||
|
|
|
||||||
|
|
@ -41,23 +41,23 @@ class PasswdModule extends Module
|
||||||
|
|
||||||
// some sanity checks
|
// some sanity checks
|
||||||
if(empty($data)) {
|
if(empty($data)) {
|
||||||
$errorMessage = dgettext("plugin_passwd", 'No data received.');
|
$errorMessage = _('No data received.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(empty($data['username'])) {
|
if(empty($data['username'])) {
|
||||||
$errorMessage = dgettext("plugin_passwd", 'User name is empty.');
|
$errorMessage = _('User name is empty.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(empty($data['current_password'])) {
|
if(empty($data['current_password'])) {
|
||||||
$errorMessage = dgettext("plugin_passwd", 'Current password is empty.');
|
$errorMessage = _('Current password is empty.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(empty($data['new_password']) || empty($data['new_password_repeat'])) {
|
if(empty($data['new_password']) || empty($data['new_password_repeat'])) {
|
||||||
$errorMessage = dgettext("plugin_passwd", 'New password is empty.');
|
$errorMessage = _('New password is empty.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if($data['new_password'] !== $data['new_password_repeat']) {
|
if($data['new_password'] !== $data['new_password_repeat']) {
|
||||||
$errorMessage = dgettext("plugin_passwd", 'New passwords do not match.');
|
$errorMessage = _('New passwords does not match.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(empty($errorMessage)) {
|
if(empty($errorMessage)) {
|
||||||
|
|
@ -90,87 +90,57 @@ class PasswdModule extends Module
|
||||||
// check connection is successfull
|
// check connection is successfull
|
||||||
if(ldap_errno($ldapconn) === 0) {
|
if(ldap_errno($ldapconn) === 0) {
|
||||||
// get the users uid, if we have a multi tenant installation then remove company name from user name
|
// get the users uid, if we have a multi tenant installation then remove company name from user name
|
||||||
if (PLUGIN_PASSWD_LOGIN_WITH_TENANT){
|
$parts = explode('@', $data['username']);
|
||||||
$parts = explode('@', $data['username']);
|
$uid = $parts[0];
|
||||||
$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
|
// search for the user dn that will be used to do login into LDAP
|
||||||
$userdn = ldap_search (
|
$userdn = ldap_search (
|
||||||
$ldapconn, // connection-identify
|
$ldapconn, // connection-identify
|
||||||
PLUGIN_PASSWD_LDAP_BASEDN, // basedn
|
PLUGIN_PASSWD_LDAP_BASEDN, // basedn
|
||||||
'uid=' . $uid, // search filter
|
'uid=' . $uid, // search filter
|
||||||
array('dn', 'objectClass') // needed attributes. we need dn and objectclass
|
array('dn') // needed attributes. we need the dn
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($userdn) {
|
if ($userdn) {
|
||||||
$entries = ldap_get_entries($ldapconn, $userdn);
|
$userdn = ldap_get_entries($ldapconn, $userdn);
|
||||||
$userdn = $entries[0]['dn'];
|
$userdn = $userdn[0]['dn'];
|
||||||
|
|
||||||
// bind to ldap directory
|
// 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
|
// login with current password if that fails then current password is wrong
|
||||||
ldap_bind($ldapconn, $userdn, $data['current_password']);
|
$bind = ldap_bind($ladpconn, $userdn, $data['current_password']);
|
||||||
|
|
||||||
if(ldap_errno($ldapconn) === 0) {
|
if(ldap_errno($ldapconn) === 0) {
|
||||||
|
|
||||||
$passwd = $data['new_password'];
|
$passwd = $data['new_password'];
|
||||||
|
$passwdRepeat = $data['new_password_repeat'];
|
||||||
|
|
||||||
if ($this->checkPasswordStrenth($passwd)) {
|
if($this->checkPasswordStrenth($passwd)) {
|
||||||
$password_hash = $this->sshaEncode($passwd);
|
$password_hash = $this->sshaEncode($passwd);
|
||||||
$entry = array('userPassword' => $password_hash);
|
$entry = array('userPassword' => $password_hash);
|
||||||
if (in_array('sambaSamAccount', $entries[0]['objectclass'])) {
|
$return_mod = ldap_modify($ldapconn, $userdn, $entry);
|
||||||
$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) {
|
if (ldap_errno($ldapconn) === 0) {
|
||||||
// password changed successfully
|
// password changed successfully
|
||||||
|
|
||||||
// write new password to session because we don't want user to re-authenticate
|
// write new password to session because we don't want user to re-authenticate
|
||||||
session_start();
|
session_start();
|
||||||
// if user has openssl module installed
|
$_SESSION['password'] = $passwd;
|
||||||
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();
|
session_write_close();
|
||||||
|
|
||||||
// send feedback to client
|
// send feedback to client
|
||||||
$this->sendFeedback(true, array(
|
$this->sendFeedback(true, array(
|
||||||
'info' => array(
|
'info' => array(
|
||||||
'display_message' => dgettext("plugin_passwd", 'Password is changed successfully.')
|
'display_message' => _('Password is changed successfully.')
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
$errorMessage = dgettext("plugin_passwd", 'Password is not changed.');
|
$errorMessage = _('Password is not changed.');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$errorMessage = dgettext("plugin_passwd", 'Password is weak. Password should contain capital, non-capital letters and numbers. Password should have 8 to 20 characters.');
|
$errorMessage = _('Password is weak. Password should contain capital, non capital letters and numbers. Password shuold have 8 to 20 characters.');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$errorMessage = dgettext("plugin_passwd", 'Current password does not match.');
|
$errorMessage = _('Current password does not match.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// release ldap-bind
|
// release ldap-bind
|
||||||
|
|
@ -182,8 +152,8 @@ class PasswdModule extends Module
|
||||||
$this->sendFeedback(false, array(
|
$this->sendFeedback(false, array(
|
||||||
'type' => ERROR_ZARAFA,
|
'type' => ERROR_ZARAFA,
|
||||||
'info' => array(
|
'info' => array(
|
||||||
'ldap_error' => ldap_errno($ldapconn),
|
'ldap_error' => ldap_errno(),
|
||||||
'ldap_error_name' => ldap_error($ldapconn),
|
'ldap_error_name' => ldap_error(),
|
||||||
'display_message' => $errorMessage
|
'display_message' => $errorMessage
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
|
|
@ -191,76 +161,42 @@ class PasswdModule extends Module
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function will try to change user's password via MAPI in SOAP connection.
|
* Function will execute zarafa-passwd command and will try to change user's password,
|
||||||
|
* this method is unsecure and unreliable.
|
||||||
* @param {Array} $data data sent by client.
|
* @param {Array} $data data sent by client.
|
||||||
*/
|
*/
|
||||||
public function saveInDB($data)
|
public function saveInDB($data)
|
||||||
{
|
{
|
||||||
$errorMessage = '';
|
$errorMessage = '';
|
||||||
$passwd = $data['new_password'];
|
$passwd = $data['new_password'];
|
||||||
|
$passwdRepeat = $data['new_password_repeat'];
|
||||||
|
|
||||||
/*
|
if($this->checkPasswordStrenth($passwd)) {
|
||||||
// get current session password
|
$passwd_cmd = '/usr/bin/zarafa-passwd -u %s -o %s -p %s';
|
||||||
$sessionPass = $_SESSION['password'];
|
|
||||||
// if user has openssl module installed
|
// all information correct, change password
|
||||||
if (function_exists("openssl_decrypt")) {
|
$cmd = sprintf($passwd_cmd, $data['username'], $data['current_password'], $passwd);
|
||||||
if (version_compare(phpversion(), "5.3.3", "<")) {
|
exec($cmd, $arrayout, $retval);
|
||||||
$sessionPass = openssl_decrypt($sessionPass, "des-ede3-cbc", PASSWORD_KEY, 0);
|
|
||||||
|
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.')
|
||||||
|
)
|
||||||
|
));
|
||||||
} else {
|
} else {
|
||||||
$sessionPass = openssl_decrypt($sessionPass, "des-ede3-cbc", PASSWORD_KEY, 0, PASSWORD_IV);
|
$errorMessage = _('Password is not changed.');
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
} else {
|
||||||
$errorMessage = dgettext("plugin_passwd", 'Current password does not match.');
|
$errorMessage = _('Password is weak. Password should contain capital, non capital letters and numbers. Password shuold have 8 to 20 characters.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!empty($errorMessage)) {
|
if(!empty($errorMessage)) {
|
||||||
|
|
@ -285,6 +221,7 @@ class PasswdModule extends Module
|
||||||
*/
|
*/
|
||||||
public function checkPasswordStrenth($password)
|
public function checkPasswordStrenth($password)
|
||||||
{
|
{
|
||||||
|
// @FIXME should be moved to client side
|
||||||
if (preg_match("#.*^(?=.{8,20})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).*$#", $password)) {
|
if (preg_match("#.*^(?=.{8,20})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).*$#", $password)) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ class Pluginpasswd extends Plugin {
|
||||||
'zarafa' => Array(
|
'zarafa' => Array(
|
||||||
'v1' => Array(
|
'v1' => Array(
|
||||||
'plugins' => Array(
|
'plugins' => Array(
|
||||||
'passwd' => Array(
|
'sugarcrm' => Array(
|
||||||
'enable' => PLUGIN_PASSWD_USER_DEFAULT_ENABLE,
|
'enable' => PLUGIN_PASSWD_USER_DEFAULT_ENABLE,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
.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%;
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
.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.
|
Before Width: | Height: | Size: 452 B |
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue