Commit 4c0183630bda780eb58e93cb1f3a1ec7e9d67dcd

Authored by Leonardo Merlin
1 parent 105102b0

proposal-box: vote with captch (initial commit)

src/app/components/auth/auth.service.js
@@ -53,11 +53,7 @@ @@ -53,11 +53,7 @@
53 } 53 }
54 54
55 function activate (code) { 55 function activate (code) {
56 - var url = '/api/v1/activate';  
57 - // var data = {  
58 - // private_token: API.token,  
59 - // activation_code: code  
60 - // }; 56 + var url = PATH.host + '/api/v1/activate';
61 var encodedData = 'private_token=' + API.token; 57 var encodedData = 'private_token=' + API.token;
62 encodedData += '&activation_code=' + code; 58 encodedData += '&activation_code=' + code;
63 59
@@ -77,12 +73,7 @@ @@ -77,12 +73,7 @@
77 } 73 }
78 74
79 function changePassword (code, newPassword, newPasswordConfirmation){ 75 function changePassword (code, newPassword, newPasswordConfirmation){
80 - var url = '/api/v1/new_password';  
81 - // var data = {  
82 - // code: code,  
83 - // password: newPassword,  
84 - // password_confirmation: newPasswordConfirmation  
85 - // }; 76 + var url = PATH.host + '/api/v1/new_password';
86 var encodedData = 'code=' + code; 77 var encodedData = 'code=' + code;
87 encodedData += '&password=' + newPassword; 78 encodedData += '&password=' + newPassword;
88 encodedData += '&password_confirmation=' + newPasswordConfirmation; 79 encodedData += '&password_confirmation=' + newPasswordConfirmation;
@@ -103,7 +94,7 @@ @@ -103,7 +94,7 @@
103 } 94 }
104 95
105 function forgotPassword (data){ 96 function forgotPassword (data){
106 - var url = 'http://hom.login.dialoga.gov.br/api/v1/forgot_password'; 97 + var url = PATH.host + '/api/v1/forgot_password';
107 var encodedData = ([ 98 var encodedData = ([
108 'value=' + data.login, 99 'value=' + data.login,
109 'captcha_text=' + data.captcha_text, 100 'captcha_text=' + data.captcha_text,
@@ -129,8 +120,7 @@ @@ -129,8 +120,7 @@
129 } 120 }
130 121
131 function login (credentials) { 122 function login (credentials) {
132 - var hostProd = 'http://login.dialoga.gov.br';  
133 - var url = hostProd + '/api/v1/login'; 123 + var url = PATH.host + '/api/v1/login';
134 var encodedData = 'login=' + credentials.username + '&password=' + credentials.password; 124 var encodedData = 'login=' + credentials.username + '&password=' + credentials.password;
135 125
136 return $http 126 return $http
@@ -149,6 +139,13 @@ @@ -149,6 +139,13 @@
149 }); 139 });
150 } 140 }
151 141
  142 + function loginCaptcha (data) {
  143 + var url = PATH.host + '/api/v1/login-captcha';
  144 + var encodedData = angular.element.param(data);
  145 +
  146 + return $http.post(url, encodedData);
  147 + }
  148 +
