diff --git a/src/middleware/nasc.ts b/src/middleware/nasc.ts index 7a79e85..8dd6bbe 100644 --- a/src/middleware/nasc.ts +++ b/src/middleware/nasc.ts @@ -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; \ No newline at end of file +export default NASCMiddleware;