diff --git a/src/database.ts b/src/database.ts index 3e31e8a..7441771 100644 --- a/src/database.ts +++ b/src/database.ts @@ -1,7 +1,8 @@ import mongoose from 'mongoose'; import bcrypt from 'bcrypt'; import joi from 'joi'; -import { nintendoPasswordHash, decryptToken, unpackToken } from '@/util'; +import { nintendoPasswordHash } from '@/util'; +import { OAuthToken } from '@/models/oauth_token'; import { PNID } from '@/models/pnid'; import { Server } from '@/models/server'; import { LOG_ERROR } from '@/logger'; @@ -110,20 +111,26 @@ async function getPNIDByOAuthToken(token: string, expectedSystemType: SystemType verifyConnected(); try { - const decryptedToken = decryptToken(Buffer.from(token, 'hex')); - const unpackedToken = unpackToken(decryptedToken); + const oauthToken = await OAuthToken.findOne({ + token: token + }); - if (unpackedToken.system_type !== expectedSystemType) { - return null; - } - if (unpackedToken.token_type !== expectedTokenType) { + if (!oauthToken) { return null; } - const pnid = await getPNIDByPID(unpackedToken.pid); + if (oauthToken.info.system_type !== expectedSystemType) { + return null; + } + + if (oauthToken.info.token_type !== expectedTokenType) { + return null; + } + + const pnid = await getPNIDByPID(oauthToken.pid); if (pnid) { - const expireTime = Math.floor((Number(unpackedToken.expire_time) / 1000)); + const expireTime = Math.floor((Number(oauthToken.info.expires) / 1000)); if (Math.floor(Date.now() / 1000) > expireTime) { return null; diff --git a/src/services/api/routes/v1/resetPassword.ts b/src/services/api/routes/v1/resetPassword.ts index b7c5dcc..1f1fb43 100644 --- a/src/services/api/routes/v1/resetPassword.ts +++ b/src/services/api/routes/v1/resetPassword.ts @@ -1,8 +1,11 @@ import express from 'express'; import bcrypt from 'bcrypt'; -import { PNID } from '@/models/pnid'; -import { decryptToken, unpackToken, nintendoPasswordHash } from '@/util'; -import type { Token } from '@/types/common/token'; +import { PasswordResetToken } from '@/models/password_reset_token'; +import { nintendoPasswordHash } from '@/util'; +import { SystemType } from '@/types/common/system-types'; +import { TokenType } from '@/types/common/token-types'; +import { getPNIDByPID } from '@/database'; +import type { HydratedPNIDDocument } from '@/types/mongoose/pnid'; const router = express.Router(); @@ -27,10 +30,53 @@ router.post('/', async (request: express.Request, response: express.Response): P return; } - let unpackedToken: Token; + let pnid: HydratedPNIDDocument | null = null; try { - const decryptedToken = await decryptToken(Buffer.from(token, 'hex')); - unpackedToken = unpackToken(decryptedToken); + const passwordResetToken = await PasswordResetToken.findOne({ + token: token + }); + + if (!passwordResetToken) { + response.status(400).json({ + app: 'api', + status: 400, + error: 'Invalid token' + }); + + return; + } + + if (passwordResetToken.info.system_type !== SystemType.PasswordReset) { + response.status(400).json({ + app: 'api', + status: 400, + error: 'Invalid token' + }); + + return; + } + + if (passwordResetToken.info.token_type !== TokenType.PasswordReset) { + response.status(400).json({ + app: 'api', + status: 400, + error: 'Invalid token' + }); + + return; + } + + if (passwordResetToken.info.expires < new Date()) { + response.status(400).json({ + app: 'api', + status: 400, + error: 'Token expired' + }); + + return; + } + + pnid = await getPNIDByPID(passwordResetToken.pid); } catch { response.status(400).json({ app: 'api', @@ -41,18 +87,6 @@ router.post('/', async (request: express.Request, response: express.Response): P return; } - if (unpackedToken.expire_time < Date.now()) { - response.status(400).json({ - app: 'api', - status: 400, - error: 'Token expired' - }); - - return; - } - - const pnid = await PNID.findOne({ pid: unpackedToken.pid }); - if (!pnid) { response.status(400).json({ app: 'api', diff --git a/src/services/nnas/routes/account-settings.ts b/src/services/nnas/routes/account-settings.ts index 3d614d2..5fa5dbc 100644 --- a/src/services/nnas/routes/account-settings.ts +++ b/src/services/nnas/routes/account-settings.ts @@ -4,14 +4,14 @@ import got from 'got'; import { z } from 'zod'; import { getServerByClientID, getPNIDByPID } from '@/database'; import { LOG_ERROR } from '@/logger'; -import { decryptToken, unpackToken, getValueFromHeaders, sendConfirmationEmail } from '@/util'; +import { getValueFromHeaders, sendConfirmationEmail } from '@/util'; import { config } from '@/config-manager'; +import { IndependentServiceToken } from '@/models/independent_service_token'; import timezones from '@/services/nnas/timezones.json'; import regionsList from '@/services/nnas/regions.json'; import type { HydratedServerDocument } from '@/types/mongoose/server'; import type { HydratedPNIDDocument } from '@/types/mongoose/pnid'; import type { AccountSettings } from '@/types/services/nnas/account-settings'; -import type { Token } from '@/types/common/token'; import type { RegionLanguages } from '@/types/services/nnas/region-languages'; import type { RegionTimezone, RegionTimezones } from '@/types/services/nnas/region-timezones'; import type { Country, Region } from '@/types/services/nnas/regions'; @@ -44,13 +44,22 @@ router.get('/ui/profile', async function (request: express.Request, response: ex return; } - const aes_key: string = server?.aes_key; - const decryptedToken = decryptToken(Buffer.from(token, 'base64'), aes_key); + const serviceToken = await IndependentServiceToken.findOne({ + token: token + }); - const tokenContents: Token = unpackToken(decryptedToken); + if (!serviceToken) { + response.sendStatus(504); + return; + } + + if (serviceToken.client_id !== '3f3928cc6f780638d360f0485cef973f') { + response.sendStatus(504); + return; + } try { - const PNID: HydratedPNIDDocument | null = await getPNIDByPID(tokenContents.pid); + const PNID: HydratedPNIDDocument | null = await getPNIDByPID(serviceToken.pid); if (!PNID) { response.sendStatus(504); @@ -127,12 +136,22 @@ router.post('/update', async function (request: express.Request, response: expre return; } - const aesKey = server?.aes_key; - const decryptedToken = decryptToken(Buffer.from(token, 'base64'), aesKey); - const tokenContents: Token = unpackToken(decryptedToken); + const serviceToken = await IndependentServiceToken.findOne({ + token: token + }); + + if (!serviceToken) { + response.sendStatus(504); + return; + } + + if (serviceToken.client_id !== '3f3928cc6f780638d360f0485cef973f') { + response.sendStatus(504); + return; + } try { - const pnid: HydratedPNIDDocument | null = await getPNIDByPID(tokenContents.pid); + const pnid: HydratedPNIDDocument | null = await getPNIDByPID(serviceToken.pid); const personBody: AccountSettings = request.body; if (!pnid) {