152 function logout () { 149 function logout () {
153 150
154 Session.destroy(); 151 Session.destroy();
@@ -190,6 +187,7 @@ @@ -190,6 +187,7 @@
190 changePassword: changePassword, 187 changePassword: changePassword,
191 forgotPassword: forgotPassword, 188 forgotPassword: forgotPassword,
192 login: login, 189 login: login,
  190 + loginCaptcha: loginCaptcha,
193 logout: logout, 191 logout: logout,
194 isAuthenticated: isAuthenticated, 192 isAuthenticated: isAuthenticated,
195 isAuthorized: isAuthorized 193 isAuthorized: isAuthorized
src/app/components/proposal-box/proposal-box.directive.js
@@ -9,15 +9,19 @@ @@ -9,15 +9,19 @@
9 function proposalBox() { 9 function proposalBox() {
10 10
11 /** @ngInject */ 11 /** @ngInject */
12 - function ProposalBoxController($scope, $rootScope, $state, VOTE_STATUS, VOTE_OPTIONS, $log) { 12 + function ProposalBoxController($scope, $rootScope, $state, $timeout, $interval, $window, VOTE_STATUS, VOTE_OPTIONS, AuthService, $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.$rootScope = $rootScope; 17 vm.$rootScope = $rootScope;
18 vm.$state = $state; 18 vm.$state = $state;
  19 + vm.$timeout = $timeout;
  20 + vm.$interval = $interval;
  21 + vm.$window = $window;
19 vm.VOTE_STATUS = VOTE_STATUS; 22 vm.VOTE_STATUS = VOTE_STATUS;
20 vm.VOTE_OPTIONS = VOTE_OPTIONS; 23 vm.VOTE_OPTIONS = VOTE_OPTIONS;
  24 + vm.AuthService = AuthService;
21 vm.$log = $log; 25 vm.$log = $log;
22 26
23 vm.init(); 27 vm.init();
@@ -28,11 +32,11 @@ @@ -28,11 +32,11 @@
28 32
29 var vm = this; 33 var vm = this;
30 34
31 - vm.canVote = vm.canVote || false; 35 + vm.showVote = vm.showVote || false;
32 vm.focus = vm.focus || false; 36 vm.focus = vm.focus || false;
33 vm.STATE = null; 37 vm.STATE = null;
34 vm.errorOnSkip = false; 38 vm.errorOnSkip = false;
35 - vm.showAuthMessage = null; 39 + vm.showCaptchaForm = null;
36 vm.voteProposalRedirectURI = null; 40 vm.voteProposalRedirectURI = null;
37 41
38 var slug = vm.topic.slug; 42 var slug = vm.topic.slug;
@@ -68,6 +72,21 @@ @@ -68,6 +72,21 @@
68 72
69 vm.message = data.message; 73 vm.message = data.message;
70 }); 74 });
  75 +
  76 + // Load captcha
  77 + var stop = null;
  78 + stop = vm.$interval(function(){
  79 + var $el = angular.element('#serpro_captcha');
  80 +
  81 + if ($el && $el.length > 0 ){
  82 + vm.$window.initCaptcha($el[0]);
  83 + vm.$interval.cancel(stop);
  84 + stop = undefined;
  85 + }else{
  86 + vm.$log.debug('captcha element not found.');
  87 + }
  88 +
  89 + }, 10);
71 }; 90 };
72 91
73 ProposalBoxController.prototype.showContent = function (slug) { 92 ProposalBoxController.prototype.showContent = function (slug) {
@@ -81,18 +100,56 @@ @@ -81,18 +100,56 @@
81 }); 100 });
82 }; 101 };
83 102
  103 + ProposalBoxController.prototype.canVote = function () {
  104 + return false;
  105 + };
  106 +
  107 + ProposalBoxController.prototype.submitCaptcha = function ($event, captchaForm) {
  108 + var vm = this;
  109 +
  110 + var target = $event.target;
  111 + var $target = angular.element(target);
  112 + var $captcha = $target.find('[name="txtToken_captcha_serpro_gov_br"]');
  113 +
  114 + vm.sendingCaptcha = true;
  115 + vm.AuthService.loginCaptcha({
  116 + captcha_text: captchaForm.captcha_text.$modelValue,
  117 + txtToken_captcha_serpro_gov_br: $captcha.val()
  118 + }).then(function(data) {
  119 + // SUCCESS
  120 + vm.$log.debug('register success.data', data);
  121 +
  122 + // get captcha_token
  123 + }, function(data) {
  124 + // ERROR
  125 + vm.$log.debug('register error.data', data);
  126 +
  127 + vm.sendingCaptchaError = {code: data.status };
  128 +
  129 + if(data.status === 404){
  130 + vm.$log.error('The api service is out!?');
  131 + }
  132 +
  133 + }, function(data){
  134 + // UPDATE
  135 + vm.$log.debug('register update.data', data);
  136 + }).finally(function(){
  137 + vm.sendingCaptcha = false;
  138 + });
  139 + };
  140 +
