Commit ada226844f4e879c74dab102e16ccee63d3f4bbc

Authored by Leonardo Merlin
Committed by Evandro Junior
1 parent 1bd18994

Add reCaptcha (issue #56)

@@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
7 "angular-breadcrumb": "~0.4.1", 7 "angular-breadcrumb": "~0.4.1",
8 "angular-cookies": "~1.4.0", 8 "angular-cookies": "~1.4.0",
9 "angular-messages": "ng-messages#*", 9 "angular-messages": "ng-messages#*",
  10 + "angular-recaptcha": "~2.2.5",
10 "angular-sanitize": "~1.4.0", 11 "angular-sanitize": "~1.4.0",
11 "angular-slugify": "~1.0.1", 12 "angular-slugify": "~1.0.1",
12 "angular-socialshare": "angularjs-socialshare#~0.1.13", 13 "angular-socialshare": "angularjs-socialshare#~0.1.13",
src/app/components/proposal-box/proposal-box.directive.js
@@ -9,21 +9,23 @@ @@ -9,21 +9,23 @@
9 function proposalBox() { 9 function proposalBox() {
10 10
11 /** @ngInject */ 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 $log.debug('ProposalBoxController'); 13 $log.debug('ProposalBoxController');
14 14
15 var vm = this; 15 var vm = this;
16 vm.$scope = $scope; 16 vm.$scope = $scope;
  17 + vm.$location = $location;
17 vm.$rootScope = $rootScope; 18 vm.$rootScope = $rootScope;
18 vm.$state = $state; 19 vm.$state = $state;
19 vm.$timeout = $timeout; 20 vm.$timeout = $timeout;
20 vm.$interval = $interval; 21 vm.$interval = $interval;
21 vm.$window = $window; 22 vm.$window = $window;
  23 + vm.APP = APP;
22 vm.VOTE_STATUS = VOTE_STATUS; 24 vm.VOTE_STATUS = VOTE_STATUS;
23 vm.VOTE_OPTIONS = VOTE_OPTIONS; 25 vm.VOTE_OPTIONS = VOTE_OPTIONS;
24 vm.AuthService = AuthService; 26 vm.AuthService = AuthService;
  27 + vm.vcRecaptchaService = vcRecaptchaService;
25 vm.$log = $log; 28 vm.$log = $log;
26 - vm.$location = $location;  
27 29
28 vm.init(); 30 vm.init();
29 vm.addListeners(); 31 vm.addListeners();
@@ -39,6 +41,8 @@ @@ -39,6 +41,8 @@
39 vm.STATE = null; 41 vm.STATE = null;
40 vm.errorOnSkip = false; 42 vm.errorOnSkip = false;
41 vm.showCaptchaForm = null; 43 vm.showCaptchaForm = null;
  44 + vm.recaptchaWidgetId = null;
  45 + vm.recaptchaResponse = null;
42 vm.voteProposalRedirectURI = null; 46 vm.voteProposalRedirectURI = null;
43 vm.proposalsImg = null; 47 vm.proposalsImg = null;
44 48
@@ -86,20 +90,27 @@ @@ -86,20 +90,27 @@
86 vm.messageCode = data.code; 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 ProposalBoxController.prototype.canVote = function() { 116 ProposalBoxController.prototype.canVote = function() {
@@ -113,12 +124,10 @@ @@ -113,12 +124,10 @@
113 124
114 var target = $event.target; 125 var target = $event.target;
115 var $target = angular.element(target); 126 var $target = angular.element(target);
116 - var $captcha = $target.find('[name="txtToken_captcha_serpro_gov_br"]');  
117 127
118 vm.sendingCaptcha = true; 128 vm.sendingCaptcha = true;
119 vm.AuthService.loginCaptcha({ 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 }).then(function(data) { 131 }).then(function(data) {
123 // SUCCESS 132 // SUCCESS
124 vm.$log.debug('register success.data', data); 133 vm.$log.debug('register success.data', data);
@@ -131,22 +140,23 @@ @@ -131,22 +140,23 @@
131 // hide captcha form 140 // hide captcha form
132 vm.showCaptchaForm = false; 141 vm.showCaptchaForm = false;
133 142
134 - }, function(data) { 143 + })
  144 + .catch(function(data) {
135 // ERROR 145 // ERROR
136 vm.$log.debug('register error.data', data); 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 if (angular.equals(vm.sendingCaptchaError.message, 'Internal captcha validation error')) { 156 if (angular.equals(vm.sendingCaptchaError.message, 'Internal captcha validation error')) {
144 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.'; 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 }).finally(function() { 160 }).finally(function() {
151 vm.sendingCaptcha = false; 161 vm.sendingCaptcha = false;
152 }); 162 });
@@ -161,11 +171,10 @@ @@ -161,11 +171,10 @@
161 vm.message = null; 171 vm.message = null;
162 172
163 // reload new captcha 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 // focus on input 176 // focus on input
168 - angular.element('#captcha_text').val('').focus(); 177 + // angular.element('#captcha_text').val('').focus();
169 }; 178 };
170 179
171 ProposalBoxController.prototype.vote = function(value) { 180 ProposalBoxController.prototype.vote = function(value) {
src/app/components/proposal-box/proposal-box.html
@@ -93,12 +93,14 @@ @@ -93,12 +93,14 @@
93 <div ng-hide="vm.sendingCaptchaError"> 93 <div ng-hide="vm.sendingCaptchaError">
94 <form name="captchaForm" ng-submit="vm.submitCaptcha($event, captchaForm)"> 94 <form name="captchaForm" ng-submit="vm.submitCaptcha($event, captchaForm)">
95 <div class="form-group"> 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 </div> 104 </div>
103 <div class="form-group"> 105 <div class="form-group">
104 <button type="submit" class="btn btn-lg btn-block btn-submit">Enviar</button> 106 <button type="submit" class="btn btn-lg btn-block btn-submit">Enviar</button>
src/app/index.constants.js
@@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
11 .constant('APP', { 11 .constant('APP', {
12 facebook_app_id: '1', 12 facebook_app_id: '1',
13 google_app_id: '4', 13 google_app_id: '4',
  14 + recaptcha_key: '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI',
14 }) 15 })
15 .constant('API', { 16 .constant('API', {
16 token: null, 17 token: null,
src/app/index.module.js
@@ -2,6 +2,6 @@ @@ -2,6 +2,6 @@
2 'use strict'; 2 'use strict';
3 3
4 angular 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,7 +6,7 @@
6 .controller('AuthPageController', AuthPageController); 6 .controller('AuthPageController', AuthPageController);
7 7
8 /** @ngInject */ 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 var vm = this; 10 var vm = this;
11 11
12 vm.$scope = $scope; 12 vm.$scope = $scope;
@@ -21,6 +21,7 @@ @@ -21,6 +21,7 @@
21 vm.AuthService = AuthService; 21 vm.AuthService = AuthService;
22 vm.DialogaService = DialogaService; 22 vm.DialogaService = DialogaService;
23 vm.Session = Session; 23 vm.Session = Session;
  24 + vm.vcRecaptchaService = vcRecaptchaService;
24 vm.$log = $log; 25 vm.$log = $log;
25 26
26 vm.init(); 27 vm.init();
@@ -42,6 +43,8 @@ @@ -42,6 +43,8 @@
42 vm.loadingTerms = null; 43 vm.loadingTerms = null;
43 vm.delay = 3; // segundos 44 vm.delay = 3; // segundos
44 vm.countdown = 0; 45 vm.countdown = 0;
  46 + vm.recaptchaResponse = null;
  47 + vm.recaptchaWidgetId = null;
45 48
46 vm.search = vm.$location.search(); 49 vm.search = vm.$location.search();
47 var redirect = vm.search.redirect_uri || ''; 50 var redirect = vm.search.redirect_uri || '';
@@ -62,7 +65,6 @@ @@ -62,7 +65,6 @@
62 vm.$scope.$on(vm.AUTH_EVENTS.logoutSuccess, function() { 65 vm.$scope.$on(vm.AUTH_EVENTS.logoutSuccess, function() {
63 vm.clearMessages(); 66 vm.clearMessages();
64 vm.currentUser = vm.Session.getCurrentUser(); 67 vm.currentUser = vm.Session.getCurrentUser();
65 - vm._attachCaptcha();  
66 }); 68 });
67 }; 69 };
68 70
@@ -104,7 +106,7 @@ @@ -104,7 +106,7 @@
104 var private_token = response.data.private_token; 106 var private_token = response.data.private_token;
105 107
106 // Garante que o 'user' sempre terá a propriedade 'private_token' 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 response.data.user.private_token = private_token; 110 response.data.user.private_token = private_token;
109 } 111 }
110 112
@@ -117,23 +119,27 @@ @@ -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 AuthPageController.prototype.onClickLogout = function() { 145 AuthPageController.prototype.onClickLogout = function() {
@@ -145,8 +151,8 @@ @@ -145,8 +151,8 @@
145 AuthPageController.prototype.submitSignup = function($event, credentials) { 151 AuthPageController.prototype.submitSignup = function($event, credentials) {
146 var vm = this; 152 var vm = this;
147 153
148 - credentials.txtToken_captcha_serpro_gov_br = getCaptchaValFromEvent($event);  
149 - 154 + credentials.recaptcha_response = vm.recaptchaResponse;
  155 +
150 vm.AuthService.register(credentials) 156 vm.AuthService.register(credentials)
151 .then(function(/*response*/) { 157 .then(function(/*response*/) {
152 // SUCCESS 158 // SUCCESS
@@ -154,14 +160,12 @@ @@ -154,14 +160,12 @@
154 vm.signupSuccess = true; 160 vm.signupSuccess = true;
155 // vm._startRedirect(); 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 vm.signupError = true; 170 vm.signupError = true;
167 vm.signupErrorTitle = 'Erro!'; 171 vm.signupErrorTitle = 'Erro!';
@@ -179,6 +183,9 @@ @@ -179,6 +183,9 @@
179 if (response.status >= 500 && response.status < 600) { 183 if (response.status >= 500 && response.status < 600) {
180 vm.internalError = true; 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,8 +227,7 @@
220 // get form data 227 // get form data
221 var data = { 228 var data = {
222 login: recoverForm.login.$modelValue, 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 var promiseRequest = vm.AuthService.forgotPassword(data); 233 var promiseRequest = vm.AuthService.forgotPassword(data);
@@ -265,12 +271,10 @@ @@ -265,12 +271,10 @@
265 // get form data 271 // get form data
266 var data = { 272 var data = {
267 login: confirmationForm.login.$modelValue, 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 // get captcha token 277 // get captcha token
273 -  
274 vm.AuthService.resendConfirmation(data) 278 vm.AuthService.resendConfirmation(data)
275 .then(function(response) { 279 .then(function(response) {
276 vm.$log.debug('resendConfirmation success.response', response); 280 vm.$log.debug('resendConfirmation success.response', response);
@@ -287,7 +291,8 @@ @@ -287,7 +291,8 @@
287 vm.resendConfirmationSuccessMessage = 'Em instantes você receberá em seu e-mail um link para confirmar o seu cadastro.'; 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 vm.$log.debug('resendConfirmation error.response', response); 296 vm.$log.debug('resendConfirmation error.response', response);
292 297
293 vm.resendConfirmationError = true; 298 vm.resendConfirmationError = true;
@@ -300,8 +305,9 @@ @@ -300,8 +305,9 @@
300 if (response.status >= 500 && response.status < 600) { 305 if (response.status >= 500 && response.status < 600) {
301 vm.internalError = true; 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,8 +388,4 @@
382 var url = 'http://login.dialoga.gov.br/plugin/oauth_client/google_oauth2?oauth_client_popup=true&id=' + vm.APP.google_app_id; 388 var url = 'http://login.dialoga.gov.br/plugin/oauth_client/google_oauth2?oauth_client_popup=true&id=' + vm.APP.google_app_id;
383 vm.$window.oauthClientAction(url); 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,15 +48,14 @@
48 <validation-messages field=" recoverPassForm.login"></validation-messages> 48 <validation-messages field=" recoverPassForm.login"></validation-messages>
49 </div> 49 </div>
50 <div class="form-group"> 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 </div> 59 </div>
61 <div class="form-group"> 60 <div class="form-group">
62 <button class="btn btn-lg btn-submit" type="submit">Solicitar alteração de senha</button> 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,14 +60,14 @@
60 <validation-messages field=" confirmationForm.login"></validation-messages> 60 <validation-messages field=" confirmationForm.login"></validation-messages>
61 </div> 61 </div>
62 <div class="form-group"> 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 </div> 71 </div>
72 <div class="form-group"> 72 <div class="form-group">
73 <button class="btn btn-lg btn-submit" type="submit">Solicitar novo e-mail de confirmação</button> 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,15 +247,14 @@
247 <validation-messages field="signupForm.user_terms_accepted"></validation-messages> 247 <validation-messages field="signupForm.user_terms_accepted"></validation-messages>
248 </div> 248 </div>
249 <div class="form-group"> 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 </div> 258 </div>
260 <div class="form-group"> 259 <div class="form-group">
261 <button type="submit" class="btn btn-lg btn-block btn-submit" ng-class=" {'disabled' : !pageAuth.signup.user_terms_accepted }">Cadastrar</button> 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,14 +6,16 @@
6 .controller('DuvidasPageController', DuvidasPageController); 6 .controller('DuvidasPageController', DuvidasPageController);
7 7
8 /** @ngInject */ 8 /** @ngInject */
9 - function DuvidasPageController(DialogaService, $interval, $window, $log) { 9 + function DuvidasPageController(DialogaService, APP, $interval, $window, vcRecaptchaService, $log) {
10 $log.debug('DuvidasPageController'); 10 $log.debug('DuvidasPageController');
11 11
12 var vm = this; 12 var vm = this;
13 13
14 vm.DialogaService = DialogaService; 14 vm.DialogaService = DialogaService;
  15 + vm.APP = APP;
15 vm.$interval = $interval; 16 vm.$interval = $interval;
16 vm.$window = $window; 17 vm.$window = $window;
  18 + vm.vcRecaptchaService = vcRecaptchaService;
17 vm.$log = $log; 19 vm.$log = $log;
18 20
19 vm.init(); 21 vm.init();
@@ -28,6 +30,8 @@ @@ -28,6 +30,8 @@
28 vm.error = false; 30 vm.error = false;
29 vm.sendingContactForm = false; 31 vm.sendingContactForm = false;
30 vm.questions = []; 32 vm.questions = [];
  33 + vm.recaptchaResponse = null;
  34 + vm.recaptchaWidgetId = null;
31 35
32 }; 36 };
33 37
@@ -51,23 +55,27 @@ @@ -51,23 +55,27 @@
51 DuvidasPageController.prototype.attachListeners = function () { 55 DuvidasPageController.prototype.attachListeners = function () {
52 var vm = this; 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 DuvidasPageController.prototype.submitContactForm = function ($event, contactForm) { 81 DuvidasPageController.prototype.submitContactForm = function ($event, contactForm) {
@@ -82,11 +90,8 @@ @@ -82,11 +90,8 @@
82 subject: contactForm.inputSubject.$modelValue, 90 subject: contactForm.inputSubject.$modelValue,
83 message: contactForm.inputMessage.$modelValue 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 vm.DialogaService.sendContactForm(data) 96 vm.DialogaService.sendContactForm(data)
92 .then(function(response){ 97 .then(function(response){
src/app/pages/duvidas/duvidas.html
@@ -89,12 +89,14 @@ @@ -89,12 +89,14 @@
89 <div class="col-sm-4 form-group pull-right"> 89 <div class="col-sm-4 form-group pull-right">
90 90
91 <div class="form-group"> 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 </div> 100 </div>
99 101
100 <div class="row" ng-show="pageDuvidas.sendingContactForm"> 102 <div class="row" ng-show="pageDuvidas.sendingContactForm">
src/index.html
@@ -25,6 +25,9 @@ @@ -25,6 +25,9 @@
25 <!-- css files will be automatically insert here --> 25 <!-- css files will be automatically insert here -->
26 <!-- endinject --> 26 <!-- endinject -->
27 <!-- endbuild --> 27 <!-- endbuild -->
  28 +
  29 + <!-- Google reCaptcha -->
  30 + <script src="https://www.google.com/recaptcha/api.js?onload=vcRecaptchaApiLoaded&render=explicit" async defer></script>
28 </head> 31 </head>
29 <body ng-cloak> 32 <body ng-cloak>
30 33
@@ -72,7 +75,6 @@ @@ -72,7 +75,6 @@
72 <!-- endinject --> 75 <!-- endinject -->
73 <!-- endbuild --> 76 <!-- endbuild -->
74 <script defer="defer" src="http://barra.brasil.gov.br/barra.js" type="text/javascript"></script> 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 <!-- INJECT-GOOGLE-ANALYTICS --> 79 <!-- INJECT-GOOGLE-ANALYTICS -->
78 </body> 80 </body>