diff --git a/cdn/content/decrypted/rjVlM7hUXPxmYQJh/Festival.byaml b/cdn/content/decrypted/rjVlM7hUXPxmYQJh/Festival.byaml new file mode 100644 index 0000000..0143320 Binary files /dev/null and b/cdn/content/decrypted/rjVlM7hUXPxmYQJh/Festival.byaml differ diff --git a/cdn/content/decrypted/rjVlM7hUXPxmYQJh/HapTexture.bfres b/cdn/content/decrypted/rjVlM7hUXPxmYQJh/HapTexture.bfres new file mode 100644 index 0000000..cbd4198 Binary files /dev/null and b/cdn/content/decrypted/rjVlM7hUXPxmYQJh/HapTexture.bfres differ diff --git a/cdn/content/decrypted/rjVlM7hUXPxmYQJh/PanelTexture.bfres b/cdn/content/decrypted/rjVlM7hUXPxmYQJh/PanelTexture.bfres new file mode 100644 index 0000000..93e9922 Binary files /dev/null and b/cdn/content/decrypted/rjVlM7hUXPxmYQJh/PanelTexture.bfres differ diff --git a/cdn/content/encrypted/rjVlM7hUXPxmYQJh/10afe8d3e18cf6c14fc6762c496ba0d6 b/cdn/content/encrypted/rjVlM7hUXPxmYQJh/10afe8d3e18cf6c14fc6762c496ba0d6 new file mode 100644 index 0000000..51e1ec9 Binary files /dev/null and b/cdn/content/encrypted/rjVlM7hUXPxmYQJh/10afe8d3e18cf6c14fc6762c496ba0d6 differ diff --git a/encrypt-contents.js b/encrypt-contents.js new file mode 100644 index 0000000..7782d5d --- /dev/null +++ b/encrypt-contents.js @@ -0,0 +1,21 @@ +const BOSS = require('boss-js'); +const path = require('path'); +const fs = require('fs-extra'); +const crypto = require('crypto'); +require('dotenv').config(); + +// PROVIDE THESE KEYS YOURSELF +const { BOSS_AES_KEY, BOSS_HMAC_KEY } = process.env; + +const decryptedFilePath = path.normalize(path.resolve(__dirname, process.argv[2])); +const encryptedFolderName = path.basename(path.dirname(decryptedFilePath)); +const encryptedFolderPath = path.normalize(path.resolve(decryptedFilePath, '../../../encrypted', encryptedFolderName)); + +fs.ensureDirSync(encryptedFolderPath); + +const encryptedContents = BOSS.encryptWiiU(decryptedFilePath, BOSS_AES_KEY, BOSS_HMAC_KEY); +const hash = crypto.createHash('md5').update(encryptedContents).digest('hex'); + +const encryptedFilePath = path.normalize(path.resolve(encryptedFolderPath, hash)); + +fs.writeFileSync(encryptedFilePath, encryptedContents); \ No newline at end of file diff --git a/src/server.js b/src/server.js index 30b445f..5704206 100644 --- a/src/server.js +++ b/src/server.js @@ -10,6 +10,7 @@ const app = express(); const nptsService = require('./services/npts'); const npplService = require('./services/nppl'); +const npdiService = require('./services/npdi'); // START APPLICATION app.set('etag', false); @@ -25,6 +26,7 @@ app.use(express.urlencoded({ app.use(nptsService); app.use(npplService); +app.use(npdiService); // 404 handler logger.info('Creating 404 status handler'); diff --git a/src/services/npdi.js b/src/services/npdi.js new file mode 100644 index 0000000..d1e49b2 --- /dev/null +++ b/src/services/npdi.js @@ -0,0 +1,31 @@ +const path = require('path'); +const fs = require('fs-extra'); +const express = require('express'); +const subdomain = require('express-subdomain'); + +// Router to handle the subdomain restriction +const npdi = express.Router(); + +// Setup routes +npdi.get('/p01/data/1/:titleHash/:fileVersion/:fileHash', (request, response) => { + const { titleHash, fileHash } = request.params; + const contentPath = path.normalize(`${__dirname}/../../cdn/content/encrypted/${titleHash}/${fileHash}`); + + if (fs.existsSync(contentPath)) { + response.set('Content-Type', 'applicatoin/octet-stream'); + response.set('Content-Disposition', 'attachment'); + response.set('Content-Transfer-Encoding', 'binary'); + response.set('Content-Type', 'applicatoin/octet-stream'); + response.sendFile(contentPath); + } else { + response.sendStatus(404); + } +}); + +// Main router for endpoints +const router = express.Router(); + +// Create subdomain +router.use(subdomain('npdi.app', npdi)); + +module.exports = router; \ No newline at end of file