Skip to content
This repository was archived by the owner on Mar 21, 2025. It is now read-only.

FINERACT-2006: Forgot password on login page #3544

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 12 additions & 17 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -349,24 +349,19 @@ module.exports = function(grunt) {
}
},

devcode: {
options: {
html: true, // html files parsing?
js: true, // javascript files parsing?
css: false, // css files parsing?
clean: true, // removes devcode comments even if code was not removed
block: {
open: 'devcode', // with this string we open a block of code
close: 'endcode' // with this string we close a block of code
},
dest: 'dist' // default destination which overwrittes environment variable
},
dist : { // settings for task used with 'devcode:dist'
preprocess: {

dist: {
src: ['dist/**/*.js','dist/**/*.html','dist/*.js','dist/*.html'],
dst: ['dist/'],
options: {
source: 'dist/',
dest: 'dist/',
env: 'production'
inline: true,
context: {
DEBUG: false,
NODE_ENV: 'production'
}
}

}
},

Expand Down Expand Up @@ -425,7 +420,7 @@ module.exports = function(grunt) {

// Default task(s).
grunt.registerTask('default', ['clean', 'jshint', 'copy:dev']);
grunt.registerTask('prod', ['clean:dist', 'clean:server', 'compass:dist', 'copy:prod', 'copy:tests', 'concat', 'uglify:prod', 'devcode:dist', 'hashres','replace']);
grunt.registerTask('prod', ['clean:dist', 'clean:server', 'compass:dist', 'copy:prod', 'copy:tests', 'concat', 'uglify:prod', 'preprocess:dist', 'hashres', 'replace']);
grunt.registerTask('dev', ['clean', 'compass:dev', 'copy:dev']);
grunt.registerTask('test', ['karma']);
grunt.registerTask('deploy', ['prod', 'gh-pages']);
Expand Down
3 changes: 3 additions & 0 deletions app/global-translations/locale-en.json
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@
"error.msg.parameter.unsupported": "The parameter `{{params[0].value}}` has been passed and is not supported for this request.",
"error.msg.column.mandatory": "Mandatory field not provided.",
"error.msg.header": "You have the following errors:",
"error.msg.username.not.found": "Username not found in the system.",
"validation.msg.validation.errors.exist": "Validation errors exist.",
"validation.msg.productivecollectionsheet.staffId.cannot.be.blank": "Staff is mandatory.",
"validation.msg.domain.rule.violation": "Errors contain reason for domain rule violation.",
Expand Down Expand Up @@ -625,6 +626,7 @@
"label.anchor.advsearch": "Advanced search",
"label.anchor.keyboardshortcut": "Keyboard Shortcuts",
"label.anchor.save": "Save",
"label.anchor.forgotpassword": "Forgot Password",
"#Inputs": "..",
"label.input.searchbyuser": "Search by user",
"label.input.clienttemplate": "Client Template",
Expand Down Expand Up @@ -4414,6 +4416,7 @@
"label.tooltip.fixed.pricipal.percentage.per.installment" : "Principal portion of the instalments except the last installment will be fixed to this value.",
"label.input.change.fixed.principal.percentage.per.installment" : "Change Fixed Principal % per instalment",
"label.input.new.fixed.principal.percentage.per.installment" : "New Fixed Principal % per instalment",
"success.forgot.password.reset":"Password reset Successfully! Check your email.",

"----End---": "--End of file--- "
}
34 changes: 29 additions & 5 deletions app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -91,34 +91,58 @@
<div class="alert alert-danger" ng-show="authenticationFailed">
{{ authenticationErrorMessage | translate }}
</div>
<div class="alert alert-success" ng-show="forgotPasswordSuccess">
{{ forgotPasswordMessage | translate }}
</div>
<div class="alert alert-danger" ng-show="forgotPasswordFailure">
{{ forgotPasswordMessage | translate }}
</div>

<form class="form">

<div class="form-group">
<div class="form-group" >
<label for="uid">{{ 'label.input.username' | translate | uppercase }}</label>
<input type="text" name="username" id="uid" class="form-control"
ng-model="loginCredentials.username"
placeholder="{{ 'label.input.username' | translate |lowercase }}"
required/>
</div>

<div class="form-group">
<div class="form-group" ng-hide="isforgotpassword">
<label for="pwd">{{ 'label.input.password' | translate | uppercase }}</label>
<input type="password" name="password" id="pwd" class="form-control"
ng-model="loginCredentials.password" autocomplete="new-password"
placeholder="{{ 'label.input.password' | translate | lowercase }}"
required/>
ng-required="!isforgotpassword"/>
</div>

<div class="form-group">
<button class="btn btn-block btn-primary" type="submit" data-ng-show="!load" data-ng-click="login()"
<div class="form-group" >
<button ng-hide="isforgotpassword" class="btn btn-block btn-primary" type="submit" data-ng-show="!load" data-ng-click="login()"
id="login-button">
{{'label.button.signin' | translate }}
</button>
<button ng-show="isforgotpassword" class="btn btn-block btn-primary" type="submit" data-ng-show="!load" data-ng-click="forgotpassword()"
id="login-button">
{{'label.button.submit' | translate }}
</button>
<button class="btn btn-block btn-primary" type="submit" data-ng-show="load">
<img data-ng-src="images/ring.svg" alt=""> <b>loading...</b>
</button>
</div>

<div class="form-group">
<ul class="list-unstyled">
<li><a target="#"
data-ng-click="isforgotpassword = !isforgotpassword">
<p ng-show="!isforgotpassword">
{{ 'label.anchor.forgotpassword' | translate }}
</p>
<p ng-show="isforgotpassword">
{{ 'label.button.back' | translate }}
</p>
</a></li>
</ul>
</div>

</form>

Expand Down
2 changes: 1 addition & 1 deletion app/scripts/controllers/client/ViewClientController.js
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@


scope.entitySubTypeFilter = function (datatable) {
if (datatable.entitySubType === scope.entitySubType) {
if (datatable.entitySubType.toLowerCase() === scope.entitySubType.toLowerCase()) {
return true;
}
}
Expand Down
28 changes: 28 additions & 0 deletions app/scripts/controllers/main/LoginFormController.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
scope.loginCredentials = {};
scope.passwordDetails = {};
scope.authenticationFailed = false;
scope.forgotPasswordFailure = false;
scope.forgotPasswordSuccess = false;
scope.load = false;

scope.twoFactorRequired = false;
Expand All @@ -13,6 +15,7 @@
scope.otpToken = null;
scope.selectedDeliveryMethodName = null;
scope.twofactorRememberMe = false;
scope.isforgotpassword = false;

scope.login = function () {
scope.authenticationFailed = false;
Expand Down Expand Up @@ -111,7 +114,32 @@
}
scope.otpTokenError = true;
});
scope.forgotpassword = function () {
authenticationService.forgotPassword(scope.loginCredentials);
delete scope.loginCredentials.username;
};

scope.$on("UserForgotPasswordFailureEvent", function (event, data, status) {
scope.forgotPasswordFailure = true;
scope.forgotPasswordSuccess = false;
scope.authenticationFailed = false;
scope.load = false;
if(status == 404) {
scope.forgotPasswordMessage = 'error.msg.username.not.found';
} else {
scope.forgotPasswordMessage = 'error.connection.failed';
}
});

scope.$on("UserForgotPasswordSuccessEvent", function (event, data) {
scope.load = false;
scope.forgotPasswordSuccess = true;
scope.forgotPasswordFailure = false;
scope.authenticationFailed = false;
scope.forgotPasswordMessage = 'success.forgot.password.reset';
scope.loginCredentials.username='';
scope.load = false;
});

}
});
Expand Down
18 changes: 18 additions & 0 deletions app/scripts/services/AuthenticationService.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,24 @@

httpService.post(apiVer + "/twofactor/invalidate", '{"token": "' + twoFactorAccessToken + '"}');
});

this.forgotPassword = function (credentials) {
httpService.post(apiVer + "/password/forgot-password", { "username": credentials.username})
.then(onForgotPasswordSuccess)
.catch(onForgotPasswordFailure);
};


var onForgotPasswordSuccess = function (response) {
var data = response.data;
scope.$broadcast("UserForgotPasswordSuccessEvent", data);
};

var onForgotPasswordFailure = function (response) {
var data = response.data;
var status = response.status;
scope.$broadcast("UserForgotPasswordFailureEvent", data, status);
};
}
});
mifosX.ng.services.service('AuthenticationService', ['$rootScope', 'HttpService', 'SECURITY', 'localStorageService','$timeout','webStorage', mifosX.services.AuthenticationService]).run(function ($log) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"grunt-contrib-requirejs": "1.0.0",
"grunt-contrib-uglify": "5.0.0",
"grunt-contrib-watch": "1.1.0",
"grunt-devcode": "0.0.4",
"grunt-preprocess": "5.1.0",
"grunt-gh-pages": "4.0.0",
"grunt-hashres": "0.4.1",
"grunt-html-validation": "0.1.18",
Expand Down