From 326a804beebe39add0c550f54bc5d5dd31dca1de Mon Sep 17 00:00:00 2001 From: Francisco Buceta Date: Sun, 14 Jul 2019 02:48:39 +0200 Subject: [PATCH] feat(repository): add hidden properties in model --- docs/site/Model.md | 25 +++++++++++++++++++ .../src/__tests__/unit/model/model.unit.ts | 24 ++++++++++++++++-- packages/repository/src/model.ts | 3 ++- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/docs/site/Model.md b/docs/site/Model.md index 95692a412fe5..1887a4eb6847 100644 --- a/docs/site/Model.md +++ b/docs/site/Model.md @@ -194,6 +194,31 @@ Additionally, the model decorator is able to build the properties object through the information passed in or inferred by the property decorators, so the properties key value pair can also be omitted. +#### Hidden properties + +The properties are stored in the database, available in JS/TS code, can be set +via POST/PUT/PATCH requests, but they are removed from response bodies +(`.toJSON()` output). + +To hide a property, you can use the `hiddenProperties` setting like this: + +```ts +@model({ + settings: { + hiddenProperties: ['password'] + } +}) +class MyUserModel extends Entity { + @property({id: true}) + id: number; + @property({type: 'string'}) + email: string; + @property({type: 'string'}) + password: string; + ... +} +``` + ### Property Decorator The property decorator takes in the same arguments used in LoopBack 3 for diff --git a/packages/repository/src/__tests__/unit/model/model.unit.ts b/packages/repository/src/__tests__/unit/model/model.unit.ts index 91488375f018..5f4974ac0a8a 100644 --- a/packages/repository/src/__tests__/unit/model/model.unit.ts +++ b/packages/repository/src/__tests__/unit/model/model.unit.ts @@ -35,8 +35,10 @@ describe('model', () => { userDef .addProperty('id', {type: 'string', id: true}) .addProperty('email', 'string') + .addProperty('password', 'string') .addProperty('firstName', String) - .addProperty('lastName', STRING); + .addProperty('lastName', STRING) + .addSetting('hiddenProperties', ['password']); const flexibleDef = new ModelDefinition('Flexible'); flexibleDef @@ -101,11 +103,11 @@ describe('model', () => { } } - // eslint-disable-next-line @typescript-eslint/no-unused-vars class User extends Entity { static definition = userDef; id: string; email: string; + password: string; firstName: string; constructor(data?: Partial) { @@ -154,6 +156,15 @@ describe('model', () => { return customer; } + function createUser() { + const user = new User(); + user.id = '123'; + user.email = 'xyz@example.com'; + user.password = '1234test'; + user.firstName = 'Test User'; + return user; + } + it('adds properties', () => { expect(customerDef.name).to.eql('Customer'); expect(customerDef.properties).have.properties( @@ -408,4 +419,13 @@ describe('model', () => { class MyModel extends Entity {} expect(MyModel.modelName).to.equal('MyModel'); }); + + it('excludes hidden properties from toJSON() output', () => { + const user = createUser(); + expect(user.toJSON()).to.eql({ + id: '123', + email: 'xyz@example.com', + firstName: 'Test User', + }); + }); }); diff --git a/packages/repository/src/model.ts b/packages/repository/src/model.ts index b925d641f5da..6e4986df0483 100644 --- a/packages/repository/src/model.ts +++ b/packages/repository/src/model.ts @@ -211,8 +211,9 @@ export abstract class Model { }; const json: AnyObject = {}; + const hiddenProperties: string[] = def.settings.hiddenProperties || []; for (const p in def.properties) { - if (p in this) { + if (p in this && !hiddenProperties.includes(p)) { copyPropertyAsJson(p); } }