diff --git a/GovBr/GovBrStrategy.php b/GovBr/GovBrStrategy.php index 65d80d3..ad10bd7 100644 --- a/GovBr/GovBrStrategy.php +++ b/GovBr/GovBrStrategy.php @@ -281,9 +281,19 @@ public static function verifyUpdateData($user, $response) } } } + $user->profile->hasSeenSocialLinkingModal = true; $user->profile->save(true); $app->enableAccessControl(); + $seal = $app->repo('Seal')->find($app->config['auth.config']['strategies']['govbr']['applySealId']); + $sealRelation = $app->repo('SealRelation')->findOneBy(['seal' => $seal, 'agent' => $user->profile->id]); + + if ($sealRelation) { + $sealRelation->createTimestamp = new DateTime(); + $app->em->persist($sealRelation); + $app->em->flush(); + } + if($allAgents = $app->repo("Agent")->findBy(['userId' => $user->id, '_type' => 1])){ if(count($allAgents) == 1){ @@ -291,6 +301,9 @@ public static function verifyUpdateData($user, $response) $_agent->setAsUserProfile(); } } + + setcookie('errorRedirectLocation', '', time() - 3600, '/'); + unset($_COOKIE['errorRedirectLocation']); self::getFile($user->profile, $userinfo->picture, $userinfo->access_token); } @@ -310,4 +323,45 @@ public static function mask($val, $mask) { } return $maskared; } + + public static function validateErrors($response, $user) + { + $app = App::i(); + $errors = []; + + if($agents_meta = self::getAgentsByDocumento($response)) { + if(count($agents_meta) > 1) { + $errors['cpf-duplicado'] = 'cpf-duplicado'; + } + } + + if($agents_meta = self::getUsersByEmail($response)) { + if(count($agents_meta) > 1) { + $errors['email-duplicado'] = 'email-duplicado'; + } + } + + $metadataFieldCpf = $app->config['auth.config']['metadataFieldCPF']; + if($agents_meta[0]->profile->{$metadataFieldCpf} != $user->profile->{$metadataFieldCpf}){ + $errors['cpf-diferente'] = 'cpf-diferente'; + } + + return $errors; + } + + public static function getAgentsByDocumento($response) + { + $app = App::i(); + $metadataFieldCpf = $app->config['auth.config']['metadataFieldCPF']; + $cpf = self::mask($response['auth']['raw']['cpf'],'###.###.###-##'); + return $cpf ? $app->repo('AgentMeta')->findBy(["key" => $metadataFieldCpf, "value" => $cpf]) : []; + + } + + public static function getUsersByEmail($response) + { + $app = App::i(); + $email = $response['auth']['info']['email']; + return $email ? $app->repo('User')->findBy(['email' => $email]) : []; + } } diff --git a/Plugin.php b/Plugin.php index 9ad2020..a0ec01c 100644 --- a/Plugin.php +++ b/Plugin.php @@ -11,15 +11,16 @@ include('GovBr/GovBrStrategy.php'); class Plugin extends \MapasCulturais\Plugin { - + public function _init() { $app = App::i(); - + $plugin = $this; + // register translation text domain i::load_textdomain( 'multipleLocal', __DIR__ . "/translations" ); - + // Load JS & CSS - $app->hook('GET(<>.<<*>>):before', function() use ($app) { + $app->hook('GET(<<*>>.<<*>>):before', function() use ($app) { $app->view->enqueueStyle('app-v2', 'multipleLocal-v2', 'css/plugin-MultiplLocalAuth.css'); }); @@ -34,6 +35,51 @@ public function _init() { $this->part('password/change-password'); }); + $app->hook('template(panel.<>.user-mail):end ', function() use ($app, $plugin) { + /** @var \MapasCulturais\Theme $this */ + $current_user = $app->user; + $can_seal = !$current_user->is('guest'); + + if ($app->config['auth.config']['strategies']['govbr']['visible'] && $can_seal) { + $has_govbr_seal = $plugin->hasGovBrSeal($current_user); + $this->part('govbr/govbr-data', [ + 'has_govbr_seal' => $has_govbr_seal, + 'button_class' => 'login-govbr--panel', + 'seal_class' => 'seal-govbr--panel', + ]); + } + }); + + $app->hook('template(agent.single.single1-entity-info-mc-share-links):before', function() use ($app, $plugin) { + /** @var \MapasCulturais\Theme $this */ + $current_user = $app->user; + $can_seal = !$current_user->is('guest') && $this->controller->requestedEntity->id == $current_user->profile->id; + + if ($app->config['auth.config']['strategies']['govbr']['visible'] && $can_seal) { + $has_govbr_seal = $plugin->hasGovBrSeal($current_user); + $this->part('govbr/govbr-data', [ + 'has_govbr_seal' => $has_govbr_seal, + 'button_class' => 'col-12', + 'seal_class' => 'col-12', + ]); + } + }); + + $app->hook('template(agent.edit.edit1-entity-info-site):after', function() use ($app, $plugin) { + /** @var \MapasCulturais\Theme $this */ + $current_user = $app->user; + $can_seal = !$current_user->is('guest') && $this->controller->requestedEntity->id == $current_user->profile->id; + + if ($app->config['auth.config']['strategies']['govbr']['visible'] && $can_seal) { + $has_govbr_seal = $plugin->hasGovBrSeal($current_user); + $this->part('govbr/govbr-data', [ + 'has_govbr_seal' => $has_govbr_seal, + 'button_class' => 'col-12', + 'seal_class' => 'col-12', + ]); + } + }); + $app->hook('entity(User).permissionsList,doctrine.emum(permission_action).values', function (&$permissions) { $permissions[] = 'changePassword'; }); @@ -42,13 +88,54 @@ public function _init() { $labels['changePassword'] = i::__('modificar senha'); }); + $app->hook("controller(seal).render(sealrelation)", function(&$template, $seal) use ($app) { + $govbr_seal = $app->config['auth.config']['strategies']['govbr']['applySealId']; + + if ($seal['relation']->seal->id == $govbr_seal) { + $template = "certificado-govbr"; + } + }); + + // Carrega novos ícones 'iconfy' na estrutura default + $app->hook('component(mc-icon).iconset', function(&$iconset){ + $iconset['cursor-click'] = "mynaui:click-solid"; + }); + + $app->hook('template(<<*>>.main-header):after', function() use ($app) { + $is_admin = $app->user->is('admin'); + $govbr_visible = $app->config['auth.config']['strategies']['govbr']['visible']; + $has_seen_modal = !$app->user->is('guest') ? $app->user->profile->hasSeenSocialLinkingModal : false; + $govbr_seal = $app->config['auth.config']['strategies']['govbr']['applySealId']; + $seal_relation = !$app->user->is('guest') && $govbr_seal ? $app->repo('SealRelation')->findOneBy(['seal' => $govbr_seal, 'agent' => $app->user->profile->id]) : false; + + if ($govbr_visible && !$app->user->is('guest') && !$has_seen_modal && !$seal_relation && !$is_admin) { + $this->part('govbr/govbr-modal'); + } + }); + + $app->hook('POST(site.desabilitar-modal)', function() use($app) { + $this->requireAuthentication(); + + $agent_id = $this->data['agentId']; + $agent = $app->repo('Agent')->find($agent_id); + + if($agent) { + $agent->hasSeenSocialLinkingModal = true; + $agent->save(true); + + $this->json(true); + } + + $this->errorJson(false); + }); + if (php_sapi_name() == "cli") { if (!isset($_SERVER['HTTP_HOST'])) { $_SERVER['HTTP_HOST'] = 'localhost'; } } } - + public function register() { $this->registerUserMetadata(Provider::$passMetaName, ['label' => i::__('Senha')]); $this->registerUserMetadata(Provider::$recoverTokenMetadata, ['label' => i::__('Token para recuperação de senha')]); @@ -56,6 +143,18 @@ public function register() { $this->registerUserMetadata(Provider::$accountIsActiveMetadata, ['label' => i::__('Conta ativa?')]); $this->registerUserMetadata(Provider::$tokenVerifyAccountMetadata, ['label' => i::__('Token de verificação')]); $this->registerUserMetadata(Provider::$loginAttempMetadata, ['label' => i::__('Número de tentativas de login')]); - $this->registerUserMetadata(Provider::$timeBlockedloginAttempMetadata, ['label' => i::__('Tempo de bloqueio por excesso de tentativas')]); + $this->registerUserMetadata(Provider::$timeBlockedloginAttempMetadata, ['label' => i::__('Tempo de bloqueio por excesso de tentativas')]); + $this->registerAgentMetadata('hasSeenSocialLinkingModal', [ + 'label' => i::__('Indica se o usuário já viu o modal de vinculação com redes sociais'), + 'type' => 'boolean', + 'default' => false + ]); + } + + public function hasGovBrSeal($user) { + $app = App::i(); + $seal = $app->repo('Seal')->find($app->config['auth.config']['strategies']['govbr']['applySealId']); + $seal_relation = $app->repo('SealRelation')->findOneBy(['seal' => $seal, 'agent' => $user->profile->id]); + return !empty($seal_relation); } } diff --git a/Provider.php b/Provider.php index 2878e78..bbd6dc8 100644 --- a/Provider.php +++ b/Provider.php @@ -39,6 +39,8 @@ function __construct ($config) { 'loginOnRegister' => env('AUTH_LOGIN_ON_REGISTER', false), 'enableLoginByCPF' => env('AUTH_LOGIN_BY_CPF', true), + 'requireCpf' => env('AUTH_REQUIRED_CPF', true), + 'passwordMustHaveCapitalLetters' => env('AUTH_PASS_CAPITAL_LETTERS', true), 'passwordMustHaveLowercaseLetters' => env('AUTH_PASS_LOWERCASE_LETTERS', true), 'passwordMustHaveSpecialCharacters' => env('AUTH_PASS_SPECIAL_CHARS', true), @@ -63,7 +65,7 @@ function __construct ($config) { 'urlImageToUseInEmails' => env('AUTH_EMAIL_IMAGE'), 'urlTermsOfUse' => env('LINK_TERMOS', $app->createUrl('auth', 'termos-e-condicoes')), - 'statusCreateAgent' => env('STATUS_CREATE_AGENT', Agent::STATUS_DRAFT), + 'statusCreateAgent' => env('STATUS_CREATE_AGENT', Agent::STATUS_ENABLED), 'strategies' => [ 'Facebook' => [ 'visible' => env('AUTH_FACEBOOK_CLIENT_ID', false), @@ -108,7 +110,8 @@ function __construct ($config) { 'state_salt' => env('AUTH_GOV_BR_STATE_SALT', null), 'applySealId' => env('AUTH_GOV_BR_APPLY_SEAL_ID', null), 'menssagem_authenticated' => env('AUTH_GOV_BR_MENSSAGEM_AUTHENTICATED','Usuário já se autenticou pelo GovBr'), - 'dic_agent_fields_update' => env('AUTH_GOV_BR_DICT_AGENT_FIELDS_UPDATE','[]') + 'dic_agent_fields_update' => env('AUTH_GOV_BR_DICT_AGENT_FIELDS_UPDATE','[]'), + 'supportEmail' => env('AUTH_GOV_BR_SUPPORT_EMAIL', false) ] ] ]; @@ -424,44 +427,6 @@ protected function _init() { echo "
  • $label
  • "; }); - - $app->hook('ALL(panel.my-account)', function () use($app,$config){ - - $email = filter_var($app->request->post('email'),FILTER_SANITIZE_EMAIL); - if ($email) { - $app->auth->processMyAccount(); - } - - $has_seal_govbr = false; - if($config['strategies']['govbr']['visible']){ - - $agent = $app->user->profile; - $relations = $agent->getSealRelations(); - $sealId = $config['strategies']['govbr']['applySealId']; - - foreach($relations as $relation){ - if($relation->seal->id == $sealId){ - $has_seal_govbr = true; - break; - } - } - } - - $active = $this->template == 'panel/my-account' ? 'class="active"' : ''; - $user = $app->user; - $email = $user->email ? $user->email : ''; - $this->render('multiple-local-auth--my-account',[ - 'email' => $email, - 'form_action' => $app->createUrl('panel', 'my-account'), - 'feedback_success' => $app->auth->feedback_success, - 'feedback_msg' => $app->auth->feedback_msg, - 'config' => $config, - 'has_seal_govbr' => $has_seal_govbr, - 'menssagem_authenticated' => $config['strategies']['govbr']['menssagem_authenticated'] - - ]); - - }); $app->applyHook('auth.provider.init'); } @@ -586,29 +551,32 @@ function validateRegisterFields() { if($config['enableLoginByCPF']) { // validate cpf - if(empty($cpf) || !$this->validateCPF($cpf)) { + if($config['requireCpf'] && !$this->validateCPF($cpf)) { array_push($errors['user']['cpf'], i::__('Por favor, informe um cpf válido.', 'multipleLocal')); $hasErrors = true; } - $foundAgent = []; - $metadataFieldCpf = $this->getMetadataFieldCpfFromConfig(); - $_cpf = implode("','", [$cpf, preg_replace('/[^0-9]/i', '', $cpf)]); - $foundAgent = $conn->fetchAll("SELECT * FROM agent_meta WHERE key IN ('{$metadataFieldCpf}', 'cpf') AND value IN ('{$_cpf}')"); - - // creates an array with agents with status == 1, because the user can have, for example, 3 agents, but 2 have status == 0 - $existAgent = []; - if($foundAgent){ - foreach ($foundAgent as $agentMeta) { - if($agentMeta->owner->status >= 0) { - $existAgent[] = $agentMeta; + if($this->validateCPF($cpf)) { + $foundAgent = []; + $metadataFieldCpf = $this->getMetadataFieldCpfFromConfig(); + + $_cpf = implode("','", [$cpf, preg_replace('/[^0-9]/i', '', $cpf)]); + $foundAgent = $conn->fetchAll("SELECT * FROM agent_meta WHERE key IN ('{$metadataFieldCpf}', 'cpf') AND value IN ('{$_cpf}')"); + + // creates an array with agents with status == 1, because the user can have, for example, 3 agents, but 2 have status == 0 + $existAgent = []; + if($foundAgent){ + foreach ($foundAgent as $agentMeta) { + if($agentMeta->owner->status >= 0) { + $existAgent[] = $agentMeta; + } } } - } - if(count($existAgent) > 0) { - array_push($errors['user']['cpf'], i::__('Este CPF já esta em uso. Tente recuperar a sua senha.', 'multipleLocal')); - $hasErrors = true; + if(count($existAgent) > 0) { + array_push($errors['user']['cpf'], i::__('Este CPF já esta em uso. Tente recuperar a sua senha.', 'multipleLocal')); + $hasErrors = true; + } } } @@ -1329,28 +1297,32 @@ protected function _validateResponse(){ $valid = false; // o usuário ainda não tentou se autenticar - if(!is_array($response)) + if(!is_array($response)) { return false; - // verifica se a resposta é um erro - if (array_key_exists('error', $response)) { - - $app->flash('auth error', 'Opauth returns error auth response'); - } else { - /** - * Auth response validation - * - * To validate that the auth response received is unaltered, especially auth response that - * is sent through GET or POST. - */ - if (empty($response['auth']) || empty($response['timestamp']) || empty($response['signature']) || empty($response['auth']['provider']) || empty($response['auth']['uid'])) { - $app->flash('auth error', 'Invalid auth response: Missing key auth response components.'); - } elseif (!$this->opauth->validate(sha1(print_r($response['auth'], true)), $response['timestamp'], $response['signature'], $reason)) { - $app->flash('auth error', "Invalid auth response: {$reason}"); - } else { - $valid = true; - } } - return $valid; + + return true; + + // verifica se a resposta é um erro + // if (array_key_exists('error', $response)) { + + // $app->flash('auth error', 'Opauth returns error auth response'); + // } else { + // /** + // * Auth response validation + // * + // * To validate that the auth response received is unaltered, especially auth response that + // * is sent through GET or POST. + // */ + // if (empty($response['auth']) || empty($response['timestamp']) || empty($response['signature']) || empty($response['auth']['provider']) || empty($response['auth']['uid'])) { + // $app->flash('auth error', 'Invalid auth response: Missing key auth response components.'); + // } elseif (!$this->opauth->validate(sha1(print_r($response['auth'], true)), $response['timestamp'], $response['signature'], $reason)) { + // $app->flash('auth error', "Invalid auth response: {$reason}"); + // } else { + // $valid = true; + // } + // } + // return $valid; } public function getMetadataFieldCpfFromConfig() { @@ -1377,8 +1349,8 @@ public function _getAuthenticatedUser() { $app = App::i(); $response = $this->_getResponse(); - $auth_uid = $response['auth']['uid']; - $auth_provider = $app->getRegisteredAuthProviderId($response['auth']['provider']); + // $auth_uid = $response['auth']['uid']; + // $auth_provider = $app->getRegisteredAuthProviderId($response['auth']['provider']); $cpf = (isset($response['auth']['raw']['cpf'])) ? $this->mask($response['auth']['raw']['cpf'],'###.###.###-##') : null; if (!empty($cpf)) { @@ -1393,7 +1365,9 @@ public function _getAuthenticatedUser() { if (empty($user)) { $email = $response['auth']['info']['email']; $user = $app->repo('User')->findOneBy(['email' => $email]); - } + } + + $this->authenticateUser($user); return $user; }else{ @@ -1405,11 +1379,39 @@ public function _getAuthenticatedUser() { * @return boolean true if the response is valid or false if the response is not valid */ public function processResponse(){ + $app = App::i(); + // se autenticou if($this->_validateResponse()){ // e ainda não existe um usuário no sistema $user = $this->_getAuthenticatedUser(); $response = $this->_getResponse(); + + if($response && $provider_class = $response['auth']['provider']."Strategy"){ + if(method_exists($provider_class, "validateErrors")){ + if($errors = $provider_class::validateErrors($response, $user)){ + $_SESSION['strategy-error'] = $errors; + + $cookie = json_decode($_COOKIE['errorRedirectLocation'], true); + setcookie('errorRedirectLocation', '', time() - 3600, '/'); + unset($_COOKIE['errorRedirectLocation']); + + if($cookie['isAuth']) { + $params = $cookie['controller'] == 'agent' ? ['id' => $user->profile->id] : []; + header('Location: ' . $app->createUrl($cookie['controller'], $cookie['action'], $params)); + exit; + } else { + session_unset(); + $_SESSION['strategy-error'] = $errors; + $_SESSION['strategy-error-cpf'] = $user->profile->cpf; + http_response_code(302); + header('Location: '.$app->createUrl($cookie['controller'], $cookie['action'])); + exit; + } + } + } + } + if(!$user){ $user = $this->createUser($response); @@ -1464,96 +1466,115 @@ function authenticateUser(Entities\User $user) { } protected function _createUser($response) { - $app = App::i(); + try { + $app = App::i(); - $app->disableAccessControl(); + $app->disableAccessControl(); - $config = $this->_config; + $config = $this->_config; - $user = null; - if($provider_class = $response['auth']['provider']."Strategy"){ - if(method_exists($provider_class, "newAccountCheck")){ - if($user = $provider_class::newAccountCheck($response)){ - $agent = $user->profile; + $user = null; + if($response && $provider_class = $response['auth']['provider']."Strategy"){ + if(method_exists($provider_class, "newAccountCheck")){ + if($user = $provider_class::newAccountCheck($response)){ + $agent = $user->profile; + } } } - } - - if(!$user){ - // cria o usuário - $user = new Entities\User; - $user->authProvider = $response['auth']['provider']; - $user->authUid = $response['auth']['uid']; - $user->email = $response['auth']['info']['email']; - $app->em->persist($user); - - // cria um agente do tipo user profile para o usuário criado acima - $agent = new Entities\Agent($user); + if(!$user){ + $app->em->beginTransaction(); - if(isset($response['auth']['info']['name'])){ - $agent->name = $response['auth']['info']['name']; - } - elseif(isset($response['auth']['info']['first_name']) && isset($response['auth']['info']['last_name'])){ - $agent->name = $response['auth']['info']['first_name'] . ' ' . $response['auth']['info']['last_name']; - } - elseif(isset($response['auth']['agentData']['name'])){ - $agent->name = $response['auth']['agentData']['name']; - } - else{ - $agent->name = ''; - } - - if(isset($response['auth']['info']['phone_number'])){ - $metadataFieldPhone = $this->getMetadataFieldPhone(); - $metadataFieldPhone = $this->getMetadataFieldPhone(); - $metadataFieldPhone = $this->getMetadataFieldPhone(); - $agent->$metadataFieldPhone = $response['auth']['info']['phone_number']; - } + // cria o usuário + $user = new Entities\User; + $user->authProvider = $response['auth']['provider']; + $user->authUid = $response['auth']['uid']; + $user->email = $response['auth']['info']['email']; - if(isset($response['auth']['agentData']['shortDescription'])){ - $agent->shortDescription = $response['auth']['agentData']['shortDescription']; - } + $app->em->persist($user); + + // cria um agente do tipo user profile para o usuário criado acima + $agent = new Entities\Agent($user); + + if(isset($response['auth']['info']['name'])){ + $agent->name = $response['auth']['info']['name']; + } + elseif(isset($response['auth']['info']['first_name']) && isset($response['auth']['info']['last_name'])){ + $agent->name = $response['auth']['info']['first_name'] . ' ' . $response['auth']['info']['last_name']; + } + elseif(isset($response['auth']['agentData']['name'])){ + $agent->name = $response['auth']['agentData']['name']; + } + else{ + $agent->name = ''; + } + + if(isset($response['auth']['info']['phone_number'])){ + $metadataFieldPhone = $this->getMetadataFieldPhone(); + $metadataFieldPhone = $this->getMetadataFieldPhone(); + $metadataFieldPhone = $this->getMetadataFieldPhone(); + $agent->$metadataFieldPhone = $response['auth']['info']['phone_number']; + } - if(isset($response['auth']['agentData']['terms:area'])){ - $agent->terms['area'] = $response['auth']['agentData']['terms:area']; - } + if(isset($response['auth']['agentData']['shortDescription'])){ + $agent->shortDescription = $response['auth']['agentData']['shortDescription']; + } - if(isset($response['auth']['info']['phone_number'])){ - $metadataFieldPhone = $this->getMetadataFieldPhone(); - $agent->setMetadata($metadataFieldPhone, $response['auth']['info']['phone_number']); - } + if(isset($response['auth']['agentData']['terms:area'])){ + $agent->terms['area'] = $response['auth']['agentData']['terms:area']; + } - //cpf - $cpf = (isset($response['auth']['info']['cpf']) && $response['auth']['info']['cpf'] != "") ? $this->mask($response['auth']['info']['cpf'],'###.###.###-##') : null; - if(!empty($cpf)){ - $metadataFieldCpf = $this->getMetadataFieldCpfFromConfig(); - $agent->$metadataFieldCpf = $cpf; - } + if(isset($response['auth']['info']['phone_number'])){ + $metadataFieldPhone = $this->getMetadataFieldPhone(); + $agent->setMetadata($metadataFieldPhone, $response['auth']['info']['phone_number']); + } - $agent->status = (int) $config['statusCreateAgent'] ?? '0'; - $agent->emailPrivado = $user->email; - - $agent->save(); - $app->em->flush(); + //cpf + $cpf = (isset($response['auth']['info']['cpf']) && $response['auth']['info']['cpf'] != "") ? $this->mask($response['auth']['info']['cpf'],'###.###.###-##') : null; + if(!empty($cpf)){ + $metadataFieldCpf = $this->getMetadataFieldCpfFromConfig(); + $agent->$metadataFieldCpf = $cpf; + } - $user->profile = $agent; + // Valida se algum campo obrigatório não foi preenchido + if ( + empty($agent->$metadataFieldCpf) || + empty($agent->name) || + empty($agent->shortDescription) || + (isset($agent->terms['area']) && $agent->terms['area'] === []) + ) { + $agent->status = 0; + } else { + $agent->status = (int) $config['statusCreateAgent'] ?? '0'; + } - $user->save(true); + $agent->emailPrivado = $user->email; + $agent->save(); + $app->em->flush(); + + $user->profile = $agent; + $user->save(true); + $app->em->flush(); + + $user->createPermissionsCacheForUsers([$user]); + $agent->createPermissionsCacheForUsers([$user]); - $user->createPermissionsCacheForUsers([$user]); - $agent->createPermissionsCacheForUsers([$user]); - } + $app->em->commit(); + } - $app->enableAccessControl(); - $redirectUrl = $agent->status == Agent::STATUS_DRAFT ? $agent->editUrl : $this->getRedirectPath(); - $app->applyHookBoundTo($this, 'auth.createUser:redirectUrl', [&$redirectUrl]); + $app->enableAccessControl(); + $redirectUrl = $agent->status == Agent::STATUS_DRAFT ? $agent->editUrl : $this->getRedirectPath(); + $app->applyHookBoundTo($this, 'auth.createUser:redirectUrl', [&$redirectUrl]); - if ($redirectUrl) { - $this->_setRedirectPath($redirectUrl); + if ($redirectUrl) { + $this->_setRedirectPath($redirectUrl); + } + + return $user; + } catch(\Exception $e) { + $app->em->rollback(); + throw $e; } - - return $user; } function mask($val, $mask) { diff --git a/assets-src/sass/1-settings/_s-mixins.scss b/assets-src/sass/1-settings/_s-mixins.scss new file mode 100644 index 0000000..d67c737 --- /dev/null +++ b/assets-src/sass/1-settings/_s-mixins.scss @@ -0,0 +1,13 @@ +@use 'sass:math'; + +@function size($value, $unit: 'px') { + @if $unit == 'rem' { + @return #{$value}rem; + } + @else if $unit == 'px' { + @return #{math.div($value, 16)}rem; + } + @else { + @return #{$value}#{$unit}; + } +} \ No newline at end of file diff --git a/assets-src/sass/3-layouts/_l_govbr-certificate.scss b/assets-src/sass/3-layouts/_l_govbr-certificate.scss new file mode 100644 index 0000000..62f4cc4 --- /dev/null +++ b/assets-src/sass/3-layouts/_l_govbr-certificate.scss @@ -0,0 +1,175 @@ +@use '../1-settings/s-mixins' as *; + +@media print { + * { + -webkit-print-color-adjust: exact; /* Preserva as cores exatas */ + } + + @page { + size: landscape; + margin: 1cm; + } + + body, html { + orientation: landscape; + background-color: white; + margin: 0; + padding: 0; + } + .main-footer { + display: none; + } + .main-footer__reg { + display: none; + } + .main-footer__content--links { + display: none; + } + .theme-logo__logo--img { + display: none; + } + .main-header { + display: none; + } + .govbr-certificate { + margin: 0 !important; + max-width: 100% !important; + max-height: 100% !important; + height: 100vh !important; + + &__footer { + justify-content: space-between !important; + } + } + #print { + aspect-ratio: 1.414 / 1 !important; + } +} + +.govbr-certificate { + aspect-ratio: 1.414 / 1; + align-content: space-between; + background: var(--mc-gray-100); + background: linear-gradient( + 180deg, + var(--mc-gray-300) 0%, + var(--mc-gray-100) 20%, + var(--mc-white) 100% + ); + padding: size(35); + display: grid; + gap: size(15); + position: relative; + overflow: hidden; + max-width: size(900); + border: var(--mc-border-hairline) var(--mc-gray-300); + margin: size(32) auto; + + &__quote { + display: grid; + gap: 8px; + border-left: 2px solid var(--mc-warning-500); + padding-left: 16px; + padding-bottom: 25px; + } + + &__date { + font-size: var(--mc-font-size-xxxs); + } + + &__header { + display: flex; + align-items: center; + gap: size(25); + justify-items: end; + z-index: 1; + grid-template-columns: size(195) 1fr; + width: 100%; + justify-content: space-between; + } + + + &__cadastro { + font-size: size(16); + text-transform: uppercase;; + } + + &__header-left { + display: flex; + align-items: center; + gap: 8px; + + .iconify { + font-size: var(--mc-font-size-xl); + color: var(--mc-success-500); + } + } + + &__header-right { + img { + max-width: 150px; + } + } + + &__content { + display: grid; + z-index: 1; + gap: size(20); + margin: 0 size(5); + } + + &__text { + text-align: justify; + font-weight: var(--mc-font-regular); + font-size: var(--mc-font-size-sm); + } + + + &__footer { + display: flex; + justify-content: space-between; + z-index: 1; + padding: size(25) 0 size(0); + flex-wrap: wrap; + gap: size(10); + align-items: flex-end; + + @media (max-width: size(785)) { + justify-content: center; + } + } + + &__profile-link { + align-items: flex-end; + color: var(--mc-low-700); + display: flex; + gap: size(15); + } + + &__profile-click { + align-items: center; + background-color: var(--mc-primary-500); + color: white; + display: flex; + height: size(60); + justify-content: center; + width: size(60); + + .iconify { + font-size: size(30); + } + } + + &__profile-qrcode { + display: grid; + } + + &__profile-text { + font-size: var(--mc-font-size-xxxs); + line-height: var(--mc-font-size-xxxs); + } + + &__footer-right { + width: 200px; + } +} \ No newline at end of file diff --git a/assets-src/sass/4-components/_c-create-account.scss b/assets-src/sass/4-components/_c-create-account.scss index e4765b6..918a9e8 100644 --- a/assets-src/sass/4-components/_c-create-account.scss +++ b/assets-src/sass/4-components/_c-create-account.scss @@ -1,14 +1,19 @@ -.mc-breadcrumb { - li { - display: flex; - color: var(--mc-primary-500); +@use '../1-settings/s-mixins' as *; + +.controller-auth { - &::before { - content: url('https://api.iconify.design/fe/arrow-left.svg?width=16&height=16'); - height: 16px; - margin-inline-end: 5px; - width: 16px; + .mc-breadcrumb { + li { + display: flex; color: var(--mc-primary-500); + + &::before { + content: url('https://api.iconify.design/fe/arrow-left.svg?width=16&height=16'); + height: 16px; + margin-inline-end: 5px; + width: 16px; + color: var(--mc-primary-500); + } } } } @@ -18,14 +23,23 @@ margin: 32px auto; padding: 0 16px; + hr { + width: 100%; + } + .mc-card { padding: 24px; - + &.card-created { margin: 80px 0; } } - + + &__button { + max-width: size(473); + margin: 0 auto; + } + &__title { margin: 35px 0; @@ -47,13 +61,51 @@ } &__timeline { - margin-bottom: 24px; - width: 100%; - + margin-inline: auto; + margin-bottom: 31px; + width: 80%; + .stepper { overflow: hidden; margin: 0px -3.7%; width: 108%; + + .count { + width: 40px; + height: 40px; + } + + .step { + & .label { + width: 40px; + position: relative; + top: -33px; + z-index: 2; + left: 0px; + } + + &.active { + & .label { + color: var(--mc-white); + } + + &:first-child { + .label { + text-align: center; + } + } + } + + &::before { + top: size(20); + } + + &.passedby { + & .label { + color: var(--mc-white); + } + } + } } @media (max-width: 560px) { @@ -64,7 +116,7 @@ &::before { top: 16px; } - + .count { width: 32px; height: 32px; @@ -75,20 +127,6 @@ } &__step { - .title { - font-weight: 700; - font-size: 18px; - line-height: 25px; - margin: 8px 0 4px; - - .subtitle { - font-weight: 400; - font-size: 14px; - line-height: 19px; - margin-top: 16px; - } - } - .document-label { display: flex; align-items: center; @@ -103,8 +141,8 @@ } } - .password { - position: relative; + .password { + position: relative; &-rules { margin-top:1em; font-size: 14px; @@ -129,7 +167,7 @@ } } - + .g-recaptcha { display: flex; @@ -151,16 +189,16 @@ &--button { text-align: center; display: block; - + .img { width: 50px; float: left; text-align: left; display: flex; align-items: center; - + img { - height: 16px; + height: 16px; } @media (max-width: 500px) { @@ -170,12 +208,12 @@ } } } - + &.google { border: var(--mc-border-hairline) var(--mc-low-500); color: var(--mc-low-700); } - + &.govbr { border: var(--mc-border-hairline) #1351B4; background-color: #1351B4; @@ -188,7 +226,7 @@ font-size: 13px; } } - } + } } .term { @@ -196,14 +234,14 @@ /* entire scrollbar */ &::-webkit-scrollbar { - width: 6px; + width: 6px; } - + /* tracking area */ &::-webkit-scrollbar-track { background: unset; } - + /* scroll thumb */ &::-webkit-scrollbar-thumb { background-color: #6C6C6C; @@ -241,6 +279,37 @@ } } + &__step-title { + border-bottom: var(--mc-border-hairline) var(--mc-gray-300); + padding-bottom: size(11); + display: grid; + gap: size(16); + + .subtitle { + font-weight: 400; + font-size: var(--mc-font-size-xxs); + } + } + + &__modal { + max-width: size(992); + margin: 0 auto; + + .modal__content { + padding: 0 0 0 size(25); + overflow-y: auto; + margin-right: size(25); + } + } + + &__modal-content { + padding: 0 size(5); + } + + &__term-link { + cursor: pointer; + } + &__created { .title { align-items: center; @@ -287,26 +356,26 @@ border-radius: var(--mc-border-radius-sm); } - &::-webkit-progress-value { + &::-webkit-progress-value { border-radius: var(--mc-border-radius-sm); transition: 1s; } &.fraco { &::-webkit-progress-value { - background: red; + background: red; } } &.medio { &::-webkit-progress-value { - background: yellow; + background: yellow; } } &.forte { &::-webkit-progress-value { - background: green; + background: green; } } } diff --git a/assets-src/sass/4-components/_c-login-govbr.scss b/assets-src/sass/4-components/_c-login-govbr.scss new file mode 100644 index 0000000..4f6e282 --- /dev/null +++ b/assets-src/sass/4-components/_c-login-govbr.scss @@ -0,0 +1,52 @@ +@use '../1-settings/s-mixins' as *; + +.login-govbr { + + &__content { + display: grid; + gap: 20px; + max-width: size(520); + } + + &__error { + margin-top: size(16); + width: 100%; + + a { + color: inherit; + } + } + + .button.govbr { + align-items: center; + background-color: #1351b4; + color: #fff; + display: flex; + justify-content: center; + padding: 8px 16px; + + &:not(.button--large) { + width: fit-content; + } + + > img { + height: 1em; + width: auto; + } + } + + &--panel { + margin: size(16) 0; + + .button.govbr { + width: fit-content; + } + } + + &.modal__content, .modal__content { + + .button.govbr { + width: 100%; + } + } +} diff --git a/assets-src/sass/4-components/_c-seal-govbr.scss b/assets-src/sass/4-components/_c-seal-govbr.scss new file mode 100644 index 0000000..9ec4e57 --- /dev/null +++ b/assets-src/sass/4-components/_c-seal-govbr.scss @@ -0,0 +1,14 @@ +@use '../1-settings/s-mixins' as *; + +.seal-govbr { + + &__content { + align-items: center; + display: flex; + gap: 1ex; + } + + &--panel { + margin: size(16) 0; + } +} diff --git a/assets-src/sass/plugin-MultiplLocalAuth.scss b/assets-src/sass/plugin-MultiplLocalAuth.scss index cfa0541..6fff0ad 100755 --- a/assets-src/sass/plugin-MultiplLocalAuth.scss +++ b/assets-src/sass/plugin-MultiplLocalAuth.scss @@ -11,12 +11,14 @@ /* ----- 3: LAYOUT ------- */ - +@import '3-layouts/l_govbr-certificate'; /* ----- 4: COMPONENTS ------- */ @import '4-components/c-change-password'; @import '4-components/c-create-account'; +@import '4-components/c-login-govbr'; @import '4-components/c-login'; +@import '4-components/c-seal-govbr'; /* ----- 5: AREAS ------- */ diff --git a/assets/img/certificate/govbr-logo.svg b/assets/img/certificate/govbr-logo.svg new file mode 100644 index 0000000..0cf1f4c --- /dev/null +++ b/assets/img/certificate/govbr-logo.svg @@ -0,0 +1,23 @@ + + + + + background + + + + Layer 1 + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/img/govbr-white.svg b/assets/img/govbr-white.svg new file mode 100644 index 0000000..c763215 --- /dev/null +++ b/assets/img/govbr-white.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/components/create-account/script.js b/components/create-account/script.js index bc83102..5bb6aa2 100644 --- a/components/create-account/script.js +++ b/components/create-account/script.js @@ -17,7 +17,7 @@ app.component('create-account', { return { actualStep: globalState['stepper'] ?? 0, - totalSteps: termsQtd + 2, + totalSteps: termsQtd > 0 ? 3 : 2, terms, passwordRules: {}, strongness: 0, @@ -31,6 +31,13 @@ app.component('create-account', { recaptchaResponse: '', created: false, emailSent: false, + govbr: { + nome: '', + nascimento: '', + cpf: '', + email: '', + telefone: '', + } } }, @@ -54,7 +61,7 @@ app.component('create-account', { computed: { arraySteps() { - let steps = Object.entries(this.terms).length + 2; + let steps = this.totalSteps; let totalSteps = []; for (let i = 0; i < steps; i++) { totalSteps.push(i); @@ -70,6 +77,14 @@ app.component('create-account', { return JSON.parse(this.config); }, + isTermsAccepted() { + const allTerms = Object.keys(this.terms); + + return this.slugs.length === allTerms.length && + this.slugs.every((item) => allTerms.includes(item)) && + allTerms.every((item) => this.slugs.includes(item)); + }, + passwordStrongness() { if (this.password) { let passwordMustHaveCapitalLetters = /[A-Z]/; @@ -149,7 +164,7 @@ app.component('create-account', { async goToStep(step) { const globalState = useGlobalState(); - if (this.actualStep == 0) { + if (this.actualStep == 0 && false) { if (await this.validateFields()) { this.actualStep = step; if (step == this.totalSteps - 1) { @@ -175,7 +190,9 @@ app.component('create-account', { /* Terms */ acceptTerm(slug) { - this.slugs.push(slug); + if (!this.slugs.includes(slug)) { + this.slugs.push(slug); + } }, /* Do register */ diff --git a/components/create-account/template.php b/components/create-account/template.php index a776a64..b8a592c 100644 --- a/components/create-account/template.php +++ b/components/create-account/template.php @@ -2,7 +2,7 @@ /** * @var \MapasCulturais\Themes\BaseV2\Theme $this * @var \MapasCulturais\App $app - * + * */ use MapasCulturais\i; @@ -17,7 +17,7 @@ '); ?> -