Commit 4c0183630bda780eb58e93cb1f3a1ec7e9d67dcd
1 parent
105102b0
Exists in
master
and in
8 other branches
proposal-box: vote with captch (initial commit)
Showing
5 changed files
with
123 additions
and
30 deletions
Show diff stats
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"> |