UNPKG

indexnow-submit

Version:

CLI tool to use IndexNow to notify search engines of website changes

137 lines 20.3 kB
#!/usr/bin/env node import { Command } from 'commander'; import { promises as fsp } from 'fs'; import { postURLlist, indexNowURL, fetchURLsFromSitemap, submitSingleURL, fetchURLsFromRSSAtom } from './index.js'; const program = new Command(); program .name('indexnow-submit') .description('CLI to help with IndexNOW') .version('0.1.0'); program.command('sitemap-fetch') .description('Fetch the URLs in a sitemap') .argument('<url>', 'Sitemap URL to fetch') .requiredOption('-o, --output <fileName>', 'File name for output') .option('-m, --max-age <maxAgeDuration>', 'ISO8601 Duration string describing oldest sitemap entry to fetch') .action(async (url, options, command) => { if (!url) throw new Error(`No URL given ${url}`); if (!options.output) throw new Error(`No output file given`); // console.log(`${command.name()} ${url} ${options.maxAge}`); const items = await fetchURLsFromSitemap(url, options.maxAge); // console.log(items); let txt = ''; for (const item of items) { txt += item.loc[0] + '\n'; } // console.log(`topost`, txt); await fsp.writeFile(options.output, txt, 'utf-8'); }); program.command('submit-single') .description('Submit a single URL to a search engine') .argument('<url>', 'The article URL to submit') .requiredOption('-e, --engine <searchEngine>', 'Search engine domain name') .option('-f, --key-file <fileName>', 'Name of file containing key') .option('-k, --key <key>', 'IndexNOW key') .action(async (url, options, command) => { console.log(`${command.name()} ${url}`, options); if (options.fileName && options.key) { throw new Error(`Only one of --key-file or --key can be specified`); } if (!options.keyFile && !options.key) { throw new Error(`Either --key-file or --key is required`); } // https://<searchengine>/indexnow?url=url-changed&key=your-key const key = await keyFromOptions(options); await submitSingleURL(options.engine, url, key); }); program.command('submit-urls') .description('Submit many URLs to a search engine') .argument('<urlFile>', 'File containing list of URLs, one per line') .requiredOption('-e, --engine <searchEngine>', 'Search engine domain name') .requiredOption('-h, --host <hostName>', 'Your website domain name') .option('-f, --key-file <fileName>', 'Name of file containing key') .option('-k, --key <key>', 'IndexNOW key') .action(async (urlFile, options, command) => { // POST /indexnow HTTP/1.1 // Content-Type: application/json; charset=utf-8 // Host: <searchengine> // { // "host": "www.example.com", // "key": "aaa6c957e47d498589ee7a33281997cb", // "keyLocation": "https://www.example.com/myIndexNowKey63638.txt", // "urlList": [ // "https://www.example.com/url1", // "https://www.example.com/folder/url2", // "https://www.example.com/url3" // ] // } // console.log(`${command.name()} ${urlFile}`, options); if (options.fileName && options.key) { throw new Error(`Only one of --key-file or --key can be specified`); } if (!options.keyFile && !options.key) { throw new Error(`Either --key-file or --key is required`); } const u = indexNowURL(options.engine); const key = await keyFromOptions(options); const urls = await fsp.readFile(urlFile, 'utf-8'); const urlList = urls.split('\n').filter(U => { // I observed a zero-length string at the end // of the array. This skips such strings. return U.length > 0; }); // console.log(`urlList`, urlList); // No need to post anything if (urlList.length <= 0) return; await postURLlist(options.engine, options.host, key, urlList); }); program.command('submit-from-feed') .description('Parse an RSS or ATOM feed, submitting some URLs to search engine') .argument('<feedURL>', 'The URL for an RSS or Atom feed') .requiredOption('-e, --engine <searchEngine>', 'Search engine domain name') .requiredOption('-h, --host <hostName>', 'Your website domain name') .option('-f, --key-file <fileName>', 'Name of file containing key') .option('-k, --key <key>', 'IndexNOW key') .option('-m, --max-age <maxAgeDuration>', 'ISO8601 Duration string describing oldest sitemap entry to fetch') .action(async (feedURL, options, command) => { // console.log(`${command.name()} ${feedURL}`, options); if (options.fileName && options.key) { throw new Error(`Only one of --key-file or --key can be specified`); } if (!options.keyFile && !options.key) { throw new Error(`Either --key-file or --key is required`); } const u = indexNowURL(options.engine); const key = await keyFromOptions(options); const urlList = await fetchURLsFromRSSAtom(feedURL, options.maxAge); // console.log(urlList); // No need to post anything if (urlList.length <= 0) { console.log('No URLs to post, nothing to do'); return; } else { console.log(`Submitting these URLs to ${options.engine}`, urlList); } await postURLlist(options.engine, options.host, key, urlList); }); // Generate key into directory program.parse(process.argv); async function keyFromOptions(options) { let key; if (options.keyFile) { key = await fsp.readFile(options.keyFile, 'utf-8'); } else if (options.key) { key = options.key; } else { throw new Error(`No key supplied`); } // Using genkey.sh there are newlines at the end // of the file. Newlines cause failure. return key.replace(/\n+$/, ''); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vbGliL2NsaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBRUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwQyxPQUFPLEVBQUUsUUFBUSxJQUFJLEdBQUcsRUFBRSxNQUFNLElBQUksQ0FBQztBQUVyQyxPQUFPLEVBQ0gsV0FBVyxFQUFFLFdBQVcsRUFBRSxvQkFBb0IsRUFBRSxlQUFlLEVBQy9ELG9CQUFvQixFQUN2QixNQUFNLFlBQVksQ0FBQztBQUVwQixNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0FBRzlCLE9BQU87S0FDSixJQUFJLENBQUMsaUJBQWlCLENBQUM7S0FDdkIsV0FBVyxDQUFDLDJCQUEyQixDQUFDO0tBQ3hDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUVwQixPQUFPLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQztLQUMzQixXQUFXLENBQUMsNkJBQTZCLENBQUM7S0FDMUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxzQkFBc0IsQ0FBQztLQUN6QyxjQUFjLENBQUMseUJBQXlCLEVBQUUsc0JBQXNCLENBQUM7S0FDakUsTUFBTSxDQUFDLGdDQUFnQyxFQUFFLGtFQUFrRSxDQUFDO0tBQzVHLE1BQU0sQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsRUFBRTtJQUVwQyxJQUFJLENBQUMsR0FBRztRQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0JBQWdCLEdBQUcsRUFBRSxDQUFDLENBQUM7SUFDakQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNO1FBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO0lBRTdELDZEQUE2RDtJQUU3RCxNQUFNLEtBQUssR0FBRyxNQUFNLG9CQUFvQixDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7SUFFOUQsc0JBQXNC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LGlCQUFpQixDQUFDLENBQUM7S0FDdEM7SUFFRCxnREFBZ0Q7SUFDaEQsd0NBQXdDO0lBQ3hDLE9BQU8sR0FBRyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDbkMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIiMhL3Vzci9iaW4vZW52IG5vZGVcblxuaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gJ2NvbW1hbmRlcic7XG5pbXBvcnQgeyBwcm9taXNlcyBhcyBmc3AgfSBmcm9tICdmcyc7XG5cbmltcG9ydCB7XG4gICAgcG9zdFVSTGxpc3QsIGluZGV4Tm93VVJMLCBmZXRjaFVSTHNGcm9tU2l0ZW1hcCwgc3VibWl0U2luZ2xlVVJMLFxuICAgIGZldGNoVVJMc0Zyb21SU1NBdG9tXG59IGZyb20gJy4vaW5kZXguanMnO1xuXG5jb25zdCBwcm9ncmFtID0gbmV3IENvbW1hbmQoKTtcblxuXG5wcm9ncmFtXG4gIC5uYW1lKCdpbmRleG5vdy1zdWJtaXQnKVxuICAuZGVzY3JpcHRpb24oJ0NMSSB0byBoZWxwIHdpdGggSW5kZXhOT1cnKVxuICAudmVyc2lvbignMC4xLjAnKTtcblxucHJvZ3JhbS5jb21tYW5kKCdzaXRlbWFwLWZldGNoJylcbiAgICAuZGVzY3JpcHRpb24oJ0ZldGNoIHRoZSBVUkxzIGluIGEgc2l0ZW1hcCcpXG4gICAgLmFyZ3VtZW50KCc8dXJsPicsICdTaXRlbWFwIFVSTCB0byBmZXRjaCcpXG4gICAgLnJlcXVpcmVkT3B0aW9uKCctbywgLS1vdXRwdXQgPGZpbGVOYW1lPicsICdGaWxlIG5hbWUgZm9yIG91dHB1dCcpXG4gICAgLm9wdGlvbignLW0sIC0tbWF4LWFnZSA8bWF4QWdlRHVyYXRpb24+JywgJ0lTTzg2MDEgRHVyYXRpb24gc3RyaW5nIGRlc2NyaWJpbmcgb2xkZXN0IHNpdGVtYXAgZW50cnkgdG8gZmV0Y2gnKVxuICAgIC5hY3Rpb24oYXN5bmMgKHVybCwgb3B0aW9ucywgY29tbWFuZCkgPT4ge1xuXG4gICAgICAgIGlmICghdXJsKSB0aHJvdyBuZXcgRXJyb3IoYE5vIFVSTCBnaXZlbiAke3VybH1gKTtcbiAgICAgICAgaWYgKCFvcHRpb25zLm91dHB1dCkgdGhyb3cgbmV3IEVycm9yKGBObyBvdXRwdXQgZmlsZSBnaXZlbmApO1xuXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKGAke2NvbW1hbmQubmFtZSgpfSAke3VybH0gJHtvcHRpb25zLm1heEFnZX1gKTtcblxuICAgICAgICBjb25zdCBpdGVtcyA9IGF3YWl0IGZldGNoVVJMc0Zyb21TaXRlbWFwKHVybCwgb3B0aW9ucy5tYXhBZ2UpO1xuXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKGl0ZW1zKTtcbiAgICAgICAgbGV0IHR4dCA9ICcnO1xuICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpIHtcbiAgICAgICAgICAgIHR4dCArPSBpdGVtLmxvY1swXSArICdcXG4nO1xuICAgICAgICB9XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKGB0b3Bvc3RgLCB0eHQpO1xuXG4gICAgICAgIGF3YWl0IGZzcC53cml0ZUZpbGUob3B0aW9ucy5vdXRwdXQsIHR4dCwgJ3V0Zi04Jyk7XG4gICAgfSk7XG5cbnByb2dyYW0uY29tbWFuZCgnc3VibWl0LXNpbmdsZScpXG4gICAgLmRlc2NyaXB0aW9uKCdTdWJtaXQgYSBzaW5nbGUgVVJMIHRvIGEgc2VhcmNoIGVuZ2luZScpXG4gICAgLmFyZ3VtZW50KCc8dXJsPicsICdUaGUgYXJ0aWNsZSBVUkwgdG8gc3VibWl0JylcbiAgICAucmVxdWlyZWRPcHRpb24oJy1lLCAtLWVuZ2luZSA8c2VhcmNoRW5naW5lPicsICdTZWFyY2ggZW5naW5lIGRvbWFpbiBuYW1lJylcbiAgICAub3B0aW9uKCctZiwgLS1rZXktZmlsZSA8ZmlsZU5hbWU+JywgJ05hbWUgb2YgZmlsZSBjb250YWluaW5nIGtleScpXG4gICAgLm9wdGlvbignLWssIC0ta2V5IDxrZXk+JywgJ0luZGV4Tk9XIGtleScpXG4gICAgLmFjdGlvbihhc3luYyAodXJsLCBvcHRpb25zLCBjb21tYW5kKSA9PiB7XG5cbiAgICAgICAgY29uc29sZS5sb2coYCR7Y29tbWFuZC5uYW1lKCl9ICR7dXJsfWAsIG9wdGlvbnMpO1xuXG4gICAgICAgIGlmIChvcHRpb25zLmZpbGVOYW1lICYmIG9wdGlvbnMua2V5KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE9ubHkgb25lIG9mIC0ta2V5LWZpbGUgb3IgLS1rZXkgY2FuIGJlIHNwZWNpZmllZGApO1xuICAgICAgICB9XG4gICAgICAgIGlmICghb3B0aW9ucy5rZXlGaWxlICYmICFvcHRpb25zLmtleSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFaXRoZXIgLS1rZXktZmlsZSBvciAtLWtleSBpcyByZXF1aXJlZGApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gaHR0cHM6Ly88c2VhcmNoZW5naW5lPi9pbmRleG5vdz91cmw9dXJsLWNoYW5nZWQma2V5PXlvdXIta2V5XG5cbiAgICAgICAgY29uc3Qga2V5ID0gYXdhaXQga2V5RnJvbU9wdGlvbnMob3B0aW9ucyk7XG5cbiAgICAgICAgYXdhaXQgc3VibWl0U2luZ2xlVVJMKG9wdGlvbnMuZW5naW5lLCB1cmwsIGtleSk7XG5cbiAgICB9KTtcblxucHJvZ3JhbS5jb21tYW5kKCdzdWJtaXQtdXJscycpXG4gICAgLmRlc2NyaXB0aW9uKCdTdWJtaXQgbWFueSBVUkxzIHRvIGEgc2VhcmNoIGVuZ2luZScpXG4gICAgLmFyZ3VtZW50KCc8dXJsRmlsZT4nLCAnRmlsZSBjb250YWluaW5nIGxpc3Qgb2YgVVJMcywgb25lIHBlciBsaW5lJylcbiAgICAucmVxdWlyZWRPcHRpb24oJy1lLCAtLWVuZ2luZSA8c2VhcmNoRW5naW5lPicsICdTZWFyY2ggZW5naW5lIGRvbWFpbiBuYW1lJylcbiAgICAucmVxdWlyZWRPcHRpb24oJy1oLCAtLWhvc3QgPGhvc3ROYW1lPicsICdZb3VyIHdlYnNpdGUgZG9tYWluIG5hbWUnKVxuICAgIC5vcHRpb24oJy1mLCAtLWtleS1maWxlIDxmaWxlTmFtZT4nLCAnTmFtZSBvZiBmaWxlIGNvbnRhaW5pbmcga2V5JylcbiAgICAub3B0aW9uKCctaywgLS1rZXkgPGtleT4nLCAnSW5kZXhOT1cga2V5JylcbiAgICAuYWN0aW9uKGFzeW5jICh1cmxGaWxlLCBvcHRpb25zLCBjb21tYW5kKSA9PiB7XG5cbiAgICAgICAgLy8gUE9TVCAvaW5kZXhub3cgSFRUUC8xLjFcbiAgICAgICAgLy8gQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PXV0Zi04XG4gICAgICAgIC8vIEhvc3Q6IDxzZWFyY2hlbmdpbmU+XG4gICAgICAgIC8vIHtcbiAgICAgICAgLy8gICAgIFwiaG9zdFwiOiBcInd3dy5leGFtcGxlLmNvbVwiLFxuICAgICAgICAvLyAgICAgXCJrZXlcIjogXCJhYWE2Yzk1N2U0N2Q0OTg1ODllZTdhMzMyODE5OTdjYlwiLFxuICAgICAgICAvLyAgICAgXCJrZXlMb2NhdGlvblwiOiBcImh0dHBzOi8vd3d3LmV4YW1wbGUuY29tL215SW5kZXhOb3dLZXk2MzYzOC50eHRcIixcbiAgICAgICAgLy8gICAgIFwidXJsTGlzdFwiOiBbXG4gICAgICAgIC8vICAgICAgICAgXCJodHRwczovL3d3dy5leGFtcGxlLmNvbS91cmwxXCIsXG4gICAgICAgIC8vICAgICAgICAgXCJodHRwczovL3d3dy5leGFtcGxlLmNvbS9mb2xkZXIvdXJsMlwiLFxuICAgICAgICAvLyAgICAgICAgIFwiaHR0cHM6Ly93d3cuZXhhbXBsZS5jb20vdXJsM1wiXG4gICAgICAgIC8vICAgICBdXG4gICAgICAgIC8vIH1cblxuICAgICAgICAvLyBjb25zb2xlLmxvZyhgJHtjb21tYW5kLm5hbWUoKX0gJHt1cmxGaWxlfWAsIG9wdGlvbnMpO1xuXG4gICAgICAgIGlmIChvcHRpb25zLmZpbGVOYW1lICYmIG9wdGlvbnMua2V5KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE9ubHkgb25lIG9mIC0ta2V5LWZpbGUgb3IgLS1rZXkgY2FuIGJlIHNwZWNpZmllZGApO1xuICAgICAgICB9XG4gICAgICAgIGlmICghb3B0aW9ucy5rZXlGaWxlICYmICFvcHRpb25zLmtleSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFaXRoZXIgLS1rZXktZmlsZSBvciAtLWtleSBpcyByZXF1aXJlZGApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdSA9IGluZGV4Tm93VVJMKG9wdGlvbnMuZW5naW5lKTtcblxuICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBrZXlGcm9tT3B0aW9ucyhvcHRpb25zKTtcblxuICAgICAgICBjb25zdCB1cmxzID0gYXdhaXQgZnNwLnJlYWRGaWxlKHVybEZpbGUsICd1dGYtOCcpO1xuICAgICAgICBjb25zdCB1cmxMaXN0ID0gdXJscy5zcGxpdCgnXFxuJykuZmlsdGVyKFUgPT4ge1xuICAgICAgICAgICAgLy8gSSBvYnNlcnZlZCBhIHplcm8tbGVuZ3RoIHN0cmluZyBhdCB0aGUgZW5kIFxuICAgICAgICAgICAgLy8gb2YgdGhlIGFycmF5LiAgVGhpcyBza2lwcyBzdWNoIHN0cmluZ3MuXG4gICAgICAgICAgICByZXR1cm4gVS5sZW5ndGggPiAwXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb25zb2xlLmxvZyhgdXJsTGlzdGAsIHVybExpc3QpO1xuXG4gICAgICAgIC8vIE5vIG5lZWQgdG8gcG9zdCBhbnl0aGluZ1xuICAgICAgICBpZiAodXJsTGlzdC5sZW5ndGggPD0gMCkgcmV0dXJuO1xuXG4gICAgICAgIGF3YWl0IHBvc3RVUkxsaXN0KG9wdGlvbnMuZW5naW5lLCBvcHRpb25zLmhvc3QsIGtleSwgdXJsTGlzdCk7XG4gICAgfSk7XG5cbnByb2dyYW0uY29tbWFuZCgnc3VibWl0LWZyb20tZmVlZCcpXG4gICAgLmRlc2NyaXB0aW9uKCdQYXJzZSBhbiBSU1Mgb3IgQVRPTSBmZWVkLCBzdWJtaXR0aW5nIHNvbWUgVVJMcyB0byBzZWFyY2ggZW5naW5lJylcbiAgICAuYXJndW1lbnQoJzxmZWVkVVJMPicsICdUaGUgVVJMIGZvciBhbiBSU1Mgb3IgQXRvbSBmZWVkJylcbiAgICAucmVxdWlyZWRPcHRpb24oJy1lLCAtLWVuZ2luZSA8c2VhcmNoRW5naW5lPicsICdTZWFyY2ggZW5naW5lIGRvbWFpbiBuYW1lJylcbiAgICAucmVxdWlyZWRPcHRpb24oJy1oLCAtLWhvc3QgPGhvc3ROYW1lPicsICdZb3VyIHdlYnNpdGUgZG9tYWluIG5hbWUnKVxuICAgIC5vcHRpb24oJy1mLCAtLWtleS1maWxlIDxmaWxlTmFtZT4nLCAnTmFtZSBvZiBmaWxlIGNvbnRhaW5pbmcga2V5JylcbiAgICAub3B0aW9uKCctaywgLS1rZXkgPGtleT4nLCAnSW5kZXhOT1cga2V5JylcbiAgICAub3B0aW9uKCctbSwgLS1tYXgtYWdlIDxtYXhBZ2VEdXJhdGlvbj4nLCAnSVNPODYwMSBEdXJhdGlvbiBzdHJpbmcgZGVzY3JpYmluZyBvbGRlc3Qgc2l0ZW1hcCBlbnRyeSB0byBmZXRjaCcpXG4gICAgLmFjdGlvbihhc3luYyAoZmVlZFVSTCwgb3B0aW9ucywgY29tbWFuZCkgPT4ge1xuXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKGAke2NvbW1hbmQubmFtZSgpfSAke2ZlZWRVUkx9YCwgb3B0aW9ucyk7XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuZmlsZU5hbWUgJiYgb3B0aW9ucy5rZXkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgT25seSBvbmUgb2YgLS1rZXktZmlsZSBvciAtLWtleSBjYW4gYmUgc3BlY2lmaWVkYCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFvcHRpb25zLmtleUZpbGUgJiYgIW9wdGlvbnMua2V5KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEVpdGhlciAtLWtleS1maWxlIG9yIC0ta2V5IGlzIHJlcXVpcmVkYCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB1ID0gaW5kZXhOb3dVUkwob3B0aW9ucy5lbmdpbmUpO1xuXG4gICAgICAgIGNvbnN0IGtleSA9IGF3YWl0IGtleUZyb21PcHRpb25zKG9wdGlvbnMpO1xuXG4gICAgICAgIGNvbnN0IHVybExpc3QgPSBhd2FpdCBmZXRjaFVSTHNGcm9tUlNTQXRvbShmZWVkVVJMLCBvcHRpb25zLm1heEFnZSk7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKHVybExpc3QpO1xuXG4gICAgICAgIC8vIE5vIG5lZWQgdG8gcG9zdCBhbnl0aGluZ1xuICAgICAgICBpZiAodXJsTGlzdC5sZW5ndGggPD0gMCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ05vIFVSTHMgdG8gcG9zdCwgbm90aGluZyB0byBkbycpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYFN1Ym1pdHRpbmcgdGhlc2UgVVJMcyB0byAke29wdGlvbnMuZW5naW5lfWAsIHVybExpc3QpO1xuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgcG9zdFVSTGxpc3Qob3B0aW9ucy5lbmdpbmUsIG9wdGlvbnMuaG9zdCwga2V5LCB1cmxMaXN0KTtcbiAgICB9KTtcblxuLy8gR2VuZXJhdGUga2V5IGludG8gZGlyZWN0b3J5XG5cbnByb2dyYW0ucGFyc2UocHJvY2Vzcy5hcmd2KTtcblxuXG5hc3luYyBmdW5jdGlvbiBrZXlGcm9tT3B0aW9ucyhvcHRpb25zKSB7XG5cbiAgICBsZXQga2V5O1xuICAgIGlmIChvcHRpb25zLmtleUZpbGUpIHtcbiAgICAgICAga2V5ID0gYXdhaXQgZnNwLnJlYWRGaWxlKG9wdGlvbnMua2V5RmlsZSwgJ3V0Zi04Jyk7XG4gICAgfSBlbHNlIGlmIChvcHRpb25zLmtleSkge1xuICAgICAgICBrZXkgPSBvcHRpb25zLmtleTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIGtleSBzdXBwbGllZGApO1xuICAgIH1cblxuICAgIC8vIFVzaW5nIGdlbmtleS5zaCB0aGVyZSBhcmUgbmV3bGluZXMgYXQgdGhlIGVuZFxuICAgIC8vIG9mIHRoZSBmaWxlLiAgTmV3bGluZXMgY2F1c2UgZmFpbHVyZS5cbiAgICByZXR1cm4ga2V5LnJlcGxhY2UoL1xcbiskLywgJycpO1xufVxuIl19