Skip to content
This repository has been archived by the owner on Aug 31, 2024. It is now read-only.

L10n es #52

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions credits.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ dead-horse @dead-horse
hemanth.hm @hemanth
Yoshua Wuyts @yoshuawuyts
Christophe Porteneuve @tdd
Alvaro Martinez de Miguel @demipel8
71 changes: 71 additions & 0 deletions exercises/authentication/problem.es.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
En ejercicios anteriores, hemos aprendido `route`, `body-parser` y `session`. En este ejercicio, intentaremos combinarlos todos para crear una app muy simple con funcionalidad de login y logout. Definamos las siguientes rutas:

- `/` - Si el usuario esta logueado, debería ver `hola mundo`. Si no, debería recibir un error `401` porque no esta logueado.
- `/login` - Si el método es `GET`, devolverá un formulario. Si es `POST`, validara el cuerpo de la petición e intentara loguear al usuario, si el login tiene éxito, se redireccionara a ´/´.
- `/logout` - Debería desloguear al usuario y redirigirle a `/login`.

En este ejemplo no vamos a crear usuarios. La única autenticación posible será:

```
username = username
password = password
```

Cualquier otra combinación recibira un error `400`.

PISTAS

Ya hemos creado la base para esta app, ¡Completémosla!

```
var koa = require('koa');
var parse = require('co-body');
var session = require('koa-session');

var form = '<form action="/login" method="POST">\
<input name="username" type="text" value="username">\
<input name="password" type="password" placeholder="The password is \'password\'">\
<button type="submit">Submit</button>\
</form>';

var app = koa();

// usa koa-session en algun sitio por el principio de la app
// necesitamos crear `.keys` para las cookies firmadas y el módulo cookie-session
app.keys = ['secret1', 'secret2', 'secret3'];
app.use(session(app));

/**
* Si `this.session.authenticated` existe, el usuario vera 'hola mundo'
* si no, recibita un error 401` porque no esta autenticados.
*/

app.use(function* home(next) {
if (this.request.path !== '/') return yield next;

});

/**
* Si tiene éxito, el usuario autentificado es redireccionado a `/`.
* pista: usa `this.redirect`
*/

app.use(function* login(next) {
if (this.request.path !== '/login') return yield next;
if (this.request.method === 'GET') return this.body = form;

});

/**
* Redireccionemos a /login` despues de cada respuesta.
* Si un usuario accede a /logout` cuando ya se ha deslogieado,
* se considerara un "success" y no un error.
*/

app.use(function* logout(next) {
if (this.request.path !== '/logout') return yield next;

});

app.listen(process.argv[2]);
```
59 changes: 59 additions & 0 deletions exercises/authentication/solution_es/solution.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
var koa = require('koa');
var parse = require('co-body');
var session = require('koa-session');

var form = '<form action="/login" method="POST">\
<input name="username" type="text" value="username">\
<input name="password" type="password" placeholder="The password is \'password\'">\
<button type="submit">Submit</button>\
</form>';

var app = koa();

// usa koa-session en algun sitio por el principio de la app
// necesitamos crear `.keys` para las cookies firmadas y el módulo cookie-session
app.keys = ['secret1', 'secret2', 'secret3'];
app.use(session(app));

/**
* Si `this.session.authenticated` existe, el usuario vera 'hola mundo'
* si no, recibita un error 401` porque no esta autenticados.
*/

app.use(function* home(next) {
if (this.request.path !== '/') return yield next;
if (this.session.authenticated) return this.body = 'hola mundo';
this.status = 401;
});

/**
* Si tiene éxito, el usuario autentificado es redireccionado a `/`.
* pista: usa `this.redirect`
*/

app.use(function* login(next) {
if (this.request.path !== '/login') return yield next;
if (this.request.method === 'GET') return this.body = form;
if (this.request.method !== 'POST') return;

var body = yield parse(this);
if (body.username !== 'username'
|| body.password !== 'password') return this.status = 400;

this.session.authenticated = true;
this.redirect('/');
});

/**
* Redireccionemos a /login` despues de cada respuesta.
* Si un usuario accede a /logout` cuando ya se ha deslogieado,
* se considerara un "success" y no un error.
*/

app.use(function* logout(next) {
if (this.request.path !== '/logout') return yield next;
this.session.authenticated = false;
this.redirect('/login');
});

app.listen(process.argv[2]);
6 changes: 6 additions & 0 deletions exercises/authentication/solution_es/solution.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
GET / : usuario no logueado recibe error 401
POST /login : error 400 cuando el usuario o la contraseña es incorrecto
POST /login : login realizado con éxito
GET / : hola mundo
GET /logout : el usuario es redirigido a `/login`
GET / : usuario deslogueado user recibe error 401
35 changes: 35 additions & 0 deletions exercises/content_headers/problem.es.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
Crea una app que compruebe el Content-Type de la petición. Si es `application/json`, devuelve `{message: 'hi!'}` con las cabeceras de contenido pertinentes. Para el resto, devuelve `ok` como un string.

PISTAS

Tanto una petición como una respuesta pueden tener varios tipos de cabeceras de contenido. Algunas son:

```
Content-Type
Content-Length
Content-Encoding
```

Entre muchas otras, estamos particularmente interesados en `type` y `length`. Koa tiene getters/setters para type y length:

```
this.request.type
this.request.length
this.response.type
this.response.length
```

Inferir `this.request.type` es un poco dificil. Por ejemplo, ¿Como puedes saber si la petición es un texto? No quieres usar una expresión regular o probar todos los mime types posibles. Por ello, Koa tiene `this.request.is()` preparado para ti:

```
this.request.is('image/*') // => image/png
this.request.is('text') // => text o false
```

Koa también tiene `this.response.is()`, al igual que `this.request.is()` pero para la respuesta.

Aprende más de request.is():

```
http://koajs.com/#request-is-types-
```
11 changes: 11 additions & 0 deletions exercises/content_headers/solution_es/solution.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
var koa = require('koa');

var app = koa();

app.use(function* () {
this.body = this.request.is('json')
? { message: 'hi!' }
: 'ok';
});

app.listen(process.argv[2]);
2 changes: 2 additions & 0 deletions exercises/content_headers/solution_es/solution.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{"message":"hi!"}
ok
46 changes: 46 additions & 0 deletions exercises/cookie/problem.es.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
Crea una app que haga uso de cookies para guardar el numero de visitas que hacen los usuarios.

1. la clave de la cookie es `view`, tienes que guardar el número de visitas en esta cookie.
2. cada vez que se le pregunte al servidor, este debe responder `{cuenta} views`.
3. la cookie tiene que estar firamada(`signed`).

visita a `/`:
=>
cuerpo de la respuesta: `1 views`
set-cookie: `view=1`

visita a `/` again:
=>
cuerpo de la respuesta: `2 views`
set-cookie: `view=2`

PISTAS

koa usa el mdulo `cookies` para gestionar cookies.

```
https://github.com/expressjs/cookies
```

APIs:

`ctx.cookies.get(name, [options])`: Get cookie name con opciones(options)
- `signed`: the cookie requested should be signed

`ctx.cookies.set(name, value, [options])`: Set cookie name a un valor(value) con opciones(options)

- `signed`: firmar el valor de la cookie
- `expires`: añade una fecha de expiración a la cookie
- `path`: path de la cookie, '/' por defecto
- `domain`: dominio de la cookie
- `secure`: exigir SSL/TLS para la cookie
- `httpOnly`: server-accessible cookie, true por defecto

No olvides añadir `options.signed` en `get` y `set` para confirmar que la cookie este firmada.

Y para usar cookies firmadas, tiene que añadir `app.keys`:

```
var app = koa();
app.keys = ['secret', 'keys'];
```
14 changes: 14 additions & 0 deletions exercises/cookie/solution_es/solution.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
var koa = require('koa');

var app = koa();

// para usar cookies firmadas, necesitamos app.keys
app.keys = ['secret', 'keys'];

app.use(function *(){
var n = ~~this.cookies.get('view', { signed: true }) + 1;
this.cookies.set('view', n, { signed: true });
this.body = n + ' views';
});

app.listen(process.argv[2]);
3 changes: 3 additions & 0 deletions exercises/cookie/solution_es/solution.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
primera visita: 1 views
otra visita: 2 views
cookie firmada no puede ser alterada
38 changes: 38 additions & 0 deletions exercises/error_handling/problem.es.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
Añade un middleware para el manejo de errores en esta aplicacion de Koa.
El middleware `errorHandler` debe atrapar todos los errores y responder al cliente con `internal server error` y un status `500`.

```
var koa = require('koa');

var app = koa();

app.use(errorHandler());

app.use(function* () {
if (this.path === '/error') throw new Error('ooops');
this.body = 'OK';
});

function errorHandler() {
return function* (next) {
// try catch todo el downstream errors aquí
};
}

app.listen(process.argv[2]);

```


PISTAS

En Koa, el manejo de errores se realiza a través de `try/catch` (excepto con event emitters). Puede que no hayas visto últimamente esta aproximación si has estado trabajando con Express y las mayoría de frameworks de node.
Al contrario que en Express, los manejadores de errores son simplemente decoradores que añades al principio de tu pila de middlewares.

Puedes asignar el status de la respuesta así:

```
this.status = 404;
```

Cada app de Koa en una instancia de EventEmmiter. Todo los errores que no son atrapados por algún middleware son enviados a `app.on('error', function (err, context) {})`. Esto es útil para logear. Si creas tu propio gestor de errores (ej. atrapandolos), tendras que emitir los eventos manualmente.
28 changes: 28 additions & 0 deletions exercises/error_handling/solution_es/solution.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
var koa = require('koa');

var app = koa();

app.use(errorHandler());

app.use(function* () {
if (this.path === '/error') throw new Error('ooops');
this.body = 'OK';
});

function errorHandler() {
return function* (next) {
// atrapamos todos los error aquí
try {
yield next;
} catch (err) {
// fijamos el status
this.status = 500;
// asignamos el cuerpo de la respuesta
this.body = 'internal server error';
// podemos emitir en la app para el log
// this.app.emit('error', err, this);
}
};
}

app.listen(process.argv[2]);
4 changes: 4 additions & 0 deletions exercises/error_handling/solution_es/solution.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
responde "OK" al pedir `/`
el status de la respuesta es 200 al pedir `/`
responde "internal server error" al pedir `/error`
el status de la respuesta es 500 al pedir `/error`
Loading