84 ProposalBoxController.prototype.vote = function (value) { 141 ProposalBoxController.prototype.vote = function (value) {
85 var vm = this; 142 var vm = this;
86 143
87 - if(vm.$rootScope.currentUser){ 144 + if(vm.canVote()){
88 vm.$scope.$emit('proposal-box:vote', { 145 vm.$scope.$emit('proposal-box:vote', {
89 OPTION: value, 146 OPTION: value,
90 proposal_id: vm.proposal.id 147 proposal_id: vm.proposal.id
91 }); 148 });
92 vm.$log.debug('Sending vote', value); 149 vm.$log.debug('Sending vote', value);
93 }else{ 150 }else{
94 - vm.$log.info('Must be logged in...');  
95 - vm.showAuthMessage = true; 151 + vm.$log.debug('You cannot vote.');
  152 + vm.showCaptchaForm = true;
96 } 153 }
97 }; 154 };
98 155
@@ -135,7 +192,7 @@ @@ -135,7 +192,7 @@
135 proposal: '=', 192 proposal: '=',
136 topic: '=', 193 topic: '=',
137 category: '=', 194 category: '=',
138 - canVote: '=', 195 + showVote: '=',
139 focus: '@' 196 focus: '@'
140 // @ -> Text binding / one-way binding 197 // @ -> Text binding / one-way binding
141 // = -> Direct model binding / two-way binding 198 // = -> Direct model binding / two-way binding
src/app/components/proposal-box/proposal-box.html
@@ -65,18 +65,48 @@ @@ -65,18 +65,48 @@
65 </div> 65 </div>
66 </div> 66 </div>
67 </div> 67 </div>
68 - <div ng-show="vm.showAuthMessage"> 68 + <div ng-show="vm.showCaptchaForm">
69 <div class="proposal-message-panel"> 69 <div class="proposal-message-panel">
70 <div class="row"> 70 <div class="row">
71 <div class="row-height"> 71 <div class="row-height">
72 <div class="col-sm-12 col-height col-middle"> 72 <div class="col-sm-12 col-height col-middle">
73 <div class="inside inside-full-height"> 73 <div class="inside inside-full-height">
74 <div class="content text-center"> 74 <div class="content text-center">
75 - <p>Você precisa estar logado para votar na proposta</p>  
76 - <br>  
77 - <p>  
78 - <a ui-sref="entrar({redirect_uri: vm.voteProposalRedirectURI})">Clique aqui para ir para a página de login</a>  
79 - </p> 75 + <div ng-if="vm.sendingCaptcha">
  76 + <p>Enviando captcha...</p>
  77 + </div>
  78 + <div ng-if="!vm.sendingCaptcha">
  79 +
  80 + <div class="row" class="feedback-message" ng-if="vm.sendingCaptchaError">
  81 + <div class="col-sm-12">
  82 + <div class="feedback--title alert alert-danger">Erro!</div>
  83 + <div class="feedback--message" ng-if="vm.sendingCaptchaError.code === 404">
  84 + <p>
  85 + Houve uma falha. Já estamos trabalhando para resolver o problema.
  86 + <br/> Por favor, tente novamente mais tarde
  87 + </p>
  88 + </div>
  89 + </div>
  90 + </div>
  91 + <div ng-if="!vm.sendingCaptchaError">
  92 + <form name="captchaForm" ng-submit="vm.submitCaptcha($event, captchaForm)">
  93 + <div class="form-group">
  94 + <div id="serpro_captcha" class="captcha"></div>
  95 + <div class="captcha">Digite os caracteres acima:</div>
  96 + <div class="captcha">
  97 + <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>
  98 + <validation-messages field="captchaForm.captcha_text"></validation-messages>
  99 + </div>
  100 + </div>
  101 + <div class="form-group">
  102 + <button type="submit" class="btn btn-lg btn-block btn-submit">Enviar</button>
  103 + </div>
  104 + <div class="form-group">
  105 + <button class="btn btn-link" ng-click="vm.showCaptchaForm = false">Voltar</button>
  106 + </div>
  107 + </form>
  108 + </div>
  109 + </div>
