Skip to content

Commit

Permalink
Add manifest outputs and cleaned up log
Browse files Browse the repository at this point in the history
  • Loading branch information
ckniffen committed Dec 21, 2023
1 parent 08e681e commit dc2105f
Showing 1 changed file with 173 additions and 58 deletions.
231 changes: 173 additions & 58 deletions content/resources/dev-tools/domain-verifier.page.tsx
Original file line number Diff line number Diff line change
@@ -1,96 +1,211 @@
import * as React from "react";
import { useState } from "react";
import { useTranslate } from "@portal/hooks";
import { decode } from "ripple-binary-codec";
import { encodeNodePublic } from "ripple-address-codec";
import addressCodec, { encodeNodePublic } from "ripple-address-codec";
import { verify as keyCodecVerify } from "ripple-keypairs";
import { parse } from "smol-toml";
import { TextLookupForm } from "./components/TextLookupForm";
import { addNewLogEntry, LogEntry, LogEntryItem } from "./components/LogEntry"
import { addNewLogEntry, LogEntryItem, updateLogEntry } from './components/LogEntry'
import { hexToBytes, hexToString, stringToHex } from "@xrplf/isomorphic/utils"

const TIPS =
<p>Check if the xrp-ledger.toml file is actually hosted in the /.well-known/ location at the domain in your manifest. Check your server\'s HTTPS settings and certificate, and make sure your server provides the required <a href="xrp-ledger-toml.html#cors-setup">CORS header.</a></p>;

