Is it possible to 'protect' a property and exclude it from select statements
TypeORM goes well with routing-controllers so you should use it, behind the scenes it uses class-transformer to serialize and deserialize your data. So you can use the @Exclude
decorator from that library to prevent certain properties being sent down to the clients.
It also uses the class-validator library to validate the data when specifying it as the type in the controller functions. These are powerful toys. Here is a small example of how you can leverage both:
import { Entity, Column, PrimaryGeneratedColumn, Index, OneToMany } from "typeorm";
import { Exclude, Expose } from "class-transformer";
import { IsNotEmpty, IsEmail, MinLength, MaxLength, Min, Max, IsNumber, IsString } from "class-validator";
@Entity()
export class User extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@Column()
@IsNotEmpty()
@IsEmail()
@Index({ unique: true })
email: string;
@Exclude()
@Column()
passwordHash: string;
@Column()
@IsNotEmpty()
@IsString()
firstName: string;
@Column()
@IsNotEmpty()
@IsString()
lastName: string;
@Column({ type: 'integer', default: Gender.NotSpecified })
@IsNumber()
@Min(1)
@Max(3)
gender: Gender;
@Expose()
get admin() {
return this.role == Role.Admin;
}
@Expose()
get stylist() {
return this.role == Role.Stylist;
}
}
If you use an another server-side library you can still take advantage of class-transformer and class-validator. You just need to call the validate function manually in your routes, for example for restify you can write:
import {validate } from "class-validator";
import {plainToClass} from "class-transformer";
// ... more code
server.post('/hello', function create(req, res, next) {
let bodyJSON = parseBodyTheWayYouWant(req.body);
let post = plainToClass(bodyJSON);
validate(post)
return next();
});
You can use delete
Exemple Find All users
async findUsers(){
const users:User[] = await userRepository.find();
return users.map(user => {
delete user.password;
delete user.salt;
return user;
}) ;
}
Exemple Find User By Id
async findUserById(id){
const user:User = await userRepository.findOne(id);
delete user.password;
return user;
}
I think a more accurate answer would be to set select: false
on column options:
@Column({ select: false })
password: string;
And explicitly select the column like this:
const user = await getRepository(User)
.createQueryBuilder()
.addSelect('password')
.getOne()