fix(api): keep push token and serial out of the device list

getDevicesForUser did find({ user }) with no projection, so the device
list endpoint returned the full document, including the fcmToken push
credential and the hardware serial, straight to the browser. Neither is
used by the dashboard or the Android client.

The query now projects both fields out with '-fcmToken -serial'. Only the
user-facing list is narrowed; getDeviceById, which feeds the guards and
internal logic, is untouched.

Guarded by the existing getDevicesForUser test, rewritten to assert the
projection and seen to fail against the pre-change single-argument call.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
isra el
2026-07-19 18:37:40 +03:00
parent e58412fa14
commit 8b635a2344
2 changed files with 12 additions and 3 deletions

View File

@@ -279,12 +279,17 @@ describe('GatewayService', () => {
{ _id: 'device2', model: 'iPhone 13' },
]
it('should return all devices for a user', async () => {
it('should return a user\'s devices without the push token or serial', async () => {
mockDeviceModel.find.mockResolvedValue(mockDevices)
const result = await service.getDevicesForUser(mockUser)
expect(mockDeviceModel.find).toHaveBeenCalledWith({ user: mockUser._id })
const [filter, projection] = mockDeviceModel.find.mock.calls[0]
expect(filter).toEqual({ user: mockUser._id })
// fcmToken is a push credential and serial is a hardware id; neither
// should be shipped to the browser in the device list.
expect(projection).toContain('-fcmToken')
expect(projection).toContain('-serial')
expect(result).toEqual(mockDevices)
})
})

View File

@@ -140,7 +140,11 @@ export class GatewayService {
}
async getDevicesForUser(user: User): Promise<any> {
return await this.deviceModel.find({ user: user._id })
// Exclude the push credential and hardware serial from the client response.
return await this.deviceModel.find(
{ user: user._id },
'-fcmToken -serial',
)
}
async getDeviceById(deviceId: string): Promise<any> {