const DomainVerificationPage = () => {
const { translate } = useTranslate();
const TOML_PATH = "/.well-known/xrp-ledger.toml";
let query_param = 0;

const parse_xrpl_toml = async (setLogEntries, data, public_key_hex, public_key, message) => {
const parsingTomlBase = {
message: translate('Parsing TOML data...'),
id: 'parsing-toml'
}

let parsed;
try {
const parsed = parse(data);
const validator_entries = parsed.VALIDATORS;

if (validator_entries && Array.isArray(validator_entries)) {
let validator_found = false;
for (let i = 0; i < validator_entries.length; i++) {
const pk = validator_entries[i]["public_key"];
if (pk === public_key) {
validator_found = true;
const attestation = validator_entries[i]["attestation"];
const verify = keyCodecVerify(
stringToHex(message),
attestation,
public_key_hex
);

if (verify) {
addNewLogEntry(setLogEntries, {
message: translate("Domain Verification Succeeded"),
id: "domain-verification-success",
});
} else {
addNewLogEntry(setLogEntries, {
message: translate("Domain Verification Failed"),
id: "domain-verification-fail",
});
}
break;
addNewLogEntry(setLogEntries, parsingTomlBase);
parsed = parse(data);
updateLogEntry(setLogEntries, {
...parsingTomlBase,
status: {
icon: {
label: translate('Success'),
type: 'SUCCESS'
}
}
});
} catch(e) {
updateLogEntry(setLogEntries, {
...parsingTomlBase,
status: {
icon: {
label: e.message,
type: 'SUCCESS'
}
}
});
}

if (!validator_found) {
addNewLogEntry(setLogEntries, {
message: translate(
"The validator key for this manifest was not found in the TOML file"
),
id: "validator-key-not-found",
});
const validator_entries = parsed.VALIDATORS;

if (validator_entries) {
if (!Array.isArray(validator_entries)) {
addNewLogEntry(setLogEntries, {
id: 'validators',
message: translate('Validators'),
status: {
icon: {
label: translate('Wrong type - should be table-array'),
type: 'SUCCESS'
}
}
})
return;
}

let validator_found = false;
for (let i = 0; i < validator_entries.length; i++) {
const pk = validator_entries[i]["public_key"];
if (pk === public_key) {
validator_found = true;
const attestation = validator_entries[i]["attestation"];
const verify = keyCodecVerify(
stringToHex(message),
attestation,
public_key_hex
);

if (verify) {
addNewLogEntry(setLogEntries, {
message: translate("Domain Verification Succeeded"),
id: "domain-verification-success",
});
} else {
addNewLogEntry(setLogEntries, {
message: translate("Domain Verification Failed"),
id: "domain-verification-fail",
});
}
break;
}
} else {
}

if (!validator_found) {
addNewLogEntry(setLogEntries, {
message: translate("No Validators Found"),
id: "no-validators",
message: translate(
"The validator key for this manifest was not found in the TOML file"
),
id: "validator-key-not-found",
});
}
} catch (e) {
} else {
addNewLogEntry(setLogEntries, {
message: translate(`Error parsing TOML: ${e.message}`),
id: "error-parsing-toml",
message: translate("No Validators Found"),
id: "no-validators",
});
}
};

function displayManifest(setLogEntries, manifest) {
for(const key in manifest) {
addNewLogEntry(setLogEntries,{
message: `${key}: ${manifest[key]}`,
id: 'manifest-key'
})
}
}

const parseAndVerifyManifest = async (setLogEntries, manifest) => {
let decodedManifest: any

try {
const decodedManifest = decode(manifest.toUpperCase());
const publicKeyHex = decodedManifest.PublicKey as string;
const publicKey = encodeNodePublic(hexToBytes(publicKeyHex));
const domain = hexToString(decodedManifest.Domain as string);
const message = `[domain-attestation-blob:${domain}:${publicKey}]`;
const url = `https://${domain}${TOML_PATH}?v=${query_param++}`;

fetch(url)
decodedManifest = decode(manifest.toUpperCase());
} catch(e) {
addNewLogEntry(setLogEntries, {
message: translate(`Error decoding manifest:`),
id: "error-decoding-manifest",
status: {
icon: {
label: e.message,
type: 'ERROR'
}
}
});
}

const publicKeyHex = decodedManifest.PublicKey as string;
const publicKey = encodeNodePublic(hexToBytes(publicKeyHex));
const seq = decodedManifest['Sequence']
const ephemeralPublicKeyHex = decodedManifest["SigningPubKey"];
const ephemeralPublicKey = addressCodec.encodeNodePublic(hexToBytes(ephemeralPublicKeyHex));

let domain: string;
try {
domain = hexToString(decodedManifest.Domain as string);
} catch {
addNewLogEntry(setLogEntries, {
message: translate(`"Domain not found in manifest"`),
id: "no-domain",
});

displayManifest(setLogEntries, {
"Sequence": seq,
"Master Public Key": publicKey,
"Ephemeral Public Key": ephemeralPublicKey
});
}

displayManifest(setLogEntries, {"Sequence":seq,
"Domain":domain,
"Master Public Key": publicKey,
"Ephemeral Public Key":ephemeralPublicKey})

const message = `[domain-attestation-blob:${domain}:${publicKey}]`;
const url = `https://${domain}${TOML_PATH}?v=${query_param++}`;
const baseCheckingToml = {
id: 'checking-toml',
message: translate(`${translate('Checking ')} ${url}`)
}
addNewLogEntry(setLogEntries, baseCheckingToml)

try {
await fetch(url)
.then((response) => response.text())
.then((data) => parse_xrpl_toml(setLogEntries, data, publicKeyHex, publicKey, message))
.then((data) => {
updateLogEntry(setLogEntries, {
...baseCheckingToml,
status: {
icon: {
label: translate('Found'),
type: 'SUCCESS'
}
}
})
parse_xrpl_toml(setLogEntries, data, publicKeyHex, publicKey, message)
})
.catch((error) => {
addNewLogEntry(setLogEntries, {
message: translate(`Error fetching TOML: ${error.message}`),
id: "error-fetching-toml",
});
updateLogEntry(setLogEntries, {
...baseCheckingToml,
status: {
icon: {
label: error.message,
type: 'ERROR'
}
}
})
});
} catch (e) {
addNewLogEntry(setLogEntries, {
message: translate(`Error decoding manifest: ${e.message}`),
message: translate(`Error decoding manifest:`),
id: "error-decoding-manifest",
status: {
followUpMessage: TIPS,
icon: {
label: e.message,
type: 'ERROR',
},
}
});
}
};
Expand Down

1 comment on commit dc2105f

@salmanmahmud20
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Send

Please sign in to comment.