cdk-nag
Version:
Check CDK v2 applications for best practices using a combination on available rule packs.
115 lines • 13.7 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
/*
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
const path_1 = require("path");
const aws_cdk_lib_1 = require("aws-cdk-lib");
const aws_sns_1 = require("aws-cdk-lib/aws-sns");
const nag_rules_1 = require("../../nag-rules");
/**
* SNS topics require SSL requests for publishing
* @param node the CfnResource to check
*/
exports.default = Object.defineProperty((node) => {
if (node instanceof aws_sns_1.CfnTopic) {
const topicKey = aws_cdk_lib_1.Stack.of(node).resolve(node.kmsMasterKeyId);
if (topicKey === undefined) {
const topicLogicalId = nag_rules_1.NagRules.resolveResourceFromIntrinsic(node, node.ref);
const topicName = aws_cdk_lib_1.Stack.of(node).resolve(node.topicName);
let found = false;
for (const child of aws_cdk_lib_1.Stack.of(node).node.findAll()) {
if (child instanceof aws_sns_1.CfnTopicPolicy) {
if (isMatchingCompliantPolicy(child, topicLogicalId, topicName)) {
found = true;
break;
}
}
}
if (!found) {
return nag_rules_1.NagRuleCompliance.NON_COMPLIANT;
}
}
return nag_rules_1.NagRuleCompliance.COMPLIANT;
}
else {
return nag_rules_1.NagRuleCompliance.NOT_APPLICABLE;
}
}, 'name', { value: (0, path_1.parse)(__filename).name });
/**
* Helper function to check whether the topic Policy requires SSL on the given topic.
* @param node The CfnTopicPolicy to check.
* @param topicLogicalId The Cfn Logical ID of the topic.
* @param topicName The name of the topic.
* @returns Whether the CfnTopicPolicy requires SSL on the given topic.
*/
function isMatchingCompliantPolicy(node, topicLogicalId, topicName) {
let found = false;
for (const topic of node.topics) {
const resolvedTopic = nag_rules_1.NagRules.resolveResourceFromIntrinsic(node, topic);
if (resolvedTopic === topicLogicalId ||
(topicName !== undefined && resolvedTopic.endsWith(topicName))) {
found = true;
break;
}
}
if (!found) {
return false;
}
const resolvedPolicyDocument = aws_cdk_lib_1.Stack.of(node).resolve(node.policyDocument);
for (const statement of resolvedPolicyDocument.Statement) {
const resolvedStatement = aws_cdk_lib_1.Stack.of(node).resolve(statement);
const secureTransport = resolvedStatement?.Condition?.Bool?.['aws:SecureTransport'];
if (resolvedStatement.Effect === 'Deny' &&
checkMatchingAction(resolvedStatement.Action) === true &&
checkMatchingPrincipal(resolvedStatement.Principal) === true &&
(secureTransport === 'false' || secureTransport === false)) {
return true;
}
}
return false;
}
/**
* Helper function to check whether the topic Policy applies to topic actions
* @param node The CfnTopicPolicy to check
* @param actions The action in the topic policy
* @returns Whether the CfnTopicPolicy applies to topic actions
*/
function checkMatchingAction(actions) {
if (Array.isArray(actions)) {
for (const action of actions) {
if (action.toLowerCase() === 'sns:publish') {
return true;
}
}
}
else if (actions.toLowerCase() === 'sns:publish') {
return true;
}
return false;
}
/**
* Helper function to check whether the topic Policy applies to all principals
* @param node The CfnTopicPolicy to check
* @param principal The principals in the topic policy
* @returns Whether the CfnTopicPolicy applies to all principals
*/
function checkMatchingPrincipal(principals) {
if (principals === '*') {
return true;
}
const awsPrincipal = principals.AWS;
if (Array.isArray(awsPrincipal)) {
for (const account of awsPrincipal) {
if (account === '*') {
return true;
}
}
}
else if (awsPrincipal === '*') {
return true;
}
return false;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU05TVG9waWNTU0xQdWJsaXNoT25seS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9ydWxlcy9zbnMvU05TVG9waWNTU0xQdWJsaXNoT25seS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBOzs7RUFHRTtBQUNGLCtCQUE2QjtBQUM3Qiw2Q0FBaUQ7QUFDakQsaURBQStEO0FBQy9ELCtDQUE4RDtBQUU5RDs7O0dBR0c7QUFDSCxrQkFBZSxNQUFNLENBQUMsY0FBYyxDQUNsQyxDQUFDLElBQWlCLEVBQXFCLEVBQUU7SUFDdkMsSUFBSSxJQUFJLFlBQVksa0JBQVEsRUFBRSxDQUFDO1FBQzdCLE1BQU0sUUFBUSxHQUFHLG1CQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDN0QsSUFBSSxRQUFRLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDM0IsTUFBTSxjQUFjLEdBQUcsb0JBQVEsQ0FBQyw0QkFBNEIsQ0FDMUQsSUFBSSxFQUNKLElBQUksQ0FBQyxHQUFHLENBQ1QsQ0FBQztZQUNGLE1BQU0sU0FBUyxHQUFHLG1CQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDekQsSUFBSSxLQUFLLEdBQUcsS0FBSyxDQUFDO1lBQ2xCLEtBQUssTUFBTSxLQUFLLElBQUksbUJBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUM7Z0JBQ2xELElBQUksS0FBSyxZQUFZLHdCQUFjLEVBQUUsQ0FBQztvQkFDcEMsSUFBSSx5QkFBeUIsQ0FBQyxLQUFLLEVBQUUsY0FBYyxFQUFFLFNBQVMsQ0FBQyxFQUFFLENBQUM7d0JBQ2hFLEtBQUssR0FBRyxJQUFJLENBQUM7d0JBQ2IsTUFBTTtvQkFDUixDQUFDO2dCQUNILENBQUM7WUFDSCxDQUFDO1lBQ0QsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNYLE9BQU8sNkJBQWlCLENBQUMsYUFBYSxDQUFDO1lBQ3pDLENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyw2QkFBaUIsQ0FBQyxTQUFTLENBQUM7SUFDckMsQ0FBQztTQUFNLENBQUM7UUFDTixPQUFPLDZCQUFpQixDQUFDLGNBQWMsQ0FBQztJQUMxQyxDQUFDO0FBQ0gsQ0FBQyxFQUNELE1BQU0sRUFDTixFQUFFLEtBQUssRUFBRSxJQUFBLFlBQUssRUFBQyxVQUFVLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FDbEMsQ0FBQztBQUVGOzs7Ozs7R0FNRztBQUNILFNBQVMseUJBQXlCLENBQ2hDLElBQW9CLEVBQ3BCLGNBQXNCLEVBQ3RCLFNBQTZCO0lBRTdCLElBQUksS0FBSyxHQUFHLEtBQUssQ0FBQztJQUNsQixLQUFLLE1BQU0sS0FBSyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNoQyxNQUFNLGFBQWEsR0FBRyxvQkFBUSxDQUFDLDRCQUE0QixDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN6RSxJQUNFLGFBQWEsS0FBSyxjQUFjO1lBQ2hDLENBQUMsU0FBUyxLQUFLLFNBQVMsSUFBYSxhQUFjLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQ3hFLENBQUM7WUFDRCxLQUFLLEdBQUcsSUFBSSxDQUFDO1lBQ2IsTUFBTTtRQUNSLENBQUM7SUFDSCxDQUFDO0lBQ0QsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ1gsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBQ0QsTUFBTSxzQkFBc0IsR0FBRyxtQkFBSyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQzNFLEtBQUssTUFBTSxTQUFTLElBQUksc0JBQXNCLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDekQsTUFBTSxpQkFBaUIsR0FBRyxtQkFBSyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDNUQsTUFBTSxlQUFlLEdBQ25CLGlCQUFpQixFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQzlELElBQ0UsaUJBQWlCLENBQUMsTUFBTSxLQUFLLE1BQU07WUFDbkMsbUJBQW1CLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLEtBQUssSUFBSTtZQUN0RCxzQkFBc0IsQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsS0FBSyxJQUFJO1lBQzVELENBQUMsZUFBZSxLQUFLLE9BQU8sSUFBSSxlQUFlLEtBQUssS0FBSyxDQUFDLEVBQzFELENBQUM7WUFDRCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFTLG1CQUFtQixDQUFDLE9BQVk7SUFDdkMsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDM0IsS0FBSyxNQUFNLE1BQU0sSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUM3QixJQUFJLE1BQU0sQ0FBQyxXQUFXLEVBQUUsS0FBSyxhQUFhLEVBQUUsQ0FBQztnQkFDM0MsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7U0FBTSxJQUFJLE9BQU8sQ0FBQyxXQUFXLEVBQUUsS0FBSyxhQUFhLEVBQUUsQ0FBQztRQUNuRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQVMsc0JBQXNCLENBQUMsVUFBZTtJQUM3QyxJQUFJLFVBQVUsS0FBSyxHQUFHLEVBQUUsQ0FBQztRQUN2QixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFDRCxNQUFNLFlBQVksR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDO0lBQ3BDLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1FBQ2hDLEtBQUssTUFBTSxPQUFPLElBQUksWUFBWSxFQUFFLENBQUM7WUFDbkMsSUFBSSxPQUFPLEtBQUssR0FBRyxFQUFFLENBQUM7Z0JBQ3BCLE9BQU8sSUFBSSxDQUFDO1lBQ2QsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO1NBQU0sSUFBSSxZQUFZLEtBQUssR0FBRyxFQUFFLENBQUM7UUFDaEMsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCBBbWF6b24uY29tLCBJbmMuIG9yIGl0cyBhZmZpbGlhdGVzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiovXG5pbXBvcnQgeyBwYXJzZSB9IGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgQ2ZuUmVzb3VyY2UsIFN0YWNrIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgQ2ZuVG9waWMsIENmblRvcGljUG9saWN5IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLXNucyc7XG5pbXBvcnQgeyBOYWdSdWxlQ29tcGxpYW5jZSwgTmFnUnVsZXMgfSBmcm9tICcuLi8uLi9uYWctcnVsZXMnO1xuXG4vKipcbiAqIFNOUyB0b3BpY3MgcmVxdWlyZSBTU0wgcmVxdWVzdHMgZm9yIHB1Ymxpc2hpbmdcbiAqIEBwYXJhbSBub2RlIHRoZSBDZm5SZXNvdXJjZSB0byBjaGVja1xuICovXG5leHBvcnQgZGVmYXVsdCBPYmplY3QuZGVmaW5lUHJvcGVydHkoXG4gIChub2RlOiBDZm5SZXNvdXJjZSk6IE5hZ1J1bGVDb21wbGlhbmNlID0+IHtcbiAgICBpZiAobm9kZSBpbnN0YW5jZW9mIENmblRvcGljKSB7XG4gICAgICBjb25zdCB0b3BpY0tleSA9IFN0YWNrLm9mKG5vZGUpLnJlc29sdmUobm9kZS5rbXNNYXN0ZXJLZXlJZCk7XG4gICAgICBpZiAodG9waWNLZXkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCB0b3BpY0xvZ2ljYWxJZCA9IE5hZ1J1bGVzLnJlc29sdmVSZXNvdXJjZUZyb21JbnRyaW5zaWMoXG4gICAgICAgICAgbm9kZSxcbiAgICAgICAgICBub2RlLnJlZlxuICAgICAgICApO1xuICAgICAgICBjb25zdCB0b3BpY05hbWUgPSBTdGFjay5vZihub2RlKS5yZXNvbHZlKG5vZGUudG9waWNOYW1lKTtcbiAgICAgICAgbGV0IGZvdW5kID0gZmFsc2U7XG4gICAgICAgIGZvciAoY29uc3QgY2hpbGQgb2YgU3RhY2sub2Yobm9kZSkubm9kZS5maW5kQWxsKCkpIHtcbiAgICAgICAgICBpZiAoY2hpbGQgaW5zdGFuY2VvZiBDZm5Ub3BpY1BvbGljeSkge1xuICAgICAgICAgICAgaWYgKGlzTWF0Y2hpbmdDb21wbGlhbnRQb2xpY3koY2hpbGQsIHRvcGljTG9naWNhbElkLCB0b3BpY05hbWUpKSB7XG4gICAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICghZm91bmQpIHtcbiAgICAgICAgICByZXR1cm4gTmFnUnVsZUNvbXBsaWFuY2UuTk9OX0NPTVBMSUFOVDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIE5hZ1J1bGVDb21wbGlhbmNlLkNPTVBMSUFOVDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIE5hZ1J1bGVDb21wbGlhbmNlLk5PVF9BUFBMSUNBQkxFO1xuICAgIH1cbiAgfSxcbiAgJ25hbWUnLFxuICB7IHZhbHVlOiBwYXJzZShfX2ZpbGVuYW1lKS5uYW1lIH1cbik7XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIHRvIGNoZWNrIHdoZXRoZXIgdGhlIHRvcGljIFBvbGljeSByZXF1aXJlcyBTU0wgb24gdGhlIGdpdmVuIHRvcGljLlxuICogQHBhcmFtIG5vZGUgVGhlIENmblRvcGljUG9saWN5IHRvIGNoZWNrLlxuICogQHBhcmFtIHRvcGljTG9naWNhbElkIFRoZSBDZm4gTG9naWNhbCBJRCBvZiB0aGUgdG9waWMuXG4gKiBAcGFyYW0gdG9waWNOYW1lIFRoZSBuYW1lIG9mIHRoZSB0b3BpYy5cbiAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIENmblRvcGljUG9saWN5IHJlcXVpcmVzIFNTTCBvbiB0aGUgZ2l2ZW4gdG9waWMuXG4gKi9cbmZ1bmN0aW9uIGlzTWF0Y2hpbmdDb21wbGlhbnRQb2xpY3koXG4gIG5vZGU6IENmblRvcGljUG9saWN5LFxuICB0b3BpY0xvZ2ljYWxJZDogc3RyaW5nLFxuICB0b3BpY05hbWU6IHN0cmluZyB8IHVuZGVmaW5lZFxuKTogYm9vbGVhbiB7XG4gIGxldCBmb3VuZCA9IGZhbHNlO1xuICBmb3IgKGNvbnN0IHRvcGljIG9mIG5vZGUudG9waWNzKSB7XG4gICAgY29uc3QgcmVzb2x2ZWRUb3BpYyA9IE5hZ1J1bGVzLnJlc29sdmVSZXNvdXJjZUZyb21JbnRyaW5zaWMobm9kZSwgdG9waWMpO1xuICAgIGlmIChcbiAgICAgIHJlc29sdmVkVG9waWMgPT09IHRvcGljTG9naWNhbElkIHx8XG4gICAgICAodG9waWNOYW1lICE9PSB1bmRlZmluZWQgJiYgKDxzdHJpbmc+cmVzb2x2ZWRUb3BpYykuZW5kc1dpdGgodG9waWNOYW1lKSlcbiAgICApIHtcbiAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICBpZiAoIWZvdW5kKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGNvbnN0IHJlc29sdmVkUG9saWN5RG9jdW1lbnQgPSBTdGFjay5vZihub2RlKS5yZXNvbHZlKG5vZGUucG9saWN5RG9jdW1lbnQpO1xuICBmb3IgKGNvbnN0IHN0YXRlbWVudCBvZiByZXNvbHZlZFBvbGljeURvY3VtZW50LlN0YXRlbWVudCkge1xuICAgIGNvbnN0IHJlc29sdmVkU3RhdGVtZW50ID0gU3RhY2sub2Yobm9kZSkucmVzb2x2ZShzdGF0ZW1lbnQpO1xuICAgIGNvbnN0IHNlY3VyZVRyYW5zcG9ydCA9XG4gICAgICByZXNvbHZlZFN0YXRlbWVudD8uQ29uZGl0aW9uPy5Cb29sPy5bJ2F3czpTZWN1cmVUcmFuc3BvcnQnXTtcbiAgICBpZiAoXG4gICAgICByZXNvbHZlZFN0YXRlbWVudC5FZmZlY3QgPT09ICdEZW55JyAmJlxuICAgICAgY2hlY2tNYXRjaGluZ0FjdGlvbihyZXNvbHZlZFN0YXRlbWVudC5BY3Rpb24pID09PSB0cnVlICYmXG4gICAgICBjaGVja01hdGNoaW5nUHJpbmNpcGFsKHJlc29sdmVkU3RhdGVtZW50LlByaW5jaXBhbCkgPT09IHRydWUgJiZcbiAgICAgIChzZWN1cmVUcmFuc3BvcnQgPT09ICdmYWxzZScgfHwgc2VjdXJlVHJhbnNwb3J0ID09PSBmYWxzZSlcbiAgICApIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIHRvIGNoZWNrIHdoZXRoZXIgdGhlIHRvcGljIFBvbGljeSBhcHBsaWVzIHRvIHRvcGljIGFjdGlvbnNcbiAqIEBwYXJhbSBub2RlIFRoZSBDZm5Ub3BpY1BvbGljeSB0byBjaGVja1xuICogQHBhcmFtIGFjdGlvbnMgVGhlIGFjdGlvbiBpbiB0aGUgdG9waWMgcG9saWN5XG4gKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBDZm5Ub3BpY1BvbGljeSBhcHBsaWVzIHRvIHRvcGljIGFjdGlvbnNcbiAqL1xuZnVuY3Rpb24gY2hlY2tNYXRjaGluZ0FjdGlvbihhY3Rpb25zOiBhbnkpOiBib29sZWFuIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoYWN0aW9ucykpIHtcbiAgICBmb3IgKGNvbnN0IGFjdGlvbiBvZiBhY3Rpb25zKSB7XG4gICAgICBpZiAoYWN0aW9uLnRvTG93ZXJDYXNlKCkgPT09ICdzbnM6cHVibGlzaCcpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYgKGFjdGlvbnMudG9Mb3dlckNhc2UoKSA9PT0gJ3NuczpwdWJsaXNoJykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gY2hlY2sgd2hldGhlciB0aGUgdG9waWMgUG9saWN5IGFwcGxpZXMgdG8gYWxsIHByaW5jaXBhbHNcbiAqIEBwYXJhbSBub2RlIFRoZSBDZm5Ub3BpY1BvbGljeSB0byBjaGVja1xuICogQHBhcmFtIHByaW5jaXBhbCBUaGUgcHJpbmNpcGFscyBpbiB0aGUgdG9waWMgcG9saWN5XG4gKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBDZm5Ub3BpY1BvbGljeSBhcHBsaWVzIHRvIGFsbCBwcmluY2lwYWxzXG4gKi9cbmZ1bmN0aW9uIGNoZWNrTWF0Y2hpbmdQcmluY2lwYWwocHJpbmNpcGFsczogYW55KTogYm9vbGVhbiB7XG4gIGlmIChwcmluY2lwYWxzID09PSAnKicpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBjb25zdCBhd3NQcmluY2lwYWwgPSBwcmluY2lwYWxzLkFXUztcbiAgaWYgKEFycmF5LmlzQXJyYXkoYXdzUHJpbmNpcGFsKSkge1xuICAgIGZvciAoY29uc3QgYWNjb3VudCBvZiBhd3NQcmluY2lwYWwpIHtcbiAgICAgIGlmIChhY2NvdW50ID09PSAnKicpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYgKGF3c1ByaW5jaXBhbCA9PT0gJyonKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuIl19
;