diff --git a/README.md b/README.md index 1e0e814..0bc793c 100644 --- a/README.md +++ b/README.md @@ -45,3 +45,26 @@ Configurations are loaded through environment variables. `.env` files are suppor ## S3 server The S3 server is optional, you can set `PN_BOSS_CONFIG_CDN_DISK_PATH` if you want to use a local folder as CDN source instead. + +# BOSS CLI + +The CLI is a helper to interact with the content of the BOSS server. + +```sh +npm run build +npm run cli -- --help +``` + +## CLI configuration + +Configurations are loaded through environment variables. `.env` files are supported. + +| Environment variable | Description | | +| --------------------------- | ------------------------------------------------------------------------------------------- | -------- | +| `PN_BOSS_CLI_GRPC_HOST` | The Host that the BOSS GRPC server is on. Example: `localhost:5678` | Required | +| `PN_BOSS_CLI_GRPC_APIKEY` | Master API key of the BOSS GRPC server. | Required | +| `PN_BOSS_CLI_WIIU_AES_KEY` | The BOSS WiiU AES key, needs to be dumped from a console | Optional | +| `PN_BOSS_CLI_WIIU_HMAC_KEY` | The BOSS WiiU HMAC key, needs to be dumped from a console | Optional | +| `PN_BOSS_CLI_NPDI_URL` | The URL of the NPDI part the BOSS HTTP server, only needed when downloading | Optional | +| `PN_BOSS_CLI_NPDI_HOST` | The Host header for the NPDI requests. Use when you don't have NPDI exposed to the internet | Optional | + \ No newline at end of file diff --git a/src/cli/files.cmd.ts b/src/cli/files.cmd.ts index a79c9fe..4c3131e 100644 --- a/src/cli/files.cmd.ts +++ b/src/cli/files.cmd.ts @@ -75,7 +75,12 @@ const downloadCmd = new Command('download') process.exit(1); } - const fetchResult = await fetch(`${ctx.npdiDomain}/p01/data/1/${file.bossAppId}/${file.dataId}/${file.hash}`); + const npdi = ctx.getNpdiUrl(); + const fetchResult = await fetch(`${npdi.url}/p01/data/1/${file.bossAppId}/${file.dataId}/${file.hash}`, { + headers: { + Host: npdi.host + } + }); if (fetchResult.status > 299) { console.error(`Failed to download: invalid status code (${fetchResult.status})`); process.exit(1); diff --git a/src/cli/utils.ts b/src/cli/utils.ts index 3da42a1..c82a3ee 100644 --- a/src/cli/utils.ts +++ b/src/cli/utils.ts @@ -4,30 +4,30 @@ import dotenv from 'dotenv'; import type { BOSSClient } from '@pretendonetwork/grpc/boss/boss_service'; export type WiiUKeys = { aesKey: string; hmacKey: string }; +export type NpdiUrl = { + host: string; + url: string; +}; export type CliContext = { grpc: BOSSClient; - npdiDomain: string; + getNpdiUrl: () => NpdiUrl; getWiiUKeys: () => WiiUKeys; }; export function getCliContext(): CliContext { dotenv.config(); - const grpcAddress = process.env.PN_BOSS_CONFIG_GRPC_BOSS_SERVER_ADDRESS ?? ''; - const grpcPort = process.env.PN_BOSS_CONFIG_GRPC_BOSS_SERVER_PORT ?? ''; - const grpcKey = process.env.PN_BOSS_CONFIG_GRPC_BOSS_SERVER_API_KEY ?? ''; + const grpcHost = process.env.PN_BOSS_CLI_GRPC_HOST ?? ''; + const grpcKey = process.env.PN_BOSS_CLI_GRPC_APIKEY ?? ''; - if (!grpcAddress) { - throw new Error('Missing env variable PN_BOSS_CONFIG_GRPC_BOSS_SERVER_ADDRESS'); - } - if (!grpcPort) { - throw new Error('Missing env variable PN_BOSS_CONFIG_GRPC_BOSS_SERVER_PORT'); + if (!grpcHost) { + throw new Error('Missing env variable PN_BOSS_CLI_GRPC_HOST'); } if (!grpcKey) { - throw new Error('Missing env variable PN_BOSS_CONFIG_GRPC_BOSS_SERVER_API_KEY'); + throw new Error('Missing env variable PN_BOSS_CLI_GRPC_APIKEY'); } - const channel = createChannel(grpcAddress + ':' + grpcPort); + const channel = createChannel(grpcHost); const client: BOSSClient = createClient(BOSSDefinition, channel, { '*': { metadata: new Metadata({ @@ -38,16 +38,24 @@ export function getCliContext(): CliContext { return { grpc: client, - npdiDomain: (process.env.PN_BOSS_CONFIG_DOMAINS_NPDI ?? 'npdi.cdn.pretendo.cc').split(',')[0], + getNpdiUrl(): NpdiUrl { + const npdiUrl = process.env.PN_BOSS_CLI_NPDI_URL ?? 'https://npdi.cdn.pretendo.cc'; + const npdiHost = process.env.PN_BOSS_CLI_NPDI_HOST ?? new URL(npdiUrl).host; + + return { + url: npdiUrl, + host: npdiHost + }; + }, getWiiUKeys(): WiiUKeys { - const aesKey = process.env.PN_BOSS_CONFIG_BOSS_WIIU_AES_KEY ?? ''; - const hmacKey = process.env.PN_BOSS_CONFIG_BOSS_WIIU_HMAC_KEY ?? ''; + const aesKey = process.env.PN_BOSS_CLI_WIIU_AES_KEY ?? ''; + const hmacKey = process.env.PN_BOSS_CLI_WIIU_HMAC_KEY ?? ''; if (!aesKey) { - throw new Error('Missing env variable PN_BOSS_CONFIG_BOSS_WIIU_AES_KEY - needed for decryption'); + throw new Error('Missing env variable PN_BOSS_CLI_WIIU_AES_KEY - needed for decryption'); } if (!hmacKey) { - throw new Error('Missing env variable PN_BOSS_CONFIG_BOSS_WIIU_HMAC_KEY - needed for decryption'); + throw new Error('Missing env variable PN_BOSS_CLI_WIIU_HMAC_KEY - needed for decryption'); } return { aesKey,