mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-20 07:26:19 +00:00
Add runtime toggle docs and secure mode switches
This commit is contained in:
+14
-4
@@ -1,4 +1,4 @@
|
||||
import { installSecureFetch, secureUrl } from './secure-assets';
|
||||
import { getClientMode, installSecureFetch, secureUrl } from './secure-assets';
|
||||
|
||||
installSecureFetch();
|
||||
|
||||
@@ -17,12 +17,22 @@ const setBootDebug = (message: string) =>
|
||||
setBootDebug('boot: secure fetch installed');
|
||||
|
||||
const search = new URLSearchParams(window.location.search);
|
||||
const clientMode = getClientMode();
|
||||
const cacheBustUrl = (path: string): string =>
|
||||
{
|
||||
const url = new URL(path.replace(/^\/+/, ''), `${ window.location.origin }/`);
|
||||
|
||||
(window as any).NitroSecureApiUrl = 'http://192.168.1.52:2096/';
|
||||
url.searchParams.set('v', Date.now().toString(36));
|
||||
|
||||
return url.toString();
|
||||
};
|
||||
|
||||
(window as any).NitroSecureApiUrl = clientMode.apiBaseUrl || 'http://192.168.1.52:2096/';
|
||||
(window as any).NitroClientMode = clientMode;
|
||||
(window as any).NitroConfig = {
|
||||
'config.urls': [
|
||||
secureUrl('config', 'renderer-config.json', true),
|
||||
secureUrl('config', 'ui-config.json', true)
|
||||
clientMode.secureAssetsEnabled ? secureUrl('config', 'renderer-config.json', true) : cacheBustUrl('renderer-config.json'),
|
||||
clientMode.secureAssetsEnabled ? secureUrl('config', 'ui-config.json', true) : cacheBustUrl('ui-config.json')
|
||||
],
|
||||
'sso.ticket': search.get('sso') || null,
|
||||
'forward.type': search.get('room') ? 2 : -1,
|
||||
|
||||
+78
-1
@@ -4,6 +4,21 @@ type SecureSession = {
|
||||
fingerprint: string;
|
||||
};
|
||||
|
||||
export type NitroClientMode = {
|
||||
distObfuscationEnabled: boolean;
|
||||
secureAssetsEnabled: boolean;
|
||||
secureApiEnabled: boolean;
|
||||
apiBaseUrl?: string;
|
||||
plainConfigBaseUrl?: string;
|
||||
plainGamedataBaseUrl?: string;
|
||||
};
|
||||
|
||||
const CLIENT_MODE_DEFAULTS: NitroClientMode = {
|
||||
distObfuscationEnabled: true,
|
||||
secureAssetsEnabled: true,
|
||||
secureApiEnabled: true
|
||||
};
|
||||
|
||||
const isDebugEnabled = (): boolean =>
|
||||
{
|
||||
try
|
||||
@@ -73,6 +88,29 @@ const REKEY_ENDPOINTS = new Set([
|
||||
'/api/auth/logout'
|
||||
]);
|
||||
|
||||
export const getClientMode = (): NitroClientMode =>
|
||||
{
|
||||
try
|
||||
{
|
||||
const configured = (window as any).__nitroClientMode;
|
||||
|
||||
if(configured && typeof configured === 'object')
|
||||
{
|
||||
return {
|
||||
distObfuscationEnabled: configured.distObfuscationEnabled !== false,
|
||||
secureAssetsEnabled: configured.secureAssetsEnabled !== false,
|
||||
secureApiEnabled: configured.secureApiEnabled !== false,
|
||||
apiBaseUrl: typeof configured.apiBaseUrl === 'string' ? configured.apiBaseUrl : '',
|
||||
plainConfigBaseUrl: typeof configured.plainConfigBaseUrl === 'string' ? configured.plainConfigBaseUrl : '',
|
||||
plainGamedataBaseUrl: typeof configured.plainGamedataBaseUrl === 'string' ? configured.plainGamedataBaseUrl : ''
|
||||
};
|
||||
}
|
||||
}
|
||||
catch {}
|
||||
|
||||
return { ...CLIENT_MODE_DEFAULTS };
|
||||
};
|
||||
|
||||
const bytesToBase64 = (bytes: ArrayBuffer): string =>
|
||||
{
|
||||
let binary = '';
|
||||
@@ -149,6 +187,9 @@ const deriveAesKey = async (privateKey: CryptoKey, serverKeyBase64: string): Pro
|
||||
|
||||
const getApiBase = (): string =>
|
||||
{
|
||||
const mode = getClientMode();
|
||||
if(typeof mode.apiBaseUrl === 'string' && mode.apiBaseUrl.length) return mode.apiBaseUrl.replace(/\/$/, '');
|
||||
|
||||
const configured = (window as any).NitroSecureApiUrl;
|
||||
|
||||
if(typeof configured === 'string' && configured.length) return configured.replace(/\/$/, '');
|
||||
@@ -156,8 +197,42 @@ const getApiBase = (): string =>
|
||||
return 'http://localhost:8443/';
|
||||
};
|
||||
|
||||
const getPlainAssetBase = (kind: 'config' | 'gamedata'): string =>
|
||||
{
|
||||
const mode = getClientMode();
|
||||
const configured = kind === 'config' ? mode.plainConfigBaseUrl : mode.plainGamedataBaseUrl;
|
||||
|
||||
if(typeof configured === 'string' && configured.length) return configured.endsWith('/') ? configured : `${ configured }/`;
|
||||
|
||||
if(kind === 'config') return `${ window.location.origin }/`;
|
||||
|
||||
return `${ window.location.origin }/nitro/gamedata/`;
|
||||
};
|
||||
|
||||
const mapSecureAssetRequestToPlainUrl = (requestUrl: string): string =>
|
||||
{
|
||||
const url = new URL(requestUrl, window.location.href);
|
||||
const kind = (url.searchParams.get('kind') || 'config') as 'config' | 'gamedata';
|
||||
const file = (url.searchParams.get('file') || '').replace(/^[\\/]+/, '');
|
||||
const plainUrl = new URL(file, getPlainAssetBase(kind));
|
||||
const cacheBust = url.searchParams.get('v');
|
||||
|
||||
if(cacheBust) plainUrl.searchParams.set('v', cacheBust);
|
||||
|
||||
return plainUrl.toString();
|
||||
};
|
||||
|
||||
export const secureUrl = (kind: 'config' | 'gamedata', file: string, cacheBust = false): string =>
|
||||
{
|
||||
if(!getClientMode().secureAssetsEnabled)
|
||||
{
|
||||
const plainUrl = new URL(file.replace(/^\/+/, ''), `${ window.location.origin }/`);
|
||||
|
||||
if(cacheBust) plainUrl.searchParams.set('v', Date.now().toString(36));
|
||||
|
||||
return plainUrl.toString();
|
||||
}
|
||||
|
||||
const base = getApiBase();
|
||||
const version = cacheBust ? `&v=${ encodeURIComponent(Date.now().toString(36)) }` : '';
|
||||
|
||||
@@ -364,6 +439,8 @@ export const installSecureFetch = (): void =>
|
||||
|
||||
if(requestUrl.includes('/nitro-sec/file'))
|
||||
{
|
||||
if(!getClientMode().secureAssetsEnabled) return nativeFetch(mapSecureAssetRequestToPlainUrl(requestUrl), init);
|
||||
|
||||
const method = init?.method || (input instanceof Request ? input.method : 'GET');
|
||||
const cacheKey = method.toUpperCase() === 'GET' ? normalizeSecureCacheKey(requestUrl) : null;
|
||||
|
||||
@@ -405,7 +482,7 @@ export const installSecureFetch = (): void =>
|
||||
return cloneCachedResponse(responsePromise);
|
||||
}
|
||||
|
||||
if(isApiUrl(requestUrl))
|
||||
if(getClientMode().secureApiEnabled && isApiUrl(requestUrl))
|
||||
{
|
||||
const method = (init?.method || (input instanceof Request ? input.method : 'GET')).toUpperCase();
|
||||
const session = await getSecureSession();
|
||||
|
||||
Reference in New Issue
Block a user