diff --git a/docs/site/Model.md b/docs/site/Model.md index 95692a412fe5..843891d82ee9 100644 --- a/docs/site/Model.md +++ b/docs/site/Model.md @@ -194,6 +194,28 @@ 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. +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 5ee92aca509f..2c96390d5967 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( @@ -403,4 +414,13 @@ describe('model', () => { class MyModel extends Entity {} expect(MyModel.modelName).to.equal('MyModel'); }); + + it('hidden password from userModel', () => { + 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 ab4a68b7de77..7e797c84a7ff 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: Array = def.settings.hiddenProperties || []; // ToDo (frbuceta): Short-term solution for (const p in def.properties) { - if (p in this) { + if (p in this && hiddenProperties.indexOf(p) === -1) { copyPropertyAsJson(p); } }