From 2f69cfc5acd862cb154615fae5f335876ad8162d Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sat, 11 Dec 2021 07:51:58 -0500 Subject: [PATCH] Added (temporary) Cemu-specific handling --- src/middleware/cemu.js | 12 ++++++++++ src/middleware/pnid.js | 6 ++++- src/services/account/index.js | 5 +++++ src/services/account/routes/oauth.js | 29 +++++++++++++++---------- src/services/account/routes/provider.js | 12 ++++++++-- 5 files changed, 49 insertions(+), 15 deletions(-) create mode 100644 src/middleware/cemu.js diff --git a/src/middleware/cemu.js b/src/middleware/cemu.js new file mode 100644 index 0000000..ffecb0a --- /dev/null +++ b/src/middleware/cemu.js @@ -0,0 +1,12 @@ +const xmlbuilder = require('xmlbuilder'); +const database = require('../database'); + +async function CemuMiddleware(request, response, next) { + const subdomain = request.subdomains.reverse().join('.'); + + request.isCemu = subdomain === 'c.account'; + + return next(); +} + +module.exports = CemuMiddleware; \ No newline at end of file diff --git a/src/middleware/pnid.js b/src/middleware/pnid.js index 6e4c676..262dfa3 100644 --- a/src/middleware/pnid.js +++ b/src/middleware/pnid.js @@ -8,9 +8,13 @@ async function PNIDMiddleware(request, response, next) { return next(); } - const [type, token] = headers.authorization.split(' '); + let [type, token] = headers.authorization.split(' '); let user; + if (request.isCemu) { + token = Buffer.from(token, 'hex').toString('base64'); + } + if (type === 'Basic') { user = await database.getUserBasic(token); } else { diff --git a/src/services/account/index.js b/src/services/account/index.js index 713944f..86fe036 100644 --- a/src/services/account/index.js +++ b/src/services/account/index.js @@ -2,6 +2,7 @@ const express = require('express'); const subdomain = require('express-subdomain'); +const cemuMiddleware = require('../../middleware/cemu'); const pnidMiddleware = require('../../middleware/pnid'); const logger = require('../../../logger'); const routes = require('./routes'); @@ -10,6 +11,7 @@ const routes = require('./routes'); const account = express.Router(); logger.info('[ACCOUNT] Importing middleware'); +account.use(cemuMiddleware); account.use(pnidMiddleware); // Setup routes @@ -30,4 +32,7 @@ const router = express.Router(); logger.info('[ACCOUNT] Creating \'account\' subdomain'); router.use(subdomain('account', account)); +logger.info('[ACCOUNT] Creating \'c.account\' subdomain'); +router.use(subdomain('c.account', account)); + module.exports = router; \ No newline at end of file diff --git a/src/services/account/routes/oauth.js b/src/services/account/routes/oauth.js index 4d1f1b0..012da20 100644 --- a/src/services/account/routes/oauth.js +++ b/src/services/account/routes/oauth.js @@ -50,6 +50,16 @@ router.post('/access_token/generate', clientHeaderCheck, async (request, respons const pnid = await database.getUserByUsername(user_id); + if (!pnid || !bcrypt.compareSync(password, pnid.password)) { + response.status(400); + return response.send(xmlbuilder.create({ + error: { + code: '0106', + message: 'Invalid account ID or password' + } + }).end()); + } + if (pnid.get('access_level') < 0) { return response.status(400).send(xmlbuilder.create({ errors: { @@ -61,16 +71,6 @@ router.post('/access_token/generate', clientHeaderCheck, async (request, respons }).end()); } - if (!pnid || !bcrypt.compareSync(password, pnid.password)) { - response.status(400); - return response.send(xmlbuilder.create({ - error: { - code: '0106', - message: 'Invalid account ID or password' - } - }).end()); - } - const cryptoPath = `${__dirname}/../../../../certs/access`; if (!fs.pathExistsSync(cryptoPath)) { @@ -99,8 +99,13 @@ router.post('/access_token/generate', clientHeaderCheck, async (request, respons expire_time: BigInt(Date.now() + (3600 * 1000)) }; - const accessToken = util.generateToken(null, accessTokenOptions); - const refreshToken = util.generateToken(null, refreshTokenOptions); + let accessToken = util.generateToken(null, accessTokenOptions); + let refreshToken = util.generateToken(null, refreshTokenOptions); + + if (request.isCemu) { + accessToken = Buffer.from(accessToken, 'base64').toString('hex'); + refreshToken = Buffer.from(refreshToken, 'base64').toString('hex'); + } response.send(xmlbuilder.create({ OAuth20: { diff --git a/src/services/account/routes/provider.js b/src/services/account/routes/provider.js index ceadf43..30989c5 100644 --- a/src/services/account/routes/provider.js +++ b/src/services/account/routes/provider.js @@ -61,7 +61,11 @@ router.get('/service_token/@me', async (request, response) => { expire_time: BigInt(Date.now() + (3600 * 1000)) }; - const serviceToken = util.generateToken(cryptoOptions, tokenOptions); + let serviceToken = util.generateToken(cryptoOptions, tokenOptions); + + if (request.isCemu) { + serviceToken = Buffer.from(serviceToken, 'base64').toString('hex'); + } response.send(xmlbuilder.create({ service_token: { @@ -147,7 +151,11 @@ router.get('/nex_token/@me', async (request, response) => { return response.send('0008Not Found'); } - const nexToken = util.generateToken(cryptoOptions, tokenOptions); + let nexToken = util.generateToken(cryptoOptions, tokenOptions); + + if (request.isCemu) { + nexToken = Buffer.from(nexToken, 'base64').toString('hex'); + } response.send(xmlbuilder.create({ nex_token: {