Started Walet RPC auth work without adding MD5 Digest support
This commit is contained in:
@@ -11,8 +11,6 @@ const MAX_TRANSFERS = 4096;
|
||||
const configSchema = z.object({
|
||||
network: z.literal('mainnet'),
|
||||
url: z.string().min(1).max(2048),
|
||||
username: z.string().min(1).max(256),
|
||||
password: z.string().min(1).max(1024),
|
||||
}).strict();
|
||||
const rpcEnvelopeSchema = z.object({
|
||||
jsonrpc: z.literal('2.0'), id: z.string().uuid(), result: z.record(z.string(), z.unknown()).optional(),
|
||||
@@ -137,18 +135,18 @@ export async function loadMoneroObserverConfig(env: NodeJS.ProcessEnv = process.
|
||||
if (process.platform !== 'win32' && (info.mode & 0o077) !== 0) throw new Error();
|
||||
const parsed = configSchema.parse(JSON.parse(await readFile(path, 'utf8')));
|
||||
validateEndpoint(parsed.url);
|
||||
if (/[\r\n\x00]/.test(parsed.username) || /[\r\n\x00]/.test(parsed.password)) throw new Error();
|
||||
return parsed;
|
||||
} catch {
|
||||
throw new Error('Invalid or inaccessible Monero wallet-RPC config; credentials must be in a protected regular file');
|
||||
throw new Error('Invalid or inaccessible protected Monero wallet-RPC configuration');
|
||||
}
|
||||
}
|
||||
|
||||
/** Restricted read-only surface. No generic RPC method, subaddress creation, transfer or sweep API exists. */
|
||||
/** Restricted RPC surface. Authentication is delegated to an explicitly injected secure transport. */
|
||||
function createWalletRpc(config: z.infer<typeof configSchema>, transport: MoneroFixtureTransport,
|
||||
allowedMethods: readonly ('get_height' | 'get_address' | 'get_transfers' | 'validate_address' | 'create_address')[]) {
|
||||
const endpoint = validateEndpoint(config.url);
|
||||
const authorization = `Basic ${Buffer.from(`${config.username}:${config.password}`).toString('base64')}`;
|
||||
// Removed Basic auth header
|
||||
async function rpc(method: 'get_height' | 'get_address' | 'get_transfers' | 'validate_address' | 'create_address', params: Record<string, unknown> = {}) {
|
||||
if (!allowedMethods.includes(method)) throw new Error('Monero wallet-RPC method is not allowed for this client');
|
||||
const id = randomUUID(), controller = new AbortController();
|
||||
@@ -159,7 +157,7 @@ function createWalletRpc(config: z.infer<typeof configSchema>, transport: Monero
|
||||
let response: Response;
|
||||
try {
|
||||
response = await transport(endpoint.href, { method: 'POST', redirect: 'error', signal: controller.signal,
|
||||
headers: { authorization, accept: 'application/json', 'content-type': 'application/json' },
|
||||
headers: { accept: 'application/json', 'content-type': 'application/json' },
|
||||
body: JSON.stringify({ jsonrpc: '2.0', id, method, params }) });
|
||||
} catch { throw new Error('Monero wallet-RPC request failed'); }
|
||||
if (!response.ok || response.redirected || !response.body ||
|
||||
@@ -194,7 +192,7 @@ function createWalletRpc(config: z.infer<typeof configSchema>, transport: Monero
|
||||
}
|
||||
|
||||
/** Read-only observer capability. It deliberately cannot create addresses or move funds. */
|
||||
export function createMoneroWalletObserver(config: z.infer<typeof configSchema>, transport: MoneroFixtureTransport = fetch) {
|
||||
export function createMoneroWalletObserver(config: z.infer<typeof configSchema>, transport: MoneroFixtureTransport) {
|
||||
const rpc = createWalletRpc(config, transport, ['get_height', 'get_address', 'get_transfers']);
|
||||
return {
|
||||
async verifyMainnetWallet(): Promise<string> {
|
||||
@@ -254,11 +252,11 @@ export async function moneroWalletFingerprint(primaryAddress: string): Promise<s
|
||||
* from API and withdrawal capabilities. This
|
||||
* client is intentionally not attached to startup, routes, UI, or automatic crediting.
|
||||
*/
|
||||
export function createMoneroDepositAddressRpc(config: z.infer<typeof configSchema>, transport: MoneroFixtureTransport = fetch) {
|
||||
export function createMoneroDepositAddressRpc(config: z.infer<typeof configSchema>, transport: MoneroFixtureTransport) {
|
||||
const rpc = createWalletRpc(config, transport, ['get_address', 'validate_address', 'create_address']);
|
||||
return {
|
||||
async verifyWallet(): Promise<string> {
|
||||
const address = addressResultSchema.parse(await rpc('get_address', { account_index: 0 }));
|
||||
const address = addressResultSchema.parse(await rpc('get_address', { account_index: 0, address_index: [0] }));
|
||||
await validateXmrAddress(address.address);
|
||||
validateAddressResultSchema.parse(await rpc('validate_address', { address: address.address }));
|
||||
return moneroWalletFingerprint(address.address);
|
||||
|
||||
Reference in New Issue
Block a user