class-transformer
class-transformer copied to clipboard
fix: plainToClass overwrites ObjectIds
Description
Hi, I'm trying to use plainToClass to remove sensitive data from objects in my API, but the plainToClass function overwrites the ObjectIds with new values. Below is a minimal code snippet that demonstrates it.
Minimal code-snippet showcasing the problem
import { Expose, plainToClass } from "class-transformer";
import { ObjectId } from "mongodb";
import "reflect-metadata";
class Obj {
@Expose()
field1: ObjectId;
@Expose()
field2: ObjectId;
@Expose()
field3: ObjectId;
}
let objects = [];
let fieldCount = 3;
let fields = ["field1", "field2", "field3"];
let objectCount = 10;
// gen objects with random objectIds
for (let x = 0; x < objectCount; x++) {
let obj: any = {};
for (const field of fields) {
obj[field] = new ObjectId();
}
objects.push(obj);
}
console.log(objects.length);
// let classObjects = []
let mismatchedCount = 0;
for (const obj of objects) {
let clsObj = plainToClass(Obj, obj, { excludeExtraneousValues: true });
for (const field of fields) {
if (clsObj[field].toString() != obj[field].toString()) {
console.log(
`mismatched: \nafter: ${JSON.stringify(
clsObj
)} \nbefore:${JSON.stringify(obj)}`
);
mismatchedCount += 1;
break;
}
}
}
console.log(`mismatched count: ${mismatchedCount}`);
Output:
10
mismatched:
after: {"field1":"622e0f388601f22386f635fb","field2":"622e0f388601f22386f635fc","field3":"622e0f388601f22386f635fd"}
before:{"field1":"622e0f388601f22386f635dd","field2":"622e0f388601f22386f635de","field3":"622e0f388601f22386f635df"}
mismatched:
after: {"field1":"622e0f388601f22386f635fe","field2":"622e0f388601f22386f635ff","field3":"622e0f388601f22386f63600"}
before:{"field1":"622e0f388601f22386f635e0","field2":"622e0f388601f22386f635e1","field3":"622e0f388601f22386f635e2"}
mismatched:
after: {"field1":"622e0f388601f22386f63601","field2":"622e0f388601f22386f63602","field3":"622e0f388601f22386f63603"}
before:{"field1":"622e0f388601f22386f635e3","field2":"622e0f388601f22386f635e4","field3":"622e0f388601f22386f635e5"}
mismatched:
after: {"field1":"622e0f388601f22386f63604","field2":"622e0f388601f22386f63605","field3":"622e0f388601f22386f63606"}
before:{"field1":"622e0f388601f22386f635e6","field2":"622e0f388601f22386f635e7","field3":"622e0f388601f22386f635e8"}
mismatched:
after: {"field1":"622e0f388601f22386f63607","field2":"622e0f388601f22386f63608","field3":"622e0f388601f22386f63609"}
before:{"field1":"622e0f388601f22386f635e9","field2":"622e0f388601f22386f635ea","field3":"622e0f388601f22386f635eb"}
mismatched:
after: {"field1":"622e0f388601f22386f6360a","field2":"622e0f388601f22386f6360b","field3":"622e0f388601f22386f6360c"}
before:{"field1":"622e0f388601f22386f635ec","field2":"622e0f388601f22386f635ed","field3":"622e0f388601f22386f635ee"}
mismatched:
after: {"field1":"622e0f388601f22386f6360d","field2":"622e0f388601f22386f6360e","field3":"622e0f388601f22386f6360f"}
before:{"field1":"622e0f388601f22386f635ef","field2":"622e0f388601f22386f635f0","field3":"622e0f388601f22386f635f1"}
mismatched:
after: {"field1":"622e0f388601f22386f63610","field2":"622e0f388601f22386f63611","field3":"622e0f388601f22386f63612"}
before:{"field1":"622e0f388601f22386f635f2","field2":"622e0f388601f22386f635f3","field3":"622e0f388601f22386f635f4"}
mismatched:
after: {"field1":"622e0f388601f22386f63613","field2":"622e0f388601f22386f63614","field3":"622e0f388601f22386f63615"}
before:{"field1":"622e0f388601f22386f635f5","field2":"622e0f388601f22386f635f6","field3":"622e0f388601f22386f635f7"}
mismatched:
after: {"field1":"622e0f388601f22386f63616","field2":"622e0f388601f22386f63617","field3":"622e0f388601f22386f63618"}
before:{"field1":"622e0f388601f22386f635f8","field2":"622e0f388601f22386f635f9","field3":"622e0f388601f22386f635fa"}
mismatched count: 10
am using this workaround. i hope they fix this soon
export class AuthResDto {
@Expose()
@Transform((value) => value.obj._id.toString())
_id: ObjectId;
@Expose()
email: string;
}