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 | 53 | } |
| 54 | 54 | |
| 55 | 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 | 57 | var encodedData = 'private_token=' + API.token; |
| 62 | 58 | encodedData += '&activation_code=' + code; |
| 63 | 59 | |
| ... | ... | @@ -77,12 +73,7 @@ |
| 77 | 73 | } |
| 78 | 74 | |
| 79 | 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 | 77 | var encodedData = 'code=' + code; |
| 87 | 78 | encodedData += '&password=' + newPassword; |
| 88 | 79 | encodedData += '&password_confirmation=' + newPasswordConfirmation; |
| ... | ... | @@ -103,7 +94,7 @@ |
| 103 | 94 | } |
| 104 | 95 | |
| 105 | 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 | 98 | var encodedData = ([ |
| 108 | 99 | 'value=' + data.login, |
| 109 | 100 | 'captcha_text=' + data.captcha_text, |
| ... | ... | @@ -129,8 +120,7 @@ |
| 129 | 120 | } |
| 130 | 121 | |
| 131 | 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 | 124 | var encodedData = 'login=' + credentials.username + '&password=' + credentials.password; |
| 135 | 125 | |
| 136 | 126 | return $http |
| ... | ... | @@ -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 | 149 | function logout () { |
| 153 | 150 | |
| 154 | 151 | Session.destroy(); |
| ... | ... | @@ -190,6 +187,7 @@ |
| 190 | 187 | changePassword: changePassword, |
| 191 | 188 | forgotPassword: forgotPassword, |
| 192 | 189 | login: login, |
| 190 | + loginCaptcha: loginCaptcha, | |
| 193 | 191 | logout: logout, |
| 194 | 192 | isAuthenticated: isAuthenticated, |
| 195 | 193 | isAuthorized: isAuthorized | ... | ... |
src/app/components/proposal-box/proposal-box.directive.js
| ... | ... | @@ -9,15 +9,19 @@ |
| 9 | 9 | function proposalBox() { |
| 10 | 10 | |
| 11 | 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 | 13 | $log.debug('ProposalBoxController'); |
| 14 | 14 | |
| 15 | 15 | var vm = this; |
| 16 | 16 | vm.$scope = $scope; |
| 17 | 17 | vm.$rootScope = $rootScope; |
| 18 | 18 | vm.$state = $state; |
| 19 | + vm.$timeout = $timeout; | |
| 20 | + vm.$interval = $interval; | |
| 21 | + vm.$window = $window; | |
| 19 | 22 | vm.VOTE_STATUS = VOTE_STATUS; |
| 20 | 23 | vm.VOTE_OPTIONS = VOTE_OPTIONS; |
| 24 | + vm.AuthService = AuthService; | |
| 21 | 25 | vm.$log = $log; |
| 22 | 26 | |
| 23 | 27 | vm.init(); |
| ... | ... | @@ -28,11 +32,11 @@ |
| 28 | 32 | |
| 29 | 33 | var vm = this; |
| 30 | 34 | |
| 31 | - vm.canVote = vm.canVote || false; | |
| 35 | + vm.showVote = vm.showVote || false; | |
| 32 | 36 | vm.focus = vm.focus || false; |
| 33 | 37 | vm.STATE = null; |
| 34 | 38 | vm.errorOnSkip = false; |
| 35 | - vm.showAuthMessage = null; | |
| 39 | + vm.showCaptchaForm = null; | |
| 36 | 40 | vm.voteProposalRedirectURI = null; |
| 37 | 41 | |
| 38 | 42 | var slug = vm.topic.slug; |
| ... | ... | @@ -68,6 +72,21 @@ |
| 68 | 72 | |
| 69 | 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 | 92 | ProposalBoxController.prototype.showContent = function (slug) { |
| ... | ... | @@ -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 | 141 | ProposalBoxController.prototype.vote = function (value) { |
| 85 | 142 | var vm = this; |
| 86 | 143 | |
| 87 | - if(vm.$rootScope.currentUser){ | |
| 144 | + if(vm.canVote()){ | |
| 88 | 145 | vm.$scope.$emit('proposal-box:vote', { |
| 89 | 146 | OPTION: value, |
| 90 | 147 | proposal_id: vm.proposal.id |
| 91 | 148 | }); |
| 92 | 149 | vm.$log.debug('Sending vote', value); |
| 93 | 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 | 192 | proposal: '=', |
| 136 | 193 | topic: '=', |
| 137 | 194 | category: '=', |
| 138 | - canVote: '=', | |
| 195 | + showVote: '=', | |
| 139 | 196 | focus: '@' |
| 140 | 197 | // @ -> Text binding / one-way binding |
| 141 | 198 | // = -> Direct model binding / two-way binding | ... | ... |
src/app/components/proposal-box/proposal-box.html
| ... | ... | @@ -65,18 +65,48 @@ |
| 65 | 65 | </div> |
| 66 | 66 | </div> |
| 67 | 67 | </div> |
| 68 | - <div ng-show="vm.showAuthMessage"> | |
| 68 | + <div ng-show="vm.showCaptchaForm"> | |
| 69 | 69 | <div class="proposal-message-panel"> |
| 70 | 70 | <div class="row"> |
| 71 | 71 | <div class="row-height"> |
| 72 | 72 | <div class="col-sm-12 col-height col-middle"> |
| 73 | 73 | <div class="inside inside-full-height"> |
| 74 | 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 | 110 | </div> |
| 81 | 111 | </div> |
| 82 | 112 | </div> |
| ... | ... | @@ -112,12 +142,12 @@ |
| 112 | 142 | <div class="proposal-box--content"> |
| 113 | 143 | <div class="proposal-box--content-inner">{{vm.proposal.abstract}}</div> |
| 114 | 144 | </div> |
| 115 | - <div ng-hide="vm.canVote" class="proposal-box--join"> | |
| 145 | + <div ng-hide="vm.showVote" class="proposal-box--join"> | |
| 116 | 146 | <button class="btn btn-link color-theme-common-fg" ng-click="vm.showContent(vm.topic.slug)"> |
| 117 | 147 | Participe |
| 118 | 148 | </button> |
| 119 | 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 | 151 | <div class="row"> |
| 122 | 152 | <div class="col-xs-4"> |
| 123 | 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 | 91 | .content { |
| 92 | 92 | color: #262626; |
| 93 | 93 | font-size: 24px; |
| 94 | + font-size: 2.4rem; | |
| 94 | 95 | font-weight: bold; |
| 95 | 96 | line-height: 24px; |
| 96 | 97 | padding: 10px 30px; |
| 98 | + | |
| 99 | + form { | |
| 100 | + font-size: 18px; | |
| 101 | + font-size: 1.8rem; | |
| 102 | + } | |
| 97 | 103 | } |
| 98 | 104 | |
| 99 | 105 | .message-icon { |
| ... | ... | @@ -108,11 +114,13 @@ |
| 108 | 114 | |
| 109 | 115 | &--title { |
| 110 | 116 | font-size: 22px; |
| 117 | + font-size: 2.2rem; | |
| 111 | 118 | font-weight: bold; |
| 112 | 119 | } |
| 113 | 120 | |
| 114 | 121 | &--message { |
| 115 | 122 | font-size: 14px; |
| 123 | + font-size: 1.4rem; | |
| 116 | 124 | font-weight: normal; |
| 117 | 125 | line-height: 20px; |
| 118 | 126 | margin-top: 48px; | ... | ... |
src/app/components/proposal-grid/proposal-grid.html
| 1 | 1 | <div class="proposal-grid row"> |
| 2 | 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 | 4 | <div ng-if="$odd" class="clearfix"></div> |
| 5 | 5 | </div> |
| 6 | 6 | <div class="animate-repeat" ng-if="results.length == 0"> | ... | ... |