diff --git a/Decidim/DecidimStrategy.php b/Decidim/DecidimStrategy.php new file mode 100644 index 0000000..f298641 --- /dev/null +++ b/Decidim/DecidimStrategy.php @@ -0,0 +1,245 @@ + 'email'); + */ + public $defaults = ['redirect_uri' => '{complete_url_to_strategy}oauth2callback']; + + /** + * Auth request + */ + public function request(){ + $url = $this->strategy['auth_endpoint']; + $params = array( + 'client_id' => $this->strategy['client_id'], + 'client_secret' => $this->strategy['client_secret'], + 'redirect_uri' => $this->strategy['redirect_uri'], + 'response_type' => 'code', + 'scope' => $this->strategy['scope'] + ); + foreach ($this->optionals as $key){ + if (!empty($this->strategy[$key])) $params[$key] = $this->strategy[$key]; + } + + $this->clientGet($url, $params); + } + + /** + * Internal callback, after OAuth + */ + public function oauth2callback(){ + if (array_key_exists('code', $_GET) && !empty($_GET['code'])){ + $code = $_GET['code']; + $url = $this->strategy['token_endpoint']; + $params = array( + 'code' => $code, + 'client_id' => $this->strategy['client_id'], + 'client_secret' => $this->strategy['client_secret'], + 'redirect_uri' => $this->strategy['redirect_uri'], + 'grant_type' => 'authorization_code' + ); + $response = $this->serverPost($url, $params, null, $headers); + + $results = json_decode($response); + + if (!empty($results) && !empty($results->access_token)){ + + $userinfo = $this->userinfo($results->access_token); + + + $this->auth = array( + 'uid' => $userinfo['id'], + 'info' => array(), + 'credentials' => array( + 'token' => $results->access_token, + 'expires' => date('c', time() + $results->expires_in) + ), + 'raw' => $userinfo + ); + + + if (!empty($results->refresh_token)) + { + $this->auth['credentials']['refresh_token'] = $results->refresh_token; + } + + $this->mapProfile($userinfo, 'name', 'info.name'); + $this->mapProfile($userinfo, 'email', 'info.email'); + $this->mapProfile($userinfo, 'given_name', 'info.first_name'); + $this->mapProfile($userinfo, 'family_name', 'info.last_name'); + $this->mapProfile($userinfo, 'picture', 'info.image'); + + $this->callback(); + } + else{ + $error = array( + 'code' => 'access_token_error', + 'message' => 'Failed when attempting to obtain access token', + 'raw' => array( + 'response' => $response, + 'headers' => $headers + ) + ); + $this->errorCallback($error); + } + } + else{ + $error = array( + 'code' => 'oauth2callback_error', + 'raw' => $_GET + ); + + $this->errorCallback($error); + } + } + + /** + * Queries Google API for user info + * + * @param string $access_token + * @return array Parsed JSON results + */ + private function userinfo($access_token){ + $options = [ + 'http' => [ + 'header' => "Authorization: Bearer {$access_token}\r\nAccept: application/json", + 'ignore_errors' => true, + 'method' => 'GET' + ] + ]; + + // Alterado para passar os headers corretamente e manter o uso do serverGet + $userinfo = $this->serverGet($this->strategy['userinfo_endpoint'], [], $options, $responseHeaders); + // $userinfo = $this->serverGet($this->strategy['userinfo_endpoint'], array('access_token' => $access_token), null, $headers); + + if (!empty($userinfo)){ + return $this->recursiveGetObjectVars(json_decode($userinfo)); + } + else{ + $error = array( + 'code' => 'userinfo_error', + 'message' => 'Failed when attempting to query for user information', + 'raw' => array( + 'response' => $userinfo, + 'headers' => $headers + ) + ); + $this->errorCallback($error); + } + } + + /** + * Atualiza dados do usuário autenticado a partir da resposta da estratégia Decidim. + * + * @param \MapasCulturais\Entities\User $user Usuário autenticado que terá os dados atualizados. + * @param array $response Resposta completa retornada pela estratégia Decidim. + * @return void + */ + public static function verifyUpdateData($user, $response) + { + $app = App::i(); + + $userinfo = (object) $response['auth']['raw']; + + self::getFile($user->profile, $userinfo->image); + } + + /** + * Faz o download de uma imagem remota e salva como avatar para o agente informado. + * + * @param \MapasCulturais\Entities\Agent $owner Agente proprietário do avatar. + * @param string|null $url URL da imagem a ser baixada. + * @return void + */ + public static function getFile($owner, $url){ + + $curl = new Curl; + $curl->get($url); + $curl->close(); + $response = $curl->response; + + if(mb_strpos($response, 'não encontrada')){ + return; + } + + $tmp = tempnam("/tmp", ""); + $handle = fopen($tmp, "wb"); + fwrite($handle,$response); + fclose($handle); + + // Confere MIME e extensões aceitas + if (!self::checkFileType($tmp)) { + unlink($tmp); + return; + } + + $mime = mime_content_type($tmp) ?: 'application/octet-stream'; + + $extension = match ($mime) { + 'image/jpeg', 'image/jpg' => 'jpg', + 'image/png' => 'png', + 'image/gif' => 'gif', + 'image/webp' => 'webp', + default => null, + }; + + if(!$extension) { + unlink($tmp); + return; + } + + $basename = sprintf('%s.%s', md5(uniqid('', true)), $extension); + + $class_name = $owner->fileClassName; + + $file = new $class_name([ + "name" => $basename, + "type" => $mime, + "tmp_name" => $tmp, + "error" => 0, + "size" => filesize($tmp) + ]); + + $file->group = "avatar"; + $file->owner = $owner; + $file->save(true); + + if(is_file($tmp)) { + unlink($tmp); + } + } + + /** + * Verifica se um arquivo temporário corresponde a um formato de imagem suportado. + * + * @param string $filename Caminho absoluto do arquivo temporário a ser verificado. + * @return bool Retorna true se o arquivo for uma imagem suportada; caso contrário, false. + */ + public static function checkFileType($filename) + { + $finfo = finfo_open(FILEINFO_MIME_TYPE); + $mimetype = finfo_file($finfo, $filename); + if ($mimetype == 'image/jpg' || $mimetype == 'image/jpeg' || $mimetype == 'image/gif' || $mimetype == 'image/png') { + $is_image = true; + } else { + $is_image = false; + } + + return $is_image; + } + +} diff --git a/Plugin.php b/Plugin.php index 9ad2020..94e4a8d 100644 --- a/Plugin.php +++ b/Plugin.php @@ -9,6 +9,7 @@ include('LinkedIn/LinkedInStrategy.php'); include('LoginCidadao/LoginCidadaoStrategy.php'); include('GovBr/GovBrStrategy.php'); +include('Decidim/DecidimStrategy.php'); class Plugin extends \MapasCulturais\Plugin { diff --git a/Provider.php b/Provider.php index a252964..477a745 100644 --- a/Provider.php +++ b/Provider.php @@ -1,11 +1,12 @@ 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 +66,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), @@ -109,6 +112,17 @@ function __construct ($config) { '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','[]') + ], + 'decidim' => [ + 'visible' => env('AUTH_DECIDIM_CLIENT_ID', false), + 'client_id' => env('AUTH_DECIDIM_CLIENT_ID', null), + 'client_secret' => env('AUTH_DECIDIM_CLIENT_SECRET', null), + 'redirect_uri' => env('AUTH_DECIDIM_REDIRECT_URI', null), + 'scope' => env('AUTH_DECIDIM_SCOPE', null), + 'auth_endpoint' => env('AUTH_DECIDIM_AUTH_ENDPOINT', null), + 'token_endpoint' => env('AUTH_DECIDIM_TOKEN_ENDPOINT', null), + 'userinfo_endpoint' => env('AUTH_DECIDIM_USERINFO_ENDPOINT', null), + 'button_text' => env('AUTH_DECIDIM_BUTTON_TEXT', 'Entrar com Decidim'), ] ] ]; @@ -335,6 +349,8 @@ protected function _init() { $login = $app->auth->doLogin(); if ($login['success']) { + $app->applyHook('auth.successful'); + $this->json([ 'error' => false, 'redirectTo' => $app->auth->getRedirectPath() @@ -548,29 +564,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; + } } } @@ -1161,6 +1180,15 @@ function doRegister() { $baseUrl = $app->getBaseUrl(); + if(!$user) { + $error['user']['createUser'] = i::__('Não foi possível criar o usuário. Entre em contato com suporte', 'multipleLocal'); + + return [ + 'success' => false, + 'errors' => $error + ]; + } + //ATENÇÃO !! Se for necessario "padronizar" os emails com header/footers, é necessario adapatar o 'mustache', e criar uma mini estrutura de pasta de emails em 'MultipleLocalAuth\views' $mustache = new \Mustache_Engine(); $site_name = $app->siteName; @@ -1195,7 +1223,8 @@ function doRegister() { $user->{self::$tokenVerifyAccountMetadata} = $token; $user->{self::$accountIsActiveMetadata} = '0'; $app->modules['LGPD']->acceptTerms($app->request->post('slugs'), $user); - $user->save(); + $user->save(true); + $app->enableAccessControl(); @@ -1296,7 +1325,7 @@ protected function _validateResponse(){ // verifica se a resposta é um erro if (array_key_exists('error', $response)) { - $app->flash('auth error', 'Opauth returns error auth response'); + // $app->flash('auth error', 'Opauth returns error auth response'); } else { /** * Auth response validation @@ -1424,24 +1453,33 @@ function authenticateUser(Entities\User $user) { $this->_setAuthenticatedUser($user); $_SESSION['multipleLocalUserId'] = $user->id; } - - protected function _createUser($response) { + + protected function _createUser($response) + { $app = App::i(); + /** @var \MapasCulturais\Connection $conn */ + $conn = $app->em->getConnection(); + $app->disableAccessControl(); $config = $this->_config; $user = null; - if($provider_class = $response['auth']['provider']."Strategy"){ - if(method_exists($provider_class, "newAccountCheck")){ - if($user = $provider_class::newAccountCheck($response)){ + if ($provider_class = $response['auth']['provider'] . "Strategy") { + if (method_exists($provider_class, "newAccountCheck")) { + if ($user = $provider_class::newAccountCheck($response)) { $agent = $user->profile; } } } - if(!$user){ + if ($user) { + return $user; + } + + try { + $app->em->beginTransaction(); // cria o usuário $user = new Entities\User; $user->authProvider = $response['auth']['provider']; @@ -1449,73 +1487,79 @@ protected function _createUser($response) { $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(isset($response['auth']['info']['name'])){ + 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'])){ + } 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'])){ + } elseif (isset($response['auth']['agentData']['name'])) { $agent->name = $response['auth']['agentData']['name']; - } - else{ + } else { $agent->name = ''; } - - if(isset($response['auth']['info']['phone_number'])){ - $metadataFieldPhone = $this->getMetadataFieldPhone(); - $metadataFieldPhone = $this->getMetadataFieldPhone(); - $metadataFieldPhone = $this->getMetadataFieldPhone(); + + 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']['shortDescription'])){ + if (isset($response['auth']['agentData']['shortDescription'])) { $agent->shortDescription = $response['auth']['agentData']['shortDescription']; } - if(isset($response['auth']['agentData']['terms:area'])){ + if (isset($response['auth']['agentData']['terms:area'])) { $agent->terms['area'] = $response['auth']['agentData']['terms:area']; } - if(isset($response['auth']['info']['phone_number'])){ - $metadataFieldPhone = $this->getMetadataFieldPhone(); + if (isset($response['auth']['info']['phone_number'])) { + $metadataFieldPhone = $this->getMetadataFieldPhone(); $agent->setMetadata($metadataFieldPhone, $response['auth']['info']['phone_number']); } //cpf - $cpf = (isset($response['auth']['info']['cpf']) && $response['auth']['info']['cpf'] != "") ? $this->mask($response['auth']['info']['cpf'],'###.###.###-##') : null; - if(!empty($cpf)){ - $metadataFieldCpf = $this->getMetadataFieldCpfFromConfig(); + $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; } $agent->status = (int) $config['statusCreateAgent'] ?? '0'; $agent->emailPrivado = $user->email; - - $agent->save(); - $app->em->flush(); + $agent->save(true); + $user->profile = $agent; $user->save(true); + if(!$conn->fetchScalar("SELECT profile_id FROM usr where id = {$user->id}")) { + throw new Exception("Error create agent"); + } + $user->createPermissionsCacheForUsers([$user]); $agent->createPermissionsCacheForUsers([$user]); - } - - $app->enableAccessControl(); - $redirectUrl = $agent->status == Agent::STATUS_DRAFT ? $agent->editUrl : $this->getRedirectPath(); - $app->applyHookBoundTo($this, 'auth.createUser:redirectUrl', [&$redirectUrl]); - if ($redirectUrl) { - $this->_setRedirectPath($redirectUrl); + $app->em->commit(); + + $app->enableAccessControl(); + $redirectUrl = $agent->status == Agent::STATUS_DRAFT ? $agent->editUrl : $this->getRedirectPath(); + $app->applyHookBoundTo($this, 'auth.createUser:redirectUrl', [&$redirectUrl]); + + if ($redirectUrl) { + $this->_setRedirectPath($redirectUrl); + } + + return $user; + + } catch (\Throwable $th) { + $app->em->rollback(); + return null; } - - return $user; } function mask($val, $mask) { diff --git a/README.md b/README.md index e910937..3a4a7db 100644 --- a/README.md +++ b/README.md @@ -1,117 +1,149 @@ # MultipleLocalAuth -Plugin que implementa um método de autenticação local para o Mapas Culturais, em conjunto com login via redes sociais. - -## Instalação e Configuração - -Faça download ou clone do plugin e coloque a pasta MultipleLocalAuth no pasta dos plugins do Mapas Culturais. - -No arquivo de configuração do Mapas Culturais, config.php, você deve: - -1. Ativar o plugin -2. Configurar MultipleLocalAuth como seu Provider de autenticação -3. Configurar as chaves das redes sociais - -Para ativar o plugin, adicione na sua array de Plugins: -``` +Plugin de autenticação para o Mapas Culturais que combina login local (e-mail e CPF) com múltiplas estratégias sociais (Google, Facebook, LinkedIn, Twitter, Login Cidadão, Gov.br, Decidim etc.), regras de senha configuráveis e proteção contra abuso. + +## Recursos principais +- Cadastro local com fluxo multi-etapas, validação de CPF e aceite de termos LGPD. +- Login por e-mail ou CPF, com limite de tentativas e bloqueio temporário automático. +- Confirmação de conta por e-mail, recuperação de senha com token e troca de senha pelo painel. +- Integração com Google reCAPTCHA v2 (visível) para login, cadastro e recuperação. +- Autenticação social via Opauth (Google, Facebook, LinkedIn, Twitter, Login Cidadão, Gov.br, Decidim) com mapeamento automático de dados. +- Atualização opcional de avatar e metadados ao autenticar via Gov.br ou Decidim. +- Componentes Vue (`login`, `create-account`, `change-password`, `password-strongness`) prontos para a Base V2. + +## Instalação +1. Faça download/clonagem deste repositório e coloque a pasta `MultipleLocalAuth` em `protected/application/plugins/` do Mapas Culturais. +2. Garanta que o módulo `LGPD` esteja habilitado, pois o cadastro consome `LGPD::acceptTerms`. +3. Instale dependências do Mapas Culturais (este plugin não adiciona dependências externas além das que já vêm com o core/opauth). + +## Configuração +Edite `config.php` do Mapas Culturais: + +```php 'plugins' => [ // ... outros plugins 'MultipleLocalAuth' => [ 'namespace' => 'MultipleLocalAuth', ], ], -``` - -Para definir este plugin como seu método de autenticação, defina a configuraço *auth.provider*: -``` -'auth.provider' => '\MultipleLocalAuth\Provider', -``` -Finalmente, defina a configuração *auth.config* para definir as estratégias utilizadas e as chaves dos serviços: +'auth.provider' => \MultipleLocalAuth\Provider::class, -``` 'auth.config' => [ - - //SALT da senha do usuario - 'salt' => 'LT_SECURITY_SALT_SECURITY_SALT_SECURITY_SALT_SECURITY_SALT_SECU', - - 'timeout' => '24 hours', - - //url de suporte por chat para ser enviado nos emails - 'urlSupportChat' => 'https://www.google.com', - - //url de suporte por email para ser enviado nos emails - 'urlSupportEmail' => 'https://www.google.com', - - //url do site de suporte para ser enviado nos emails - 'urlSupportSite' => 'https://www.google.com', - - //url dos termos de uso para utilizar a plataforma - 'urlTermsOfUse' => 'https://www.google.com', - - //url de uma imagem para ser enviado como plano de fundo nos emails - 'urlImageToUseInEmails' => 'https://mapacultural.juazeiro.ce.gov.br/files/project/1561/file/963893/blob-3d922310b0a1eb1c16791a06023f56df.png', - - //Habilita registro e login através do CPF - 'enableLoginByCPF' => true, - - //apelido do metadata que será salvo o campo CPF - 'metadataFieldCPF' => 'documento', - - //Regra para saber se o usuario deve ou não confiar o email para poder utilizar o sistema - 'userMustConfirmEmailToUseTheSystem' => false, - - //Regra de força de senha - Ter no mínimo 1 letra maiúscula - 'passwordMustHaveCapitalLetters' => true, - - //Regra de força de senha - Ter no mínimo 1 letra minúscula - 'passwordMustHaveLowercaseLetters' => true, - - //Regra de força de senha - Ter no mínimo 1 caractere especial - 'passwordMustHaveSpecialCharacters' => true, - - //Regra de força de senha - Ter no mínimo 1 caractere numérico - 'passwordMustHaveNumbers' => true, - - //Regra de força de senha - Ter no mínimo n caracteres - 'minimumPasswordLength' => 6, - - //Configuração de GOOGLE Recaptcha - 'google-recaptcha-secret' => '6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe', - 'google-recaptcha-sitekey' => '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI', - - //Tempo da sessao do usuario em segundos - 'sessionTime' => 7200, - - //Limite de tentativas não sucedidas de login antes de bloquear o usuario por X minutos - 'numberloginAttemp' => '5', - - //Tempo de bloqueio do usuario em segundos, após romper limites de tentativas não sucedidas - 'timeBlockedloginAttemp' => '900', - - //Estratégias de autenticação - 'strategies' => [ - 'Facebook' => array( - 'app_id' => 'SUA_APP_ID', - 'app_secret' => 'SUA_APP_SECRET', - 'scope' => 'email' - ), - 'LinkedIn' => array( - 'api_key' => 'SUA_API_KEY', - 'secret_key' => 'SUA_SECRET_KEY', - 'redirect_uri' => URL_DO_SEU_SITE . '/autenticacao/linkedin/oauth2callback', - 'scope' => 'r_emailaddress' - ), - 'Google' => array( - 'client_id' => 'SEU_CLIENT_ID', - 'client_secret' => 'SEU_CLIENT_SECRET', - 'redirect_uri' => URL_DO_SEU_SITE . '/autenticacao/google/oauth2callback', - 'scope' => 'email' - ), - 'Twitter' => array( - 'app_id' => 'SUA_APP_ID', - 'app_secret' => 'SUA_APP_SECRET', - ), - ] + // ajuste conforme as tabelas abaixo ], ``` + +### Opções gerais +| Chave | Descrição | Padrão | Variável `.env` | +| --- | --- | --- | --- | +| `salt` | Salt usado pelo Opauth | `env('AUTH_SALT')` | `AUTH_SALT` | +| `timeout` | Tempo máximo da sessão OAuth | `24 hours` | `AUTH_TIMEOUT` | +| `loginOnRegister` | Autenticar automaticamente após cadastro | `false` | `AUTH_LOGIN_ON_REGISTER` | +| `enableLoginByCPF` | Permite login/cadastro via CPF | `true` | `AUTH_LOGIN_BY_CPF` | +| `requireCpf` | Exige CPF no cadastro | `true` | `AUTH_REQUIRED_CPF` | +| `metadataFieldCPF` | Campo de metadata que armazena CPF | `documento` | `AUTH_METADATA_FIELD_DOCUMENT` | +| `metadataFieldPhone` | Campo de metadata que armazena telefone | `telefone1` | `AUTH_METADATA_FIELD_PHONE` | +| `userMustConfirmEmailToUseTheSystem` | Exige validação por e-mail antes do uso | `false` | `AUTH_EMAIL_CONFIRMATION` | +| `sessionTime` | Duração da sessão (segundos) | `7200` | `AUTH_SESSION_TIME` | +| `statusCreateAgent` | Status default do agente criado | `Agent::STATUS_ENABLED` | `STATUS_CREATE_AGENT` | + +### Comunicação e suporte +| Chave | Uso | Padrão | Variável `.env` | +| --- | --- | --- | --- | +| `urlSupportChat` | Link incluído nos e-mails | `''` | `AUTH_SUPPORT_CHAT` | +| `urlSupportEmail` | Link de contato por e-mail | `''` | `AUTH_SUPPORT_EMAIL` | +| `urlSupportSite` | URL geral de suporte | `''` | `AUTH_SUPPORT_SITE` | +| `textSupportSite` | Texto exibido com o link | `''` | `AUTH_SUPPORT_TEXT` | +| `urlImageToUseInEmails` | Imagem de fundo para e-mails | `null` | `AUTH_EMAIL_IMAGE` | +| `urlTermsOfUse` | URL dos termos de uso | `auth/termos-e-condicoes` | `LINK_TERMOS` | + +### Regras de senha +| Chave | Descrição | Padrão | Variável `.env` | +| --- | --- | --- | --- | +| `passwordMustHaveCapitalLetters` | Exigir letra maiúscula | `true` | `AUTH_PASS_CAPITAL_LETTERS` | +| `passwordMustHaveLowercaseLetters` | Exigir letra minúscula | `true` | `AUTH_PASS_LOWERCASE_LETTERS` | +| `passwordMustHaveSpecialCharacters` | Exigir caractere especial | `true` | `AUTH_PASS_SPECIAL_CHARS` | +| `passwordMustHaveNumbers` | Exigir número | `true` | `AUTH_PASS_NUMBERS` | +| `minimumPasswordLength` | Tamanho mínimo da senha | `6` | `AUTH_PASS_LENGTH` | + +### Proteção contra abuso +| Chave | Descrição | Padrão | Variável `.env` | +| --- | --- | --- | --- | +| `numberloginAttemp` | Tentativas antes do bloqueio | `5` | `AUTH_NUMBER_ATTEMPTS` | +| `timeBlockedloginAttemp` | Tempo de bloqueio (segundos) | `900` | `AUTH_BLOCK_TIME` | + +### Google reCAPTCHA v2 +| Chave | Descrição | Padrão | +| --- | --- | --- | +| `google-recaptcha-secret` | Secret da integração | `env('GOOGLE_RECAPTCHA_SECRET')` | +| `google-recaptcha-sitekey` | Site key usada no front | `env('GOOGLE_RECAPTCHA_SITEKEY')` | + +Se ambas as chaves estiverem ausentes, o captcha é desativado. + +### Estratégias de autenticação +Cada estratégia pode receber `visible => bool` para controlar se o botão aparece na interface. + +#### Google +- `client_id`, `client_secret`, `redirect_uri`, `scope` (`email profile` por padrão). + +#### Facebook +- `app_id`, `app_secret`, `scope` (default `email`). + +#### LinkedIn +- `api_key`, `secret_key`, `redirect_uri`, `scope` (default `r_emailaddress`). + +#### Twitter +- `app_id`, `app_secret`. (Fluxo direto do Opauth). + +#### Login Cidadão +- `client_id`, `client_secret`, `auth_endpoint`, `token_endpoint`, `userinfo_endpoint`, `redirect_uri`, `scope`. + +#### Gov.br +- `client_id`, `client_secret`, `scope`, `auth_endpoint`, `token_endpoint`, `userinfo_endpoint`, `redirect_uri`. +- `state_salt`, `code_verifier`, `code_challenge`, `code_challenge_method` para PKCE. +- `applySealId` (opcional): selo aplicado ao agente autenticado. +- `dic_agent_fields_update`: mapa de campos que podem ser atualizados automaticamente (JSON, ex: `{"name": "full_name"}`). +- `menssagem_authenticated`: mensagem exibida quando o usuário já autenticou via Gov.br. + +#### Decidim +- `client_id`, `client_secret`, `auth_endpoint`, `token_endpoint`, `userinfo_endpoint`, `redirect_uri`, `scope`. +- Atualiza automaticamente avatar do agente com a imagem fornecida. + +Você pode adicionar ou remover estratégias conforme necessário; qualquer estratégia Opauth disponível no diretório do plugin pode ser configurada. + +## Fluxos e endpoints +- `GET auth.index`: renderiza o componente de login. +- `GET auth.register`: fluxo multi-etapas de cadastro. +- `GET auth.recover`: formulário para solicitar redefinição de senha. +- `GET auth.confirma-email`: valida o token enviado por e-mail e ativa a conta. +- `POST auth.validate`: validação assíncrona do primeiro passo do cadastro. +- `POST auth.register`: criação de conta (gera agente, token de verificação e envia e-mail). +- `POST auth.login`: autenticação local (com bloqueio por tentativas via metadata). +- `POST auth.recover` / `POST auth.dorecover`: solicitação e conclusão da recuperação de senha. +- `POST auth.changepassword` / `POST auth.newpassword`: alteração de senha logado ou via token. +- `POST auth.adminchangeuseremail` / `POST auth.adminchangeuserpassword`: rotinas administrativas (acessos protegidos). +- `GET auth.passwordvalidationinfos`: retorna as regras de senha atuais para o front-end. + +## Componentes que acompanham o plugin +- `components/login`: formulário de login com reCAPTCHA, recuperação de senha e botões sociais. +- `components/create-account`: esteira de cadastro com validações de senha, CPF e aceite de termos LGPD. +- `components/change-password`: formulário para troca de senha no painel. +- `components/password-strongness`: barra de força da senha, reutilizada em cadastro e redefinição. + +Todos os componentes carregam textos a partir de `components/*/texts.php`, permitindo tradução personalizada. + +## Personalização +- E-mails: templates Mustache em `views/auth/email-to-validate-account.html` e `views/auth/email-resert-password.html`. Você pode copiar/adaptar mantendo as variáveis esperadas. +- Telas: `views/auth/*.php` rendem os componentes Vue; é possível sobrescrever esses arquivos em um tema customizado. +- Estilos: CSS compilado em `assets/css/plugin-MultiplLocalAuth.css`. O SCSS-fonte está em `assets-src/sass/`. +- Traduções: arquivos `.po` em `translations/` (domínio `multipleLocal`). + +## Boas práticas +- Configure o cron/serviço de fila de e-mail do Mapas Culturais antes de habilitar a confirmação por e-mail. +- Ajuste `metadataFieldCPF`/`metadataFieldPhone` para corresponder ao schema de metadados do seu deployment. +- Revise as mensagens carregadas via `textSupportSite`, `urlSupport*` para garantir contato adequado ao usuário. +- Gere URLs de callback das estratégias sociais com HTTPS e defina-as nos painéis dos provedores. + +--- +Mantemos este documento atualizado a partir do código-fonte do plugin. Contribuições são bem-vindas! \ No newline at end of file diff --git a/components/create-account/script.js b/components/create-account/script.js index bc83102..a7e4d8c 100644 --- a/components/create-account/script.js +++ b/components/create-account/script.js @@ -300,6 +300,17 @@ app.component('create-account', { if (this.agent.terms.area.length == 0) { errors.agent.push(__('Área de atuação obrigatória', 'create-account')); } + + // Validação de campos obrigatórios das taxonomias + Object.keys($TAXONOMIES).forEach(taxonomy => { + const t = $TAXONOMIES[taxonomy]; + if (t.required && t.entities.includes('MapasCulturais\\Entities\\Agent')) { + if(this.agent.terms[taxonomy].length == 0) { + errors.agent.push(`${t.description} ${__('required', 'create-account')}`); + } + } + }); + if (errors.agent.length > 0) { this.throwErrors(errors); return false; diff --git a/components/create-account/template.php b/components/create-account/template.php index a776a64..3f125fa 100644 --- a/components/create-account/template.php +++ b/components/create-account/template.php @@ -15,6 +15,8 @@ mc-stepper password-strongness '); + +$taxonomies = $app->getRegisteredTaxonomies("MapasCulturais\Entities\Agent"); ?>
@@ -105,7 +107,12 @@ prop="name" fieldDescription=""> "> - "> + + + required): ?> + + + diff --git a/components/create-account/texts.php b/components/create-account/texts.php index 775370e..db2b025 100644 --- a/components/create-account/texts.php +++ b/components/create-account/texts.php @@ -5,5 +5,6 @@ 'Nome obrigatório' => i::__('O nome é obrigatório!'), 'Descrição obrigatória' => i::__('A descrição é obrigatória!'), 'Área de atuação obrigatória' => i::__('A área de atuação é obrigatória!'), + 'required' => i::__('é um campo obrigatório!'), ]; \ No newline at end of file diff --git a/components/login/template.php b/components/login/template.php index 1ddbe24..b1d6f80 100644 --- a/components/login/template.php +++ b/components/login/template.php @@ -60,6 +60,10 @@ + + {{configs.strategies.decidim.button_text}} + +
diff --git a/translations/es_AR.mo b/translations/es_AR.mo new file mode 100644 index 0000000..aeb86e6 Binary files /dev/null and b/translations/es_AR.mo differ diff --git a/translations/es_AR.po b/translations/es_AR.po new file mode 100644 index 0000000..e332910 --- /dev/null +++ b/translations/es_AR.po @@ -0,0 +1,598 @@ +msgid "" +msgstr "" +"Project-Id-Version: Multiple Local Auth\n" +"POT-Creation-Date: 2024-02-28 11:07-0300\n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: es_ES\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.4.2\n" +"X-Poedit-Basepath: ..\n" +"X-Poedit-KeywordsList: _e;__;esc_attr_e;i::__\n" +"X-Poedit-SourceCharset: UTF-8\n" +"X-Poedit-SearchPath-0: .\n" + +#: Plugin.php:42 +msgid "modificar senha" +msgstr "modificar contraseña" + +#: Plugin.php:53 components/change-password/template.php:33 +#: components/create-account/template.php:56 components/login/template.php:36 +#: components/login/template.php:125 +msgid "Senha" +msgstr "Contraseña" + +#: Plugin.php:54 +msgid "Token para recuperação de senha" +msgstr "Token de recuperación de contraseña" + +#: Plugin.php:55 +msgid "Timestamp do token para recuperação de senha" +msgstr "Marca de tiempo del token para la recuperación de la contraseña" + +#: Plugin.php:56 +msgid "Conta ativa?" +msgstr "¿Cuenta activa?" + +#: Plugin.php:57 +msgid "Token de verificação" +msgstr "Token de verificación" + +#: Plugin.php:58 +msgid "Número de tentativas de login" +msgstr "Número de intentos de inicio de sesión" + +#: Plugin.php:59 +msgid "Tempo de bloqueio por excesso de tentativas" +msgstr "Tiempo de bloqueo debido a intentos excesivos" + +#: Provider.php:161 +msgid "Token inválidos" +msgstr "Token incorrectos" + +#: Provider.php:422 +msgid "Minha conta" +msgstr "Mi cuenta" + +#: Provider.php:524 +msgid "Sua senha deve conter pelo menos " +msgstr "La contraseña debe contener al menos " + +#: Provider.php:527 +msgid " Sua senha deve conter pelo menos 1 número!" +msgstr " ¡Su contraseña debe contener al menos 1 número!" + +#: Provider.php:530 +msgid " Sua senha deve conter pelo menos 1 letra maiúscula!" +msgstr " ¡Su contraseña debe contener al menos 1 letra mayúscula !" + +#: Provider.php:533 +msgid " Sua senha deve conter pelo menos 1 letra minúscula!" +msgstr " ¡Su contraseña debe contener al menos 1 letra minúscula!" + +#: Provider.php:536 +msgid " Sua senha deve conter pelo menos 1 caractere especial!" +msgstr " ¡Su contraseña debe contener al menos 1 carácter especial!" + +#: Provider.php:539 +msgid "Por favor, insira sua senha." +msgstr "Por favor, introduzca su contraseña." + +#: Provider.php:543 +msgid "As senhas não conferem." +msgstr "Las contraseñas no coinciden." + +#: Provider.php:575 Provider.php:742 Provider.php:1031 +msgid "Captcha incorreto, tente novamente!" +msgstr "¡Captcha incorrecto, inténtalo de nuevo!" + +#: Provider.php:587 +msgid "Por favor, informe um cpf válido." +msgstr "Por favor, introduzca una ci válida." + +#: Provider.php:611 +msgid "Este CPF já esta em uso. Tente recuperar a sua senha." +msgstr "Esta CI ya está en uso. Intente recuperar su contraseña." + +#: Provider.php:622 +msgid "Este endereço de email já está em uso. Tente recuperar a sua senha." +msgstr "" +"Esta dirección de correo electrónico ya está en uso. Intente recuperar su " +"contraseña." + +#: Provider.php:628 +msgid "Por favor, informe um email válido." +msgstr "Por favor, ingrese un correo electrónico válido." + +#: Provider.php:675 +msgid "Token não encontrado." +msgstr "Token no encontrado." + +#: Provider.php:694 +msgid "Este token expirou." +msgstr "Este token expiró." + +#: Provider.php:750 +msgid "Email não encontrado" +msgstr "Email no encontrado" + +#: Provider.php:776 +#, php-format +msgid "Pedido de recuperação de senha para %s" +msgstr "Pedido de recuperación de contraseña para %s" + +#: Provider.php:811 +msgid "" +"Erro ao enviar email de recuperação. Entre em contato com os administradors " +"do site." +msgstr "" +"Error al enviar el correo electrónico de recuperación. Entre en contacto con " +"los administradores del sitio." + +#: Provider.php:848 Provider.php:899 +msgid "Insira sua nova senha." +msgstr "Agregar su nueva contraseña." + +#: Provider.php:894 +msgid "Senha atual inválida." +msgstr "Contraseña actual incorrecta." + +#: Provider.php:921 +msgid "A senha deve conter uma letra maiúscula" +msgstr "La contraseña debe contener una letra mayúscula" + +#: Provider.php:922 +msgid "A senha deve conter uma letra minúscula" +msgstr "La contraseña debe contener una letra minúscula" + +#: Provider.php:923 +msgid "A senha deve conter um caractere especial" +msgstr "La contraseña debe contener un carácter especial" + +#: Provider.php:924 +msgid "A senha deve conter um número " +msgstr "La contraseña debe contener un número " + +#: Provider.php:925 +msgid "O tamanho mínimo da senha é de: " +msgstr "La longitud mínima de la contraseña es: " + +#: Provider.php:1062 +msgid "CPF ou senha incorreta, tente novamente!" +msgstr "¡CI o contraseña incorrecta, inténtalo de nuevo!" + +#: Provider.php:1084 +msgid "" +"Você possui 2 ou mais agente com o mesmo CPF! Por favor entre em contato com " +"o suporte." +msgstr "" +"¡Tienes 2 o más agentes con la misma CI! Por favor contacta al servicio de " +"soporte." + +#: Provider.php:1089 +msgid "" +"Você possui 2 ou mais agentes inativos com o mesmo CPF! Por favor entre em " +"contato com o suporte." +msgstr "" +"¡Tienes 2 o más agentes inactivos con la misma CI! Por favor contacta con el " +"servicio de soporte." + +#: Provider.php:1095 +msgid "CPF ou senha incorreta. Utilize o CPF do seu agente principal." +msgstr "CI o contraseña incorrectas. Utilice la CI de su agente principal." + +#: Provider.php:1115 Provider.php:1149 +msgid "Usuário ou senha inválidos." +msgstr "Usuario o contraseña incorrectos." + +#: Provider.php:1121 +msgid "Verifique seu email para validar a sua conta." +msgstr "Revise su correo electrónico para validar su cuenta." + +#: Provider.php:1130 +msgid "Login bloqueado, tente novamente em " +msgstr "Inicio de sesión bloqueado, inténtalo de nuevo en " + +#: Provider.php:1455 +msgid "É preciso estar autenticado para realizar esta ação" +msgstr "Es preciso está autenticado para realizar esta acción" + +#: components/change-password/template.php:15 +msgid "Senha:" +msgstr "Contraseña:" + +#: components/change-password/template.php:27 +#: views/panel/multiple-local-auth--my-account.php:33 +msgid "Senha atual" +msgstr "Contraseña actual" + +#: components/change-password/template.php:37 +msgid "A senha deve ter:" +msgstr "La contraseña debe tener:" + +#: components/change-password/template.php:38 +msgid "" +" caracteres, um número, um caractere especial (! @ # $ & *), pelo menos uma " +"letra maiúscula e uma minúscula." +msgstr "" +" caracteres, un número, un carácter especial (! @ # $ & *), al menos una " +"letra mayúscula y una letra minúscula." + +#: components/change-password/template.php:43 +msgid "Confirme a senha" +msgstr "Confirmar contraseña" + +#: components/change-password/template.php:54 +#: components/change-password/template.php:59 components/login/template.php:93 +msgid "Alterar senha" +msgstr "Cambiar contraseña" + +#: components/change-password/template.php:60 +msgid "Cancelar" +msgstr "Cancelar" + +#: components/create-account/script.js:302 +msgid "Nome obrigatório" +msgstr "Nombre obligatorio" + +#: components/create-account/script.js:305 +msgid "Descrição obrigatória" +msgstr "Descripción obligatoria" + +#: components/create-account/script.js:308 +msgid "Área de atuação obrigatória" +msgstr "Área de actuación obligatoria" + +#: components/create-account/template.php:23 +msgid "Novo cadastro" +msgstr "Nuevo registro" + +#: components/create-account/template.php:24 +#, php-format +msgid "Siga os passos para criar o seu cadastro no %s." +msgstr "Siga los pasos para crear su registro en %s." + +#: components/create-account/template.php:38 components/login/template.php:89 +msgid "E-mail" +msgstr "E-mail" + +#: components/create-account/template.php:43 +msgid "CPF" +msgstr "CI" + +#: components/create-account/template.php:46 +msgid "Por que pedimos este dado" +msgstr "Por qué pedimos este dato" + +#: components/create-account/template.php:48 +msgid "Texto sobre o motivo da coleta do CPF" +msgstr "Texto sobre el motivo de la recogida del dato de la CI" + +#: components/create-account/template.php:62 +msgid "Confirme sua senha" +msgstr "Confirmar contraseña" + +#: components/create-account/template.php:71 +msgid "Continuar" +msgstr "Continuar" + +#: components/create-account/template.php:79 components/login/template.php:55 +msgid "Entrar com Gov.br" +msgstr "Entrar con Gob.uy" + +#: components/create-account/template.php:83 components/login/template.php:60 +msgid "Entrar com Google" +msgstr "Entrar con Google" + +#: components/create-account/template.php:94 +msgid "Voltar e excluir minhas informações" +msgstr "Volver atrás y borrar mi información" + +#: components/create-account/template.php:101 +msgid "Falta pouco para finalizar o seu cadastro!" +msgstr "Queda poco para que finalice su registro!" + +#: components/create-account/template.php:102 +msgid "Dê um nome e faça uma breve descrição sua." +msgstr "Ponte un nombre y una breve descripción." + +#: components/create-account/template.php:106 +msgid "Nome" +msgstr "Nombre" + +#: components/create-account/template.php:106 +msgid "As pessoas irão encontrar você por esse nome." +msgstr "Las personas te encontrarán por ese nombre." + +#: components/create-account/template.php:107 +msgid "Mini Bio" +msgstr "Mini Bio" + +#: components/create-account/template.php:108 +msgid "Área de atuação" +msgstr "Área de actuación" + +#: components/create-account/template.php:112 +msgid "Criar cadastro" +msgstr "Crear registro" + +#: components/create-account/template.php:123 +msgid "E-mail de confirmação enviado!" +msgstr "Confirmación enviada por correo electrónico!" + +#: components/create-account/template.php:124 +msgid "Seu cadastro foi criado com sucesso!" +msgstr "Su registro fue realizado con éxito!" + +#: components/create-account/template.php:127 +#, php-format +msgid "Acesse seu e-mail para confirmar a criação de seu cadastro no %s." +msgstr "" +"Acceda a su correo electrónico para confirmar la creación de su registro en " +"%s." + +#: components/create-account/template.php:129 +msgid "Acessar meu cadastro" +msgstr "Acceder a mi inscripción" + +#: components/create-account/texts.php:5 +msgid "O nome é obrigatório!" +msgstr "El nombre es obligatorio!" + +#: components/create-account/texts.php:6 +msgid "A descrição é obrigatória!" +msgstr "La descripción es obligatoria!" + +#: components/create-account/texts.php:7 +msgid "A área de atuação é obrigatória!" +msgstr "El área de actuación es obligatoria!" + +#: components/login/template.php:23 +msgid "Boas vindas!" +msgstr "Bienvenid@!" + +#: components/login/template.php:24 +#, php-format +msgid "Entre na sua conta do %s" +msgstr "Entre en su cuenta de %s" + +#: components/login/template.php:31 +msgid "E-mail ou CPF" +msgstr "E-mail o CI" + +#: components/login/template.php:38 +msgid "Esqueci minha senha" +msgstr "Olvidé mi contraseña" + +#: components/login/template.php:46 +msgid "Entrar" +msgstr "Ingresar" + +#: components/login/template.php:49 +msgid "Ou entre com" +msgstr "O entre con" + +#: components/login/template.php:67 +#, php-format +msgid "Ainda não tem cadastro no %s? Realize seu cadastro agora!" +msgstr "Todavía no está registrado en %s? Realice su registro ahora!" + +#: components/login/template.php:70 +msgid "Fazer cadastro" +msgstr "Hacer registro" + +#: components/login/template.php:82 components/login/template.php:103 +#: views/auth/confirm-email.php:20 +msgid "Alteração de senha" +msgstr "Cambio de contraseña" + +#: components/login/template.php:83 +msgid "Se você esqueceu a senha, não se preocupe, todo mundo passa por isso." +msgstr "" +"Si has olvidado tu contraseña, no te preocupes, todo el mundo pasa por eso." + +#: components/login/template.php:83 +msgid "Digite seu e-mail para criar uma nova." +msgstr "Escriba su correo electrónico para crear su cuenta." + +#: components/login/template.php:94 components/login/template.php:109 +#: views/auth/register.php:16 +msgid "Voltar" +msgstr "Volver" + +#: components/login/template.php:105 views/auth/confirm-email.php:22 +msgid "Enviamos as instruções de alteração de senha para seu e-mail." +msgstr "" +"Enviamos las instrucciones para el cambio de contraseña a su correo " +"electrónico." + +#: components/login/template.php:108 +msgid "Não recebi o e-mail" +msgstr "No recibí el correo electrónico" + +#: components/login/template.php:119 +msgid "Redefinir senha de acesso" +msgstr "Redefinir contraseña de acceso" + +#: components/login/template.php:131 +msgid "Confirme sua nova senha" +msgstr "Confirmar nueva contraseña" + +#: components/login/template.php:139 +msgid "Redefinir senha" +msgstr "Redefinir contraseña" + +#: components/password-strongness/template.php:12 +msgid "Força da senha" +msgstr "Fuerza de la contraseña" + +#: components/password-strongness/template.php:18 +msgid "A senha deve conter:" +msgstr "La contraseña debe contener:" + +#: components/password-strongness/texts.php:6 +msgid "{num} caracteres" +msgstr "{num} caracteres" + +#: components/password-strongness/texts.php:7 +msgid "pelo menos uma letra maiúscula" +msgstr "por lo menos una letra mayúscula" + +#: components/password-strongness/texts.php:8 +msgid "pelo menos uma letra minúscula" +msgstr "por lo menos una letra mayúscula" + +#: components/password-strongness/texts.php:9 +msgid "um caracter especial (! @ # $ % & * < > ?)" +msgstr "un carácter especial (! @ # $ % & * < > ?)" + +#: components/password-strongness/texts.php:10 +msgid "um número" +msgstr "un número" + +#: views/auth/confirm-email.php:25 +msgid "Entrar na minha conta" +msgstr "Entrar a mi cuenta" + +#: views/panel/multiple-local-auth--my-account.php:19 +#: views/panel/multiple-local-auth--my-account.php:53 +msgid "Guardar alteraçoes" +msgstr "Guardar cambios" + +#: views/panel/multiple-local-auth--my-account.php:20 +msgid "Trocar e-mail" +msgstr "Cambiar contraseña" + +#: views/panel/multiple-local-auth--my-account.php:24 +msgid "Email" +msgstr "E-mail" + +#: views/panel/multiple-local-auth--my-account.php:30 +msgid "Trocar Senha" +msgstr "Cambiar contraseña" + +#: views/panel/multiple-local-auth--my-account.php:40 +msgid "Nova senha" +msgstr "Nueva contraseña" + +#: views/panel/multiple-local-auth--my-account.php:48 +msgid "Confirmar nova senha" +msgstr "Confirmar nueva contraseña" + +#: views/panel/multiple-local-auth--my-account.php:65 +msgid "Vincular conta com" +msgstr "Vincular cuenta con" + +#~ msgid "Email validado com sucesso" +#~ msgstr "Email validado con éxito" + +#~ msgid "Senha alterada com sucesso. Agora você pode fazer login" +#~ msgstr "Contraseña cambiada con éxito! Usted puede ingresar ahora" + +#~ msgid "Por favor, informe seu nome" +#~ msgstr "Por favor, ingrese su nombre" + +#~ msgid "Este endereço de email já está em uso" +#~ msgstr "Esta dirección de email ya está en uso" + +#~ msgid "Email alterado com sucesso" +#~ msgstr "Email cambiado con éxito" + +#~ msgid "Informe um email válido" +#~ msgstr "Ingrese un email válido" + +#~ msgid "Email e senha alterados com sucecsso" +#~ msgstr "Email y contraseña cambiados con éxito" + +#~ msgid "Senha alterada com sucesso" +#~ msgstr "Contraseña cambiada con éxito" + +#~ msgid "Email ou token inválidos" +#~ msgstr "Email o token incorrectos" + +#~ msgid "Senha alterada com sucesso! Você pode fazer login agora" +#~ msgstr "Contraseña cambiada con éxito! Ahora puede ingresar" + +#~ msgid "" +#~ "Sucesso: Um e-mail foi enviado com instruções para recuperação da senha." +#~ msgstr "" +#~ "Un mensaje de correo electrónico fue enviado con instrucciones para " +#~ "recuperar la contraseña." + +#~ msgid "CPF ou senha incorreta" +#~ msgstr "CI o contraseña incorrectas" + +#~ msgid "Sucesso: Um e-mail lhe foi enviado com detalhes sobre a plataforma " +#~ msgstr "" +#~ "Éxito: se le envió un correo electrónico con detalles sobre la plataforma " + +#~ msgid "Informação" +#~ msgstr "Información" + +#~ msgid "Clique aqui para entrar no sistema" +#~ msgstr "Haga clic aquí para ingresar al sistema" + +#~ msgid "Se você já possui uma conta no " +#~ msgstr "Si ya tiene una cuenta en " + +#~ msgid "esqueci a senha" +#~ msgstr "olvidé mi contraseña" + +#~ msgid "Ou conecte usando sua conta em" +#~ msgstr "O conéctese usando su cuenta en" + +#~ msgid "Ainda não possui uma conta?" +#~ msgstr "¿Aún no tienes una cuenta?" + +#~ msgid "Crie uma conta agora" +#~ msgstr "Cree una cuenta ahora" + +#~ msgid "Para recuperar sua senha, informe o e-mail utilizado no cadastro." +#~ msgstr "" +#~ "Para recuperar su contraseña, informe el e-mail utilizado en su registro." + +#~ msgid "Se ainda não possui conta no " +#~ msgstr "Si no tiene una cuenta en " + +#~ msgid "Criar Conta" +#~ msgstr "Crear cuenta" + +#~ msgid "Recuperar" +#~ msgstr "Recuperar" + +#~ msgid "" +#~ "Alguém solicitou a recuperação da senha utilizada em %s por este email.\n" +#~ "\n" +#~ "Para recuperá-la, acesse o link: %s. /n/n Se você não pediu a recuperação " +#~ "desta senha, apenas ignore esta mensagem." +#~ msgstr "" +#~ "Alguien solicitó la recuperación de contraseña utilizada en %s por este " +#~ "email.\n" +#~ "\n" +#~ "Para recuperarla, haga clic en el link: %s./n/n Si usted no pidió la " +#~ "recuperación de esta contraseña, ignore este mensaje." + +#~ msgid "Registrar-se" +#~ msgstr "Registrarse" + +#~ msgid "Redes Sociais" +#~ msgstr "Redes Sociales" + +#~ msgid "Utilize sua conta em outros serviços para autenticar-se" +#~ msgstr "Utilice su cuenta en otros servicios para autenticarse" + +#~ msgid "Clique para marcar/desmarcar este" +#~ msgstr "Haga clic para marcar/desmarcar este" + +#~ msgid "Este" +#~ msgstr "Este" + +#~ msgid "Para relacionar o selo ao" +#~ msgstr "Para relacionar el sello al" + +#~ msgid "teste pt" +#~ msgstr "teste es" diff --git a/translations/es_ES.mo b/translations/es_ES.mo old mode 100644 new mode 100755 index 4172e6c..4e28068 Binary files a/translations/es_ES.mo and b/translations/es_ES.mo differ diff --git a/translations/es_ES.po b/translations/es_ES.po old mode 100644 new mode 100755 index 8cf5ccc..f4a9f10 --- a/translations/es_ES.po +++ b/translations/es_ES.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: Multiple Local Auth\n" -"POT-Creation-Date: 2017-01-12 02:36-0300\n" +"POT-Creation-Date: 2025-04-07 19:07-0300\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -9,193 +9,521 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.5.4\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.6\n" "X-Poedit-Basepath: ..\n" "X-Poedit-KeywordsList: _e;__;esc_attr_e;i::__\n" "X-Poedit-SourceCharset: UTF-8\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-SearchPath-0: .\n" +"X-Poedit-SearchPathExcluded-0: assets\n" + +#: Plugin.php:42 +msgid "modificar senha" +msgstr "modificar contraseña" + +#: Plugin.php:53 components/change-password/template.php:33 +#: components/create-account/template.php:56 components/login/template.php:36 +#: components/login/template.php:125 +msgid "Senha" +msgstr "Contraseña" + +#: Plugin.php:54 +msgid "Token para recuperação de senha" +msgstr "Token de recuperación de contraseña" + +#: Plugin.php:55 +msgid "Timestamp do token para recuperação de senha" +msgstr "Marca de tiempo del token para la recuperación de la contraseña" -#: Provider.php:119 +#: Plugin.php:56 +msgid "Conta ativa?" +msgstr "¿Cuenta activa?" + +#: Plugin.php:57 +msgid "Token de verificação" +msgstr "Token de verificación" + +#: Plugin.php:58 +msgid "Número de tentativas de login" +msgstr "Número de intentos de inicio de sesión" + +#: Plugin.php:59 +msgid "Tempo de bloqueio por excesso de tentativas" +msgstr "Tiempo de bloqueo debido a intentos excesivos" + +#: Provider.php:163 +msgid "Token inválidos" +msgstr "Token incorrectos" + +#: Provider.php:424 msgid "Minha conta" msgstr "Mi cuenta" -#: Provider.php:152 -msgid "A senha deve conter no mínimo 6 caracteres" -msgstr "La contraseña debe contener al menos 6 caracteres" +#: Provider.php:488 +msgid "Sua senha deve conter pelo menos " +msgstr "La contraseña debe contener al menos " + +#: Provider.php:491 +msgid " Sua senha deve conter pelo menos 1 número!" +msgstr " ¡Su contraseña debe contener al menos 1 número!" -#: Provider.php:155 -msgid "As senhas não conferem" -msgstr "Las contraseñas no coinciden" +#: Provider.php:494 +msgid " Sua senha deve conter pelo menos 1 letra maiúscula!" +msgstr " ¡Su contraseña debe contener al menos 1 letra mayúscula !" -#: Provider.php:173 -msgid "Por favor, informe seu nome" -msgstr "Por favor, ingrese su nombre" +#: Provider.php:497 +msgid " Sua senha deve conter pelo menos 1 letra minúscula!" +msgstr " ¡Su contraseña debe contener al menos 1 letra minúscula!" -#: Provider.php:178 -msgid "Este endereço de email já está em uso" -msgstr "Esta dirección de email ya está en uso" +#: Provider.php:500 +msgid " Sua senha deve conter pelo menos 1 caractere especial!" +msgstr " ¡Su contraseña debe contener al menos 1 carácter especial!" -#: Provider.php:182 -msgid "Por favor, informe um email válido" -msgstr "Por favor, ingrese un email válido" +#: Provider.php:503 +msgid "Por favor, insira sua senha." +msgstr "Por favor, introduzca su contraseña." -#: Provider.php:207 -msgid "Email alterado com sucesso" -msgstr "Email cambiado con éxito" +#: Provider.php:507 +msgid "As senhas não conferem." +msgstr "Las contraseñas no coinciden." -#: Provider.php:210 -msgid "Informe um email válido" -msgstr "Ingrese un email válido" +#: Provider.php:542 Provider.php:708 Provider.php:997 +msgid "Captcha incorreto, tente novamente!" +msgstr "¡Captcha incorrecto, inténtalo de nuevo!" -#: Provider.php:227 -msgid "Email e senha alterados com sucecsso" -msgstr "Email y contraseña cambiados con éxito" +#: Provider.php:554 +msgid "Por favor, informe um cpf válido." +msgstr "Por favor, introduzca una ci válida." -#: Provider.php:227 -msgid "Senha alterada com sucesso" -msgstr "Contraseña cambiada con éxito" +#: Provider.php:576 +msgid "Este CPF já esta em uso. Tente recuperar a sua senha." +msgstr "Esta CI ya está en uso. Intente recuperar su contraseña." -#: Provider.php:234 -msgid "Senha inválida" -msgstr "Contraseña incorrecta" +#: Provider.php:588 +msgid "Este endereço de email já está em uso. Tente recuperar a sua senha." +msgstr "" +"Esta dirección de correo electrónico ya está en uso. Intente recuperar su " +"contraseña." -#: Provider.php:269 Provider.php:279 -msgid "Email ou token inválidos" -msgstr "Email o token incorrectos" +#: Provider.php:594 +msgid "Por favor, informe um email válido." +msgstr "Por favor, ingrese un correo electrónico válido." -#: Provider.php:290 -msgid "Este token expirou" -msgstr "Este token expiró" +#: Provider.php:641 +msgid "Token não encontrado." +msgstr "Token no encontrado." -#: Provider.php:305 -msgid "Senha alterada com sucesso! Você pode fazer login agora" -msgstr "Contraseña cambiada con éxito! Ahora puede ingresar" +#: Provider.php:660 +msgid "Este token expirou." +msgstr "Este token expiró." -#: Provider.php:318 +#: Provider.php:716 msgid "Email não encontrado" msgstr "Email no encontrado" -#: Provider.php:337 +#: Provider.php:742 #, php-format msgid "Pedido de recuperação de senha para %s" msgstr "Pedido de recuperación de contraseña para %s" -#: Provider.php:338 -#, php-format +#: Provider.php:777 msgid "" -"Alguém solicitou a recuperação da senha utilizada em %s por este email.\n" -"\n" -"Para recuperá-la, acesse o link: %s. /n/n Se você não pediu a recuperação " -"desta senha, apenas ignore esta mensagem." +"Erro ao enviar email de recuperação. Entre em contato com os administradors " +"do site." msgstr "" -"Alguien solicitó la recuperación de contraseña utilizada en %s por este " -"email.\n" -"\n" -"Para recuperarla, haga clic en el link: %s./n/n Si usted no pidió la " -"recuperación de esta contraseña, ignore este mensaje." +"Error al enviar el correo electrónico de recuperación. Entre en contacto con " +"los administradores del sitio." + +#: Provider.php:814 Provider.php:865 +msgid "Insira sua nova senha." +msgstr "Ingrese su nueva contraseña." + +#: Provider.php:860 +msgid "Senha atual inválida." +msgstr "Contraseña actual no válida." + +#: Provider.php:887 +msgid "A senha deve conter uma letra maiúscula" +msgstr "La contraseña debe contener una letra mayúscula" + +#: Provider.php:888 +msgid "A senha deve conter uma letra minúscula" +msgstr "La contraseña debe contener una letra minúscula" -#: Provider.php:355 +#: Provider.php:889 +msgid "A senha deve conter um caractere especial" +msgstr "La contraseña debe contener un carácter especial" + +#: Provider.php:890 +msgid "A senha deve conter um número " +msgstr "La contraseña debe contener un número " + +#: Provider.php:891 +msgid "O tamanho mínimo da senha é de: " +msgstr "La longitud mínima de la contraseña es: " + +#: Provider.php:1028 +msgid "CPF ou senha incorreta, tente novamente!" +msgstr "¡CI o contraseña incorrecta, inténtalo de nuevo!" + +#: Provider.php:1050 msgid "" -"Sucesso: Um e-mail foi enviado com instruções para recuperação da senha." +"Você possui 2 ou mais agente com o mesmo CPF! Por favor entre em contato com " +"o suporte." msgstr "" -"Un mensaje de correo electrónico fue enviado con instrucciones para " -"recuperar la contraseña." +"¡Tienes 2 o más agentes con la misma CI! Por favor contacta al servicio de " +"soporte." -#: Provider.php:358 +#: Provider.php:1055 msgid "" -"Erro ao enviar email de recuperação. Entre em contato com os administradors " -"do site." +"Você possui 2 ou mais agentes inativos com o mesmo CPF! Por favor entre em " +"contato com o suporte." msgstr "" -"Error al enviar el correo electrónico de recuperación. Entre en contacto con " -"los administradores del sitio." +"¡Tienes 2 o más agentes inactivos con la misma CI! Por favor contacta con el " +"servicio de soporte." -#: Provider.php:384 Provider.php:397 -msgid "Usuário ou senha inválidos" -msgstr "Usuario o contraseña incorrectos" +#: Provider.php:1061 +msgid "CPF ou senha incorreta. Utilize o CPF do seu agente principal." +msgstr "CI o contraseña incorrectas. Utilice la CI de su agente principal." -#: Provider.php:598 +#: Provider.php:1081 Provider.php:1115 +msgid "Usuário ou senha inválidos." +msgstr "Usuario o contraseña incorrectos." + +#: Provider.php:1087 +msgid "Verifique seu email para validar a sua conta." +msgstr "Revise su correo electrónico para validar su cuenta." + +#: Provider.php:1096 +msgid "Login bloqueado, tente novamente em " +msgstr "Inicio de sesión bloqueado, inténtalo de nuevo en " + +#: Provider.php:1421 msgid "É preciso estar autenticado para realizar esta ação" msgstr "Es preciso está autenticado para realizar esta acción" -#: views/auth/multiple-local.php:22 views/auth/multiple-local.php:33 -msgid "Entrar" -msgstr "Ingresar" +#: components/change-password/template.php:15 +msgid "Senha:" +msgstr "Contraseña:" + +#: components/change-password/template.php:27 +msgid "Senha atual" +msgstr "Contraseña actual" + +#: components/change-password/template.php:37 +msgid "A senha deve ter:" +msgstr "La contraseña debe tener:" + +#: components/change-password/template.php:38 +msgid "" +" caracteres, um número, um caractere especial (! @ # $ & *), pelo menos uma " +"letra maiúscula e uma minúscula." +msgstr "" +" caracteres, un número, un carácter especial (!@#$&*), al menos una letra " +"mayúscula y una minúscula." + +#: components/change-password/template.php:43 +msgid "Confirme a senha" +msgstr "Confirmar contraseña" + +#: components/change-password/template.php:54 +#: components/change-password/template.php:59 components/login/template.php:93 +msgid "Alterar senha" +msgstr "Cambiar contraseña" -#: views/auth/multiple-local.php:27 views/auth/multiple-local.php:48 -#: views/auth/multiple-local.php:72 views/auth/pass-recover.php:16 +#: components/change-password/template.php:60 +msgid "Cancelar" +msgstr "Cancelar" + +#: components/create-account/script.js:295 +msgid "Nome obrigatório" +msgstr "Nombre obligatorio" + +#: components/create-account/script.js:298 +msgid "Descrição obrigatória" +msgstr "Descripción obligatoria" + +#: components/create-account/script.js:301 +msgid "Área de atuação obrigatória" +msgstr "Área de actuación obligatoria" + +#: components/create-account/template.php:23 +msgid "Novo cadastro" +msgstr "Nuevo registro" + +#: components/create-account/template.php:24 +#, php-format +msgid "Siga os passos para criar o seu cadastro no %s." +msgstr "Siga los pasos para crear su registro en %s." + +#: components/create-account/template.php:38 components/login/template.php:89 msgid "E-mail" msgstr "E-mail" -#: views/auth/multiple-local.php:30 views/auth/multiple-local.php:75 -#: views/auth/pass-recover.php:19 -msgid "Senha" -msgstr "Contraseña" +#: components/create-account/template.php:43 +msgid "CPF" +msgstr "CI" -#: views/auth/multiple-local.php:35 views/auth/multiple-local.php:43 -msgid "Esqueci minha senha" -msgstr "Olvidé mi contraseña" +#: components/create-account/template.php:46 +msgid "Por que pedimos este dado" +msgstr "Por qué pedimos este dato" + +#: components/create-account/template.php:48 +msgid "Texto sobre o motivo da coleta do CPF" +msgstr "Texto sobre el motivo de la recogida del dato de la CI" + +#: components/create-account/template.php:62 +msgid "Confirme sua senha" +msgstr "Confirmar contraseña" -#: views/auth/multiple-local.php:47 -msgid "Para recuperar sua senha, informe o e-mail utilizado no cadastro." +#: components/create-account/template.php:71 +msgid "Continuar" +msgstr "Continuar" + +#: components/create-account/template.php:79 components/login/template.php:55 +msgid "Entrar com Gov.br" msgstr "" -"Para recuperar su contraseña, informe el e-mail utilizado en su registro." -#: views/auth/multiple-local.php:52 views/auth/pass-recover.php:3 -msgid "Recuperar senha" -msgstr "Recuperar contraseña" +#: components/create-account/template.php:83 components/login/template.php:60 +msgid "Entrar com Google" +msgstr "Entrar con Google" -#: views/auth/multiple-local.php:54 -msgid "Cancelar" -msgstr "Cancelar" +#: components/create-account/template.php:94 +msgid "Voltar e excluir minhas informações" +msgstr "Regresar y borrar mi información" + +#: components/create-account/template.php:101 +msgid "Falta pouco para finalizar o seu cadastro!" +msgstr "Queda poco para que finalice su registro!" -#: views/auth/multiple-local.php:63 views/auth/multiple-local.php:81 -msgid "Registrar-se" -msgstr "Registrarse" +#: components/create-account/template.php:102 +msgid "Dê um nome e faça uma breve descrição sua." +msgstr "Ponte un nombre y haz una breve descripción de ti mismo." -#: views/auth/multiple-local.php:69 +#: components/create-account/template.php:106 msgid "Nome" msgstr "Nombre" -#: views/auth/multiple-local.php:78 views/auth/pass-recover.php:22 -msgid "Confirmar senha" -msgstr "Confirmar contraseña" +#: components/create-account/template.php:106 +msgid "As pessoas irão encontrar você por esse nome." +msgstr "Las personas te encontrarán por ese nombre." -#: views/auth/multiple-local.php:88 -msgid "Redes Sociais" -msgstr "Redes Sociales" +#: components/create-account/template.php:107 +msgid "Mini Bio" +msgstr "Mini Bio" -#: views/auth/multiple-local.php:91 -msgid "Utilize sua conta em outros serviços para autenticar-se" -msgstr "Utilice su cuenta en otros servicios para autenticarse" +#: components/create-account/template.php:108 +msgid "Área de atuação" +msgstr "Área de actuación" -#: views/auth/pass-recover.php:25 -msgid "Recuperar" -msgstr "Recuperar" +#: components/create-account/template.php:112 +msgid "Criar cadastro" +msgstr "Crear registro" -#: views/panel/my-account.php:15 views/panel/my-account.php:18 -msgid "Email" -msgstr "E-mail" +#: components/create-account/template.php:123 +msgid "E-mail de confirmação enviado!" +msgstr "¡Correo electrónico de confirmación enviado!" -#: views/panel/my-account.php:22 views/panel/my-account.php:35 -msgid "Guardar alteraçoes" -msgstr "Guardar cambios" +#: components/create-account/template.php:124 +msgid "Seu cadastro foi criado com sucesso!" +msgstr "Su registro fue creado con éxito!" -#: views/panel/my-account.php:24 -msgid "Trocar Senha" -msgstr "Cambiar contraseña" +#: components/create-account/template.php:127 +#, php-format +msgid "Acesse seu e-mail para confirmar a criação de seu cadastro no %s." +msgstr "" +"Acceda a su correo electrónico para confirmar la creación de su registro en " +"%s." -#: views/panel/my-account.php:26 -msgid "Senha atual" -msgstr "Contraseña actual" +#: components/create-account/template.php:129 +msgid "Acessar meu cadastro" +msgstr "Acceder a mi registro" + +#: components/create-account/texts.php:5 +msgid "O nome é obrigatório!" +msgstr "El nombre es obligatorio!" + +#: components/create-account/texts.php:6 +msgid "A descrição é obrigatória!" +msgstr "La descripción es obligatoria!" + +#: components/create-account/texts.php:7 +msgid "A área de atuação é obrigatória!" +msgstr "El área de actuación es obligatoria!" + +#: components/login/template.php:23 +msgid "Boas vindas!" +msgstr "Bienvenid@!" + +#: components/login/template.php:24 +#, php-format +msgid "Entre na sua conta do %s" +msgstr "Entre en su cuenta de %s" + +#: components/login/template.php:31 +msgid "E-mail ou CPF" +msgstr "E-mail o CI" + +#: components/login/template.php:38 +msgid "Esqueci minha senha" +msgstr "Olvidé mi contraseña" + +#: components/login/template.php:46 +msgid "Entrar" +msgstr "Ingresar" + +#: components/login/template.php:49 +msgid "Ou entre com" +msgstr "O entre con" + +#: components/login/template.php:67 +#, php-format +msgid "Ainda não tem cadastro no %s? Realize seu cadastro agora!" +msgstr "Todavía no está registrado en %s? Realiza el registro ahora!" + +#: components/login/template.php:70 +msgid "Fazer cadastro" +msgstr "Hacer registro" + +#: components/login/template.php:82 components/login/template.php:103 +#: views/auth/confirm-email.php:20 +msgid "Alteração de senha" +msgstr "Cambio de contraseña" + +#: components/login/template.php:83 +msgid "Se você esqueceu a senha, não se preocupe, todo mundo passa por isso." +msgstr "" +"Si has olvidado tu contraseña, no te preocupes, todo el mundo pasa por eso." + +#: components/login/template.php:83 +msgid "Digite seu e-mail para criar uma nova." +msgstr "Introduzca su dirección de correo electrónico para crear una nueva." + +#: components/login/template.php:94 components/login/template.php:109 +#: views/auth/register.php:16 +msgid "Voltar" +msgstr "Volver" + +#: components/login/template.php:105 views/auth/confirm-email.php:22 +msgid "Enviamos as instruções de alteração de senha para seu e-mail." +msgstr "" +"Enviamos las instrucciones para el cambio de contraseña a su correo " +"electrónico." + +#: components/login/template.php:108 +msgid "Não recebi o e-mail" +msgstr "No recibí el correo electrónico" + +#: components/login/template.php:119 +msgid "Redefinir senha de acesso" +msgstr "Redefinir contraseña de acceso" + +#: components/login/template.php:131 +msgid "Confirme sua nova senha" +msgstr "Confirme su nueva contraseña" + +#: components/login/template.php:139 +msgid "Redefinir senha" +msgstr "Redefinir contraseña" + +#: components/password-strongness/template.php:12 +msgid "Força da senha" +msgstr "Fuerza de la contraseña" + +#: components/password-strongness/template.php:18 +msgid "A senha deve conter:" +msgstr "La contraseña debe contener:" + +#: components/password-strongness/texts.php:6 +msgid "{num} caracteres" +msgstr "{num} caracteres" + +#: components/password-strongness/texts.php:7 +msgid "pelo menos uma letra maiúscula" +msgstr "por lo menos una letra mayúscula" + +#: components/password-strongness/texts.php:8 +msgid "pelo menos uma letra minúscula" +msgstr "por lo menos una letra minúscula" + +#: components/password-strongness/texts.php:9 +msgid "um caracter especial (! @ # $ % & * < > ?)" +msgstr "un carácter especial (! @ # $ % & * < > ?)" + +#: components/password-strongness/texts.php:10 +msgid "um número" +msgstr "un número" + +#: views/auth/confirm-email.php:25 +msgid "Entrar na minha conta" +msgstr "Entrar a mi cuenta" + +#~ msgid "Guardar alteraçoes" +#~ msgstr "Guardar cambios" + +#~ msgid "Trocar e-mail" +#~ msgstr "Cambiar e-mail" + +#~ msgid "Email" +#~ msgstr "E-mail" + +#~ msgid "Trocar Senha" +#~ msgstr "Cambiar contraseña" + +#~ msgid "Nova senha" +#~ msgstr "Nueva contraseña" + +#~ msgid "Confirmar nova senha" +#~ msgstr "Confirme su nueva contraseña" + +#~ msgid "Vincular conta com" +#~ msgstr "Vincular cuenta con" + +#~ msgid "Email alterado com sucesso" +#~ msgstr "Email cambiado con éxito" + +#~ msgid "Informe um email válido" +#~ msgstr "Ingrese un email válido" + +#~ msgid "Email e senha alterados com sucecsso" +#~ msgstr "Email y contraseña cambiados con éxito" + +#~ msgid "Senha alterada com sucesso! Você pode fazer login agora" +#~ msgstr "Contraseña cambiada con éxito! Ahora puede ingresar" + +#~ msgid "" +#~ "Alguém solicitou a recuperação da senha utilizada em %s por este email.\n" +#~ "\n" +#~ "Para recuperá-la, acesse o link: %s. /n/n Se você não pediu a recuperação " +#~ "desta senha, apenas ignore esta mensagem." +#~ msgstr "" +#~ "Alguien solicitó la recuperación de contraseña utilizada en %s por este " +#~ "email.\n" +#~ "\n" +#~ "Para recuperarla, haga clic en el link: %s./n/n Si usted no pidió la " +#~ "recuperación de esta contraseña, ignore este mensaje." + +#~ msgid "" +#~ "Sucesso: Um e-mail foi enviado com instruções para recuperação da senha." +#~ msgstr "" +#~ "Un mensaje de correo electrónico fue enviado con instrucciones para " +#~ "recuperar la contraseña." + +#~ msgid "Para recuperar sua senha, informe o e-mail utilizado no cadastro." +#~ msgstr "" +#~ "Para recuperar su contraseña, informe el e-mail utilizado en su registro." + +#~ msgid "Registrar-se" +#~ msgstr "Registrarse" + +#~ msgid "Redes Sociais" +#~ msgstr "Redes Sociales" -#: views/panel/my-account.php:29 -msgid "Nova senha" -msgstr "Nueva contraseña" +#~ msgid "Utilize sua conta em outros serviços para autenticar-se" +#~ msgstr "Utilice su cuenta en otros servicios para autenticarse" -#: views/panel/my-account.php:32 -msgid "Confirmar nova senha" -msgstr "Confirmar nueva contraseña" +#~ msgid "Recuperar" +#~ msgstr "Recuperar" #~ msgid "Clique para marcar/desmarcar este" #~ msgstr "Haga clic para marcar/desmarcar este"