Better handling of system transfered devices

If a user performs a system transfer, we can't guarantee the validity of
the linked PIDs to a device, not this device's existance on the
database. Add them to the database if necessary.
This commit is contained in:
Daniel López Guimaraes
2023-11-05 01:05:24 +00:00
parent 0242fa7450
commit aa480673d2

View File

@@ -95,6 +95,13 @@ async function NASCMiddleware(request: express.Request, response: express.Respon
return;
}
const nexAccount: HydratedNEXAccountDocument | null = await NEXAccount.findOne({ pid });
if (!nexAccount || nexAccount.access_level < 0) {
response.status(200).send(nascError('102').toString());
return;
}
let device: HydratedDeviceDocument | null = await Device.findOne({
fcdcert_hash: fcdcertHash,
});
@@ -108,13 +115,56 @@ async function NASCMiddleware(request: express.Request, response: express.Respon
if (pid) {
const linkedPIDs: number[] = device.linked_pids;
// * If a user performs a system transfer from
// * a console to another using a Nintendo account
// * during the transfer and both consoles have
// * a Pretendo account, the devices will be swapped
// * since we check it using the LFCS.
// *
// * So, the linked PIDs won't have the user's PID
// * anymore.
if (!linkedPIDs.includes(pid)) {
response.status(200).send(nascError('102').toString());
return;
const session: mongoose.ClientSession = await databaseConnection().startSession();
await session.startTransaction();
device.linked_pids.push(pid);
await device.save({ session });
await session.commitTransaction();
}
}
}
// * Workaround for edge case on system transfers
// * if a console that has a Pretendo account performs
// * a system transfer using the Nintendo account to
// * another that doesn't have a Pretendo account.
// *
// * This would make the Pretendo account to not have
// * a device on the database.
// *
// * TODO: With this change, now multiple devices can
// * have the same serial number and MAC address.
// * Do we want this? If not, are there other solutions?
if (!device && pid) {
const session: mongoose.ClientSession = await databaseConnection().startSession();
await session.startTransaction();
device = new Device({
model,
serial: serialNumber,
environment,
mac_hash: macAddressHash,
fcdcert_hash: fcdcertHash,
linked_pids: [pid]
});
await device.save({ session });
await session.commitTransaction();
}
if (titleID === '0004013000003202') {
if (password && !pid && !pidHmac) {
// Register new user
@@ -183,13 +233,6 @@ async function NASCMiddleware(request: express.Request, response: express.Respon
}
}
const nexAccount: HydratedNEXAccountDocument | null = await NEXAccount.findOne({ pid });
if (!nexAccount || nexAccount.access_level < 0) {
response.status(200).send(nascError('102').toString());
return;
}
request.nexAccount = nexAccount;
return next();
@@ -234,4 +277,4 @@ function validNintendoMACAddress(macAddress: string): boolean {
return MAC_REGEX.test(macAddress);
}
export default NASCMiddleware;
export default NASCMiddleware;