feat: use sha256 as token key

This commit is contained in:
Jonathan Barrow 2026-01-14 20:13:06 -05:00
parent a50857af89
commit d820e44d89
No known key found for this signature in database
GPG Key ID: 2A7DAA6DED5A77E5
9 changed files with 54 additions and 33 deletions

View File

@ -1,3 +1,4 @@
import crypto from 'node:crypto';
import mongoose from 'mongoose';
import bcrypt from 'bcrypt';
import joi from 'joi';
@ -112,7 +113,7 @@ async function getPNIDByOAuthToken(token: string, expectedSystemType: SystemType
try {
const oauthToken = await OAuthToken.findOne({
token: token
token: crypto.createHash('sha256').update(token).digest('hex')
});
if (!oauthToken) {

View File

@ -114,8 +114,11 @@ router.post('/', async (request: express.Request, response: express.Response): P
}
try {
const accessToken = await OAuthToken.create({
token: crypto.randomBytes(16).toString('hex'),
const accessToken = crypto.randomBytes(16).toString('hex');
const newRefreshToken = crypto.randomBytes(20).toString('hex');
await OAuthToken.create({
token: crypto.createHash('sha256').update(accessToken).digest('hex'),
client_id: 'a2efa818a34fa16b8afbc8a74eba3eda', // TODO - This is the Wii U config, change this?
client_secret: 'c91cdb5658bd4954ade78533a339cf9a', // TODO - This is the Wii U config, change this?
pid: pnid.pid,
@ -128,8 +131,8 @@ router.post('/', async (request: express.Request, response: express.Response): P
}
});
const newRefreshToken = await OAuthToken.create({
token: crypto.randomBytes(20).toString('hex'),
await OAuthToken.create({
token: crypto.createHash('sha256').update(newRefreshToken).digest('hex'),
client_id: 'a2efa818a34fa16b8afbc8a74eba3eda', // TODO - This is the Wii U config, change this?
client_secret: 'c91cdb5658bd4954ade78533a339cf9a', // TODO - This is the Wii U config, change this?
pid: pnid.pid,

View File

@ -421,8 +421,11 @@ router.post('/', async (request: express.Request, response: express.Response): P
await sendConfirmationEmail(pnid);
try {
const accessToken = await OAuthToken.create({
token: crypto.randomBytes(16).toString('hex'),
const accessToken = crypto.randomBytes(16).toString('hex');
const refreshToken = crypto.randomBytes(20).toString('hex');
await OAuthToken.create({
token: crypto.createHash('sha256').update(accessToken).digest('hex'),
client_id: 'a2efa818a34fa16b8afbc8a74eba3eda', // TODO - This is the Wii U config, change this?
client_secret: 'c91cdb5658bd4954ade78533a339cf9a', // TODO - This is the Wii U config, change this?
pid: pnid.pid,
@ -435,8 +438,8 @@ router.post('/', async (request: express.Request, response: express.Response): P
}
});
const refreshToken = await OAuthToken.create({
token: crypto.randomBytes(20).toString('hex'),
await OAuthToken.create({
token: crypto.createHash('sha256').update(refreshToken).digest('hex'),
client_id: 'a2efa818a34fa16b8afbc8a74eba3eda', // TODO - This is the Wii U config, change this?
client_secret: 'c91cdb5658bd4954ade78533a339cf9a', // TODO - This is the Wii U config, change this?
pid: pnid.pid,

View File

@ -1,3 +1,4 @@
import crypto from 'node:crypto';
import express from 'express';
import bcrypt from 'bcrypt';
import { PasswordResetToken } from '@/models/password_reset_token';
@ -33,7 +34,7 @@ router.post('/', async (request: express.Request, response: express.Response): P
let pnid: HydratedPNIDDocument | null = null;
try {
const passwordResetToken = await PasswordResetToken.findOne({
token: token
token: crypto.createHash('sha256').update(token).digest('hex')
});
if (!passwordResetToken) {

View File

@ -75,8 +75,10 @@ router.post('/', async (request: express.Request, response: express.Response): P
async function processLoginRequest(server: HydratedServerDocument, pid: number, requestParams: NASCLoginACRequestParams): Promise<URLSearchParams> {
const titleID = nintendoBase64Decode(requestParams.titleid).toString();
const nexToken = await NEXToken.create({
token: nintendoBase64Encode(crypto.randomBytes(112)),
const token = nintendoBase64Encode(crypto.randomBytes(112));
await NEXToken.create({
token: crypto.createHash('sha256').update(token).digest('hex'),
game_server_id: server.game_server_id,
pid: pid,
info: {
@ -92,7 +94,7 @@ async function processLoginRequest(server: HydratedServerDocument, pid: number,
locator: nintendoBase64Encode(`${server.ip}:${server.port}`),
retry: nintendoBase64Encode('0'),
returncd: nintendoBase64Encode('001'),
token: nexToken.token,
token: token,
datetime: nintendoBase64Encode(nascDateTime())
});
}
@ -106,8 +108,10 @@ async function processServiceTokenRequest(server: HydratedServerDocument, pid: n
expires: new Date(Date.now() + 24 * 3600 * 1000)
};
const serviceToken = await IndependentServiceToken.create({
token: nintendoBase64Encode(createServiceToken(server, serviceTokenOptions)),
const token = nintendoBase64Encode(createServiceToken(server, serviceTokenOptions));
await IndependentServiceToken.create({
token: crypto.createHash('sha256').update(token).digest('hex'),
client_id: nintendoBase64Decode(requestParams.keyhash).toString(),
title_id: serviceTokenOptions.title_id,
pid: serviceTokenOptions.pid,
@ -123,7 +127,7 @@ async function processServiceTokenRequest(server: HydratedServerDocument, pid: n
return new URLSearchParams({
retry: nintendoBase64Encode('0'),
returncd: nintendoBase64Encode('007'),
servicetoken: serviceToken.token,
servicetoken: token,
statusdata: nintendoBase64Encode('Y'),
svchost: nintendoBase64Encode('n/a'),
datetime: nintendoBase64Encode(nascDateTime())

View File

@ -45,7 +45,7 @@ router.get('/ui/profile', async function (request: express.Request, response: ex
}
const serviceToken = await IndependentServiceToken.findOne({
token: token
token: crypto.createHash('sha256').update(token).digest('hex')
});
if (!serviceToken) {
@ -137,7 +137,7 @@ router.post('/update', async function (request: express.Request, response: expre
}
const serviceToken = await IndependentServiceToken.findOne({
token: token
token: crypto.createHash('sha256').update(token).digest('hex')
});
if (!serviceToken) {

View File

@ -170,8 +170,11 @@ router.post('/access_token/generate', deviceCertificateMiddleware, consoleStatus
const clientID = request.header('x-nintendo-client-id');
const clientSecret = request.header('x-nintendo-client-secret');
const accessToken = await OAuthToken.create({
token: crypto.randomBytes(16).toString('hex'),
const accessToken = crypto.randomBytes(16).toString('hex');
const newRefreshToken = crypto.randomBytes(20).toString('hex');
await OAuthToken.create({
token: crypto.createHash('sha256').update(accessToken).digest('hex'),
client_id: clientID,
client_secret: clientSecret,
pid: pnid.pid,
@ -184,8 +187,8 @@ router.post('/access_token/generate', deviceCertificateMiddleware, consoleStatus
}
});
const newRefreshToken = await OAuthToken.create({
token: crypto.randomBytes(20).toString('hex'),
await OAuthToken.create({
token: crypto.createHash('sha256').update(newRefreshToken).digest('hex'),
client_id: clientID,
client_secret: clientSecret,
pid: pnid.pid,
@ -203,8 +206,8 @@ router.post('/access_token/generate', deviceCertificateMiddleware, consoleStatus
response.send(xmlbuilder.create({
OAuth20: {
access_token: {
token: accessToken.token,
refresh_token: newRefreshToken.token,
token: accessToken,
refresh_token: newRefreshToken,
expires_in: 3600
}
}

View File

@ -100,8 +100,10 @@ router.get('/service_token/@me', async (request: express.Request, response: expr
expires: new Date(Date.now() + 24 * 3600 * 1000)
};
const serviceToken = await IndependentServiceToken.create({
token: createServiceToken(server, serviceTokenOptions).toString('base64'),
const token = createServiceToken(server, serviceTokenOptions).toString('base64');
await IndependentServiceToken.create({
token: crypto.createHash('sha256').update(token).digest('hex'),
client_id: clientID,
title_id: serviceTokenOptions.title_id,
pid: serviceTokenOptions.pid,
@ -116,7 +118,7 @@ router.get('/service_token/@me', async (request: express.Request, response: expr
response.send(xmlbuilder.create({
service_token: {
token: serviceToken.token
token: token
}
}).end());
});
@ -221,8 +223,10 @@ router.get('/nex_token/@me', async (request: express.Request, response: express.
return;
}
const nexToken = await NEXToken.create({
token: crypto.randomBytes(36).toString('base64'),
const token = crypto.randomBytes(36).toString('base64');
await NEXToken.create({
token: crypto.createHash('sha256').update(token).digest('hex'),
game_server_id: gameServerID,
pid: pnid.pid,
info: {
@ -240,7 +244,7 @@ router.get('/nex_token/@me', async (request: express.Request, response: express.
nex_password: nexAccount.password,
pid: nexAccount.pid,
port: server.port,
token: nexToken.token
token: token
}
}).end());
});

View File

@ -171,8 +171,10 @@ export async function sendEmailConfirmedParentalControlsEmail(pnid: mongoose.Hyd
}
export async function sendForgotPasswordEmail(pnid: mongoose.HydratedDocument<IPNID, IPNIDMethods>): Promise<void> {
const passwordResetToken = await PasswordResetToken.create({
token: crypto.randomBytes(36).toString('hex'),
const token = crypto.randomBytes(36).toString('hex');
await PasswordResetToken.create({
token: crypto.createHash('sha256').update(token).digest('hex'),
pid: pnid.pid,
info: {
system_type: SystemType.PasswordReset,
@ -187,7 +189,7 @@ export async function sendForgotPasswordEmail(pnid: mongoose.HydratedDocument<IP
.addHeader('Dear {{pnid}},', { pnid: pnid.username })
.addParagraph('a password reset has been requested from this account.')
.addParagraph('If you did not request the password reset, please ignore this email. If you did request this password reset, please click the link below to reset your password.')
.addButton('Reset password', `${config.website_base}/account/reset-password?token=${encodeURIComponent(passwordResetToken.token)}`);
.addButton('Reset password', `${config.website_base}/account/reset-password?token=${encodeURIComponent(token)}`);
const mailerOptions = {
to: pnid.email.address,