80 </div> 110 </div>
81 </div> 111 </div>
82 </div> 112 </div>
@@ -112,12 +142,12 @@ @@ -112,12 +142,12 @@
112 <div class="proposal-box--content"> 142 <div class="proposal-box--content">
113 <div class="proposal-box--content-inner">{{vm.proposal.abstract}}</div> 143 <div class="proposal-box--content-inner">{{vm.proposal.abstract}}</div>
114 </div> 144 </div>
115 - <div ng-hide="vm.canVote" class="proposal-box--join"> 145 + <div ng-hide="vm.showVote" class="proposal-box--join">
116 <button class="btn btn-link color-theme-common-fg" ng-click="vm.showContent(vm.topic.slug)"> 146 <button class="btn btn-link color-theme-common-fg" ng-click="vm.showContent(vm.topic.slug)">
117 Participe 147 Participe
118 </button> 148 </button>
119 </div> 149 </div>
120 - <div ng-show="vm.canVote" class="proposal-box--actions text-center"> 150 + <div ng-show="vm.showVote" class="proposal-box--actions text-center">
121 <div class="row"> 151 <div class="row">
122 <div class="col-xs-4"> 152 <div class="col-xs-4">
123 <div class="action vote_for" ng-click="vm.vote(vm.VOTE_OPTIONS.UP)"> 153 <div class="action vote_for" ng-click="vm.vote(vm.VOTE_OPTIONS.UP)">
src/app/components/proposal-box/proposal-box.scss
@@ -91,9 +91,15 @@ @@ -91,9 +91,15 @@
91 .content { 91 .content {
92 color: #262626; 92 color: #262626;
93 font-size: 24px; 93 font-size: 24px;
  94 + font-size: 2.4rem;
94 font-weight: bold; 95 font-weight: bold;
95 line-height: 24px; 96 line-height: 24px;
96 padding: 10px 30px; 97 padding: 10px 30px;
  98 +
  99 + form {
  100 + font-size: 18px;
  101 + font-size: 1.8rem;
  102 + }
97 } 103 }
98 104
99 .message-icon { 105 .message-icon {
@@ -108,11 +114,13 @@ @@ -108,11 +114,13 @@
108 114
109 &--title { 115 &--title {
110 font-size: 22px; 116 font-size: 22px;
  117 + font-size: 2.2rem;
111 font-weight: bold; 118 font-weight: bold;
112 } 119 }
113 120
114 &--message { 121 &--message {
115 font-size: 14px; 122 font-size: 14px;
  123 + font-size: 1.4rem;
116 font-weight: normal; 124 font-weight: normal;
117 line-height: 20px; 125 line-height: 20px;
118 margin-top: 48px; 126 margin-top: 48px;
src/app/components/proposal-grid/proposal-grid.html
1 <div class="proposal-grid row"> 1 <div class="proposal-grid row">
2 <div ng-repeat="proposal in vm.proposals as results"> 2 <div ng-repeat="proposal in vm.proposals as results">
3 - <proposal-box proposal="proposal" topic="proposal.parent" category="proposal.parent.categories[0]" class="col-xs-12 col-sm-6"></proposal-box> 3 + <proposal-box proposal="proposal" topic="proposal.parent" category="proposal.parent.categories[0]" show-vote="false" class="col-xs-12 col-sm-6"></proposal-box>
4 <div ng-if="$odd" class="clearfix"></div> 4 <div ng-if="$odd" class="clearfix"></div>
5 </div> 5 </div>
6 <div class="animate-repeat" ng-if="results.length == 0"> 6 <div class="animate-repeat" ng-if="results.length == 0">