UNPKG

@lcap/nasl

Version:

NetEase Application Specific Language

127 lines 4.65 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isViewLogic = exports.cachePermission = void 0; const types_1 = require("../types"); const utils_1 = require("../utils"); const utils_2 = require("../../../utils"); const nasl_concepts_1 = require("@lcap/nasl-concepts"); const permission_1 = require("../../../generator/permission"); const storage_1 = require("../storage"); const lodash_1 = require("lodash"); const permissionKey = '__permission'; const { setter, getter } = (0, storage_1.getStorageController)(permissionKey); function cachePermission(data) { if (!utils_2.isBrowser) { return; } return setter(data); } exports.cachePermission = cachePermission; /** 获取所有调用逻辑和权限节点 */ function getCallLogicAndAuthNode(action) { function isGlobalCallLogic(data) { if (data && 'calleeName' in data && 'calleeNamespace' in data) { const name = data.calleeNamespace; return name?.startsWith('app') || name?.startsWith('extensions'); } return false; } function getAuthNode(node, path, context) { if (!node || !('concept' in node) || !(node.concept !== 'View' && node.concept !== 'BindDirective')) { return; } if (node.concept === 'View' && 'auth' in node && node.auth) { return path; } if (node.concept === 'BindDirective' && 'name' in node && node.name !== 'auth') { return context.parentPath; } } function getCallLogicAndAuthNode(object, path) { if (!object || typeof object !== 'object') { return { callLogicNodes: [], authNodes: [], }; } const callLogicNodes = []; const authNodes = []; const collect = (object, root) => { if (!object || !object.concept) { return; } (0, nasl_concepts_1.fastTraverseNaslObject)(object, root, (node, path, context) => { if (isGlobalCallLogic(node)) { callLogicNodes.push(path); } else { const authNode = getAuthNode(node, path, context); if (authNode) { authNodes.push(authNode); } } }); }; // 不是节点,但是可以做逻辑校验 if (!object.concept) { if (isGlobalCallLogic(object)) { callLogicNodes.push(path); } // 迭代子节点 for (const key of Object.keys(object)) { const item = object[key]; if (Array.isArray(item)) { item.forEach((v, i) => v && collect(v, `${path}.${key}[${v.name ? `name=${v.name}` : i}]`)); } else { collect(item, `${path}.${key}`); } } } else { collect(object, path); } return { callLogicNodes, authNodes, }; } const obj1 = getCallLogicAndAuthNode(action.object, action.path); const obj2 = getCallLogicAndAuthNode(action.oldObject, action.path); return { authNodes: obj1.authNodes.concat(obj2.authNodes), callLogicNodes: obj1.callLogicNodes.concat(obj2.callLogicNodes), }; } exports.isViewLogic = { name: 'is-view-logic', afterInstruct(action, { app: { preferenceMap } }) { // 排除非前端元素 if (!(0, utils_1.isFrontendPath)(action.path)) { return types_1.RuleResult.UnMatch; } // 调用逻辑和权限节点 const { callLogicNodes } = getCallLogicAndAuthNode(action); // 未修改全局调用,则为前端更改 if (callLogicNodes.length === 0) { return types_1.RuleResult.Frontend; } else { return preferenceMap.onDemandInterfaceGeneration === 'false' && preferenceMap.serverValidationRules === 'disabled' ? types_1.RuleResult.Frontend : types_1.RuleResult.Backend; } }, async beforeDeploy(context) { const oldPermission = await getter(); const newPermission = (0, permission_1.genPermissionData)(context.app); if ((0, lodash_1.isEqual)(oldPermission, newPermission)) { return types_1.RuleResult.Frontend; } else { await setter(newPermission); return types_1.RuleResult.Backend; } }, }; //# sourceMappingURL=is-view-logic.js.map