mirror of
https://github.com/PretendoNetwork/BOSS.git
synced 2026-03-21 17:34:19 -05:00
Convert to TypeScript
This commit is contained in:
parent
3b5aeb222c
commit
38739fef7e
|
|
@ -1 +1,2 @@
|
|||
node_modules
|
||||
dist
|
||||
*.js
|
||||
43
.eslintrc
43
.eslintrc
|
|
@ -1,43 +0,0 @@
|
|||
{
|
||||
"env": {
|
||||
"node": true,
|
||||
"commonjs": true,
|
||||
"es6": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2020
|
||||
},
|
||||
"globals": {
|
||||
"BigInt": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"rules": {
|
||||
"require-atomic-updates": "warn",
|
||||
"no-case-declarations": "off",
|
||||
"no-empty": "off",
|
||||
"no-console": "off",
|
||||
"linebreak-style": "off",
|
||||
"no-global-assign": "off",
|
||||
"prefer-const": "error",
|
||||
"no-var": "error",
|
||||
"one-var": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"indent": [
|
||||
"error",
|
||||
"tab",
|
||||
{
|
||||
"SwitchCase": 1
|
||||
}
|
||||
],
|
||||
"quotes": [
|
||||
"error",
|
||||
"single"
|
||||
],
|
||||
"semi": [
|
||||
"error",
|
||||
"always"
|
||||
]
|
||||
}
|
||||
}
|
||||
60
.eslintrc.json
Normal file
60
.eslintrc.json
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
{
|
||||
"env": {
|
||||
"node": true,
|
||||
"commonjs": true,
|
||||
"es6": true
|
||||
},
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"globals": {
|
||||
"BigInt": true
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended"
|
||||
],
|
||||
"plugins": [
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"rules": {
|
||||
"require-atomic-updates": "warn",
|
||||
"no-case-declarations": "off",
|
||||
"no-empty": "off",
|
||||
"no-console": "off",
|
||||
"linebreak-style": "off",
|
||||
"no-global-assign": "off",
|
||||
"prefer-const": "error",
|
||||
"no-var": "error",
|
||||
"no-unused-vars": "off",
|
||||
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
|
||||
"no-extra-semi": "off",
|
||||
"@typescript-eslint/no-extra-semi": "error",
|
||||
"@typescript-eslint/no-empty-interface": "warn",
|
||||
"@typescript-eslint/no-inferrable-types": "off",
|
||||
"@typescript-eslint/typedef": "error",
|
||||
"@typescript-eslint/explicit-function-return-type": "error",
|
||||
"@typescript-eslint/no-explicit-any": "warn",
|
||||
"keyword-spacing": "off",
|
||||
"@typescript-eslint/keyword-spacing": "error",
|
||||
"curly": "error",
|
||||
"brace-style": "error",
|
||||
"one-var": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"indent": [
|
||||
"error",
|
||||
"tab",
|
||||
{
|
||||
"SwitchCase": 1
|
||||
}
|
||||
],
|
||||
"quotes": [
|
||||
"error",
|
||||
"single"
|
||||
],
|
||||
"semi": [
|
||||
"error",
|
||||
"always"
|
||||
]
|
||||
}
|
||||
}
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -59,4 +59,4 @@ typings/
|
|||
|
||||
# custom
|
||||
.vscode
|
||||
config.json
|
||||
dist
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<TaskSheet>
|
||||
<TitleId>0005003010016100</TitleId>
|
||||
<TitleId>0005003010016200</TitleId>
|
||||
<TaskId>olvinfo</TaskId>
|
||||
<ServiceStatus>open</ServiceStatus>
|
||||
<Files>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<TaskSheet>
|
||||
<TitleId>0005003010016100</TitleId>
|
||||
<TitleId>0005003010016000</TitleId>
|
||||
<TaskId>olvinfo</TaskId>
|
||||
<ServiceStatus>open</ServiceStatus>
|
||||
<Files>
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
<Filename>Festival.byaml</Filename>
|
||||
<DataId>1490</DataId>
|
||||
<Type>AppData</Type>
|
||||
<Url>https://npdi.cdn.pretendo.cc/p01/data/1/bb6tOEckvgZ50ciH/1490/3d12d0e157820defea888023e06fbc3d</Url>
|
||||
<Size>18784</Size>
|
||||
<Url>https://npdi.cdn.pretendo.cc/p01/data/1/bb6tOEckvgZ50ciH/1490/2ff2eebe2d8a9c2d93eb289ef27449cf</Url>
|
||||
<Size>17924</Size>
|
||||
<Notify>
|
||||
<New>app</New>
|
||||
<LED>false</LED>
|
||||
|
|
@ -19,8 +19,8 @@
|
|||
<Filename>HapTexture.bfres</Filename>
|
||||
<DataId>1491</DataId>
|
||||
<Type>AppData</Type>
|
||||
<Url>https://npdi.cdn.pretendo.cc/p01/data/1/bb6tOEckvgZ50ciH/1491/fdb1f5522d7e8247fd5308fa7f0d5b76</Url>
|
||||
<Size>361536</Size>
|
||||
<Url>https://npdi.cdn.pretendo.cc/p01/data/1/bb6tOEckvgZ50ciH/1491/c05ad953c1111bf2dbbe0a191a401e3e</Url>
|
||||
<Size>364608</Size>
|
||||
<Notify>
|
||||
<New>app</New>
|
||||
<LED>false</LED>
|
||||
|
|
@ -30,8 +30,8 @@
|
|||
<Filename>PanelTexture.bfres</Filename>
|
||||
<DataId>1492</DataId>
|
||||
<Type>AppData</Type>
|
||||
<Url>https://npdi.cdn.pretendo.cc/p01/data/1/bb6tOEckvgZ50ciH/1492/d6b6ed30ea52d4b176e2656d7dc94e42</Url>
|
||||
<Size>475712</Size>
|
||||
<Url>https://npdi.cdn.pretendo.cc/p01/data/1/bb6tOEckvgZ50ciH/1492/fa99f04d9bb81cf6205c76c479852916</Url>
|
||||
<Size>479296</Size>
|
||||
<Notify>
|
||||
<New>app</New>
|
||||
<LED>false</LED>
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
<Filename>Festival.byaml</Filename>
|
||||
<DataId>1348</DataId>
|
||||
<Type>AppData</Type>
|
||||
<Url>https://npdi.cdn.pretendo.cc/p01/data/1/rjVlM7hUXPxmYQJh/1348/bee225fded2f9f4adae8f58c640ca9ae</Url>
|
||||
<Size>18784</Size>
|
||||
<Url>https://npdi.cdn.pretendo.cc/p01/data/1/rjVlM7hUXPxmYQJh/1348/6d2b6c4df1a666832452385cbc7f77f5</Url>
|
||||
<Size>24304</Size>
|
||||
<Notify>
|
||||
<New>app</New>
|
||||
<LED>false</LED>
|
||||
|
|
@ -19,8 +19,8 @@
|
|||
<Filename>HapTexture.bfres</Filename>
|
||||
<DataId>1347</DataId>
|
||||
<Type>AppData</Type>
|
||||
<Url>https://npdi.cdn.pretendo.cc/p01/data/1/rjVlM7hUXPxmYQJh/1347/73d21a6ec3f893b61671f34941bde0a4</Url>
|
||||
<Size>361536</Size>
|
||||
<Url>https://npdi.cdn.pretendo.cc/p01/data/1/rjVlM7hUXPxmYQJh/1347/734e5be62755592478fc5e8ca1cc34cd</Url>
|
||||
<Size>364608</Size>
|
||||
<Notify>
|
||||
<New>app</New>
|
||||
<LED>false</LED>
|
||||
|
|
@ -30,8 +30,8 @@
|
|||
<Filename>PanelTexture.bfres</Filename>
|
||||
<DataId>1349</DataId>
|
||||
<Type>AppData</Type>
|
||||
<Url>https://npdi.cdn.pretendo.cc/p01/data/1/rjVlM7hUXPxmYQJh/1349/ad76fc5663bc6d27f85d8497970f6b14</Url>
|
||||
<Size>475712</Size>
|
||||
<Url>https://npdi.cdn.pretendo.cc/p01/data/1/rjVlM7hUXPxmYQJh/1349/2283065f6cb4c57bf6881de3e7afe37f</Url>
|
||||
<Size>479296</Size>
|
||||
<Notify>
|
||||
<New>app</New>
|
||||
<LED>false</LED>
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
<Filename>Festival.byaml</Filename>
|
||||
<DataId>1357</DataId>
|
||||
<Type>AppData</Type>
|
||||
<Url>https://npdi.cdn.pretendo.cc/p01/data/1/zvGSM4kOrXpkKnpT/1357/a5eee49b5c57b9749b4cd61b2c18ec75</Url>
|
||||
<Size>18784</Size>
|
||||
<Url>https://npdi.cdn.pretendo.cc/p01/data/1/zvGSM4kOrXpkKnpT/1357/7faa9748451ccee23eaabd1dfd19c982</Url>
|
||||
<Size>23184</Size>
|
||||
<Notify>
|
||||
<New>app</New>
|
||||
<LED>false</LED>
|
||||
|
|
@ -19,8 +19,8 @@
|
|||
<Filename>HapTexture.bfres</Filename>
|
||||
<DataId>1358</DataId>
|
||||
<Type>AppData</Type>
|
||||
<Url>https://npdi.cdn.pretendo.cc/p01/data/1/zvGSM4kOrXpkKnpT/1358/e08b705678a3cea02d38f89b569fb971</Url>
|
||||
<Size>361536</Size>
|
||||
<Url>https://npdi.cdn.pretendo.cc/p01/data/1/zvGSM4kOrXpkKnpT/1358/827a01e39f4cd9208b230f5b74d7ede6</Url>
|
||||
<Size>364608</Size>
|
||||
<Notify>
|
||||
<New>app</New>
|
||||
<LED>false</LED>
|
||||
|
|
@ -30,8 +30,8 @@
|
|||
<Filename>PanelTexture.bfres</Filename>
|
||||
<DataId>1356</DataId>
|
||||
<Type>AppData</Type>
|
||||
<Url>https://npdi.cdn.pretendo.cc/p01/data/1/zvGSM4kOrXpkKnpT/1356/df0e9021d339ab02880120d273e2ab83</Url>
|
||||
<Size>475712</Size>
|
||||
<Url>https://npdi.cdn.pretendo.cc/p01/data/1/zvGSM4kOrXpkKnpT/1356/f30e8e623db8cd8f5eb4005d35d7c8bc</Url>
|
||||
<Size>479296</Size>
|
||||
<Notify>
|
||||
<New>app</New>
|
||||
<LED>false</LED>
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@ 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 { PN_BOSS_CONFIG_BOSS_WIIU_AES_KEY, PN_BOSS_CONFIG_BOSS_WIIU_HMAC_KEY } = process.env;
|
||||
|
||||
const decryptedFilePath = path.normalize(path.resolve(__dirname, process.argv[2]));
|
||||
const encryptedFolderName = path.basename(path.dirname(decryptedFilePath));
|
||||
|
|
@ -13,7 +12,7 @@ const encryptedFolderPath = path.normalize(path.resolve(decryptedFilePath, '../.
|
|||
|
||||
fs.ensureDirSync(encryptedFolderPath);
|
||||
|
||||
const encryptedContents = BOSS.encryptWiiU(decryptedFilePath, BOSS_AES_KEY, BOSS_HMAC_KEY);
|
||||
const encryptedContents = BOSS.encryptWiiU(decryptedFilePath, PN_BOSS_CONFIG_BOSS_WIIU_AES_KEY, PN_BOSS_CONFIG_BOSS_WIIU_HMAC_KEY);
|
||||
const hash = crypto.createHash('md5').update(encryptedContents).digest('hex');
|
||||
|
||||
const encryptedFilePath = path.normalize(path.resolve(encryptedFolderPath, hash));
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"http": {
|
||||
"port": 8080
|
||||
}
|
||||
}
|
||||
4162
package-lock.json
generated
4162
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
18
package.json
18
package.json
|
|
@ -1,10 +1,13 @@
|
|||
{
|
||||
"name": "BOSS",
|
||||
"name": "boss",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "./src/server.js",
|
||||
"main": "dist/server.js",
|
||||
"scripts": {
|
||||
"start": "node ."
|
||||
"lint": "npx eslint .",
|
||||
"build": "npm run lint && npm run clean && npx tsc && npx tsc-alias",
|
||||
"clean": "rimraf ./dist",
|
||||
"start": "node --enable-source-maps ."
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
|
|
@ -18,8 +21,17 @@
|
|||
"morgan": "^1.10.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.17",
|
||||
"@types/fs-extra": "^11.0.1",
|
||||
"@types/morgan": "^1.9.4",
|
||||
"@types/node": "^20.5.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.4.0",
|
||||
"@typescript-eslint/parser": "^6.4.0",
|
||||
"axios": "^0.27.2",
|
||||
"eslint": "^8.47.0",
|
||||
"fs-extra": "^10.1.0",
|
||||
"tsc-alias": "^1.8.7",
|
||||
"typescript": "^5.1.6",
|
||||
"xmlbuilder2": "^3.0.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,14 @@ const TASKSHEETS = [
|
|||
id: 'VFoY6V7u7UUq1EG5',
|
||||
files: ['olvinfo']
|
||||
},
|
||||
{
|
||||
id: 'WJDaV6ePVgrS0TRa',
|
||||
files: ['olvinfo']
|
||||
},
|
||||
{
|
||||
id: '8MNOVprfNVAJjfCM',
|
||||
files: ['olvinfo']
|
||||
},
|
||||
{
|
||||
id: '07E3nY6lAwlwrQRo',
|
||||
files: ['wood1', 'woodBGM']
|
||||
|
|
|
|||
49
src/config-manager.ts
Normal file
49
src/config-manager.ts
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
import dotenv from 'dotenv';
|
||||
import { md5 } from '@/util';
|
||||
import { LOG_INFO, LOG_ERROR } from '@/logger';
|
||||
import { Config } from '@/types/common/config';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const BOSS_WIIU_AES_KEY_HASH = Buffer.from('5202ce5099232c3d365e28379790a919', 'hex');
|
||||
const BOSS_WIIU_HMAC_KEY_HASH = Buffer.from('b4482fef177b0100090ce0dbeb8ce977', 'hex');
|
||||
const BOSS_3DS_AES_KEY_HASH = Buffer.from('86fbc2bb4cb703b2a4c6cc9961319926', 'hex');
|
||||
|
||||
LOG_INFO('Loading config');
|
||||
|
||||
export const config: Config = {
|
||||
http: {
|
||||
port: Number(process.env.PN_BOSS_CONFIG_HTTP_PORT || '')
|
||||
},
|
||||
crypto: {
|
||||
wup: {
|
||||
aes_key: Buffer.from(process.env.PN_BOSS_CONFIG_BOSS_WIIU_AES_KEY || ''),
|
||||
hmac_key: Buffer.from(process.env.PN_BOSS_CONFIG_BOSS_WIIU_HMAC_KEY || ''),
|
||||
},
|
||||
ctr: {
|
||||
aes_key: Buffer.from(process.env.PN_BOSS_CONFIG_BOSS_3DS_AES_KEY || '', 'hex')
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
LOG_INFO('Config loaded, checking integrity');
|
||||
|
||||
if (!config.http.port) {
|
||||
LOG_ERROR('Failed to find HTTP port. Set the PN_BOSS_CONFIG_HTTP_PORT environment variable');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
if (!BOSS_WIIU_AES_KEY_HASH.equals(md5(config.crypto.wup.aes_key))) {
|
||||
LOG_ERROR('Invalid BOSS WiiU AES key. Set or correct the PN_BOSS_CONFIG_BOSS_WIIU_AES_KEY environment variable');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
if (!BOSS_WIIU_HMAC_KEY_HASH.equals(md5(config.crypto.wup.hmac_key))) {
|
||||
LOG_ERROR('Invalid BOSS WiiU HMAC key. Set or correct the PN_BOSS_CONFIG_BOSS_WIIU_HMAC_KEY environment variable');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
if (!BOSS_3DS_AES_KEY_HASH.equals(md5(config.crypto.ctr.aes_key))) {
|
||||
LOG_ERROR('Invalid BOSS 3DS AES key. Set or correct the PN_BOSS_CONFIG_BOSS_3DS_AES_KEY environment variable');
|
||||
process.exit(0);
|
||||
}
|
||||
47
src/logger.ts
Normal file
47
src/logger.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import fs from 'fs-extra';
|
||||
import colors from 'colors';
|
||||
|
||||
colors.enable();
|
||||
|
||||
const root = process.env.PN_BOSS_CONFIG_LOGGER_PATH ? process.env.PN_BOSS_CONFIG_LOGGER_PATH : `${__dirname}/..`;
|
||||
fs.ensureDirSync(`${root}/logs`);
|
||||
|
||||
const streams = {
|
||||
latest: fs.createWriteStream(`${root}/logs/latest.log`),
|
||||
success: fs.createWriteStream(`${root}/logs/success.log`),
|
||||
error: fs.createWriteStream(`${root}/logs/error.log`),
|
||||
warn: fs.createWriteStream(`${root}/logs/warn.log`),
|
||||
info: fs.createWriteStream(`${root}/logs/info.log`)
|
||||
} as const;
|
||||
|
||||
export function LOG_SUCCESS(input: string): void {
|
||||
const time = new Date();
|
||||
input = `[${time.getHours()}:${time.getMinutes()}:${time.getSeconds()}] [SUCCESS]: ${input}`;
|
||||
streams.success.write(`${input}\n`);
|
||||
|
||||
console.log(`${input}`.green.bold);
|
||||
}
|
||||
|
||||
export function LOG_ERROR(input: string): void {
|
||||
const time = new Date();
|
||||
input = `[${time.getHours()}:${time.getMinutes()}:${time.getSeconds()}] [ERROR]: ${input}`;
|
||||
streams.error.write(`${input}\n`);
|
||||
|
||||
console.log(`${input}`.red.bold);
|
||||
}
|
||||
|
||||
export function LOG_WARN(input: string): void {
|
||||
const time = new Date();
|
||||
input = `[${time.getHours()}:${time.getMinutes()}:${time.getSeconds()}] [WARN]: ${input}`;
|
||||
streams.warn.write(`${input}\n`);
|
||||
|
||||
console.log(`${input}`.yellow.bold);
|
||||
}
|
||||
|
||||
export function LOG_INFO(input: string): void {
|
||||
const time = new Date();
|
||||
input = `[${time.getHours()}:${time.getMinutes()}:${time.getSeconds()}] [INFO]: ${input}`;
|
||||
streams.info.write(`${input}\n`);
|
||||
|
||||
console.log(`${input}`.cyan.bold);
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
process.title = 'Pretendo - BOSS';
|
||||
|
||||
const express = require('express');
|
||||
const morgan = require('morgan');
|
||||
const logger = require('../logger');
|
||||
const config = require('../config.json');
|
||||
|
||||
const { http: { port } } = config;
|
||||
const app = express();
|
||||
|
||||
const nptsService = require('./services/npts');
|
||||
const npplService = require('./services/nppl');
|
||||
const npdiService = require('./services/npdi');
|
||||
|
||||
// START APPLICATION
|
||||
app.set('etag', false);
|
||||
app.disable('x-powered-by');
|
||||
|
||||
// Create router
|
||||
logger.info('Setting up Middleware');
|
||||
app.use(morgan('dev'));
|
||||
app.use(express.json());
|
||||
app.use(express.urlencoded({
|
||||
extended: true
|
||||
}));
|
||||
|
||||
app.use(nptsService);
|
||||
app.use(npplService);
|
||||
app.use(npdiService);
|
||||
|
||||
// 404 handler
|
||||
logger.info('Creating 404 status handler');
|
||||
app.use((request, response) => {
|
||||
response.status(404);
|
||||
response.json({
|
||||
app: 'api',
|
||||
status: 404,
|
||||
error: 'Route not found'
|
||||
});
|
||||
});
|
||||
|
||||
// non-404 error handler
|
||||
logger.info('Creating non-404 status handler');
|
||||
app.use((error, request, response) => {
|
||||
const status = error.status || 500;
|
||||
|
||||
response.status(status);
|
||||
response.json({
|
||||
app: 'api',
|
||||
status,
|
||||
error: error.message
|
||||
});
|
||||
});
|
||||
|
||||
// Starts the server
|
||||
logger.info('Starting server');
|
||||
|
||||
app.listen(port, () => {
|
||||
logger.success(`Server started on port ${port}`);
|
||||
});
|
||||
53
src/server.ts
Normal file
53
src/server.ts
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
process.title = 'Pretendo - BOSS';
|
||||
|
||||
import express from 'express';
|
||||
import morgan from 'morgan';
|
||||
import { LOG_INFO, LOG_SUCCESS } from '@/logger';
|
||||
import { config } from '@/config-manager';
|
||||
|
||||
import nppl from '@/services/nppl';
|
||||
import npts from '@/services/npts';
|
||||
import npdi from '@/services/npdi';
|
||||
|
||||
const app = express();
|
||||
|
||||
app.set('etag', false);
|
||||
app.disable('x-powered-by');
|
||||
|
||||
LOG_INFO('Setting up Middleware');
|
||||
app.use(morgan('dev'));
|
||||
app.use(express.json());
|
||||
app.use(express.urlencoded({
|
||||
extended: true
|
||||
}));
|
||||
|
||||
app.use(nppl);
|
||||
app.use(npts);
|
||||
app.use(npdi);
|
||||
|
||||
LOG_INFO('Creating 404 status handler');
|
||||
app.use((_request, response) => {
|
||||
response.status(404);
|
||||
response.json({
|
||||
app: 'api',
|
||||
status: 404,
|
||||
error: 'Route not found'
|
||||
});
|
||||
});
|
||||
|
||||
LOG_INFO('Creating non-404 status handler');
|
||||
app.use((error: any, _request: express.Request, response: express.Response, _next: express.NextFunction) => {
|
||||
const status: number = error.status || 500;
|
||||
|
||||
response.status(status);
|
||||
response.json({
|
||||
app: 'boss',
|
||||
status: status,
|
||||
error: error
|
||||
});
|
||||
});
|
||||
|
||||
LOG_INFO('Starting server');
|
||||
app.listen(config.http.port, () => {
|
||||
LOG_SUCCESS(`Server started on port ${config.http.port}`);
|
||||
});
|
||||
|
|
@ -1,12 +1,10 @@
|
|||
const path = require('path');
|
||||
const fs = require('fs-extra');
|
||||
const express = require('express');
|
||||
const subdomain = require('express-subdomain');
|
||||
import path from 'node:path';
|
||||
import fs from 'fs-extra';
|
||||
import express from 'express';
|
||||
import subdomain from 'express-subdomain';
|
||||
|
||||
// Router to handle the subdomain restriction
|
||||
const npdi = express.Router();
|
||||
|
||||
// Setup routes
|
||||
npdi.get('/p01/data/1/:titleHash/:dataID/:fileHash', (request, response) => {
|
||||
const { titleHash, fileHash } = request.params;
|
||||
const contentPath = path.normalize(`${__dirname}/../../cdn/content/encrypted/${titleHash}/${fileHash}`);
|
||||
|
|
@ -22,10 +20,8 @@ npdi.get('/p01/data/1/:titleHash/:dataID/:fileHash', (request, response) => {
|
|||
}
|
||||
});
|
||||
|
||||
// Main router for endpoints
|
||||
const router = express.Router();
|
||||
|
||||
// Create subdomain
|
||||
router.use(subdomain('npdi.cdn', npdi));
|
||||
|
||||
module.exports = router;
|
||||
export default router;
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
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 npts = express.Router();
|
||||
|
||||
// Setup routes
|
||||
npts.get('/p01/policylist/1/1/:region', (request, response) => {
|
||||
//const { region } = request.params;
|
||||
const policylistPath = path.normalize(`${__dirname}/../../cdn/policylist/policylist.xml`);
|
||||
|
||||
if (fs.existsSync(policylistPath)) {
|
||||
response.set('Content-Type', 'application/xml; charset=utf-8');
|
||||
response.sendFile(policylistPath);
|
||||
} else {
|
||||
response.sendStatus(404);
|
||||
}
|
||||
});
|
||||
|
||||
// Main router for endpoints
|
||||
const router = express.Router();
|
||||
|
||||
// Create subdomain
|
||||
router.use(subdomain('nppl.app', npts));
|
||||
|
||||
module.exports = router;
|
||||
23
src/services/nppl.ts
Normal file
23
src/services/nppl.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import path from 'node:path';
|
||||
import fs from 'fs-extra';
|
||||
import express from 'express';
|
||||
import subdomain from 'express-subdomain';
|
||||
|
||||
const nppl = express.Router();
|
||||
|
||||
nppl.get('/p01/policylist/1/1/:region', (_request, response) => {
|
||||
const policylistPath = path.normalize(`${__dirname}/../../cdn/policylist/policylist.xml`);
|
||||
|
||||
if (fs.existsSync(policylistPath)) {
|
||||
response.set('Content-Type', 'application/xml; charset=utf-8');
|
||||
response.sendFile(policylistPath);
|
||||
} else {
|
||||
response.sendStatus(404);
|
||||
}
|
||||
});
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.use(subdomain('nppl.app', nppl));
|
||||
|
||||
export default router;
|
||||
|
|
@ -1,12 +1,10 @@
|
|||
const path = require('path');
|
||||
const fs = require('fs-extra');
|
||||
const express = require('express');
|
||||
const subdomain = require('express-subdomain');
|
||||
import path from 'node:path';
|
||||
import fs from 'fs-extra';
|
||||
import express from 'express';
|
||||
import subdomain from 'express-subdomain';
|
||||
|
||||
// Router to handle the subdomain restriction
|
||||
const npts = express.Router();
|
||||
|
||||
// Setup routes
|
||||
npts.get('/p01/tasksheet/:id/:hash/:fileName', (request, response) => {
|
||||
const { id, hash, fileName } = request.params;
|
||||
const tasksheetPath = path.normalize(`${__dirname}/../../cdn/tasksheet/${id}/${hash}/${fileName}`);
|
||||
|
|
@ -31,10 +29,8 @@ npts.get('/p01/tasksheet/:id/:hash/:subfolder/:fileName', (request, response) =>
|
|||
}
|
||||
});
|
||||
|
||||
// Main router for endpoints
|
||||
const router = express.Router();
|
||||
|
||||
// Create subdomain
|
||||
router.use(subdomain('npts.app', npts));
|
||||
|
||||
module.exports = router;
|
||||
export default router;
|
||||
14
src/types/common/config.ts
Normal file
14
src/types/common/config.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
export interface Config {
|
||||
http: {
|
||||
port: number;
|
||||
};
|
||||
crypto: {
|
||||
wup: {
|
||||
aes_key: Buffer;
|
||||
hmac_key: Buffer;
|
||||
};
|
||||
ctr: {
|
||||
aes_key: Buffer;
|
||||
};
|
||||
};
|
||||
}
|
||||
16
src/types/express-subdomain.d.ts
vendored
Normal file
16
src/types/express-subdomain.d.ts
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
// * Credit to https://github.com/bmullan91/express-subdomain/pull/61 for the types!
|
||||
|
||||
declare module 'express-subdomain'{
|
||||
import type { Request, Response, Router } from 'express';
|
||||
|
||||
/**
|
||||
* @description The subdomain function.
|
||||
* @param subdomain The subdomain to listen on.
|
||||
* @param fn The listener function, takes a response and request.
|
||||
* @returns A function call to the value passed as FN, or void (the next function).
|
||||
*/
|
||||
export default function subdomain(
|
||||
subdomain: string,
|
||||
fn: Router | ((req: Request, res: Response) => void | any)
|
||||
): (req: Request, res: Response, next: () => void) => void | typeof fn;
|
||||
}
|
||||
5
src/util.ts
Normal file
5
src/util.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import crypto from 'node:crypto';
|
||||
|
||||
export function md5(input: crypto.BinaryLike): Buffer {
|
||||
return crypto.createHash('md5').update(input).digest();
|
||||
}
|
||||
23
tsconfig.json
Normal file
23
tsconfig.json
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"sourceMap": true,
|
||||
"resolveJsonModule": true,
|
||||
"module": "commonjs",
|
||||
"esModuleInterop": true,
|
||||
"moduleResolution": "node",
|
||||
"baseUrl": "src",
|
||||
"outDir": "dist",
|
||||
"allowJs": true,
|
||||
"target": "es2022",
|
||||
"noEmitOnError": true,
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
},
|
||||
"typeRoots": [
|
||||
"node_modules/@types",
|
||||
"node_modules/@hcaptcha"
|
||||
]
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user