Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 45 additions & 15 deletions src/modules/address-book/services/address-book-legacy.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { Injectable, BadRequestException } from '@nestjs/common';
import {
Injectable,
BadRequestException,
NotFoundException,
Logger,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, In, DataSource } from 'typeorm';
import { v4 as uuidv4 } from 'uuid';
Expand All @@ -10,6 +15,7 @@ import {
} from '../entities';
import { Sysinfo, Peer } from '../../../common/entities';
import { mapOsToPlatform } from '../../../common/utils/platform.util';
import { isIpDevice } from '../../../common/utils/ip.util';

@Injectable()
/**
Expand All @@ -23,6 +29,8 @@ import { mapOsToPlatform } from '../../../common/utils/platform.util';
* Provides compatibility support for legacy clients
*/
export class AddressBookLegacyService {
private readonly logger = new Logger(AddressBookLegacyService.name);

constructor(
@InjectRepository(AddressBook)
private addressBookRepository: Repository<AddressBook>,
Expand Down Expand Up @@ -263,7 +271,19 @@ export class AddressBookLegacyService {
for (const peerData of parsedData.peers) {
// Look up or create the peer record via findOrCreatePeer, using its uuid as deviceId
// Consistent with the new API: deviceId always references peers.uuid
const peerRecord = await this.findOrCreatePeer(peerData.id);
// Non-IP devices that have never sent a heartbeat are skipped
let peerRecord: Peer;
try {
peerRecord = await this.findOrCreatePeer(peerData.id);
} catch (e) {
if (e instanceof NotFoundException) {
this.logger.warn(
`Skipping device ${peerData.id}: not registered (no heartbeat)`,
);
continue;
}
throw e;
}

const peerGuid = uuidv4();
const peer = peerRepository.create({
Expand Down Expand Up @@ -297,30 +317,40 @@ export class AddressBookLegacyService {

/**
* Find or create a device record
* Look up the device with the given id in the peers table; create it automatically if not found
* Look up the device with the given id in the peers table; if not found and
* the id is in IP format, create it automatically.
*
* Consistent with the new API: non-IP devices must have sent a heartbeat
* (i.e. already exist in the peers table) before they can be added to the
* address book. IP-format devices are created on demand because they are
* reached via direct IP and never register through heartbeats.
*
* @param id Device ID (RustDesk numeric ID, IP address, or any format of an existing record)
* @param id Device ID (RustDesk numeric ID or IP address)
* @returns Peer record
* @throws NotFoundException Thrown when the device does not exist and the id is not in IP format
*/
private async findOrCreatePeer(id: string): Promise<Peer> {
const peerRecord = await this.peerRepository.findOne({
where: { id },
order: { lastHeartbeat: 'DESC' },
});

if (peerRecord) {
return peerRecord;
}

// For devices not in the peers table, create a peer record automatically
// This includes IP-format devices (such as 192.168.1.94) and numeric-ID devices that have not sent a heartbeat yet
const newPeer = this.peerRepository.create({
uuid: uuidv4(),
id,
ver: 0,
modifiedAt: 0,
lastHeartbeat: null,
});
await this.peerRepository.save(newPeer);
return newPeer;
if (isIpDevice(id)) {
const newPeer = this.peerRepository.create({
uuid: uuidv4(),
id,
ver: 0,
modifiedAt: 0,
lastHeartbeat: null,
});
await this.peerRepository.save(newPeer);
return newPeer;
}

throw new NotFoundException(`Device ${id} does not exist`);
}
}
Loading