Commit f18db24b9c4c75d874d05e6d23ab36da5758b395
1 parent
d9e6f9c7
Exists in
feature-captcha
Add reCaptcha (issue #56)
Showing
12 changed files
with
153 additions
and
131 deletions
Show diff stats
bower.json
| ... | ... | @@ -7,6 +7,7 @@ |
| 7 | 7 | "angular-breadcrumb": "~0.4.1", |
| 8 | 8 | "angular-cookies": "~1.4.0", |
| 9 | 9 | "angular-messages": "ng-messages#*", |
| 10 | + "angular-recaptcha": "~2.2.5", | |
| 10 | 11 | "angular-sanitize": "~1.4.0", |
| 11 | 12 | "angular-slugify": "~1.0.1", |
| 12 | 13 | "angular-socialshare": "angularjs-socialshare#~0.1.13", | ... | ... |
src/app/components/proposal-box/proposal-box.directive.js
| ... | ... | @@ -9,21 +9,23 @@ |
| 9 | 9 | function proposalBox() { |
| 10 | 10 | |
| 11 | 11 | /** @ngInject */ |
| 12 | - function ProposalBoxController($scope, $location, $rootScope, $state, $timeout, $interval, $window, VOTE_STATUS, VOTE_OPTIONS, AuthService, DialogaService, $log) { | |
| 12 | + function ProposalBoxController($scope, $location, $rootScope, $state, $timeout, $interval, $window, APP, VOTE_STATUS, VOTE_OPTIONS, AuthService, DialogaService, vcRecaptchaService, $log) { | |
| 13 | 13 | $log.debug('ProposalBoxController'); |
| 14 | 14 | |
| 15 | 15 | var vm = this; |
| 16 | 16 | vm.$scope = $scope; |
| 17 | + vm.$location = $location; | |
| 17 | 18 | vm.$rootScope = $rootScope; |
| 18 | 19 | vm.$state = $state; |
| 19 | 20 | vm.$timeout = $timeout; |
| 20 | 21 | vm.$interval = $interval; |
| 21 | 22 | vm.$window = $window; |
| 23 | + vm.APP = APP; | |
| 22 | 24 | vm.VOTE_STATUS = VOTE_STATUS; |
| 23 | 25 | vm.VOTE_OPTIONS = VOTE_OPTIONS; |
| 24 | 26 | vm.AuthService = AuthService; |
| 27 | + vm.vcRecaptchaService = vcRecaptchaService; | |
| 25 | 28 | vm.$log = $log; |
| 26 | - vm.$location = $location; | |
| 27 | 29 | |
| 28 | 30 | vm.init(); |
| 29 | 31 | vm.addListeners(); |
| ... | ... | @@ -39,6 +41,8 @@ |
| 39 | 41 | vm.STATE = null; |
| 40 | 42 | vm.errorOnSkip = false; |
| 41 | 43 | vm.showCaptchaForm = null; |
| 44 | + vm.recaptchaWidgetId = null; | |
| 45 | + vm.recaptchaResponse = null; | |
| 42 | 46 | vm.voteProposalRedirectURI = null; |
| 43 | 47 | vm.proposalsImg = null; |
| 44 | 48 | |
| ... | ... | @@ -86,20 +90,27 @@ |
| 86 | 90 | vm.messageCode = data.code; |
| 87 | 91 | }); |
| 88 | 92 | |
| 89 | - // Load captcha | |
| 90 | - var stop = null; | |
| 91 | - stop = vm.$interval(function() { | |
| 92 | - var $el = angular.element('#serpro_captcha'); | |
| 93 | - | |
| 94 | - if ($el && $el.length > 0) { | |
| 95 | - vm.$window.initCaptcha($el[0]); | |
| 96 | - vm.$interval.cancel(stop); | |
| 97 | - stop = undefined; | |
| 98 | - }else { | |
| 99 | - vm.$log.debug('captcha element not found.'); | |
| 100 | - } | |
| 101 | - | |
| 102 | - }, 10); | |
| 93 | + // reCaptcha Listeners | |
| 94 | + vm.setWidgetId = function(widgetId) { | |
| 95 | + // store the `widgetId` for future usage. | |
| 96 | + // For example for getting the response with | |
| 97 | + // `recaptcha.getResponse(widgetId)`. | |
| 98 | + vm.$log.info('Created widget ID:', widgetId); | |
| 99 | + vm.recaptchaWidgetId = widgetId; | |
| 100 | + | |
| 101 | + }; | |
| 102 | + | |
| 103 | + vm.setResponse = function(response) { | |
| 104 | + | |
| 105 | + // Update local captcha response | |
| 106 | + vm.$log.debug('Response available', response); | |
| 107 | + vm.recaptchaResponse = response; | |
| 108 | + }; | |
| 109 | + | |
| 110 | + vm.cbExpiration = function() { | |
| 111 | + // reset the 'response' object that is on scope | |
| 112 | + vm.$log.debug('cbExpiration'); | |
| 113 | + }; | |
| 103 | 114 | }; |
| 104 | 115 | |
| 105 | 116 | ProposalBoxController.prototype.canVote = function() { |
| ... | ... | @@ -113,12 +124,10 @@ |
| 113 | 124 | |
| 114 | 125 | var target = $event.target; |
| 115 | 126 | var $target = angular.element(target); |
| 116 | - var $captcha = $target.find('[name="txtToken_captcha_serpro_gov_br"]'); | |
| 117 | 127 | |
| 118 | 128 | vm.sendingCaptcha = true; |
| 119 | 129 | vm.AuthService.loginCaptcha({ |
| 120 | - captcha_text: captchaForm.captcha_text.$modelValue, | |
| 121 | - txtToken_captcha_serpro_gov_br: $captcha.val() | |
| 130 | + recaptcha_response: vm.recaptchaResponse | |
| 122 | 131 | }).then(function(data) { |
| 123 | 132 | // SUCCESS |
| 124 | 133 | vm.$log.debug('register success.data', data); |
| ... | ... | @@ -131,22 +140,23 @@ |
| 131 | 140 | // hide captcha form |
| 132 | 141 | vm.showCaptchaForm = false; |
| 133 | 142 | |
| 134 | - }, function(data) { | |
| 143 | + }) | |
| 144 | + .catch(function(data) { | |
| 135 | 145 | // ERROR |
| 136 | 146 | vm.$log.debug('register error.data', data); |
| 137 | 147 | |
| 138 | - vm.sendingCaptchaError = { | |
| 139 | - code: data.status, | |
| 140 | - message: data.message || ('Erro (' + data.status + '). Já estamos trabalhando para resolver o problema.<br/>Por favor, tente novamente mais tarde') | |
| 141 | - }; | |
| 148 | + // In case of a failed validation you need to reload the captcha | |
| 149 | + // because each response can be checked just once | |
| 150 | + vm.vcRecaptchaService.reload(vm.recaptchaWidgetId); | |
| 151 | + | |
| 152 | + vm.sendingCaptchaError = {}; | |
| 153 | + vm.sendingCaptchaError.code = data.status; | |
| 154 | + vm.sendingCaptchaError.message = data.message || ('Erro (' + data.status + '). Já estamos trabalhando para resolver o problema.<br/>Por favor, tente novamente mais tarde'); | |
| 142 | 155 | |
| 143 | 156 | if (angular.equals(vm.sendingCaptchaError.message, 'Internal captcha validation error')) { |
| 144 | 157 | vm.sendingCaptchaError.message = 'Erro interno ao tentar validar captcha.<br/><br/>Já estamos trabalhando para resolver o problema.<br/>Por favor, tente novamente mais tarde.'; |
| 145 | 158 | } |
| 146 | 159 | |
| 147 | - }, function(data) { | |
| 148 | - // UPDATE | |
| 149 | - vm.$log.debug('register update.data', data); | |
| 150 | 160 | }).finally(function() { |
| 151 | 161 | vm.sendingCaptcha = false; |
| 152 | 162 | }); |
| ... | ... | @@ -161,11 +171,10 @@ |
| 161 | 171 | vm.message = null; |
| 162 | 172 | |
| 163 | 173 | // reload new captcha |
| 164 | - var $el = angular.element('#serpro_captcha'); | |
| 165 | - vm.$window.reloadCaptcha($el[0]); | |
| 174 | + vm.vcRecaptchaService.reload(vm.recaptchaWidgetId); | |
| 166 | 175 | |
| 167 | 176 | // focus on input |
| 168 | - angular.element('#captcha_text').val('').focus(); | |
| 177 | + // angular.element('#captcha_text').val('').focus(); | |
| 169 | 178 | }; |
| 170 | 179 | |
| 171 | 180 | ProposalBoxController.prototype.vote = function(value) { | ... | ... |
src/app/components/proposal-box/proposal-box.html
| ... | ... | @@ -93,12 +93,14 @@ |
| 93 | 93 | <div ng-hide="vm.sendingCaptchaError"> |
| 94 | 94 | <form name="captchaForm" ng-submit="vm.submitCaptcha($event, captchaForm)"> |
| 95 | 95 | <div class="form-group"> |
| 96 | - <div id="serpro_captcha" class="captcha"></div> | |
| 97 | - <div class="captcha">Digite os caracteres acima:</div> | |
| 98 | - <div class="captcha"> | |
| 99 | - <input type="text" name="captcha_text" id="captcha_text" aria-label="Escreva os caracteres do captcha aqui" ng-model="vm._captcha_text" ng-minlength="" ng-maxlength="" required> | |
| 100 | - <validation-messages field="captchaForm.captcha_text"></validation-messages> | |
| 101 | - </div> | |
| 96 | + <div | |
| 97 | + vc-recaptcha | |
| 98 | + theme="'light'" | |
| 99 | + key="vm.APP.recaptcha_key" | |
| 100 | + on-create="vm.setWidgetId(widgetId)" | |
| 101 | + on-success="vm.setResponse(response)" | |
| 102 | + on-expire="vm.cbExpiration()" | |
| 103 | + ></div> | |
| 102 | 104 | </div> |
| 103 | 105 | <div class="form-group"> |
| 104 | 106 | <button type="submit" class="btn btn-lg btn-block btn-submit">Enviar</button> | ... | ... |
src/app/index.constants.js
src/app/index.module.js
| ... | ... | @@ -2,6 +2,6 @@ |
| 2 | 2 | 'use strict'; |
| 3 | 3 | |
| 4 | 4 | angular |
| 5 | - .module('dialoga', ['ngAnimate', 'ngCookies', 'ngTouch', 'ngSanitize', 'ui.router', 'ngStorage', '720kb.socialshare', 'slugifier', 'ncy-angular-breadcrumb', 'ngMessages']); | |
| 5 | + .module('dialoga', ['ngAnimate', 'ngCookies', 'ngTouch', 'ngSanitize', 'ui.router', 'ngStorage', '720kb.socialshare', 'slugifier', 'ncy-angular-breadcrumb', 'ngMessages', 'vcRecaptcha']); | |
| 6 | 6 | |
| 7 | 7 | })(); | ... | ... |
src/app/pages/auth/auth.controller.js
| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | .controller('AuthPageController', AuthPageController); |
| 7 | 7 | |
| 8 | 8 | /** @ngInject */ |
| 9 | - function AuthPageController($scope, $rootScope, $window, $location, $state, $timeout, $interval, APP, AUTH_EVENTS, AuthService, DialogaService, Session, $log) { | |
| 9 | + function AuthPageController($scope, $rootScope, $window, $location, $state, $timeout, $interval, APP, AUTH_EVENTS, AuthService, DialogaService, Session, vcRecaptchaService, $log) { | |
| 10 | 10 | var vm = this; |
| 11 | 11 | |
| 12 | 12 | vm.$scope = $scope; |
| ... | ... | @@ -21,6 +21,7 @@ |
| 21 | 21 | vm.AuthService = AuthService; |
| 22 | 22 | vm.DialogaService = DialogaService; |
| 23 | 23 | vm.Session = Session; |
| 24 | + vm.vcRecaptchaService = vcRecaptchaService; | |
| 24 | 25 | vm.$log = $log; |
| 25 | 26 | |
| 26 | 27 | vm.init(); |
| ... | ... | @@ -42,6 +43,8 @@ |
| 42 | 43 | vm.loadingTerms = null; |
| 43 | 44 | vm.delay = 3; // segundos |
| 44 | 45 | vm.countdown = 0; |
| 46 | + vm.recaptchaResponse = null; | |
| 47 | + vm.recaptchaWidgetId = null; | |
| 45 | 48 | |
| 46 | 49 | vm.search = vm.$location.search(); |
| 47 | 50 | var redirect = vm.search.redirect_uri || ''; |
| ... | ... | @@ -62,7 +65,6 @@ |
| 62 | 65 | vm.$scope.$on(vm.AUTH_EVENTS.logoutSuccess, function() { |
| 63 | 66 | vm.clearMessages(); |
| 64 | 67 | vm.currentUser = vm.Session.getCurrentUser(); |
| 65 | - vm._attachCaptcha(); | |
| 66 | 68 | }); |
| 67 | 69 | }; |
| 68 | 70 | |
| ... | ... | @@ -104,7 +106,7 @@ |
| 104 | 106 | var private_token = response.data.private_token; |
| 105 | 107 | |
| 106 | 108 | // Garante que o 'user' sempre terá a propriedade 'private_token' |
| 107 | - if(response.data.user && !response.data.user.private_token){ | |
| 109 | + if (response.data.user && !response.data.user.private_token) { | |
| 108 | 110 | response.data.user.private_token = private_token; |
| 109 | 111 | } |
| 110 | 112 | |
| ... | ... | @@ -117,23 +119,27 @@ |
| 117 | 119 | } |
| 118 | 120 | }); |
| 119 | 121 | |
| 120 | - vm._attachCaptcha(); | |
| 121 | - }; | |
| 122 | - | |
| 123 | - AuthPageController.prototype._attachCaptcha = function() { | |
| 124 | - var vm = this; | |
| 125 | - | |
| 126 | - var stop = null; | |
| 127 | - stop = vm.$interval(function() { | |
| 128 | - var $el = angular.element('#serpro_captcha'); | |
| 122 | + // reCaptcha Listeners | |
| 123 | + vm.setWidgetId = function(widgetId) { | |
| 124 | + // store the `widgetId` for future usage. | |
| 125 | + // For example for getting the response with | |
| 126 | + // `recaptcha.getResponse(widgetId)`. | |
| 127 | + vm.$log.info('Created widget ID:', widgetId); | |
| 128 | + vm.recaptchaWidgetId = widgetId; | |
| 129 | + | |
| 130 | + }; | |
| 129 | 131 | |
| 130 | - if ($el && $el.length > 0) { | |
| 131 | - vm.$window.initCaptcha($el[0]); | |
| 132 | - vm.$interval.cancel(stop); | |
| 133 | - stop = undefined; | |
| 134 | - } | |
| 132 | + vm.setResponse = function(response) { | |
| 133 | + | |
| 134 | + // Update local captcha response | |
| 135 | + vm.$log.debug('Response available', response); | |
| 136 | + vm.recaptchaResponse = response; | |
| 137 | + }; | |
| 135 | 138 | |
| 136 | - }, 200); | |
| 139 | + vm.cbExpiration = function() { | |
| 140 | + // reset the 'response' object that is on scope | |
| 141 | + vm.$log.debug('cbExpiration'); | |
| 142 | + }; | |
| 137 | 143 | }; |
| 138 | 144 | |
| 139 | 145 | AuthPageController.prototype.onClickLogout = function() { |
| ... | ... | @@ -145,8 +151,8 @@ |
| 145 | 151 | AuthPageController.prototype.submitSignup = function($event, credentials) { |
| 146 | 152 | var vm = this; |
| 147 | 153 | |
| 148 | - credentials.txtToken_captcha_serpro_gov_br = getCaptchaValFromEvent($event); | |
| 149 | - | |
| 154 | + credentials.recaptcha_response = vm.recaptchaResponse; | |
| 155 | + | |
| 150 | 156 | vm.AuthService.register(credentials) |
| 151 | 157 | .then(function(/*response*/) { |
| 152 | 158 | // SUCCESS |
| ... | ... | @@ -154,14 +160,12 @@ |
| 154 | 160 | vm.signupSuccess = true; |
| 155 | 161 | // vm._startRedirect(); |
| 156 | 162 | |
| 157 | - }, function(response) { | |
| 158 | - // ERROR | |
| 159 | - | |
| 160 | - // TODO: mensagens de erro | |
| 161 | - // TODO: tratar multiplos erros | |
| 162 | - | |
| 163 | - // javascript_console_message: "Unable to reach Serpro's Captcha validation service" | |
| 164 | - // message: "Internal captcha validation error" | |
| 163 | + }) | |
| 164 | + .catch(function(response) { | |
| 165 | + | |
| 166 | + // In case of a failed validation you need to reload the captcha | |
| 167 | + // because each response can be checked just once | |
| 168 | + vm.vcRecaptchaService.reload(vm.recaptchaWidgetId); | |
| 165 | 169 | |
| 166 | 170 | vm.signupError = true; |
| 167 | 171 | vm.signupErrorTitle = 'Erro!'; |
| ... | ... | @@ -179,6 +183,9 @@ |
| 179 | 183 | if (response.status >= 500 && response.status < 600) { |
| 180 | 184 | vm.internalError = true; |
| 181 | 185 | } |
| 186 | + }) | |
| 187 | + .finally(function(){ | |
| 188 | + // vm.loadingSubmit = false; | |
| 182 | 189 | }); |
| 183 | 190 | }; |
| 184 | 191 | |
| ... | ... | @@ -220,8 +227,7 @@ |
| 220 | 227 | // get form data |
| 221 | 228 | var data = { |
| 222 | 229 | login: recoverForm.login.$modelValue, |
| 223 | - captcha_text: recoverForm.captcha_text.$modelValue, | |
| 224 | - txtToken_captcha_serpro_gov_br: getCaptchaValFromEvent($event) | |
| 230 | + recaptcha_response: vm.recaptchaResponse | |
| 225 | 231 | }; |
| 226 | 232 | |
| 227 | 233 | var promiseRequest = vm.AuthService.forgotPassword(data); |
| ... | ... | @@ -265,12 +271,10 @@ |
| 265 | 271 | // get form data |
| 266 | 272 | var data = { |
| 267 | 273 | login: confirmationForm.login.$modelValue, |
| 268 | - captcha_text: confirmationForm.captcha_text.$modelValue, | |
| 269 | - txtToken_captcha_serpro_gov_br: getCaptchaValFromEvent($event) | |
| 274 | + recaptcha_response: vm.recaptchaResponse | |
| 270 | 275 | }; |
| 271 | 276 | |
| 272 | 277 | // get captcha token |
| 273 | - | |
| 274 | 278 | vm.AuthService.resendConfirmation(data) |
| 275 | 279 | .then(function(response) { |
| 276 | 280 | vm.$log.debug('resendConfirmation success.response', response); |
| ... | ... | @@ -287,7 +291,8 @@ |
| 287 | 291 | vm.resendConfirmationSuccessMessage = 'Em instantes você receberá em seu e-mail um link para confirmar o seu cadastro.'; |
| 288 | 292 | } |
| 289 | 293 | |
| 290 | - }, function(response) { | |
| 294 | + }) | |
| 295 | + .catch(function(response) { | |
| 291 | 296 | vm.$log.debug('resendConfirmation error.response', response); |
| 292 | 297 | |
| 293 | 298 | vm.resendConfirmationError = true; |
| ... | ... | @@ -300,8 +305,9 @@ |
| 300 | 305 | if (response.status >= 500 && response.status < 600) { |
| 301 | 306 | vm.internalError = true; |
| 302 | 307 | } |
| 303 | - }).catch(function(error) { | |
| 304 | - vm.$log.debug('resendConfirmation catch.error', error); | |
| 308 | + }) | |
| 309 | + .finally(function() { | |
| 310 | + | |
| 305 | 311 | }); |
| 306 | 312 | }; |
| 307 | 313 | |
| ... | ... | @@ -382,8 +388,4 @@ |
| 382 | 388 | var url = 'http://login.dialoga.gov.br/plugin/oauth_client/google_oauth2?oauth_client_popup=true&id=' + vm.APP.google_app_id; |
| 383 | 389 | vm.$window.oauthClientAction(url); |
| 384 | 390 | }; |
| 385 | - | |
| 386 | - function getCaptchaValFromEvent($event) { | |
| 387 | - return angular.element($event.target).find('[name="txtToken_captcha_serpro_gov_br"]').val(); | |
| 388 | - } | |
| 389 | 391 | })(); | ... | ... |
src/app/pages/auth/recover.html
| ... | ... | @@ -48,15 +48,14 @@ |
| 48 | 48 | <validation-messages field=" recoverPassForm.login"></validation-messages> |
| 49 | 49 | </div> |
| 50 | 50 | <div class="form-group"> |
| 51 | - <div id="serpro_captcha" class="captcha"> | |
| 52 | - </div> | |
| 53 | - <div class="captcha"> | |
| 54 | - Digite os caracteres acima: | |
| 55 | - </div> | |
| 56 | - <div class="captcha"> | |
| 57 | - <input type="text" name="captcha_text" id="captcha_text" aria-label="Escreva os caracteres do captcha aqui" ng-model="pageAuth.signup.captcha_text" ng-minlength="" ng-maxlength="" required> | |
| 58 | - <validation-messages field="recoverPassForm.captcha_text"></validation-messages> | |
| 59 | - </div> | |
| 51 | + <div | |
| 52 | + vc-recaptcha | |
| 53 | + theme="'light'" | |
| 54 | + key="pageAuth.APP.recaptcha_key" | |
| 55 | + on-create="pageAuth.setWidgetId(widgetId)" | |
| 56 | + on-success="pageAuth.setResponse(response)" | |
| 57 | + on-expire="pageAuth.cbExpiration()" | |
| 58 | + ></div> | |
| 60 | 59 | </div> |
| 61 | 60 | <div class="form-group"> |
| 62 | 61 | <button class="btn btn-lg btn-submit" type="submit">Solicitar alteração de senha</button> | ... | ... |
src/app/pages/auth/resend-confirmation.html
| ... | ... | @@ -60,14 +60,14 @@ |
| 60 | 60 | <validation-messages field=" confirmationForm.login"></validation-messages> |
| 61 | 61 | </div> |
| 62 | 62 | <div class="form-group"> |
| 63 | - <div id="serpro_captcha" class="captcha"></div> | |
| 64 | - <div class="captcha"> | |
| 65 | - Digite os caracteres acima: | |
| 66 | - </div> | |
| 67 | - <div class="captcha"> | |
| 68 | - <input type="text" name="captcha_text" id="captcha_text" aria-label="Escreva os caracteres do captcha aqui" ng-model="pageAuth.signup.captcha_text" ng-minlength="" ng-maxlength="" required> | |
| 69 | - <validation-messages field="confirmationForm.captcha_text"></validation-messages> | |
| 70 | - </div> | |
| 63 | + <div | |
| 64 | + vc-recaptcha | |
| 65 | + theme="'light'" | |
| 66 | + key="pageAuth.APP.recaptcha_key" | |
| 67 | + on-create="pageAuth.setWidgetId(widgetId)" | |
| 68 | + on-success="pageAuth.setResponse(response)" | |
| 69 | + on-expire="pageAuth.cbExpiration()" | |
| 70 | + ></div> | |
| 71 | 71 | </div> |
| 72 | 72 | <div class="form-group"> |
| 73 | 73 | <button class="btn btn-lg btn-submit" type="submit">Solicitar novo e-mail de confirmação</button> | ... | ... |
src/app/pages/auth/signin.html
| ... | ... | @@ -247,15 +247,14 @@ |
| 247 | 247 | <validation-messages field="signupForm.user_terms_accepted"></validation-messages> |
| 248 | 248 | </div> |
| 249 | 249 | <div class="form-group"> |
| 250 | - <div id="serpro_captcha" class="captcha"> | |
| 251 | - </div> | |
| 252 | - <div class="captcha"> | |
| 253 | - Digite os caracteres acima: | |
| 254 | - </div> | |
| 255 | - <div class="captcha"> | |
| 256 | - <input type="text" name="captcha_text" id="captcha_text" aria-label="Escreva os caracteres do captcha aqui" ng-model="pageAuth.signup.captcha_text" ng-minlength="" ng-maxlength="" required> | |
| 257 | - <validation-messages field="signupForm.captcha_text"></validation-messages> | |
| 258 | - </div> | |
| 250 | + <div | |
| 251 | + vc-recaptcha | |
| 252 | + theme="'light'" | |
| 253 | + key="pageAuth.APP.recaptcha_key" | |
| 254 | + on-create="pageAuth.setWidgetId(widgetId)" | |
| 255 | + on-success="pageAuth.setResponse(response)" | |
| 256 | + on-expire="pageAuth.cbExpiration()" | |
| 257 | + ></div> | |
| 259 | 258 | </div> |
| 260 | 259 | <div class="form-group"> |
| 261 | 260 | <button type="submit" class="btn btn-lg btn-block btn-submit" ng-class=" {'disabled' : !pageAuth.signup.user_terms_accepted }">Cadastrar</button> | ... | ... |
src/app/pages/duvidas/duvidas.controller.js
| ... | ... | @@ -6,14 +6,16 @@ |
| 6 | 6 | .controller('DuvidasPageController', DuvidasPageController); |
| 7 | 7 | |
| 8 | 8 | /** @ngInject */ |
| 9 | - function DuvidasPageController(DialogaService, $interval, $window, $log) { | |
| 9 | + function DuvidasPageController(DialogaService, APP, $interval, $window, vcRecaptchaService, $log) { | |
| 10 | 10 | $log.debug('DuvidasPageController'); |
| 11 | 11 | |
| 12 | 12 | var vm = this; |
| 13 | 13 | |
| 14 | 14 | vm.DialogaService = DialogaService; |
| 15 | + vm.APP = APP; | |
| 15 | 16 | vm.$interval = $interval; |
| 16 | 17 | vm.$window = $window; |
| 18 | + vm.vcRecaptchaService = vcRecaptchaService; | |
| 17 | 19 | vm.$log = $log; |
| 18 | 20 | |
| 19 | 21 | vm.init(); |
| ... | ... | @@ -28,6 +30,8 @@ |
| 28 | 30 | vm.error = false; |
| 29 | 31 | vm.sendingContactForm = false; |
| 30 | 32 | vm.questions = []; |
| 33 | + vm.recaptchaResponse = null; | |
| 34 | + vm.recaptchaWidgetId = null; | |
| 31 | 35 | |
| 32 | 36 | }; |
| 33 | 37 | |
| ... | ... | @@ -51,23 +55,27 @@ |
| 51 | 55 | DuvidasPageController.prototype.attachListeners = function () { |
| 52 | 56 | var vm = this; |
| 53 | 57 | |
| 54 | - vm._attachCaptcha(); | |
| 55 | - }; | |
| 56 | - | |
| 57 | - DuvidasPageController.prototype._attachCaptcha = function() { | |
| 58 | - var vm = this; | |
| 59 | - | |
| 60 | - var stop = null; | |
| 61 | - stop = vm.$interval(function(){ | |
| 62 | - var $el = angular.element('#serpro_captcha'); | |
| 58 | + // reCaptcha Listeners | |
| 59 | + vm.setWidgetId = function(widgetId) { | |
| 60 | + // store the `widgetId` for future usage. | |
| 61 | + // For example for getting the response with | |
| 62 | + // `recaptcha.getResponse(widgetId)`. | |
| 63 | + vm.$log.info('Created widget ID:', widgetId); | |
| 64 | + vm.recaptchaWidgetId = widgetId; | |
| 65 | + | |
| 66 | + }; | |
| 63 | 67 | |
| 64 | - if ($el && $el.length > 0 ){ | |
| 65 | - vm.$window.initCaptcha($el[0]); | |
| 66 | - vm.$interval.cancel(stop); | |
| 67 | - stop = undefined; | |
| 68 | - } | |
| 68 | + vm.setResponse = function(response) { | |
| 69 | + | |
| 70 | + // Update local captcha response | |
| 71 | + vm.$log.debug('Response available', response); | |
| 72 | + vm.recaptchaResponse = response; | |
| 73 | + }; | |
| 69 | 74 | |
| 70 | - }, 200); | |
| 75 | + vm.cbExpiration = function() { | |
| 76 | + // reset the 'response' object that is on scope | |
| 77 | + vm.$log.debug('cbExpiration'); | |
| 78 | + }; | |
| 71 | 79 | }; |
| 72 | 80 | |
| 73 | 81 | DuvidasPageController.prototype.submitContactForm = function ($event, contactForm) { |
| ... | ... | @@ -82,11 +90,8 @@ |
| 82 | 90 | subject: contactForm.inputSubject.$modelValue, |
| 83 | 91 | message: contactForm.inputMessage.$modelValue |
| 84 | 92 | }; |
| 85 | - | |
| 86 | - var target = $event.target; | |
| 87 | - var $target = angular.element(target); | |
| 88 | - var $captcha = $target.find('[name="txtToken_captcha_serpro_gov_br"]'); | |
| 89 | - data.txtToken_captcha_serpro_gov_br = $captcha.val(); | |
| 93 | + | |
| 94 | + data.recaptcha_response = vm.recaptchaResponse; | |
| 90 | 95 | |
| 91 | 96 | vm.DialogaService.sendContactForm(data) |
| 92 | 97 | .then(function(response){ | ... | ... |
src/app/pages/duvidas/duvidas.html
| ... | ... | @@ -89,12 +89,14 @@ |
| 89 | 89 | <div class="col-sm-4 form-group pull-right"> |
| 90 | 90 | |
| 91 | 91 | <div class="form-group"> |
| 92 | - <div id="serpro_captcha" class="captcha"></div> | |
| 93 | - <div class="captcha">Digite os caracteres acima:</div> | |
| 94 | - <div class="captcha"> | |
| 95 | - <input type="text" name="captcha_text" id="captcha_text" aria-label="Escreva os caracteres do captcha aqui" ng-model="pageSignin.signup.captcha_text" ng-minlength="" ng-maxlength="" required> | |
| 96 | - <validation-messages field="contactForm.captcha_text"></validation-messages> | |
| 97 | - </div> | |
| 92 | + <div | |
| 93 | + vc-recaptcha | |
| 94 | + theme="'light'" | |
| 95 | + key="pageDuvidas.APP.recaptcha_key" | |
| 96 | + on-create="pageDuvidas.setWidgetId(widgetId)" | |
| 97 | + on-success="pageDuvidas.setResponse(response)" | |
| 98 | + on-expire="pageDuvidas.cbExpiration()" | |
| 99 | + ></div> | |
| 98 | 100 | </div> |
| 99 | 101 | |
| 100 | 102 | <div class="row" ng-show="pageDuvidas.sendingContactForm"> | ... | ... |
src/index.html
| ... | ... | @@ -25,6 +25,9 @@ |
| 25 | 25 | <!-- css files will be automatically insert here --> |
| 26 | 26 | <!-- endinject --> |
| 27 | 27 | <!-- endbuild --> |
| 28 | + | |
| 29 | + <!-- Google reCaptcha --> | |
| 30 | + <script src="https://www.google.com/recaptcha/api.js?onload=vcRecaptchaApiLoaded&render=explicit" async defer></script> | |
| 28 | 31 | </head> |
| 29 | 32 | <body ng-cloak> |
| 30 | 33 | |
| ... | ... | @@ -72,7 +75,6 @@ |
| 72 | 75 | <!-- endinject --> |
| 73 | 76 | <!-- endbuild --> |
| 74 | 77 | <script defer="defer" src="http://barra.brasil.gov.br/barra.js" type="text/javascript"></script> |
| 75 | - <script defer="defer" src="http://captcha2.servicoscorporativos.serpro.gov.br/js/captcha.serpro.gov.br.js"></script> | |
| 76 | 78 | |
| 77 | 79 | <!-- INJECT-GOOGLE-ANALYTICS --> |
| 78 | 80 | </body> | ... | ... |