question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Hiding properties from JSON

See original GitHub issue

The problem

@Entity()
export class User extends BaseEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @Column({ unique: true })
  email: string;

  @Column()
  password: string;

  @Column({ nullable: true })
  accessToken?: string;

  // tslint:disable-next-line:variable-name
  private _client?: ThridPartyClient;

  get thridPartyClient(): ThridPartyClient | undefined {
    if (!this._client && this.accessToken) {
      this._client = createThridPartyClient({accessToken: this.accessToken});
    }

    return this._client;
  }
}

Currently, when we return an instance of the above entity (or anything that contains it) from an API endpoint the entire model gets serialized into something like:

{
  "id": 1,
  "name": "Orkhan",
  "email": "myemail@me.com",
  "password": "password-hash",
  "accessToken": "blah213",
  "_client": {...}
}

The last 3 fields must not be inside json. We can of course create a new object and return it but there should be a better solution in general. Does foalts have something to offer in this case?

Workaround

We can override toJSON method in the User entity class which is used by JSON.stringify method:

function hidden(hidden: string[]) {
  return function (this: object) {
    const result = {};
    for (const x in this) {
      if (!hidden.includes(x)) {
        result[x] = this[x];
      }
    }
    return result;
  };
}

@Entity()
export class User extends BaseEntity {
 ...
  toJSON = hidden(['password', 'accessToken', '_client']);
}

Where we call hidden method with the array of field names to hide and it will return a method that returns a new copy of object by not copying specified fields. This works for arrays and nested objects too.

Proposed solution

Again I put forward laravel’s approach as an example. FoalTS can use a custom replacer to serialize json response, where we can hook in and conditionally hide fields based on some sort of a reserved field on the provided entity (like foal: { hidden: ['password'] }). This would work for arrays and nested objects too.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:14 (8 by maintainers)

github_iconTop GitHub Comments

2reactions
squareloop1commented, Sep 4, 2019

You can set a TypeORM configuration on the column like this:

@Column({ select: false })
password: string;

But if it is not a TypeORM column you’d have to manually remove it from the response I guess.

1reaction
yosbelmscommented, Feb 14, 2020

This can be solved at ORM level with single table inheritance. Split User in two logic entities but both will live in the same table:

@Entity()
@TableInheritance({ column: { type: "varchar", name: "type" } })
export class User extends BaseEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @Column({ unique: true })
  email: string;
}

@Entity()
export class SecuredUser extends User {
    @Column()
    password: string;
  
    @Column({ nullable: true })
    accessToken?: string;
  
    // tslint:disable-next-line:variable-name
    private _client?: ThridPartyClient;
  
    get thridPartyClient(): ThridPartyClient | undefined {
      if (!this._client && this.accessToken) {
        this._client = createThridPartyClient({accessToken: this.accessToken});
      }
  
      return this._client;
    }
}

Now you can query SecuredUser for security tasks (authentication, authorization) and User for the rest of the logic, manipulate, and serialize to JSON without worrying about to disclose security properties by mistake.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Hiding C# properties when serialize with JSON.NET
Yes, marking your properties with JsonIgnore is probably best. However, if you do want to chose at runtime, add a public bool ...
Read more >
C# object to json but some properties need to hide.. - C# Corner
Using this class i have to create an json file ("JsonConvert.SerializeObject(Link)") but for some cases i dont want to hide name property ......
Read more >
Hide properties of Mongoose objects in Node.JS JSON ...
Many a times, we'll encounter a situation where we'll have to hide certain properties of Mongoose objects, especially when we're sending those objects...
Read more >
Hiding or adding properites to values/json/stringify?
Question is, what is official way to add or hide properties from values/json. ... });. So as you see I remove password property...
Read more >
Safely Hide Application Properties | MuleSoft Documentation
For Mule 4.0 and later, in the mule-artifact.json file under the secureProperties key, list the property names to safely hide as a comma-separated...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found