From 84f4aa08d69945e3d3e55765d3eb419c75a318b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bajto=C5=A1?= Date: Mon, 25 Nov 2019 09:13:14 +0100 Subject: [PATCH 1/3] fix(docs): use `json` instead of `ts` syntax for JSON snippets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miroslav Bajtoš --- .../tutorials/authentication/Authentication-Tutorial.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/site/tutorials/authentication/Authentication-Tutorial.md b/docs/site/tutorials/authentication/Authentication-Tutorial.md index 6f23f3eddebd..30d56985ab3b 100644 --- a/docs/site/tutorials/authentication/Authentication-Tutorial.md +++ b/docs/site/tutorials/authentication/Authentication-Tutorial.md @@ -86,7 +86,7 @@ application, follow these steps: 1. In the `UserController` section, click on `POST /users`, click on `'Try it out'`, specify: - ```ts + ```json { "id": "1", "email": "user1@example.com", @@ -101,7 +101,7 @@ application, follow these steps: 1. In the `UserController` section, click on `POST /users/login`, click on `'Try it out'`, specify: - ```ts + ```json { "email": "user1@example.com", "password": "thel0ngp@55w0rd" @@ -114,7 +114,7 @@ application, follow these steps: For example: - ```ts + ```json { "token": "some.token.value" } @@ -163,7 +163,7 @@ application, follow these steps: The response is: - ```sh + ```json {"id":"1","name":"User One"} ``` From 5a7545277228695320f368179b6e16f061238ae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bajto=C5=A1?= Date: Mon, 25 Nov 2019 09:25:22 +0100 Subject: [PATCH 2/3] feat(docs): update Authentication Tutorial with UserCredentials MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miroslav Bajtoš --- .../authentication/Authentication-Tutorial.md | 66 +++++++++++++++---- 1 file changed, 53 insertions(+), 13 deletions(-) diff --git a/docs/site/tutorials/authentication/Authentication-Tutorial.md b/docs/site/tutorials/authentication/Authentication-Tutorial.md index 30d56985ab3b..883ccca1e40a 100644 --- a/docs/site/tutorials/authentication/Authentication-Tutorial.md +++ b/docs/site/tutorials/authentication/Authentication-Tutorial.md @@ -88,11 +88,10 @@ application, follow these steps: ```json { - "id": "1", - "email": "user1@example.com", - "password": "thel0ngp@55w0rd", - "firstName": "User", - "lastName": "One" + "email": "user1@example.com", + "password": "thel0ngp@55w0rd", + "firstName": "User", + "lastName": "One" } ``` @@ -103,7 +102,7 @@ application, follow these steps: ```json { - "email": "user1@example.com", + "email": "user1@example.com", "password": "thel0ngp@55w0rd" } ``` @@ -161,10 +160,11 @@ application, follow these steps: [HTTP 401 UnAuthorized](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401) is thrown. - The response is: + The response contains a unique value in the `id` field (generated by the + database) and `name` field with the full user name: ```json - {"id":"1","name":"User One"} + {"id": "5dd6acee242760334f6aef65", "name": "User One"} ``` ## Adding JWT Authentication to a LoopBack 4 Application @@ -768,6 +768,27 @@ In the `UserController` class in the users can be added by performing a `POST` request to the `/users` endpoint which is handled by the `create()` function. +Because user credentials like password are stored outside of the main user +profile, we need to create a new model (a +[Data Transfer Object](https://en.wikipedia.org/wiki/Data_transfer_object)) to +describe data required to create a new user. The class inherits from `User` +model to include all user profile properties, and adds a new property `password` +allowing clients to specify the password too. + +```ts +@model() +export class NewUserRequest extends User { + @property({ + type: 'string', + required: true, + }) + password: string; +} +``` + +The controller method `UserController.create` then has to remove additional +properties like `password` before passing the data to Repository (and database). + ```ts export class UserController { constructor( @@ -784,16 +805,35 @@ export class UserController { // ... @post('/users') - async create(@requestBody() user: User): Promise { + async create( + @requestBody({ + content: { + 'application/json': { + schema: getModelSchemaRef(NewUserRequest, { + title: 'NewUser', + }), + }, + }, + }) + newUserRequest: NewUserRequest, + ): Promise { // ensure a valid email value and password value - validateCredentials(_.pick(user, ['email', 'password'])); + validateCredentials(_.pick(newUserRequest, ['email', 'password'])); // encrypt the password - user.password = await this.passwordHasher.hashPassword(user.password); + const password = await this.passwordHasher.hashPassword( + newUserRequest.password, + ); // create the new user - const savedUser = await this.userRepository.create(user); - delete savedUser.password; + const savedUser = await this.userRepository.create( + _.omit(newUserRequest, 'password'), + ); + + // set the password + await this.userRepository + .userCredentials(savedUser.id) + .create({password}); return savedUser; } From 28bddf830cae4c73fe5d0f6b9a1c7c4b3e29bf7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bajto=C5=A1?= Date: Mon, 25 Nov 2019 09:34:51 +0100 Subject: [PATCH 3/3] fix(docs): improve TypeScript snippets to fix syntax highlighting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miroslav Bajtoš --- .../tutorials/authentication/Authentication-Tutorial.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/site/tutorials/authentication/Authentication-Tutorial.md b/docs/site/tutorials/authentication/Authentication-Tutorial.md index 883ccca1e40a..f77b6046f3c9 100644 --- a/docs/site/tutorials/authentication/Authentication-Tutorial.md +++ b/docs/site/tutorials/authentication/Authentication-Tutorial.md @@ -193,9 +193,7 @@ so it is important to add the component in the `ShoppingApplication` class in [loopback4-example-shopping/packages/shopping/src/application.ts](https://github.com/strongloop/loopback4-example-shopping/blob/master/packages/shopping/src/application.ts). ```ts -import { - AuthenticationComponent -} from '@loopback/authentication'; +import {AuthenticationComponent} from '@loopback/authentication'; export class ShoppingApplication extends BootMixin( ServiceMixin(RepositoryMixin(RestApplication)), @@ -209,6 +207,9 @@ export class ShoppingApplication extends BootMixin( this.component(AuthenticationComponent); // ... + } + // ... +} ``` ### Securing an Endpoint with the Authentication Decorator