mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-10-24 02:07:00 +08:00
chore(i18n,learn): processed translations (#48372)
This commit is contained in:
+17
-3
@@ -58,13 +58,27 @@ myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('Frank Roosevelt'));
|
||||
```
|
||||
|
||||
يجب عليك استخدام `.test()` لاختبار الـ regex.
|
||||
Your regex `myRegex` should return `false` for the string `FranklinRoosevelt`
|
||||
|
||||
```js
|
||||
myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('FranklinRoosevelt'));
|
||||
```
|
||||
|
||||
Your regex `myRegex` should return `false` for the string `EleanorRoosevelt`
|
||||
|
||||
```js
|
||||
myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('EleanorRoosevelt'));
|
||||
```
|
||||
|
||||
You should use `.test()` to test the regex.
|
||||
|
||||
```js
|
||||
assert(code.match(/myRegex.test\(\s*myString\s*\)/));
|
||||
```
|
||||
|
||||
يجب أن ترجع نتيجتك `true`.
|
||||
Your result should return `true`.
|
||||
|
||||
```js
|
||||
assert(result === true);
|
||||
@@ -85,6 +99,6 @@ let result = false; // Change this line
|
||||
|
||||
```js
|
||||
let myString = "Eleanor Roosevelt";
|
||||
let myRegex = /(Franklin|Eleanor).*Roosevelt/;
|
||||
let myRegex = /(Franklin|Eleanor) (([A-Z]\.?|[A-Z][a-z]+) )?Roosevelt/;
|
||||
let result = myRegex.test(myString);
|
||||
```
|
||||
|
||||
+17
-3
@@ -58,13 +58,27 @@ myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('Frank Roosevelt'));
|
||||
```
|
||||
|
||||
你應該使用 `.test()` 方法來檢測正則表達式。
|
||||
Your regex `myRegex` should return `false` for the string `FranklinRoosevelt`
|
||||
|
||||
```js
|
||||
myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('FranklinRoosevelt'));
|
||||
```
|
||||
|
||||
Your regex `myRegex` should return `false` for the string `EleanorRoosevelt`
|
||||
|
||||
```js
|
||||
myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('EleanorRoosevelt'));
|
||||
```
|
||||
|
||||
You should use `.test()` to test the regex.
|
||||
|
||||
```js
|
||||
assert(code.match(/myRegex.test\(\s*myString\s*\)/));
|
||||
```
|
||||
|
||||
你的返回結果應該爲 `true`。
|
||||
Your result should return `true`.
|
||||
|
||||
```js
|
||||
assert(result === true);
|
||||
@@ -85,6 +99,6 @@ let result = false; // Change this line
|
||||
|
||||
```js
|
||||
let myString = "Eleanor Roosevelt";
|
||||
let myRegex = /(Franklin|Eleanor).*Roosevelt/;
|
||||
let myRegex = /(Franklin|Eleanor) (([A-Z]\.?|[A-Z][a-z]+) )?Roosevelt/;
|
||||
let result = myRegex.test(myString);
|
||||
```
|
||||
|
||||
+17
-3
@@ -58,13 +58,27 @@ myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('Frank Roosevelt'));
|
||||
```
|
||||
|
||||
你应该使用 `.test()` 方法来检测正则表达式。
|
||||
Your regex `myRegex` should return `false` for the string `FranklinRoosevelt`
|
||||
|
||||
```js
|
||||
myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('FranklinRoosevelt'));
|
||||
```
|
||||
|
||||
Your regex `myRegex` should return `false` for the string `EleanorRoosevelt`
|
||||
|
||||
```js
|
||||
myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('EleanorRoosevelt'));
|
||||
```
|
||||
|
||||
You should use `.test()` to test the regex.
|
||||
|
||||
```js
|
||||
assert(code.match(/myRegex.test\(\s*myString\s*\)/));
|
||||
```
|
||||
|
||||
你的返回结果应该为 `true`。
|
||||
Your result should return `true`.
|
||||
|
||||
```js
|
||||
assert(result === true);
|
||||
@@ -85,6 +99,6 @@ let result = false; // Change this line
|
||||
|
||||
```js
|
||||
let myString = "Eleanor Roosevelt";
|
||||
let myRegex = /(Franklin|Eleanor).*Roosevelt/;
|
||||
let myRegex = /(Franklin|Eleanor) (([A-Z]\.?|[A-Z][a-z]+) )?Roosevelt/;
|
||||
let result = myRegex.test(myString);
|
||||
```
|
||||
|
||||
+17
-3
@@ -58,13 +58,27 @@ myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('Frank Roosevelt'));
|
||||
```
|
||||
|
||||
Debes usar `.test()` para probar la expresión regular.
|
||||
Your regex `myRegex` should return `false` for the string `FranklinRoosevelt`
|
||||
|
||||
```js
|
||||
myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('FranklinRoosevelt'));
|
||||
```
|
||||
|
||||
Your regex `myRegex` should return `false` for the string `EleanorRoosevelt`
|
||||
|
||||
```js
|
||||
myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('EleanorRoosevelt'));
|
||||
```
|
||||
|
||||
You should use `.test()` to test the regex.
|
||||
|
||||
```js
|
||||
assert(code.match(/myRegex.test\(\s*myString\s*\)/));
|
||||
```
|
||||
|
||||
Tu resultado debe devolver `true`.
|
||||
Your result should return `true`.
|
||||
|
||||
```js
|
||||
assert(result === true);
|
||||
@@ -85,6 +99,6 @@ let result = false; // Change this line
|
||||
|
||||
```js
|
||||
let myString = "Eleanor Roosevelt";
|
||||
let myRegex = /(Franklin|Eleanor).*Roosevelt/;
|
||||
let myRegex = /(Franklin|Eleanor) (([A-Z]\.?|[A-Z][a-z]+) )?Roosevelt/;
|
||||
let result = myRegex.test(myString);
|
||||
```
|
||||
|
||||
+17
-3
@@ -58,13 +58,27 @@ myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('Frank Roosevelt'));
|
||||
```
|
||||
|
||||
Du solltest `.test()` verwenden, um den regulären Ausdruck zu testen.
|
||||
Your regex `myRegex` should return `false` for the string `FranklinRoosevelt`
|
||||
|
||||
```js
|
||||
myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('FranklinRoosevelt'));
|
||||
```
|
||||
|
||||
Your regex `myRegex` should return `false` for the string `EleanorRoosevelt`
|
||||
|
||||
```js
|
||||
myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('EleanorRoosevelt'));
|
||||
```
|
||||
|
||||
You should use `.test()` to test the regex.
|
||||
|
||||
```js
|
||||
assert(code.match(/myRegex.test\(\s*myString\s*\)/));
|
||||
```
|
||||
|
||||
Dein Ergebnis sollte `true` zurückgeben.
|
||||
Your result should return `true`.
|
||||
|
||||
```js
|
||||
assert(result === true);
|
||||
@@ -85,6 +99,6 @@ let result = false; // Change this line
|
||||
|
||||
```js
|
||||
let myString = "Eleanor Roosevelt";
|
||||
let myRegex = /(Franklin|Eleanor).*Roosevelt/;
|
||||
let myRegex = /(Franklin|Eleanor) (([A-Z]\.?|[A-Z][a-z]+) )?Roosevelt/;
|
||||
let result = myRegex.test(myString);
|
||||
```
|
||||
|
||||
+17
-3
@@ -58,13 +58,27 @@ myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('Frank Roosevelt'));
|
||||
```
|
||||
|
||||
Dovresti usare `.test()` per testare l'espressione regolare.
|
||||
Your regex `myRegex` should return `false` for the string `FranklinRoosevelt`
|
||||
|
||||
```js
|
||||
myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('FranklinRoosevelt'));
|
||||
```
|
||||
|
||||
Your regex `myRegex` should return `false` for the string `EleanorRoosevelt`
|
||||
|
||||
```js
|
||||
myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('EleanorRoosevelt'));
|
||||
```
|
||||
|
||||
You should use `.test()` to test the regex.
|
||||
|
||||
```js
|
||||
assert(code.match(/myRegex.test\(\s*myString\s*\)/));
|
||||
```
|
||||
|
||||
Il tuo risultato dovrebbe restituire `true`.
|
||||
Your result should return `true`.
|
||||
|
||||
```js
|
||||
assert(result === true);
|
||||
@@ -85,6 +99,6 @@ let result = false; // Change this line
|
||||
|
||||
```js
|
||||
let myString = "Eleanor Roosevelt";
|
||||
let myRegex = /(Franklin|Eleanor).*Roosevelt/;
|
||||
let myRegex = /(Franklin|Eleanor) (([A-Z]\.?|[A-Z][a-z]+) )?Roosevelt/;
|
||||
let result = myRegex.test(myString);
|
||||
```
|
||||
|
||||
+17
-3
@@ -58,13 +58,27 @@ myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('Frank Roosevelt'));
|
||||
```
|
||||
|
||||
正規表現をテストするには `.test()` を使用する必要があります。
|
||||
Your regex `myRegex` should return `false` for the string `FranklinRoosevelt`
|
||||
|
||||
```js
|
||||
myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('FranklinRoosevelt'));
|
||||
```
|
||||
|
||||
Your regex `myRegex` should return `false` for the string `EleanorRoosevelt`
|
||||
|
||||
```js
|
||||
myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('EleanorRoosevelt'));
|
||||
```
|
||||
|
||||
You should use `.test()` to test the regex.
|
||||
|
||||
```js
|
||||
assert(code.match(/myRegex.test\(\s*myString\s*\)/));
|
||||
```
|
||||
|
||||
結果は `true` を返す必要があります。
|
||||
Your result should return `true`.
|
||||
|
||||
```js
|
||||
assert(result === true);
|
||||
@@ -85,6 +99,6 @@ let result = false; // Change this line
|
||||
|
||||
```js
|
||||
let myString = "Eleanor Roosevelt";
|
||||
let myRegex = /(Franklin|Eleanor).*Roosevelt/;
|
||||
let myRegex = /(Franklin|Eleanor) (([A-Z]\.?|[A-Z][a-z]+) )?Roosevelt/;
|
||||
let result = myRegex.test(myString);
|
||||
```
|
||||
|
||||
+17
-3
@@ -58,13 +58,27 @@ myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('Frank Roosevelt'));
|
||||
```
|
||||
|
||||
Você deve usar `.test()` para testar a regex.
|
||||
Your regex `myRegex` should return `false` for the string `FranklinRoosevelt`
|
||||
|
||||
```js
|
||||
myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('FranklinRoosevelt'));
|
||||
```
|
||||
|
||||
Your regex `myRegex` should return `false` for the string `EleanorRoosevelt`
|
||||
|
||||
```js
|
||||
myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('EleanorRoosevelt'));
|
||||
```
|
||||
|
||||
You should use `.test()` to test the regex.
|
||||
|
||||
```js
|
||||
assert(code.match(/myRegex.test\(\s*myString\s*\)/));
|
||||
```
|
||||
|
||||
O resultado deve ser `true`.
|
||||
Your result should return `true`.
|
||||
|
||||
```js
|
||||
assert(result === true);
|
||||
@@ -85,6 +99,6 @@ let result = false; // Change this line
|
||||
|
||||
```js
|
||||
let myString = "Eleanor Roosevelt";
|
||||
let myRegex = /(Franklin|Eleanor).*Roosevelt/;
|
||||
let myRegex = /(Franklin|Eleanor) (([A-Z]\.?|[A-Z][a-z]+) )?Roosevelt/;
|
||||
let result = myRegex.test(myString);
|
||||
```
|
||||
|
||||
+4
-4
@@ -8,9 +8,9 @@ dashedName: announce-new-users
|
||||
|
||||
# --description--
|
||||
|
||||
Muitas salas de bate-papo são capazes de anunciar quando um usuário conecta ou desconecta e, em seguida, exibem isso para todos os usuários conectados no bate-papo. Considerando que você já está emitindo um evento ao se conectar e desconectar, você só terá que modificar esse evento para dar suporte a esse recurso. The most logical way of doing so is sending 3 pieces of data with the event: the username of the user who connected/disconnected, the current user count, and if that username connected or disconnected.
|
||||
Muitas salas de bate-papo são capazes de anunciar quando um usuário conecta ou desconecta e, em seguida, exibem isso para todos os usuários conectados no bate-papo. Considerando que você já está emitindo um evento ao se conectar e desconectar, você só terá que modificar esse evento para dar suporte a esse recurso. A maneira mais lógica de fazer isso é enviando 3 dados com o evento: o nome do usuário que se conectou/desconectou, a contagem de usuário atual e se esse nome de usuário conectou ou desconectou.
|
||||
|
||||
Change the event name to `'user'`, and pass an object along containing the fields `username`, `currentUsers`, and `connected` (to be `true` in case of connection, or `false` for disconnection of the user sent). Be sure to change both `'user count'` events and set the disconnect one to send `false` for the field `connected` instead of `true` like the event emitted on connect.
|
||||
Altere o nome do evento para `'user'` e passe um objeto junto com o evento contendo os campos `username`, `currentUsers` e `connected` (para ser `true` no caso de conexão, ou `false` em caso de desconexão do usuário). Certifique-se de alterar os dois eventos `'user count'` e defina o evento de desconexão para que envie `false` para o campo `connected` em vez de `true` como ocorre quando o evento é emitido ao conectar.
|
||||
|
||||
```js
|
||||
io.emit('user', {
|
||||
@@ -34,11 +34,11 @@ socket.on('user', data => {
|
||||
});
|
||||
```
|
||||
|
||||
Envie sua página quando você achar que ela está certa. If you're running into errors, you can check out <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135/3#announce-new-users-10" target="_blank" rel="noopener noreferrer nofollow">the project completed up to this point </a>.
|
||||
Envie sua página quando você achar que ela está certa. Se estiver encontrando erros, pode conferir <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135/3#announce-new-users-10" target="_blank" rel="noopener noreferrer nofollow">o projeto concluído até este ponto</a>.
|
||||
|
||||
# --hints--
|
||||
|
||||
Event `'user'` should be emitted with `name`, `currentUsers`, and `connected`.
|
||||
O evento `'user'` deve ser emitido com `name`, `currentUsers` e `connected`.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
|
||||
+7
-7
@@ -10,13 +10,13 @@ dashedName: authentication-strategies
|
||||
|
||||
Uma estratégia é uma maneira de autenticar um usuário. Você pode usar uma estratégia para permitir que os usuários se autentiquem com base em informações salvas localmente (se você os tem registrados primeiro) ou em uma variedade de provedores, como o Google ou o GitHub. Para este projeto, usaremos o middleware chamado Passaport. O Passaport fornece um conjunto abrangente de estratégias que suportam a autenticação usando um nome de usuário e senha, GitHub, Google e muito mais.
|
||||
|
||||
`passport-local@~1.0.0` has already been added as a dependency. Add it to your server as follows:
|
||||
`passport-local@~1.0.0` já foi adicionado como uma dependência. Adicione-o ao servidor da seguinte forma:
|
||||
|
||||
```javascript
|
||||
const LocalStrategy = require('passport-local');
|
||||
```
|
||||
|
||||
Tell passport to **use** an instantiated `LocalStrategy` object with a few settings defined. Make sure this (as well as everything from this point on) is encapsulated in the database connection since it relies on it!:
|
||||
Diga ao passport para **usar** um objeto `LocalStrategy` instanciado com algumas configurações definidas. Certifique-se de que isso (assim como tudo a partir desse ponto) esteja encapsulado na conexão do banco de dados, já que isso depende dela!:
|
||||
|
||||
```javascript
|
||||
passport.use(new LocalStrategy((username, password, done) => {
|
||||
@@ -30,13 +30,13 @@ passport.use(new LocalStrategy((username, password, done) => {
|
||||
}));
|
||||
```
|
||||
|
||||
This is defining the process to use when you try to authenticate someone locally. First, it tries to find a user in your database with the username entered. Then, it checks for the password to match. Finally, if no errors have popped up that you checked for (e.g. an incorrect password), the `user` object is returned and they are authenticated.
|
||||
Isso está definindo o processo a ser usado ao tentar autenticar alguém localmente. Primeiro, ele tenta encontrar um usuário no seu banco de dados com o nome de usuário inserido. Então, ele verifica se a senha tem correspondência. Por fim, se nenhum erro que você verificou tiver sido exibido (por exemplo, uma senha incorreta), o objeto `user` é retornado e o usuário é autenticado.
|
||||
|
||||
Many strategies are set up using different settings. Generally, it is easy to set it up based on the README in that strategy's repository. A good example of this is the GitHub strategy where you don't need to worry about a username or password because the user will be sent to GitHub's auth page to authenticate. As long as they are logged in and agree then GitHub returns their profile for you to use.
|
||||
Muitas estratégias são criadas usando configurações diferentes. Em geral, é fácil configurá-las com base no README no repositório da estratégia. Um bom exemplo disso é a estratégia do GitHub, onde não é preciso se preocupar com um nome de usuário ou senha, porque o usuário será enviado para a página de autenticação do GitHub para ser autenticado. Desde que estejam logados e que concordem com isso, o GitHub retorna seu perfil para que se possa vê-lo.
|
||||
|
||||
In the next step, you will set up how to actually call the authentication strategy to validate a user based on form data.
|
||||
Na próxima etapa, você vai configurar como chamar realmente a estratégia de autenticação para validar um usuário com base nos dados do formulário.
|
||||
|
||||
Envie sua página quando você achar que ela está certa. If you're running into errors, you can <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#authentication-strategies-6" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
|
||||
Envie sua página quando você achar que ela está certa. Se você estiver encontrando erros, pode <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#authentication-strategies-6" target="_blank" rel="noopener noreferrer nofollow">conferir o projeto concluído até este ponto</a>.
|
||||
|
||||
# --hints--
|
||||
|
||||
@@ -55,7 +55,7 @@ async (getUserInput) => {
|
||||
}
|
||||
```
|
||||
|
||||
Passport-local should be correctly required and set up.
|
||||
Passport-local deve ser solicitado e configurado corretamente.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ console.log('user ' + socket.request.user.username + ' connected');
|
||||
|
||||
Ele vai logar no console do servidor que está conectado!
|
||||
|
||||
Envie sua página quando você achar que ela está certa. If you're running into errors, you can <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#authentication-with-socketio-9" target="_blank" rel="noopener noreferrer nofollow">check out the project up to this point</a>.
|
||||
Envie sua página quando você achar que ela está certa. Se você estiver encontrando erros, pode <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#authentication-with-socketio-9" target="_blank" rel="noopener noreferrer nofollow">conferir o projeto até este ponto</a>.
|
||||
|
||||
# --hints--
|
||||
|
||||
|
||||
+2
-2
@@ -24,9 +24,9 @@ Por fim, pegue todas as rotas do servidor, cole-as em seus novos arquivos e remo
|
||||
|
||||
Continue adicionando-os até que não existam mais erros e que o arquivo do servidor não tenha mais nenhuma rota (**exceto a rota no bloco catch**)!
|
||||
|
||||
Do the same thing in your `auth.js` file with all of the things related to authentication such as the serialization and the setting up of the local strategy and erase them from your server file. Certifique-se de adicionar as dependências e de chamar `auth(app, myDataBase)` no servidor no mesmo local.
|
||||
Faça a mesma coisa no arquivo `auth.js` com tudo o que estiver relacionado à autenticação, como a serialização e a configuração da estratégia local, e apague-os do arquivo do servidor. Certifique-se de adicionar as dependências e de chamar `auth(app, myDataBase)` no servidor no mesmo local.
|
||||
|
||||
Envie sua página quando você achar que ela está certa. If you're running into errors, you can <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#clean-up-your-project-with-modules-2" target="_blank" rel="noopener noreferrer nofollow">check out an example of the completed project</a>.
|
||||
Envie sua página quando você achar que ela está certa. Se você estiver encontrando erros, pode <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#clean-up-your-project-with-modules-2" target="_blank" rel="noopener noreferrer nofollow">conferir um exemplo do projeto concluído</a>.
|
||||
|
||||
# --hints--
|
||||
|
||||
|
||||
+3
-3
@@ -38,11 +38,11 @@ socket.on('user count', function(data) {
|
||||
|
||||
Agora, tente carregar o seu aplicativo, autentique-se e você deve ver no console do client '1', representando a contagem de usuários no momento! Tente carregar mais clients, e autenticar para ver o número subir.
|
||||
|
||||
Envie sua página quando você achar que ela está certa. If you're running into errors, you can <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#communicate-by-emitting-7" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
|
||||
Envie sua página quando você achar que ela está certa. Se você estiver encontrando erros, pode <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#communicate-by-emitting-7" target="_blank" rel="noopener noreferrer nofollow">conferir o projeto concluído até este ponto</a>.
|
||||
|
||||
# --hints--
|
||||
|
||||
`currentUsers` should be defined.
|
||||
`currentUsers` deve ser definido.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
@@ -72,7 +72,7 @@ async (getUserInput) => {
|
||||
}
|
||||
```
|
||||
|
||||
Your client should be listening for `'user count'` event.
|
||||
O client deve estar escutando o evento `'user count'`.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
|
||||
+7
-7
@@ -8,11 +8,11 @@ dashedName: create-new-middleware
|
||||
|
||||
# --description--
|
||||
|
||||
As is, any user can just go to `/profile` whether they have authenticated or not by typing in the URL. You want to prevent this by checking if the user is authenticated first before rendering the profile page. Este é o exemplo perfeito de quando criar um middleware.
|
||||
Da forma como está no momento, qualquer usuário pode ir até `/profile`, já tendo sido autenticado ou não, digitando o URL. Evite isso verificando se o usuário está autenticado primeiro antes de renderizar a página de perfil. Este é o exemplo perfeito de quando criar um middleware.
|
||||
|
||||
The challenge here is creating the middleware function `ensureAuthenticated(req, res, next)`, which will check if a user is authenticated by calling Passport's `isAuthenticated` method on the `request` which checks if `req.user` is defined. If it is, then `next()` should be called. Otherwise, you can just respond to the request with a redirect to your homepage to login.
|
||||
O desafio aqui é cria a função do middleware `ensureAuthenticated(req, res, next)`, que vai verificar se um usuário está autenticado chamando o método `isAuthenticated` do Passport na `request` (solicitação), que verificará se `req.user` está definido. Se estiver, então `next()` deve ser chamado. Caso contrário, você pode apenas responder ao pedido com um redirecionamento à página inicial para fazer o login.
|
||||
|
||||
An implementation of this middleware is:
|
||||
Uma implementação deste middleware é:
|
||||
|
||||
```javascript
|
||||
function ensureAuthenticated(req, res, next) {
|
||||
@@ -23,7 +23,7 @@ function ensureAuthenticated(req, res, next) {
|
||||
};
|
||||
```
|
||||
|
||||
Create the above middleware function, then pass `ensureAuthenticated` as middleware to requests for the profile page before the argument to the GET request:
|
||||
Crie a função de middleware acima e, em seguida, passe `ensureAuthenticated` como middleware para requisições de perfil antes do argumento para a requisição GET:
|
||||
|
||||
```javascript
|
||||
app
|
||||
@@ -33,11 +33,11 @@ app
|
||||
});
|
||||
```
|
||||
|
||||
Submit your page when you think you've got it right. If you're running into errors, you can <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#create-new-middleware-8" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
|
||||
Envie sua página quando você achar que ela está certa. Se você estiver encontrando erros, pode <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#create-new-middleware-8" target="_blank" rel="noopener noreferrer nofollow">conferir o projeto concluído até este ponto</a>.
|
||||
|
||||
# --hints--
|
||||
|
||||
The middleware `ensureAuthenticated` should be implemented and attached to the `/profile` route.
|
||||
O middleware `ensureAuthenticated` deve ser implementado e anexado à rota `/profile`.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
@@ -57,7 +57,7 @@ async (getUserInput) => {
|
||||
}
|
||||
```
|
||||
|
||||
An unauthenticated GET request to `/profile` should correctly redirect to `/`.
|
||||
Uma solicitação GET não autenticado para `/profile` deve redirecionar corretamente para `/`.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
|
||||
+3
-3
@@ -18,11 +18,11 @@ socket.on('disconnect', () => {
|
||||
});
|
||||
```
|
||||
|
||||
To make sure clients continuously have the updated count of current users, you should decrease `currentUsers` by 1 when the disconnect happens then emit the `'user count'` event with the updated count.
|
||||
Para garantir que os clients tenham a contagem atualizada dos usuários atuais continuamente, você deve diminuir os `currentUsers` crie uma conta em 1 quando a desconexão acontece, emitindo o evento `'user count'` com a contagem atualizada.
|
||||
|
||||
**Observação:** assim como ocorre com `'disconnect'`, todos os outros eventos que um socket pode emitir para o servidor devem ser tratados dentro do listener que estiver conectando, onde 'socket' está definido.
|
||||
|
||||
Envie sua página quando você achar que ela está certa. If you're running into errors, you can <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#handle-a-disconnect-8" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
|
||||
Envie sua página quando você achar que ela está certa. Se você estiver encontrando erros, pode <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#handle-a-disconnect-8" target="_blank" rel="noopener noreferrer nofollow">conferir o projeto concluído até este ponto</a>.
|
||||
|
||||
# --hints--
|
||||
|
||||
@@ -37,7 +37,7 @@ async (getUserInput) => {
|
||||
}
|
||||
```
|
||||
|
||||
Your client should be listening for `'user count'` event.
|
||||
O client deve estar escutando o evento `'user count'`.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
|
||||
+4
-4
@@ -12,9 +12,9 @@ Voltando à seção de segurança da informação, você poderá ver que armazen
|
||||
|
||||
`bcrypt@~5.0.0` já foi adicionado como dependência, então solicite-o no servidor. Você precisará lidar com hashing em 2 áreas principais: onde você trata do registro/salvamento de uma nova conta e onde você verifica se uma senha está correta no login.
|
||||
|
||||
Currently on your registration route, you insert a user's plaintext password into the database like so: `password: req.body.password`. Hash the passwords instead by adding the following before your database logic: `const hash = bcrypt.hashSync(req.body.password, 12);`, and replacing the `req.body.password` in the database saving with just `password: hash`.
|
||||
No momento, na rota de registro, você insere a senha em texto simples de um usuário no banco de dados, da seguinte forma: `password: req.body.password`. Faça o hashing das senhas, em vez disso, adicionando o seguinte antes da lógica do seu banco de dados `const hash = bcrypt.hashSync(req.body.password, 12);` e substitua `req.body.password` no banco de dados, salvando apenas `password: hash`.
|
||||
|
||||
On your authentication strategy, you check for the following in your code before completing the process: `if (password !== user.password) return done(null, false);`. Depois de fazer as alterações acima, `user.password` passa a ser um hash. Antes de fazer uma alteração no código existente, observe como a instrução está verificando se a senha **não** é igual. Se não for, deve retornar não autenticada. With this in mind, change that code to look as follows to properly check the password entered against the hash:
|
||||
Na estratégia de autenticação, verificamos o seguinte no código antes de concluir o processo: `if (password !== user.password) return done(null, false);`. Depois de fazer as alterações acima, `user.password` passa a ser um hash. Antes de fazer uma alteração no código existente, observe como a instrução está verificando se a senha **não** é igual. Se não for, deve retornar não autenticada. Com isso em mente, altere o código para que se pareça assim para verificar corretamente a senha inserida com relação ao hash:
|
||||
|
||||
```js
|
||||
if (!bcrypt.compareSync(password, user.password)) {
|
||||
@@ -22,9 +22,9 @@ if (!bcrypt.compareSync(password, user.password)) {
|
||||
}
|
||||
```
|
||||
|
||||
That is all it takes to implement one of the most important security features when you have to store passwords.
|
||||
Isso é tudo o que precisamos para implementar um dos mais importantes recursos de segurança quando você tem que armazenar senhas.
|
||||
|
||||
Envie sua página quando você achar que ela está certa. If you're running into errors, you can <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#hashing-your-passwords-1" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
|
||||
Envie sua página quando você achar que ela está certa. Se você estiver encontrando erros, pode <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#hashing-your-passwords-1" target="_blank" rel="noopener noreferrer nofollow">conferir o projeto concluído até este ponto</a>.
|
||||
|
||||
# --hints--
|
||||
|
||||
|
||||
+7
-7
@@ -8,29 +8,29 @@ dashedName: how-to-put-a-profile-together
|
||||
|
||||
# --description--
|
||||
|
||||
Now that you can ensure the user accessing the `/profile` is authenticated, you can use the information contained in `req.user` on your page.
|
||||
Agora que você pode garantir que o usuário que acessou o `/profile` está autenticado, pode usar as informações contidas no `req.user` da página.
|
||||
|
||||
Pass an object containing the property `username` and value of `req.user.username` as the second argument for the `render` method of the profile view.
|
||||
Passe um objeto contendo a propriedade `username` e o valor `req.user.username` como o segundo argumento para o método `render` da visualização do perfil.
|
||||
|
||||
Then, go to your `profile.pug` view, and add the following line below the existing `h1` element, and at the same level of indentation:
|
||||
Em seguida, vá à visualização `profile.pug` e adicione a linha seguinte abaixo do elemento `h1` existente, no mesmo nível de indentação:
|
||||
|
||||
```pug
|
||||
h2.center#welcome Welcome, #{username}!
|
||||
```
|
||||
|
||||
This creates an `h2` element with the class `center` and id `welcome` containing the text `Welcome,` followed by the username.
|
||||
Isso criará um elemento `h2` com a classe `center` e com o id `welcome`, contendo o texto `Welcome,` seguido do nome de usuário.
|
||||
|
||||
Also, in `profile.pug`, add a link referring to the `/logout` route, which will host the logic to unauthenticate a user:
|
||||
Além disso, em `profile.pug`, adicione um link referindo-se à rota `/logout`, que hospedará a lógica para cancelar a autenticação de um usuário:
|
||||
|
||||
```pug
|
||||
a(href='/logout') Logout
|
||||
```
|
||||
|
||||
Submit your page when you think you've got it right. If you're running into errors, you can <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#how-to-put-a-profile-together-9" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
|
||||
Envie sua página quando você achar que ela está certa. Se você estiver encontrando erros, pode <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#how-to-put-a-profile-together-9" target="_blank" rel="noopener noreferrer nofollow">conferir o projeto concluído até este ponto</a>.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should correctly add a Pug render variable to `/profile`.
|
||||
Você deve adicionar corretamente uma variável de renderização do Pug em `/profile`.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
|
||||
+9
-9
@@ -8,23 +8,23 @@ dashedName: how-to-use-passport-strategies
|
||||
|
||||
# --description--
|
||||
|
||||
In the `index.pug` file supplied, there is a login form. It is hidden because of the inline JavaScript `if showLogin` with the form indented after it.
|
||||
No arquivo `index.pug` fornecido, existe um formulário de login. Ele está escondido por causa do JavaScript integrado `if showLogin` com o formulário indentado depois disso.
|
||||
|
||||
In the `res.render` for that page, add a new variable to the object, `showLogin: true`. When you refresh your page, you should then see the form! This form is set up to **POST** on `/login`. So, this is where you should set up to accept the POST request and authenticate the user.
|
||||
No `res.render` daquela página, adicione uma nova variável para o objeto `showLogin: true`. Ao atualizar sua página, você deverá ver o formulário! Este formulário está configurado para **POST** em `/login`. Portanto, é aqui que você deve configurar para aceitar a solicitação de POST e autenticar o usuário.
|
||||
|
||||
For this challenge, you should add the route `/login` to accept a POST request. To authenticate on this route, you need to add a middleware to do so before then sending a response. This is done by just passing another argument with the middleware before with your response. The middleware to use is `passport.authenticate('local')`.
|
||||
Para este desafio, você deve adicionar a rota `/login` para aceitar uma solicitação de POST. Para autenticar nessa rota, você precisa adicionar um middleware que faça isso antes de enviar uma resposta. Isso é feito simplesmente passando outro argumento com o middleware antes e com sua resposta. O middleware a ser usado é o `passport.authenticate('local')`.
|
||||
|
||||
`passport.authenticate` can also take some options as an argument such as `{ failureRedirect: '/' }` which is incredibly useful, so be sure to add that in as well. Add a response after using the middleware (which will only be called if the authentication middleware passes) that redirects the user to `/profile`. Add that route, as well, and make it render the view `profile.pug`.
|
||||
`passport.authenticate` também pode aceitar algumas opções como argumento, como `{ failureRedirect: '/' }`, que é incrivelmente útil. Não se esqueça de acrescentá-lo também. Adicione uma resposta após usar o middleware (que só será chamado se o middleware de autenticação passar) que redireciona o usuário para `/profile`. Adicione essa rota, também, e faça com que renderize a view `profile.pug`.
|
||||
|
||||
If the authentication was successful, the user object will be saved in `req.user`.
|
||||
Se a autenticação for bem-sucedida, o objeto do usuário será salvo em `req.user`.
|
||||
|
||||
At this point, if you enter a username and password in the form, it should redirect to the home page `/`, and the console of your server should display `'User {USERNAME} attempted to log in.'`, since we currently cannot login a user who isn't registered.
|
||||
Neste ponto, se você digitar um nome de usuário e uma senha no formulário, ele deve redirecionar para a página inicial `/`. O console do servidor deve exibir `'User {USERNAME} attempted to log in.'`, já que, no momento, não podemos fazer login com um usuário que não está registrado.
|
||||
|
||||
Submit your page when you think you've got it right. If you're running into errors, you can <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#how-to-use-passport-strategies-7" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
|
||||
Envie sua página quando você achar que ela está certa. Se você estiver encontrando erros, pode <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#how-to-use-passport-strategies-7" target="_blank" rel="noopener noreferrer nofollow">conferir o projeto concluído até este ponto</a>.
|
||||
|
||||
# --hints--
|
||||
|
||||
All steps should be correctly implemented in `server.js`.
|
||||
Todas as etapas devem ser corretamente implementadas no `server.js`.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
@@ -49,7 +49,7 @@ async (getUserInput) => {
|
||||
}
|
||||
```
|
||||
|
||||
A POST request to `/login` should correctly redirect to `/`.
|
||||
Uma solicitação POST para `/login` deve redirecionar corretamente para `/`.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
|
||||
+4
-4
@@ -8,11 +8,11 @@ dashedName: implement-the-serialization-of-a-passport-user
|
||||
|
||||
# --description--
|
||||
|
||||
You are not loading an actual user object since the database is not set up. Connect to the database once, when you start the server, and keep a persistent connection for the full life-cycle of the app. To do this, add your database's connection string (for example: `mongodb+srv://<username>:<password>@cluster0-jvwxi.mongodb.net/?retryWrites=true&w=majority`) to the environment variable `MONGO_URI`. Este é usado no arquivo `connection.js`.
|
||||
Você não está carregando um objeto do usuário de fato, já que o banco de dados não está configurado. Conecte-se ao banco de dados uma vez, ao iniciar o servidor e mantenha uma conexão persistente para todo o ciclo de vida do aplicativo. Para fazer isso, adicione a string de conexão do banco de dados (por exemplo: `mongodb+srv://<username>:<password>@cluster0-jvwxi.mongodb.net/?retryWrites=true&w=majority`) à variável de ambiente `MONGO_URI`. Este é usado no arquivo `connection.js`.
|
||||
|
||||
*If you are having issues setting up a free database on MongoDB Atlas, check out this <a href="https://www.freecodecamp.org/news/get-started-with-mongodb-atlas/" target="_blank" rel="noopener noreferrer nofollow">tutorial</a>.*
|
||||
*Se você estiver com problemas na criação de um banco de dados gratuito no MongoDB Atlas, confira o <a href="https://www.freecodecamp.org/news/get-started-with-mongodb-atlas/" target="_blank" rel="noopener noreferrer nofollow">tutorial</a>.*
|
||||
|
||||
Now you want to connect to your database, then start listening for requests. The purpose of this is to not allow requests before your database is connected or if there is a database error. To accomplish this, encompass your serialization and app routes in the following code:
|
||||
Agora, conecte-se ao nosso banco de dados. Em seguida, vamos começar a escutar solicitações. O objetivo é não permitir solicitações antes do banco de dados estar conectado ou se houver um erro no banco de dados. Para fazer isso, englobe a serialização e as rotas da aplicação no código a seguir:
|
||||
|
||||
```javascript
|
||||
myDB(async client => {
|
||||
@@ -40,7 +40,7 @@ myDB(async client => {
|
||||
|
||||
Certifique-se de descomentar o código `myDataBase` em `deserializeUser` e de editar o seu `done(null, null)` para incluir o `doc`.
|
||||
|
||||
Envie sua página quando você achar que ela está certa. If you're running into errors, you can <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#implement-the-serialization-of-a-passport-user-5" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
|
||||
Envie sua página quando você achar que ela está certa. Se você estiver encontrando erros, pode <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#implement-the-serialization-of-a-passport-user-5" target="_blank" rel="noopener noreferrer nofollow">conferir o projeto concluído até este ponto</a>.
|
||||
|
||||
# --hints--
|
||||
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@ A última parte da configuração da autenticação no GitHub é criar a própri
|
||||
|
||||
Para configurar a estratégia do GitHub, você precisa dizer ao Passport para usar uma `GitHubStrategy` instanciada, que aceite 2 argumentos: um objeto (contendo `clientID`, `clientSecret` e `callbackURL`) e uma função a ser chamada quando um usuário é autenticado com sucesso, que determinará se o usuário é novo e quais campos salvar inicialmente no objeto do banco de dados do usuário. Isto é comum em muitas estratégias, mas algumas podem exigir mais informações, conforme descrito no README do GitHub da estratégia específica. Por exemplo, O Google também requer um *scope*, o qual determina que tipo de informação a solicitação está pedindo que seja devolvida e pede ao usuário que aprove esse acesso.
|
||||
|
||||
The current strategy you are implementing authenticates users using a GitHub account and OAuth 2.0 tokens. O ID do cliente e o segredo obtidos ao criar um aplicativo são fornecidos como opções ao criar a estratégia. A estratégia também requer uma função de callback `verify`, que recebe o token de acesso e o token de atualização opcional, bem como a função `profile`, que contém o perfil do usuário autenticado no GitHub. A função de callback `verify` deve chamar `cb` fornecendo um usuário para concluir a autenticação.
|
||||
A estratégia atual que você está implementando autentica os usuários usando uma conta do GitHub e tokens OAuth 2.0. O ID do cliente e o segredo obtidos ao criar um aplicativo são fornecidos como opções ao criar a estratégia. A estratégia também requer uma função de callback `verify`, que recebe o token de acesso e o token de atualização opcional, bem como a função `profile`, que contém o perfil do usuário autenticado no GitHub. A função de callback `verify` deve chamar `cb` fornecendo um usuário para concluir a autenticação.
|
||||
|
||||
Saiba como a nova estratégia deve se parecer nesse momento:
|
||||
|
||||
@@ -31,7 +31,7 @@ passport.use(new GitHubStrategy({
|
||||
|
||||
A autenticação ainda não será bem-sucedida e realmente lançará um erro sem a lógica e a função de callback do banco de dados, mas ela deverá fazer o login com o seu perfil do GitHub no console se você tentar!
|
||||
|
||||
Envie sua página quando você achar que ela está certa. If you're running into errors, you can <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#implementation-of-social-authentication-ii-4" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
|
||||
Envie sua página quando você achar que ela está certa. Se você estiver encontrando erros, pode <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#implementation-of-social-authentication-ii-4" target="_blank" rel="noopener noreferrer nofollow">conferir o projeto concluído até este ponto</a>.
|
||||
|
||||
# --hints--
|
||||
|
||||
|
||||
+2
-2
@@ -41,9 +41,9 @@ myDataBase.findOneAndUpdate(
|
||||
|
||||
`findOneAndUpdate` permite pesquisar um objeto e atualizá-lo. Se o objeto não existir, ele será inserido e disponibilizado para a função de callback. Neste exemplo, sempre definimos o `last_login`, incrementamos a `login_count` em `1` e somente preenchemos a maioria dos campos quando um novo objeto (novo usuário) for inserido. Observe o uso dos valores padrão. Às vezes, um perfil retornado não terá todas as informações preenchidas. O usuário também pode mantê-las privadas. Neste caso, você faz o tratamento para evitar um erro.
|
||||
|
||||
You should be able to login to your app now. Try it!
|
||||
Você deve poder acessar a aplicação agora. Experimente!
|
||||
|
||||
Envie sua página quando você achar que ela está certa. If you're running into errors, you can <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#implementation-of-social-authentication-iii-5" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
|
||||
Envie sua página quando você achar que ela está certa. Se você estiver encontrando erros, pode <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#implementation-of-social-authentication-iii-5" target="_blank" rel="noopener noreferrer nofollow">conferir o projeto concluído até este ponto</a>.
|
||||
|
||||
# --hints--
|
||||
|
||||
|
||||
+11
-11
@@ -10,21 +10,21 @@ dashedName: implementation-of-social-authentication
|
||||
|
||||
O caminho básico que este tipo de autenticação vai seguir em sua aplicação é:
|
||||
|
||||
1. User clicks a button or link sending them to your route to authenticate using a specific strategy (e.g. GitHub).
|
||||
1. O usuário clica em um botão ou link que o envia para a rota de autenticação que usa uma estratégia específica (por exemplo, o GitHub).
|
||||
2. A rota chama `passport.authenticate('github')`, que os redireciona para o GitHub.
|
||||
3. A página que o usuário entra no GitHub permite que ele faça o login, se ainda não o fez. It then asks them to approve access to their profile from your app.
|
||||
4. The user is then returned to your app at a specific callback url with their profile if they are approved.
|
||||
3. A página que o usuário entra no GitHub permite que ele faça o login, se ainda não o fez. Em seguida, ela pede que eles aprovem o acesso ao seu perfil a partir da aplicação.
|
||||
4. O usuário é então retornado para a aplicação em um url específico de callback com seu perfil, se ele for aprovado.
|
||||
5. Agora que o usuário está autenticado. O aplicativo deve verificar se é um perfil que está retornando ou salvá-lo no banco de dados, se não for o caso.
|
||||
|
||||
As estratégias com OAuth exigem que você tenha, pelo menos, um *ID de client* e um *segredo de client*, que é uma maneira de o serviço verificar de quem está vindo o pedido de autenticação e se ele é válido. Estes são obtidos do site com o qual você está tentando implementar a autenticação, como o GitHub, e são exclusivos do seu aplicativo. **ELES NÃO DEVEM SER COMPARTILHADOS** e nunca devem ser enviados para um repositório público ou escritos diretamente no código. Uma prática comum é colocá-los no seu arquivo `.env` e referenciá-los assim: `process.env.GITHUB_CLIENT_ID`. For this challenge you are going to use the GitHub strategy.
|
||||
As estratégias com OAuth exigem que você tenha, pelo menos, um *ID de client* e um *segredo de client*, que é uma maneira de o serviço verificar de quem está vindo o pedido de autenticação e se ele é válido. Estes são obtidos do site com o qual você está tentando implementar a autenticação, como o GitHub, e são exclusivos do seu aplicativo. **ELES NÃO DEVEM SER COMPARTILHADOS** e nunca devem ser enviados para um repositório público ou escritos diretamente no código. Uma prática comum é colocá-los no seu arquivo `.env` e referenciá-los assim: `process.env.GITHUB_CLIENT_ID`. Para este desafio, use a estratégia do GitHub.
|
||||
|
||||
Follow these instructions to obtain your *Client ID and Secret* from GitHub. Go to your GitHub profile settings and click 'developer settings', then <a href="https://github.com/settings/developers" target="_blank" rel="noopener noreferrer nofollow">'OAuth Apps'</a>. Click 'New OAuth App', then give your app a name, paste in the URL to your Replit homepage (**Not the project code's url**) and, for the callback URL, paste in the same URL as the homepage but add `/auth/github/callback` to the end of it. This is where users will be redirected after authenticating on GitHub. After you do all that, click 'Register application'.
|
||||
Siga essas instruções para obter o *Client ID e o Segredo* do GitHub. Vá as configurações do seu perfil do GitHub e clique em 'developer settings' e <a href="https://github.com/settings/developers" target="_blank" rel="noopener noreferrer nofollow">'OAuth Apps'</a>. Clique em 'New OAuth App', nomeie sua aplicação, cole o URL de página inicial do Replit (**não o URL do código do projeto**) e, para o URL de callback, cole o mesmo URL da página inicial, mas adicione `/auth/github/callback` ao final dele. É para cá que os usuários serão redirecionados para a autenticação no GitHub. Depois de fazer tudo isso, clique em 'Register application'.
|
||||
|
||||
On the next page, click 'Generate a new client secret' to create a new client secret. Save the client ID and your client secret in your project's `.env` file as `GITHUB_CLIENT_ID` and `GITHUB_CLIENT_SECRET`.
|
||||
Na página seguinte, clique em 'Generate a new client secret' para criar um segredo de client. Salve o ID do client e seu segredo de client no arquivo `.env` do projeto como `GITHUB_CLIENT_ID` e `GITHUB_CLIENT_SECRET`.
|
||||
|
||||
In your `routes.js` file, add `showSocialAuth: true` to the homepage route, after `showRegistration: true`. Now, create 2 routes accepting GET requests: `/auth/github` and `/auth/github/callback`. The first should only call passport to authenticate `'github'`. The second should call passport to authenticate `'github'` with a failure redirect to `/`, and then if that is successful redirect to `/profile` (similar to your last project).
|
||||
No seu arquivo `routes.js`, adicione `showSocialAuth: true` à rota da página inicial, após `showRegistration: true`. Agora, crie 2 rotas aceitando solicitações de GET: `/auth/github` e `/auth/github/callback`. O primeiro deve apenas chamar o Passport para autenticar o `'github'`. O segundo deve chamar o Passport para autenticar o `'github'` com um redirecionamento de falha para `/`. Então, se tiver sucesso, redirecionar para o `/profile` (semelhante ao último projeto).
|
||||
|
||||
An example of how `/auth/github/callback` should look is similar to how you handled a normal login:
|
||||
Um exemplo de como `/auth/github/callback` deve parecer é semelhante a como manipulamos um login normal:
|
||||
|
||||
```js
|
||||
app.route('/login')
|
||||
@@ -33,11 +33,11 @@ app.route('/login')
|
||||
});
|
||||
```
|
||||
|
||||
Submit your page when you think you've got it right. If you're running into errors, you can <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#implementation-of-social-authentication-3" target="_blank" rel="noopener noreferrer nofollow">check out the project up to this point</a>.
|
||||
Envie sua página quando você achar que ela está certa. Se você estiver encontrando erros, pode <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#implementation-of-social-authentication-3" target="_blank" rel="noopener noreferrer nofollow">conferir o projeto até este ponto</a>.
|
||||
|
||||
# --hints--
|
||||
|
||||
Route `/auth/github` should be correct.
|
||||
A rota `/auth/github` deve estar correta.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
@@ -68,7 +68,7 @@ async (getUserInput) => {
|
||||
}
|
||||
```
|
||||
|
||||
Route `/auth/github/callback` should be correct.
|
||||
A rota `/auth/github/callback` deve estar correta.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
|
||||
+5
-5
@@ -8,9 +8,9 @@ dashedName: logging-a-user-out
|
||||
|
||||
# --description--
|
||||
|
||||
Criar a lógica de logout é fácil. The route should just unauthenticate the user, and redirect to the home page instead of rendering any view.
|
||||
Criar a lógica de logout é fácil. A rota deve apenas cancelar a autenticação do usuário e redirecionar para a página inicial em vez de renderizar qualquer visualização.
|
||||
|
||||
In passport, unauthenticating a user is as easy as just calling `req.logout()` before redirecting. Add this `/logout` route to do that:
|
||||
No Passport, cancelar a autenticação de um usuário é fácil. Basta chamar `req.logout()` antes de redirecionar. Adicione esta rota `/logout` para fazer isso:
|
||||
|
||||
```js
|
||||
app.route('/logout')
|
||||
@@ -20,7 +20,7 @@ app.route('/logout')
|
||||
});
|
||||
```
|
||||
|
||||
You may have noticed that you are not handling missing pages (404). A maneira comum de lidar com isso no Node é com o middleware que veremos a seguir. Adicione-o isso depois de todas as suas outras rotas:
|
||||
Você deve ter percebido que não está lidando com páginas ausentes (404). A maneira comum de lidar com isso no Node é com o middleware que veremos a seguir. Adicione-o isso depois de todas as suas outras rotas:
|
||||
|
||||
```js
|
||||
app.use((req, res, next) => {
|
||||
@@ -30,7 +30,7 @@ app.use((req, res, next) => {
|
||||
});
|
||||
```
|
||||
|
||||
Envie sua página quando você achar que ela está certa. If you're running into errors, you can <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#logging-a-user-out-10" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
|
||||
Envie sua página quando você achar que ela está certa. Se você estiver encontrando erros, pode <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#logging-a-user-out-10" target="_blank" rel="noopener noreferrer nofollow">conferir o projeto concluído até este ponto</a>.
|
||||
|
||||
# --hints--
|
||||
|
||||
@@ -49,7 +49,7 @@ async (getUserInput) => {
|
||||
}
|
||||
```
|
||||
|
||||
`/logout` should redirect to the home page.
|
||||
`/logout` deve redirecionar para a página inicial.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
|
||||
+12
-12
@@ -8,20 +8,20 @@ dashedName: registration-of-new-users
|
||||
|
||||
# --description--
|
||||
|
||||
Now you need to allow a new user on your site to register an account. In the `res.render` for the home page add a new variable to the object passed along - `showRegistration: true`. When you refresh your page, you should then see the registration form that was already created in your `index.pug` file. This form is set up to **POST** on `/register`, so create that route and have it add the user object to the database by following the logic below.
|
||||
Agora, você precisa permitir que um novo usuário crie uma conta no site. Na `res.render` para a página inicial, adicione uma nova variável para o objeto passado, `showRegistration: true`. Ao atualizar sua página, você deve então ver o formulário de registro que já foi criado no arquivo `index.pug`. Esse formulário está configurado para **POST** em `/register`, então crie essa rota e faça com que ela adicione o objeto do usuário ao banco de dados, seguindo a lógica abaixo.
|
||||
|
||||
The logic of the registration route should be as follows:
|
||||
A lógica da rota de registo deve ser a seguinte:
|
||||
|
||||
1. Register the new user
|
||||
2. Authenticate the new user
|
||||
3. Redirect to `/profile`
|
||||
1. Registrar o novo usuário
|
||||
2. Autenticar o novo usuário
|
||||
3. Redirecionar para `/profile`
|
||||
|
||||
The logic of step 1 should be as follows:
|
||||
A lógica da etapa 1 deveria ser a seguinte:
|
||||
|
||||
1. Query database with `findOne`
|
||||
2. If there is an error, call `next` with the error
|
||||
3. If a user is returned, redirect back to home
|
||||
4. If a user is not found and no errors occur, then `insertOne` into the database with the username and password. As long as no errors occur there, call `next` to go to step 2, authenticating the new user, which you already wrote the logic for in your `POST /login` route.
|
||||
1. Fazer a consulta ao banco de dados com `findOne`
|
||||
2. Se houver um erro, chamar `next` com o erro
|
||||
3. Se um usuário for retornado, redirecionar de volta para a página inicial
|
||||
4. Se um usuário não for encontrado e se nenhum erro ocorrer, usar `insertOne` para inserir um usuário no banco de dados com o nome de usuário e senha. Desde que não haja erros, chamar `next` para passar para a etapa 2, autenticando o novo usuário para o qual você já escreveu a lógica na rota `POST /login`.
|
||||
|
||||
```js
|
||||
app.route('/register')
|
||||
@@ -56,13 +56,13 @@ app.route('/register')
|
||||
);
|
||||
```
|
||||
|
||||
Envie sua página quando você achar que ela está certa. If you're running into errors, you can <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#registration-of-new-users-11" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
|
||||
Envie sua página quando você achar que ela está certa. Se você estiver encontrando erros, pode <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#registration-of-new-users-11" target="_blank" rel="noopener noreferrer nofollow">conferir o projeto concluído até este ponto</a>.
|
||||
|
||||
**OBSERVAÇÃO:** a partir deste ponto, podem surgir problemas relacionados com o uso do navegador *picture-in-picture*. Se você estiver usando uma IDE on-line que oferece uma pré-visualização do aplicativo dentro do editor, é recomendável abrir esta pré-visualização em uma nova aba.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `/register` route and display a registration form on the home page.
|
||||
Você deve ter uma rota `/register` e exibir um formulário de registro na página inicial.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
|
||||
+3
-3
@@ -22,13 +22,13 @@ Dentro do código de envio do formulário, você deve enviar um evento depois de
|
||||
socket.emit('chat message', messageToSend);
|
||||
```
|
||||
|
||||
Agora, no servidor, você deve estar escutando o socket para o evento `'chat message'` com os dados nomeados como `message`. Once the event is received, it should emit the event `'chat message'` to all sockets using `io.emit`, sending a data object containing the `username` and `message`.
|
||||
Agora, no servidor, você deve estar escutando o socket para o evento `'chat message'` com os dados nomeados como `message`. Quando o evento for recebido, ele deve emitir o evento `'chat message'` para todos os sockets usando o `io.emit` enviando um objeto de dados contendo `username` e `message`.
|
||||
|
||||
In `client.js`, you should now listen for event `'chat message'` and, when received, append a list item to `#messages` with the username, a colon, and the message!
|
||||
No `client.js`, agora, você deve escutar o evento `'chat message'` e, quando ele for recebido, associe um item de lista a `#messages` com o nome de usuário, um sinal de dois-pontos e a mensagem!
|
||||
|
||||
Neste ponto, o chat deve estar totalmente funcional e enviando mensagens para todos os clients!
|
||||
|
||||
Envie sua página quando você achar que ela está certa. If you're running into errors, you can <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#send-and-display-chat-messages-11" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
|
||||
Envie sua página quando você achar que ela está certa. Se você estiver encontrando erros, pode <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#send-and-display-chat-messages-11" target="_blank" rel="noopener noreferrer nofollow">conferir o projeto concluído até este ponto</a>.
|
||||
|
||||
# --hints--
|
||||
|
||||
|
||||
+12
-12
@@ -10,20 +10,20 @@ dashedName: serialization-of-a-user-object
|
||||
|
||||
Serialização e desserialização são conceitos importantes no que diz respeito à autenticação. Serializar um objeto significa converter seu conteúdo em uma pequena *chave* que pode ser desserializada no objeto original. Isto é o que nos permite saber quem se comunicou com o servidor sem ter que enviar os dados de autenticação, como o nome de usuário e a senha, em cada solicitação de uma nova página.
|
||||
|
||||
To set this up properly, you need to have a serialize function and a deserialize function. In Passport, these can be created with:
|
||||
Para configurar isso corretamente, você precisa ter uma função de serialização e uma função de desserialização. No Passaport, elas podem ser criadas com:
|
||||
|
||||
```javascript
|
||||
passport.serializeUser(cb);
|
||||
passport.deserializeUser(cb);
|
||||
```
|
||||
|
||||
The callback function passed to `serializeUser` is called with two arguments: the full user object, and a callback used by passport.
|
||||
A função de callback passada para `serializeUser` é chamada com 2 argumentos, o objeto de usuário completo e uma função de callback usada pelo passport.
|
||||
|
||||
The callback expects two arguments: An error, if any, and a unique key to identify the user that should be returned in the callback. You will use the user's `_id` in the object. This is guaranteed to be unique, as it is generated by MongoDB.
|
||||
A função de callback espera dois argumentos: um erro, se houver, e uma chave única para identificar o usuário que deve ser retornado na função. Você usará o `_id` do usuário no objeto. Ele com certeza será único, já que é gerado pelo MongoDB.
|
||||
|
||||
Similarly, `deserializeUser` is called with two arguments: the unique key, and a callback function.
|
||||
Do mesmo modo, `deserializeUser` é chamada com dois argumentos: a chave única e uma função de callback.
|
||||
|
||||
This callback expects two arguments: An error, if any, and the full user object. To get the full user object, make a query search for a Mongo `_id`, as shown below:
|
||||
Essa função de callback espera dois argumentos: um erro, se houver, e o objeto do usuário completo. Para obter o objeto de usuário completo, faça uma consulta por um `_id` do Mongo, como mostrado abaixo:
|
||||
|
||||
|
||||
```javascript
|
||||
@@ -38,19 +38,19 @@ passport.deserializeUser((id, done) => {
|
||||
});
|
||||
```
|
||||
|
||||
Add the two functions above to your server. The `ObjectID` class comes from the `mongodb` package. `mongodb@~3.6.0` has already been added as a dependency. Declare this class with:
|
||||
Adicione as duas funções acima ao seu servidor. A classe `ObjectID` vem do pacote `mongodb`. `mongodb@~3.6.0` já foi adicionado como uma dependência. Declare essa classe com:
|
||||
|
||||
```javascript
|
||||
const { ObjectID } = require('mongodb');
|
||||
```
|
||||
|
||||
The `deserializeUser` will throw an error until you set up the database connection. So, for now, comment out the `myDatabase.findOne` call, and just call `done(null, null)` in the `deserializeUser` callback function.
|
||||
A função `deserializeUser` lançará um erro até que você configure a conexão com o banco de dados. Então, por agora, comente a chamada de `myDatabase.findOne` e apenas chame `done(null, null)` na função de callback de `deserializeUser`.
|
||||
|
||||
Submit your page when you think you've got it right. If you're running into errors, you can <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#serialization-of-a-user-object-4" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
|
||||
Envie sua página quando você achar que ela está certa. Se você estiver encontrando erros, pode <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#serialization-of-a-user-object-4" target="_blank" rel="noopener noreferrer nofollow">conferir o projeto concluído até este ponto</a>.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should serialize user function correctly.
|
||||
Você deve serializar a função do usuário corretamente.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
@@ -70,7 +70,7 @@ async (getUserInput) => {
|
||||
}
|
||||
```
|
||||
|
||||
You should deserialize user function correctly.
|
||||
Você deve desserializar a função do usuário corretamente.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
@@ -90,7 +90,7 @@ async (getUserInput) => {
|
||||
}
|
||||
```
|
||||
|
||||
MongoDB should be a dependency.
|
||||
O MongoDB deve ser uma dependência.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
@@ -105,7 +105,7 @@ async (getUserInput) => {
|
||||
}
|
||||
```
|
||||
|
||||
Mongodb should be properly required including the ObjectId.
|
||||
O MongoDB deve ser solicitado adequadamente, incluindo o ObjectId.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
|
||||
+8
-8
@@ -20,19 +20,19 @@ Um mecanismo de templates (template engine) permite o uso de arquivos de modelo
|
||||
|
||||
`pug@~3.0.0` já foi instalado e está listado como uma dependência no arquivo `package.json`.
|
||||
|
||||
O Express precisa saber qual mecanismo de modelos você está usando. Use the `set` method to assign `pug` as the `view engine` property's value:
|
||||
O Express precisa saber qual mecanismo de modelos você está usando. Use o método `set` para atribuir `pug` como o valor de `view engine` da propriedade:
|
||||
|
||||
```javascript
|
||||
app.set('view engine', 'pug');
|
||||
```
|
||||
|
||||
After that, add another `set` method that sets the `views` property of your `app` to point to the `./views/pug` directory. This tells Express to render all views relative to that directory.
|
||||
Depois disso, adicione outro método `set` que defina a propriedade `views` do `app` para que aponte para o diretório `./views/pug`. Isto diz ao Express para renderizar todas as views relativas a esse diretório.
|
||||
|
||||
Finally, use `res.render()` in the route for your home page, passing `index` as the first argument. This will render the `pug` template.
|
||||
Por fim, use `res.render()` na rota para a sua página inicial, passando `index` como primeiro argumento. Isto vai renderizar o template `pug`.
|
||||
|
||||
If all went as planned, your app home page will no longer be blank. Instead, it will display a message indicating you've successfully rendered the Pug template!
|
||||
Se tudo correu como planejado, o aplicativo não estará mais em branco. Em vez disso, ele exibirá uma mensagem indicando que você renderizou com sucesso o modelo Pug!
|
||||
|
||||
Envie sua página quando você achar que ela está certa. If you're running into errors, you can <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#set-up-a-template-engine-1" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
|
||||
Envie sua página quando você achar que ela está certa. Se você estiver encontrando erros, pode <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#set-up-a-template-engine-1" target="_blank" rel="noopener noreferrer nofollow">conferir o projeto concluído até este ponto</a>.
|
||||
|
||||
# --hints--
|
||||
|
||||
@@ -62,7 +62,7 @@ async (getUserInput) => {
|
||||
}
|
||||
```
|
||||
|
||||
You should set the `views` property of the application to `./views/pug`.
|
||||
Você deve definir a propriedade `views` da aplicação para `./views/pug`.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
@@ -73,7 +73,7 @@ async (getUserInput) => {
|
||||
}
|
||||
```
|
||||
|
||||
Use the correct ExpressJS method to render the index page from the response.
|
||||
Use o método correto do ExpressJS para processar a página do índice a partir da resposta.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
@@ -88,7 +88,7 @@ async (getUserInput) => {
|
||||
}
|
||||
```
|
||||
|
||||
Pug should be working.
|
||||
O Pug deve funcionar.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
|
||||
+10
-10
@@ -8,13 +8,13 @@ dashedName: set-up-passport
|
||||
|
||||
# --description--
|
||||
|
||||
It's time to set up *Passport* so you can finally start allowing a user to register or log in to an account. In addition to Passport, you will use Express-session to handle sessions. Express-session has a ton of advanced features you can use, but for now you are just going to use the basics. Using this middleware saves the session id as a cookie in the client, and allows us to access the session data using that id on the server. This way, you keep personal account information out of the cookie used by the client to tell to your server clients are authenticated and keep the *key* to access the data stored on the server.
|
||||
É hora de configurar o *Passport* para que você possa finalmente começar a permitir que um usuário se registre ou faça o login em uma conta. Além do Passport, você usará Express-session para tratar das sessões. Express-session tem dezenas de recursos avançados que você pode usar, mas, no momento, você o usará apenas para o básico. Usar este middleware salva o id da sessão como um cookie no client e nos permite acessar os dados da sessão usando esse id no servidor. Desta forma, você manterá as informações da conta pessoal fora do cookie usado pelo client para informar ao servidor que os clients estão autenticados e, simplesmente, manter a *chave* para acessar os dados armazenados no servidor.
|
||||
|
||||
`passport@~0.4.1` e `express-session@~1.17.1` já estão instalados e listados como dependências no arquivo `package.json`.
|
||||
|
||||
You will need to set up the session settings and initialize Passport. First, create the variables `session` and `passport` to require `express-session` and `passport` respectively.
|
||||
Você precisará configurar as definições de sessão e inicializar o Passport. Primeiro, crie as variáveis `session` e `passport` para exigir `express-session` e `passport`, respectivamente.
|
||||
|
||||
Then, set up your Express app to use the session by defining the following options:
|
||||
Em seguida, configure a aplicação do Express para que use o session, definindo as seguintes opções:
|
||||
|
||||
```javascript
|
||||
app.use(session({
|
||||
@@ -25,15 +25,15 @@ app.use(session({
|
||||
}));
|
||||
```
|
||||
|
||||
Be sure to add `SESSION_SECRET` to your `.env` file, and give it a random value. This is used to compute the hash used to encrypt your cookie!
|
||||
Certifique-se de adicionar `SESSION_SECRET` ao arquivo `.env` e de dar a ele um valor aleatório. Isto é usado para calcular o hash usado para criptografar seu cookie!
|
||||
|
||||
After you do all that, tell your express app to **use** `passport.initialize()` and `passport.session()`.
|
||||
Depois de fazer tudo isso, informe ao aplicativo do express para que **use** `passport.initialize()` e `passport.session()`.
|
||||
|
||||
Submit your page when you think you've got it right. If you're running into errors, you can <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#set-up-passport-3" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
|
||||
Envie sua página quando você achar que ela está certa. Se você estiver encontrando erros, pode <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#set-up-passport-3" target="_blank" rel="noopener noreferrer nofollow">conferir o projeto concluído até este ponto</a>.
|
||||
|
||||
# --hints--
|
||||
|
||||
Passport and Express-session should be dependencies.
|
||||
O Passport e o Express-session devem ser dependências.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
@@ -53,7 +53,7 @@ async (getUserInput) => {
|
||||
}
|
||||
```
|
||||
|
||||
Dependencies should be correctly required.
|
||||
As dependências devem ser solicitados corretamente.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
@@ -73,7 +73,7 @@ async (getUserInput) => {
|
||||
}
|
||||
```
|
||||
|
||||
Express app should use new dependencies.
|
||||
A aplicação do Express deve usar novas dependências.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
@@ -85,7 +85,7 @@ async (getUserInput) => {
|
||||
}
|
||||
```
|
||||
|
||||
Session and session secret should be correctly set up.
|
||||
Session e session secret devem estar definidos corretamente.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
|
||||
+4
-4
@@ -19,7 +19,7 @@ const io = require('socket.io')(http);
|
||||
|
||||
Agora que o servidor *http* está montado na aplicação do *Express*, você precisa escutar o servidor *http*. Altere a linha com `app.listen` para `http.listen`.
|
||||
|
||||
A primeira coisa que precisa ser tratada é escutar uma nova conexão do client. A palavra-chave <dfn>on</dfn> faz isso - escuta um evento específico. Ela requer 2 argumentos: uma string contendo o título do evento que é emitido e uma função pela qual os dados são passados. In the case of our connection listener, use `socket` to define the data in the second argument. Um socket é um client individual que está conectado.
|
||||
A primeira coisa que precisa ser tratada é escutar uma nova conexão do client. A palavra-chave <dfn>on</dfn> faz isso - escuta um evento específico. Ela requer 2 argumentos: uma string contendo o título do evento que é emitido e uma função pela qual os dados são passados. No caso do nosso listener de conexão, use o `socket` para definir os dados no segundo argumento. Um socket é um client individual que está conectado.
|
||||
|
||||
Para escutar as conexões do servidor, adicione o seguinte na sua conexão do banco de dados:
|
||||
|
||||
@@ -36,13 +36,13 @@ Agora, para o client se conectar, basta adicionar o seguinte ao `client.js` que
|
||||
let socket = io();
|
||||
```
|
||||
|
||||
O comentário suprime o erro que você normalmente veria, já que 'io' não está definido no arquivo. You have already added a reliable CDN to the Socket.IO library on the page in `chat.pug`.
|
||||
O comentário suprime o erro que você normalmente veria, já que 'io' não está definido no arquivo. Você já adicionou um CDN confiável à biblioteca socket.io na página em `chat.pug`.
|
||||
|
||||
Now try loading up your app and authenticate and you should see in your server console `A user has connected`.
|
||||
Agora, tente carregar o aplicativo e autentique-se. Você deve ver no console do servidor a frase `A user has connected`.
|
||||
|
||||
**Observação:** `io()` só funciona ao se conectar a um socket hospedado no mesmo url/servidor. Para se conectar a um socket externo hospedado em outro lugar, você usaria `io.connect('URL');`.
|
||||
|
||||
Envie sua página quando você achar que ela está certa. If you're running into errors, you can <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#set-up-the-environment-6" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
|
||||
Envie sua página quando você achar que ela está certa. Se você estiver encontrando erros, pode <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#set-up-the-environment-6" target="_blank" rel="noopener noreferrer nofollow">conferir o projeto concluído até este ponto</a>.
|
||||
|
||||
# --hints--
|
||||
|
||||
|
||||
+9
-9
@@ -12,9 +12,9 @@ Uma das maiores características do uso de um mecanismo de modelos (template eng
|
||||
|
||||
No seu arquivo Pug, você pode usar uma variável fazendo referência ao nome da variável como `#{variable_name}` em linha com outro texto em um elemento ou usando um sinal de igual no elemento sem um espaço, como em `p=variable_name`, que atribui o valor da variável ao texto do elemento p.
|
||||
|
||||
Pug is all about using whitespace and tabs to show nested elements and cutting down on the amount of code needed to make a beautiful site.
|
||||
O Pug tem a ver com usar o espaço em branco e as tabulações para mostrar elementos aninhados e diminuir a quantidade de código necessária para fazer um belo site.
|
||||
|
||||
Take the following Pug code for example:
|
||||
Veja o seguinte código Pug, por exemplo:
|
||||
|
||||
```pug
|
||||
head
|
||||
@@ -27,7 +27,7 @@ body
|
||||
p Get on it!
|
||||
```
|
||||
|
||||
The above yields the following HTML:
|
||||
O conteúdo acima fornece o seguinte HTML:
|
||||
|
||||
```html
|
||||
<head>
|
||||
@@ -40,23 +40,23 @@ The above yields the following HTML:
|
||||
</body>
|
||||
```
|
||||
|
||||
Your `index.pug` file included in your project, uses the variables `title` and `message`.
|
||||
O arquivo `index.pug`, incluído no projeto, usa as variáveis `title` e `message`.
|
||||
|
||||
Pass those from your server to the Pug file by adding an object as a second argument to your `res.render` call with the variables and their values. Give the `title` a value of `Hello` and `message` a value of `Please log in`.
|
||||
Passe esses dados do servidor adicionando um objeto como um segundo argumento para a chamada de `res.render` com as variáveis e seus valores. Dê a `title` o valor de `Hello` e a `message` o valor de `Please log in`.
|
||||
|
||||
It should look like:
|
||||
Deve ficar assim:
|
||||
|
||||
```javascript
|
||||
res.render('index', { title: 'Hello', message: 'Please log in' });
|
||||
```
|
||||
|
||||
Now refresh your page, and you should see those values rendered in your view in the correct spot as laid out in your `index.pug` file!
|
||||
Agora atualize a página e você deve ver esses valores renderizados em sua visão no local correto, como estabelecido no arquivo `index.pug`!
|
||||
|
||||
Submit your page when you think you've got it right. If you're running into errors, you can check out the <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#use-a-template-engines-power-2" target="_blank" rel="noopener noreferrer nofollow">project completed up to this point</a>.
|
||||
Envie sua página quando você achar que ela está certa. Se você estiver encontrando erros, pode conferir o <a href="https://forum.freecodecamp.org/t/advanced-node-and-express/567135#use-a-template-engines-power-2" target="_blank" rel="noopener noreferrer nofollow">projeto concluído até este ponto</a>.
|
||||
|
||||
# --hints--
|
||||
|
||||
Pug should correctly render variables.
|
||||
O Pug deve renderizar as variáveis corretamente.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
|
||||
+2
-2
@@ -7,11 +7,11 @@ dashedName: step-5
|
||||
|
||||
# --description--
|
||||
|
||||
Remove both the horizontal and vertical scrollbars, using only one property.
|
||||
Remova as barras de rolagem horizontal e vertical usando apenas uma propriedade.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should give `body` an `overflow` of `--fcc-expected--`. But found `--fcc-actual--`.
|
||||
Você deve dar ao `body` um valor de `overflow` de `--fcc-expected--`. Mas encontrou `--fcc-actual--`.
|
||||
|
||||
```js
|
||||
assert.equal(new __helpers.CSSHelp(document).getStyle('body')?.overflow, 'hidden');
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ O elemento `h1` deve conter o texto `CatPhotoApp`. Você omitiu o texto, digitou
|
||||
assert(document.querySelector('h1').innerText.toLowerCase() === 'catphotoapp');
|
||||
```
|
||||
|
||||
You appear to be using a browser extension that is modifying the page. Be sure to turn off all browser extensions.
|
||||
Parece que você está usando uma extensão de navegador que está modificando a página. Não se esqueça de desativar todas as extensões do navegador.
|
||||
|
||||
```js
|
||||
assert.isAtMost(document.querySelectorAll('script').length, 2);
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60f5cb8875ab6a0610f05071
|
||||
title: Step 13
|
||||
title: Etapa 13
|
||||
challengeType: 0
|
||||
dashedName: step-13
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60f5d2776c854e069560fbe6
|
||||
title: Step 14
|
||||
title: Passo 14
|
||||
challengeType: 0
|
||||
dashedName: step-14
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60f5dc35c07ac1078f140916
|
||||
title: Step 15
|
||||
title: Passo 15
|
||||
challengeType: 0
|
||||
dashedName: step-15
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60f803d5241e6a0433a523a1
|
||||
title: Step 16
|
||||
title: Passo 16
|
||||
challengeType: 0
|
||||
dashedName: step-16
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60f805f813eaf2049bc2ceea
|
||||
title: Step 17
|
||||
title: Passo 17
|
||||
challengeType: 0
|
||||
dashedName: step-17
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60f80e0081e0f2052ae5b505
|
||||
title: Step 19
|
||||
title: Passo 19
|
||||
challengeType: 0
|
||||
dashedName: step-19
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60f81167d0d4910809f88945
|
||||
title: Step 20
|
||||
title: Passo 20
|
||||
challengeType: 0
|
||||
dashedName: step-20
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60f81616cff80508badf9ad5
|
||||
title: Step 21
|
||||
title: Passo 21
|
||||
challengeType: 0
|
||||
dashedName: step-21
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60f83e7bfc09900959f41e20
|
||||
title: Step 22
|
||||
title: Passo 22
|
||||
challengeType: 0
|
||||
dashedName: step-22
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60f84ec41116b209c280ba91
|
||||
title: Step 23
|
||||
title: Passo 23
|
||||
challengeType: 0
|
||||
dashedName: step-23
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60f852f645b5310a8264f555
|
||||
title: Step 24
|
||||
title: Passo 24
|
||||
challengeType: 0
|
||||
dashedName: step-24
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60f85a62fb30c80bcea0cedb
|
||||
title: Step 25
|
||||
title: Passo 25
|
||||
challengeType: 0
|
||||
dashedName: step-25
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60f8604682407e0d017bbf7f
|
||||
title: Step 26
|
||||
title: Passo 26
|
||||
challengeType: 0
|
||||
dashedName: step-26
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60f8618d191b940d62038513
|
||||
title: Step 27
|
||||
title: Passo 27
|
||||
challengeType: 0
|
||||
dashedName: step-27
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60fab4a123ce4b04526b082b
|
||||
title: Step 28
|
||||
title: Passo 28
|
||||
challengeType: 0
|
||||
dashedName: step-28
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60fab8367d35de04e5cb7929
|
||||
title: Step 30
|
||||
title: Passo 30
|
||||
challengeType: 0
|
||||
dashedName: step-30
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60fab9f17fa294054b74228c
|
||||
title: Step 31
|
||||
title: Passo 31
|
||||
challengeType: 0
|
||||
dashedName: step-31
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60fabf0dd4959805dbae09e6
|
||||
title: Step 32
|
||||
title: Passo 32
|
||||
challengeType: 0
|
||||
dashedName: step-32
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60fac4095512d3066053d73c
|
||||
title: Step 33
|
||||
title: Passo 33
|
||||
challengeType: 0
|
||||
dashedName: step-33
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60fac56271087806def55b33
|
||||
title: Step 34
|
||||
title: Passo 34
|
||||
challengeType: 0
|
||||
dashedName: step-34
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60fac8d7fdfaee0796934f20
|
||||
title: Step 35
|
||||
title: Passo 35
|
||||
challengeType: 0
|
||||
dashedName: step-35
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60faca286cb48b07f6482970
|
||||
title: Step 36
|
||||
title: Passo 36
|
||||
challengeType: 0
|
||||
dashedName: step-36
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60facde2d0dc61085b41063f
|
||||
title: Step 37
|
||||
title: Passo 37
|
||||
challengeType: 0
|
||||
dashedName: step-37
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60facf914c7b9b08d7510c2c
|
||||
title: Step 39
|
||||
title: Passo 39
|
||||
challengeType: 0
|
||||
dashedName: step-39
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60fad0a812d9890938524f50
|
||||
title: Step 40
|
||||
title: Passo 40
|
||||
challengeType: 0
|
||||
dashedName: step-40
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60fad1cafcde010995e15306
|
||||
title: Step 41
|
||||
title: Passo 41
|
||||
challengeType: 0
|
||||
dashedName: step-41
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60fad6dfcc0d930a59becf12
|
||||
title: Step 42
|
||||
title: Passo 42
|
||||
challengeType: 0
|
||||
dashedName: step-42
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60fad8e6148f310bba7890b1
|
||||
title: Step 43
|
||||
title: Passo 43
|
||||
challengeType: 0
|
||||
dashedName: step-43
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60fad99e09f9d30c1657e790
|
||||
title: Step 44
|
||||
title: Passo 44
|
||||
challengeType: 0
|
||||
dashedName: step-44
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60fadb18058e950c73925279
|
||||
title: Step 45
|
||||
title: Passo 45
|
||||
challengeType: 0
|
||||
dashedName: step-45
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60fadce90f85c50d0bb0dd4f
|
||||
title: Step 46
|
||||
title: Passo 46
|
||||
challengeType: 0
|
||||
dashedName: step-46
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60fadd972e6ffe0d6858fa2d
|
||||
title: Step 48
|
||||
title: Passo 48
|
||||
challengeType: 0
|
||||
dashedName: step-48
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60fadfa2b540b70dcfa8b771
|
||||
title: Step 49
|
||||
title: Passo 49
|
||||
challengeType: 0
|
||||
dashedName: step-49
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60fc219d333e37046f474a6e
|
||||
title: Step 50
|
||||
title: Passo 50
|
||||
challengeType: 0
|
||||
dashedName: step-50
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60fc22d1e64d1b04cdd4e602
|
||||
title: Step 51
|
||||
title: Passo 51
|
||||
challengeType: 0
|
||||
dashedName: step-51
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60fc236dc04532052926fdac
|
||||
title: Step 52
|
||||
title: Passo 52
|
||||
challengeType: 0
|
||||
dashedName: step-52
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60ffe1bc30415f042faea936
|
||||
title: Step 53
|
||||
title: Passo 53
|
||||
challengeType: 0
|
||||
dashedName: step-53
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60ffe3936796ac04959285a9
|
||||
title: Step 54
|
||||
title: Passo 54
|
||||
challengeType: 0
|
||||
dashedName: step-54
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60ffe4f4ec18cd04dc470c56
|
||||
title: Step 55
|
||||
title: Passo 55
|
||||
challengeType: 0
|
||||
dashedName: step-55
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60ffe69ee377c6055e192a46
|
||||
title: Step 56
|
||||
title: Passo 56
|
||||
challengeType: 0
|
||||
dashedName: step-56
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60ffe7d8aae62c05bcc9e7eb
|
||||
title: Step 57
|
||||
title: Passo 57
|
||||
challengeType: 0
|
||||
dashedName: step-57
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60ffe8a5ceb0e90618db06d9
|
||||
title: Step 58
|
||||
title: Passo 58
|
||||
challengeType: 0
|
||||
dashedName: step-58
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60ffe947a868ec068f7850f6
|
||||
title: Step 59
|
||||
title: Passo 59
|
||||
challengeType: 0
|
||||
dashedName: step-59
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60ffe9cb47809106eda2f2c9
|
||||
title: Step 60
|
||||
title: Passo 60
|
||||
challengeType: 0
|
||||
dashedName: step-60
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60ffec2825da1007509ddd06
|
||||
title: Step 61
|
||||
title: Passo 61
|
||||
challengeType: 0
|
||||
dashedName: step-61
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60ffecefac971607ae73c60f
|
||||
title: Step 62
|
||||
title: Passo 62
|
||||
challengeType: 0
|
||||
dashedName: step-62
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 60ffefd6479a3d084fb77cbc
|
||||
title: Step 63
|
||||
title: Passo 63
|
||||
challengeType: 0
|
||||
dashedName: step-63
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 62b30924c5e4ef0daba23b5e
|
||||
title: Step 47
|
||||
title: Passo 47
|
||||
challengeType: 0
|
||||
dashedName: step-47
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 62ff8b9dab5ac88e4d3d43a3
|
||||
title: Step 18
|
||||
title: Passo 18
|
||||
challengeType: 0
|
||||
dashedName: step-18
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 62ff8e998d3e7eae14d6ae3b
|
||||
title: Step 29
|
||||
title: Passo 29
|
||||
challengeType: 0
|
||||
dashedName: step-29
|
||||
---
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: 62ff919a7b5612c0670923a5
|
||||
title: Step 38
|
||||
title: Passo 38
|
||||
challengeType: 0
|
||||
dashedName: step-38
|
||||
---
|
||||
|
||||
+6
-6
@@ -1,31 +1,31 @@
|
||||
---
|
||||
id: 63541ef4f96cd82e8e6c788a
|
||||
title: Step 12
|
||||
title: Etapa 12
|
||||
challengeType: 0
|
||||
dashedName: step-12
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The `method` attribute specifies how to send form-data to the URL specified in the `action` attribute. The form-data can be sent via a `GET` request as URL parameters (with `method="get"`) or via a `POST` request as data in the request body (with `method="post"`).
|
||||
O atributo `method` especifica como enviar dados de formulário para o URL especificado no atributo `action`. Os dados do formulário podem ser enviados através de uma solicitação `GET` como parâmetros de URL (com `method="get"`) ou através de uma solicitação `POST` como dados no corpo da solicitação (com `method="post"`).
|
||||
|
||||
Set the `method` attribute to send your form data via a `POST` request.
|
||||
Defina o atributo `method` para que envie os dados do formulário através de uma solicitação `POST`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You shouldn't add a new `form` element.
|
||||
Você não deve adicionar um novo elemento `form`.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelectorAll('form').length, 1 )
|
||||
```
|
||||
|
||||
Your `form` element should have a `method` attribute.
|
||||
O elemento `form` deve ter um atributo `method`.
|
||||
|
||||
```js
|
||||
assert.exists(document.querySelector('form')?.getAttribute('method'));
|
||||
```
|
||||
|
||||
Your `method` attribute should be set to `post`.
|
||||
O atributo `method` deve ser definido como `post`.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelector('form')?.getAttribute('method'), 'post');
|
||||
|
||||
+2
-2
@@ -29,13 +29,13 @@ O quinto valor de `locations` deve ter uma propriedade `name` com o valor `kill
|
||||
assert.equal(locations[4].name, 'kill monster');
|
||||
```
|
||||
|
||||
Your fifth `locations` value should have a `button text` array with three `Go to town square` strings.
|
||||
O quinto valor de `locations` deve ter um array `button text` com três strings `Go to town square`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(locations[4]["button text"], ['Go to town square', 'Go to town square', 'Go to town square']);
|
||||
```
|
||||
|
||||
Your fifth `locations` value should have a `button functions` array with three `goTown` variables.
|
||||
O quinto valor de `locations` deve ter um array `button functions` com três variáveis `goTown`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(locations[4]["button functions"], [goTown, goTown, goTown]);
|
||||
|
||||
+2
-2
@@ -29,13 +29,13 @@ O sétimo valor de `locations` deve ter uma propriedade `name` com o valor `win`
|
||||
assert.equal(locations[6].name, 'win');
|
||||
```
|
||||
|
||||
Your seventh `locations` value should have a `button text` array with three `REPLAY?` strings.
|
||||
O sétimo valor de `locations` deve ter um array `button text` com três strings `REPLAY?`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(locations[6]["button text"], ['REPLAY?', 'REPLAY?', 'REPLAY?']);
|
||||
```
|
||||
|
||||
Your seventh `locations` value should have a `button functions` array with three `restart` variables.
|
||||
O sétimo valor de `locations` deve ter um array `button functions` com três variáveis `restart`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(locations[6]["button functions"], [restart, restart, restart]);
|
||||
|
||||
+2
-2
@@ -29,13 +29,13 @@ O oitavo valor de `locations` deve ter uma propriedade `name` com o valor `easte
|
||||
assert.equal(locations[7].name, "easter egg");
|
||||
```
|
||||
|
||||
Your eighth `locations` value should have a `button text` array with the strings `2`, `8`, and `Go to town square?`.
|
||||
O oitavo valor de `locations` deve ter um array `button text` com as strings `2`, `8` e `Go to town square?`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(locations[7]["button text"], ["2", "8", "Go to town square?"]);
|
||||
```
|
||||
|
||||
Your eighth `locations` value should have a `button functions` an array with the variables `pickTwo`, `pickEight`, and `goTown`.
|
||||
O oitavo valor de `locations` deve ter um array `button functions` com as variáveis `pickTwo`, `pickEight` e `goTown`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(locations[7]["button functions"], [pickTwo, pickEight, goTown]);
|
||||
|
||||
+2
-2
@@ -29,13 +29,13 @@ O sexto valor de `locations` deve ter uma propriedade `name` com o valor `lose`.
|
||||
assert.equal(locations[5].name, 'lose');
|
||||
```
|
||||
|
||||
Your sixth `locations` value should have a `button text` array with three `REPLAY?` strings.
|
||||
O sexto valor de `locations` deve ter um array `button text` com três strings `REPLAY?`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(locations[5]["button text"], ['REPLAY?', 'REPLAY?', 'REPLAY?']);
|
||||
```
|
||||
|
||||
Your sixth `locations` value should have a `button functions` array with three `restart` variables.
|
||||
O sexto valor de `locations` deve ter um array `button functions` com três variáveis `restart`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(locations[5]["button functions"], [restart, restart, restart]);
|
||||
|
||||
+17
-3
@@ -58,13 +58,27 @@ myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('Frank Roosevelt'));
|
||||
```
|
||||
|
||||
Вам слід використовувати `.test()` для перевірки регулярного виразу.
|
||||
Your regex `myRegex` should return `false` for the string `FranklinRoosevelt`
|
||||
|
||||
```js
|
||||
myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('FranklinRoosevelt'));
|
||||
```
|
||||
|
||||
Your regex `myRegex` should return `false` for the string `EleanorRoosevelt`
|
||||
|
||||
```js
|
||||
myRegex.lastIndex = 0;
|
||||
assert(!myRegex.test('EleanorRoosevelt'));
|
||||
```
|
||||
|
||||
You should use `.test()` to test the regex.
|
||||
|
||||
```js
|
||||
assert(code.match(/myRegex.test\(\s*myString\s*\)/));
|
||||
```
|
||||
|
||||
У результаті ви повинні отримати `true`.
|
||||
Your result should return `true`.
|
||||
|
||||
```js
|
||||
assert(result === true);
|
||||
@@ -85,6 +99,6 @@ let result = false; // Change this line
|
||||
|
||||
```js
|
||||
let myString = "Eleanor Roosevelt";
|
||||
let myRegex = /(Franklin|Eleanor).*Roosevelt/;
|
||||
let myRegex = /(Franklin|Eleanor) (([A-Z]\.?|[A-Z][a-z]+) )?Roosevelt/;
|
||||
let result = myRegex.test(myString);
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user