diff --git a/README.md b/README.md index 3841fda95..5f1e637a5 100644 --- a/README.md +++ b/README.md @@ -191,19 +191,19 @@ ps:核心功能已经实现,正在对接微信小程序中... | [Spring Boot](https://spring.io/projects/spring-boot) | 应用开发框架 | 2.7.7 | [文档](https://github.com/YunaiV/SpringBoot-Labs) | | [MySQL](https://www.mysql.com/cn/) | 数据库服务器 | 5.7 / 8.0+ | | | [Druid](https://github.com/alibaba/druid) | JDBC 连接池、监控组件 | 1.2.15 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) | -| [MyBatis Plus](https://mp.baomidou.com/) | MyBatis 增强工具包 | 3.5.3 | [文档](http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao) | +| [MyBatis Plus](https://mp.baomidou.com/) | MyBatis 增强工具包 | 3.5.3.1 | [文档](http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao) | | [Dynamic Datasource](https://dynamic-datasource.com/) | 动态数据源 | 3.6.1 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) | | [Redis](https://redis.io/) | key-value 数据库 | 5.0 / 6.0 | | | [Redisson](https://github.com/redisson/redisson) | Redis 客户端 | 3.18.0 | [文档](http://www.iocoder.cn/Spring-Boot/Redis/?yudao) | | [Spring MVC](https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc) | MVC 框架 | 5.3.24 | [文档](http://www.iocoder.cn/SpringMVC/MVC/?yudao) | -| [Spring Security](https://github.com/spring-projects/spring-security) | Spring 安全框架 | 5.7.5 | [文档](http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao) | +| [Spring Security](https://github.com/spring-projects/spring-security) | Spring 安全框架 | 5.7.6 | [文档](http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao) | | [Hibernate Validator](https://github.com/hibernate/hibernate-validator) | 参数校验组件 | 6.2.5 | [文档](http://www.iocoder.cn/Spring-Boot/Validation/?yudao) | | [Flowable](https://github.com/flowable/flowable-engine) | 工作流引擎 | 6.8.0 | [文档](https://doc.iocoder.cn/bpm/) | | [Quartz](https://github.com/quartz-scheduler) | 任务调度组件 | 2.3.2 | [文档](http://www.iocoder.cn/Spring-Boot/Job/?yudao) | | [Knife4j](https://gitee.com/xiaoym/knife4j) | Swagger 增强 UI 实现 | 3.0.3 | [文档](http://www.iocoder.cn/Spring-Boot/Swagger/?yudao) | | [Resilience4j](https://github.com/resilience4j/resilience4j) | 服务保障组件 | 1.7.1 | [文档](http://www.iocoder.cn/Spring-Boot/Resilience4j/?yudao) | | [SkyWalking](https://skywalking.apache.org/) | 分布式应用追踪系统 | 8.12.0 | [文档](http://www.iocoder.cn/Spring-Boot/SkyWalking/?yudao) | -| [Spring Boot Admin](https://github.com/codecentric/spring-boot-admin) | Spring Boot 监控平台 | 2.7.9 | [文档](http://www.iocoder.cn/Spring-Boot/Admin/?yudao) | +| [Spring Boot Admin](https://github.com/codecentric/spring-boot-admin) | Spring Boot 监控平台 | 2.7.10 | [文档](http://www.iocoder.cn/Spring-Boot/Admin/?yudao) | | [Jackson](https://github.com/FasterXML/jackson) | JSON 工具库 | 2.13.3 | | | [MapStruct](https://mapstruct.org/) | Java Bean 转换 | 1.5.3.Final | [文档](http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao) | | [Lombok](https://projectlombok.org/) | 消除冗长的 Java 代码 | 1.18.24 | [文档](http://www.iocoder.cn/Spring-Boot/Lombok/?yudao) | @@ -227,7 +227,7 @@ ps:核心功能已经实现,正在对接微信小程序中... | [TypeScript](https://www.typescriptlang.org/docs/) | TypeScript | 4.9.4 | | [pinia](https://pinia.vuejs.org/) | vuex5 | 2.0.28 | | [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.2.2 | -| [vxe-table](https://vxetable.cn/) | vue最强表单 | 4.3.7 | +| [vxe-table](https://vxetable.cn/) | vue最强表单 | 4.3.9 | ### [管理后台 uni-app 跨端](./yudao-ui-admin-uniapp) diff --git a/sql/optional/visualization/jimureport.mysql5.7.create.sql b/sql/optional/visualization/jimureport.mysql5.7.create.sql index e32134005..c90ea27d8 100644 --- a/sql/optional/visualization/jimureport.mysql5.7.create.sql +++ b/sql/optional/visualization/jimureport.mysql5.7.create.sql @@ -1344,6 +1344,7 @@ CREATE TABLE `jimu_report_share` ( `last_update_time` datetime NULL DEFAULT NULL COMMENT '最后更新时间', `term_of_validity` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '有效期(0:永久有效,1:1天,2:7天)', `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否过期(0未过期,1已过期)', + `preview_lock_status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '密码锁状态', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '积木报表预览权限表' ROW_FORMAT = Dynamic; diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml index 7b056c46b..065b34b33 100644 --- a/yudao-dependencies/pom.xml +++ b/yudao-dependencies/pom.xml @@ -32,7 +32,7 @@ 1.7.1 8.12.0 - 2.7.9 + 2.7.10 0.33.0 7.2.11.RELEASE @@ -41,10 +41,11 @@ 6.8.0 + 1.15.3 1.18.24 1.5.3.Final 5.8.11 - 3.1.4 + 3.1.5 2.3 1.0.5 1.2.83 @@ -63,7 +64,7 @@ 8.4.6 4.6.3 2.2.1 - 3.1.660 + 3.1.667 1.4.0 1.5.6 2.12.2 @@ -522,6 +523,12 @@ ${ip2region.version} + + org.jsoup + jsoup + ${jsoup.version} + + com.squareup.okio diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java index e220d011d..e0b5e4bb5 100644 --- a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java +++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.framework.mybatis.core.mapper; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -10,6 +9,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.support.SFunction; +import com.baomidou.mybatisplus.extension.toolkit.Db; import org.apache.ibatis.annotations.Param; import java.util.Collection; @@ -92,8 +92,22 @@ public interface BaseMapperX extends BaseMapper { entities.forEach(this::insert); } + /** + * 批量插入,适合大量数据插入 + * + * @param entities 实体们 + * @param size 插入数量 Db.saveBatch 默认为1000 + */ + default void insertBatch(Collection entities, int size) { + Db.saveBatch(entities, size); + } + default void updateBatch(T update) { update(update, new QueryWrapper<>()); } + default void updateBatch(Collection entities, int size) { + Db.updateBatchById(entities, size); + } + } diff --git a/yudao-framework/yudao-spring-boot-starter-web/pom.xml b/yudao-framework/yudao-spring-boot-starter-web/pom.xml index 8662584e3..7d277790c 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/pom.xml +++ b/yudao-framework/yudao-spring-boot-starter-web/pom.xml @@ -67,6 +67,11 @@ provided + + + org.jsoup + jsoup + diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java index d2bffb166..95955d5ee 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java @@ -2,15 +2,22 @@ package cn.iocoder.yudao.framework.web.config; import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkService; import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum; +import cn.iocoder.yudao.framework.web.core.clean.JsoupXssCleaner; +import cn.iocoder.yudao.framework.web.core.clean.XssCleaner; import cn.iocoder.yudao.framework.web.core.filter.CacheRequestBodyFilter; import cn.iocoder.yudao.framework.web.core.filter.DemoFilter; import cn.iocoder.yudao.framework.web.core.filter.XssFilter; import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler; import cn.iocoder.yudao.framework.web.core.handler.GlobalResponseBodyHandler; +import cn.iocoder.yudao.framework.web.core.json.XssStringJsonDeserializer; import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; +import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; @@ -48,7 +55,7 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer { * 设置 API 前缀,仅仅匹配 controller 包下的 * * @param configurer 配置 - * @param api API 配置 + * @param api API 配置 */ private void configurePathMatch(PathMatchConfigurer configurer, WebProperties.Api api) { AntPathMatcher antPathMatcher = new AntPathMatcher("."); @@ -104,8 +111,9 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer { * 创建 XssFilter Bean,解决 Xss 安全问题 */ @Bean - public FilterRegistrationBean xssFilter(XssProperties properties, PathMatcher pathMatcher) { - return createFilterBean(new XssFilter(properties, pathMatcher), WebFilterOrderEnum.XSS_FILTER); + @ConditionalOnBean(XssCleaner.class) + public FilterRegistrationBean xssFilter(XssProperties properties, PathMatcher pathMatcher, XssCleaner xssCleaner) { + return createFilterBean(new XssFilter(properties, pathMatcher, xssCleaner), WebFilterOrderEnum.XSS_FILTER); } /** @@ -117,6 +125,32 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer { return createFilterBean(new DemoFilter(), WebFilterOrderEnum.DEMO_FILTER); } + + /** + * Xss 清理者 + * + * @return XssCleaner + */ + @Bean + @ConditionalOnMissingBean(XssCleaner.class) + public XssCleaner xssCleaner() { + return new JsoupXssCleaner(); + } + + /** + * 注册 Jackson 的序列化器,用于处理 json 类型参数的 xss 过滤 + * + * @return Jackson2ObjectMapperBuilderCustomizer + */ + @Bean + @ConditionalOnMissingBean(name = "xssJacksonCustomizer") + @ConditionalOnBean(ObjectMapper.class) + @ConditionalOnProperty(value = "yudao.xss.enable", havingValue = "true") + public Jackson2ObjectMapperBuilderCustomizer xssJacksonCustomizer(XssCleaner xssCleaner) { + // 在反序列化时进行 xss 过滤,可以替换使用 XssStringJsonSerializer,在序列化时进行处理 + return builder -> builder.deserializerByType(String.class, new XssStringJsonDeserializer(xssCleaner)); + } + private static FilterRegistrationBean createFilterBean(T filter, Integer order) { FilterRegistrationBean bean = new FilterRegistrationBean<>(filter); bean.setOrder(order); diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/clean/JsoupXssCleaner.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/clean/JsoupXssCleaner.java new file mode 100644 index 000000000..559267c3f --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/clean/JsoupXssCleaner.java @@ -0,0 +1,80 @@ +package cn.iocoder.yudao.framework.web.core.clean; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.safety.Safelist; + +/** + * jsonp 过滤字符串 + */ +public class JsoupXssCleaner implements XssCleaner { + + private final Safelist safelist; + + /** + * 用于在 src 属性使用相对路径时,强制转换为绝对路径。 为空时不处理,值应为绝对路径的前缀(包含协议部分) + */ + private final String baseUri; + + /** + * 无参构造,默认使用 {@link JsoupXssCleaner#buildSafelist} 方法构建一个安全列表 + */ + public JsoupXssCleaner() { + this.safelist = buildSafelist(); + this.baseUri = ""; + } + + public JsoupXssCleaner(Safelist safelist) { + this.safelist = safelist; + this.baseUri = ""; + } + + public JsoupXssCleaner(String baseUri) { + this.safelist = buildSafelist(); + this.baseUri = baseUri; + } + + public JsoupXssCleaner(Safelist safelist, String baseUri) { + this.safelist = safelist; + this.baseUri = baseUri; + } + + /** + * 构建一个 Xss 清理的 Safelist 规则。 + * 基于 Safelist#relaxed() 的基础上: + * 1. 扩展支持了 style 和 class 属性 + * 2. a 标签额外支持了 target 属性 + * 3. img 标签额外支持了 data 协议,便于支持 base64 + * + * @return Safelist + */ + private Safelist buildSafelist() { + // 使用 jsoup 提供的默认的 + Safelist relaxedSafelist = Safelist.relaxed(); + // 富文本编辑时一些样式是使用 style 来进行实现的 + // 比如红色字体 style="color:red;", 所以需要给所有标签添加 style 属性 + // 注意:style 属性会有注入风险 + relaxedSafelist.addAttributes(":all", "style", "class"); + // 保留 a 标签的 target 属性 + relaxedSafelist.addAttributes("a", "target"); + // 支持img 为base64 + relaxedSafelist.addProtocols("img", "src", "data"); + + // 保留相对路径, 保留相对路径时,必须提供对应的 baseUri 属性,否则依然会被删除 + // WHITELIST.preserveRelativeLinks(false); + + // 移除 a 标签和 img 标签的一些协议限制,这会导致 xss 防注入失效,如 + // 虽然可以重写 WhiteList#isSafeAttribute 来处理,但是有隐患,所以暂时不支持相对路径 + // WHITELIST.removeProtocols("a", "href", "ftp", "http", "https", "mailto"); + // WHITELIST.removeProtocols("img", "src", "http", "https"); + + return relaxedSafelist; + } + + @Override + public String clean(String html) { + return Jsoup.clean(html, baseUri, safelist, new Document.OutputSettings().prettyPrint(false)); + } + +} + diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/clean/XssCleaner.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/clean/XssCleaner.java new file mode 100644 index 000000000..433f7e775 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/clean/XssCleaner.java @@ -0,0 +1,15 @@ +package cn.iocoder.yudao.framework.web.core.clean; + +/** + * 对 html 文本中的有 Xss 风险的数据进行清理 + */ +public interface XssCleaner { + + /** + * 清理有 Xss 风险的文本 + * + * @param html 原 html + * @return 清理后的 html + */ + String clean(String html); +} diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/filter/XssFilter.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/filter/XssFilter.java index 050a86cc1..2da18768d 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/filter/XssFilter.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/filter/XssFilter.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.framework.web.core.filter; import cn.iocoder.yudao.framework.web.config.XssProperties; +import cn.iocoder.yudao.framework.web.core.clean.XssCleaner; import lombok.AllArgsConstructor; import org.springframework.util.PathMatcher; import org.springframework.web.filter.OncePerRequestFilter; @@ -13,7 +14,7 @@ import java.io.IOException; /** * Xss 过滤器 - * + *

* 对 Xss 不了解的胖友,可以看看 http://www.iocoder.cn/Fight/The-new-girl-asked-me-why-AJAX-requests-are-not-secure-I-did-not-answer/ * * @author 芋道源码 @@ -30,10 +31,12 @@ public class XssFilter extends OncePerRequestFilter { */ private final PathMatcher pathMatcher; + private final XssCleaner xssCleaner; + @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException { - filterChain.doFilter(new XssRequestWrapper(request), response); + filterChain.doFilter(new XssRequestWrapper(request, xssCleaner), response); } @Override diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/filter/XssRequestWrapper.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/filter/XssRequestWrapper.java index 25bd20978..7beed46cc 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/filter/XssRequestWrapper.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/filter/XssRequestWrapper.java @@ -1,21 +1,10 @@ package cn.iocoder.yudao.framework.web.core.filter; -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.io.IoUtil; -import cn.hutool.core.util.ArrayUtil; -import cn.hutool.core.util.ReflectUtil; -import cn.hutool.core.util.StrUtil; -import cn.hutool.http.HTMLFilter; -import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; +import cn.iocoder.yudao.framework.web.core.clean.XssCleaner; -import javax.servlet.ReadListener; -import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStreamReader; +import java.util.LinkedHashMap; import java.util.Map; /** @@ -24,113 +13,79 @@ import java.util.Map; * @author 芋道源码 */ public class XssRequestWrapper extends HttpServletRequestWrapper { + private final XssCleaner xssCleaner; - /** - * 基于线程级别的 HTMLFilter 对象,因为它线程非安全 - */ - private static final ThreadLocal HTML_FILTER = ThreadLocal.withInitial(() -> { - HTMLFilter htmlFilter = new HTMLFilter(); - // 反射修改 encodeQuotes 属性为 false,避免 " 被转移成 " 字符 - ReflectUtil.setFieldValue(htmlFilter, "encodeQuotes", false); - return htmlFilter; - }); - - public XssRequestWrapper(HttpServletRequest request) { + public XssRequestWrapper(HttpServletRequest request, XssCleaner xssCleaner) { super(request); + this.xssCleaner = xssCleaner; } - private static String filterXss(String content) { - if (StrUtil.isEmpty(content)) { - return content; + // ============================ parameter ============================ + @Override + public Map getParameterMap() { + Map map = new LinkedHashMap<>(); + Map parameters = super.getParameterMap(); + for (Map.Entry entry : parameters.entrySet()) { + String[] values = entry.getValue(); + for (int i = 0; i < values.length; i++) { + values[i] = xssCleaner.clean(values[i]); + } + map.put(entry.getKey(), values); } - return HTML_FILTER.get().filter(content); - } - - // ========== IO 流相关 ========== - - @Override - public BufferedReader getReader() throws IOException { - return new BufferedReader(new InputStreamReader(this.getInputStream())); - } - - @Override - public ServletInputStream getInputStream() throws IOException { - // 如果非 json 请求,不进行 Xss 处理 - if (!ServletUtils.isJsonRequest(this)) { - return super.getInputStream(); - } - - // 读取内容,并过滤 - String content = IoUtil.readUtf8(super.getInputStream()); - content = filterXss(content); - final ByteArrayInputStream newInputStream = new ByteArrayInputStream(content.getBytes()); - // 返回 ServletInputStream - return new ServletInputStream() { - - @Override - public int read() { - return newInputStream.read(); - } - - @Override - public boolean isFinished() { - return true; - } - - @Override - public boolean isReady() { - return true; - } - - @Override - public void setReadListener(ReadListener readListener) {} - - }; - } - - // ========== Param 相关 ========== - - @Override - public String getParameter(String name) { - String value = super.getParameter(name); - return filterXss(value); + return map; } @Override public String[] getParameterValues(String name) { String[] values = super.getParameterValues(name); - if (ArrayUtil.isEmpty(values)) { - return values; + if (values == null) { + return null; } - // 过滤处理 - for (int i = 0; i < values.length; i++) { - values[i] = filterXss(values[i]); + int count = values.length; + String[] encodedValues = new String[count]; + for (int i = 0; i < count; i++) { + encodedValues[i] = xssCleaner.clean(values[i]); } - return values; + return encodedValues; } @Override - public Map getParameterMap() { - Map valueMap = super.getParameterMap(); - if (CollUtil.isEmpty(valueMap)) { - return valueMap; + public String getParameter(String name) { + String value = super.getParameter(name); + if (value == null) { + return null; } - // 过滤处理 - for (Map.Entry entry : valueMap.entrySet()) { - String[] values = entry.getValue(); - for (int i = 0; i < values.length; i++) { - values[i] = filterXss(values[i]); - } - } - return valueMap; + return xssCleaner.clean(value); } - // ========== Header 相关 ========== + // ============================ attribute ============================ + @Override + public Object getAttribute(String name) { + Object value = super.getAttribute(name); + if (value instanceof String) { + xssCleaner.clean((String) value); + } + return value; + } + // ============================ header ============================ @Override public String getHeader(String name) { String value = super.getHeader(name); - return filterXss(value); + if (value == null) { + return null; + } + return xssCleaner.clean(value); + } + + // ============================ queryString ============================ + @Override + public String getQueryString() { + String value = super.getQueryString(); + if (value == null) { + return null; + } + return xssCleaner.clean(value); } } diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/json/XssStringJsonDeserializer.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/json/XssStringJsonDeserializer.java new file mode 100644 index 000000000..7e1f631c7 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/json/XssStringJsonDeserializer.java @@ -0,0 +1,59 @@ +package cn.iocoder.yudao.framework.web.core.json; + +import cn.iocoder.yudao.framework.web.core.clean.XssCleaner; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StringDeserializer; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import java.io.IOException; + +/** + * XSS 过滤 jackson 反序列化器。 + * 在反序列化的过程中,会对字符串进行 XSS 过滤。 + * + * @author Hccake + */ +@Slf4j +@AllArgsConstructor +public class XssStringJsonDeserializer extends StringDeserializer { + + private final XssCleaner xssCleaner; + + @Override + public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + if (p.hasToken(JsonToken.VALUE_STRING)) { + return xssCleaner.clean(p.getText()); + } + JsonToken t = p.currentToken(); + // [databind#381] + if (t == JsonToken.START_ARRAY) { + return _deserializeFromArray(p, ctxt); + } + // need to gracefully handle byte[] data, as base64 + if (t == JsonToken.VALUE_EMBEDDED_OBJECT) { + Object ob = p.getEmbeddedObject(); + if (ob == null) { + return null; + } + if (ob instanceof byte[]) { + return ctxt.getBase64Variant().encode((byte[]) ob, false); + } + // otherwise, try conversion using toString()... + return ob.toString(); + } + // 29-Jun-2020, tatu: New! "Scalar from Object" (mostly for XML) + if (t == JsonToken.START_OBJECT) { + return ctxt.extractScalarFromObject(p, this, _valueClass); + } + + if (t.isScalarValue()) { + String text = p.getValueAsString(); + return xssCleaner.clean(text); + } + return (String) ctxt.handleUnexpectedToken(_valueClass, p); + } +} + diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/convert/codegen/CodegenConvert.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/convert/codegen/CodegenConvert.java index b0df3e34f..6c78ac7cd 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/convert/codegen/CodegenConvert.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/convert/codegen/CodegenConvert.java @@ -11,9 +11,11 @@ import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO; import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO; import com.baomidou.mybatisplus.generator.config.po.TableField; import com.baomidou.mybatisplus.generator.config.po.TableInfo; +import com.baomidou.mybatisplus.generator.config.rules.IColumnType; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Mappings; +import org.mapstruct.Named; import org.mapstruct.factory.Mappers; import java.util.List; @@ -37,7 +39,7 @@ public interface CodegenConvert { @Mappings({ @Mapping(source = "name", target = "columnName"), - @Mapping(source = "type", target = "dataType"), + @Mapping(source = "columnType", target = "dataType", qualifiedByName = "getType"), @Mapping(source = "comment", target = "columnComment"), @Mapping(source = "metaInfo.nullable", target = "nullable"), @Mapping(source = "keyFlag", target = "primaryKey"), @@ -47,6 +49,11 @@ public interface CodegenConvert { }) CodegenColumnDO convert(TableField bean); + @Named("getType") + default String getType(IColumnType jdbcType) { + return jdbcType.getType(); + } + // ========== CodegenTableDO 相关 ========== // List convertList02(List list); diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/codegen/CodegenColumnDO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/codegen/CodegenColumnDO.java index 4e7f330e5..470b9969c 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/codegen/CodegenColumnDO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/codegen/CodegenColumnDO.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.infra.enums.codegen.CodegenColumnListConditionEnu import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.generator.config.po.TableField; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; @@ -42,6 +43,7 @@ public class CodegenColumnDO extends BaseDO { private String columnName; /** * 字段类型 + * 关联 {@link TableField#getColumnType()}} */ private String dataType; /** diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/DefaultDatabaseQueryTest.java b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/DefaultDatabaseQueryTest.java index 41b1dae33..a6de8d9ee 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/DefaultDatabaseQueryTest.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/DefaultDatabaseQueryTest.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.infra.service; import cn.hutool.core.util.StrUtil; -import com.baomidou.mybatisplus.generator.IDatabaseQuery.DefaultDatabaseQuery; +import com.baomidou.mybatisplus.generator.query.DefaultQuery; import com.baomidou.mybatisplus.generator.config.DataSourceConfig; import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder; import com.baomidou.mybatisplus.generator.config.po.TableInfo; @@ -19,7 +19,7 @@ public class DefaultDatabaseQueryTest { ConfigBuilder builder = new ConfigBuilder(null, dataSourceConfig, null, null, null, null); - DefaultDatabaseQuery query = new DefaultDatabaseQuery(builder); + DefaultQuery query = new DefaultQuery(builder); long time = System.currentTimeMillis(); List tableInfos = query.queryTables(); diff --git a/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/jmreport/config/JmReportConfiguration.java b/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/jmreport/config/JmReportConfiguration.java index 59510b5ff..c679d1112 100644 --- a/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/jmreport/config/JmReportConfiguration.java +++ b/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/jmreport/config/JmReportConfiguration.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.visualization.framework.jmreport.config; +import cn.iocoder.yudao.framework.security.config.SecurityProperties; import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi; import cn.iocoder.yudao.module.visualization.framework.jmreport.core.service.JmReportTokenServiceImpl; import org.jeecg.modules.jmreport.api.JmReportTokenServiceI; @@ -18,8 +19,8 @@ public class JmReportConfiguration { @Bean @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") - public JmReportTokenServiceI jmReportTokenService(OAuth2TokenApi oAuth2TokenApi) { - return new JmReportTokenServiceImpl(oAuth2TokenApi); + public JmReportTokenServiceI jmReportTokenService(OAuth2TokenApi oAuth2TokenApi, SecurityProperties securityProperties) { + return new JmReportTokenServiceImpl(oAuth2TokenApi, securityProperties); } } diff --git a/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/jmreport/core/service/JmReportTokenServiceImpl.java b/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/jmreport/core/service/JmReportTokenServiceImpl.java index 511465786..22c4a19c8 100644 --- a/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/jmreport/core/service/JmReportTokenServiceImpl.java +++ b/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/jmreport/core/service/JmReportTokenServiceImpl.java @@ -1,7 +1,10 @@ package cn.iocoder.yudao.module.visualization.framework.jmreport.core.service; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; +import cn.iocoder.yudao.framework.security.config.SecurityProperties; import cn.iocoder.yudao.framework.security.core.LoginUser; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; @@ -10,6 +13,10 @@ import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi; import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenCheckRespDTO; import lombok.RequiredArgsConstructor; import org.jeecg.modules.jmreport.api.JmReportTokenServiceI; +import org.springframework.http.HttpHeaders; + +import javax.servlet.http.HttpServletRequest; +import java.util.Objects; /** * {@link JmReportTokenServiceI} 实现类,提供积木报表的 Token 校验、用户信息的查询等功能 @@ -19,8 +26,37 @@ import org.jeecg.modules.jmreport.api.JmReportTokenServiceI; @RequiredArgsConstructor public class JmReportTokenServiceImpl implements JmReportTokenServiceI { + /** + * 积木 token head 头 + */ + private static final String JM_TOKEN_HEADER = "X-Access-Token"; + /** + * auth 相关格式 + */ + private static final String AUTHORIZATION_FORMAT = SecurityFrameworkUtils.AUTHORIZATION_BEARER + " %s"; + private final OAuth2TokenApi oauth2TokenApi; + private final SecurityProperties securityProperties; + + /** + * 自定义 API 数据集appian自定义 Header,解决 Token 传递。 + * 参考 api数据集token机制详解 文档 + * + * @return 新 head + */ + @Override + public HttpHeaders customApiHeader() { + // 读取积木标标系统的 token + HttpServletRequest request = ServletUtils.getRequest(); + String token = request.getHeader(JM_TOKEN_HEADER); + + // 设置到 yudao 系统的 token + HttpHeaders headers = new HttpHeaders(); + headers.add(securityProperties.getTokenHeader(), String.format(AUTHORIZATION_FORMAT, token)); + return headers; + } + /** * 校验 Token 是否有效,即验证通过 * @@ -29,8 +65,40 @@ public class JmReportTokenServiceImpl implements JmReportTokenServiceI { */ @Override public Boolean verifyToken(String token) { + Long userId = SecurityFrameworkUtils.getLoginUserId(); + if (!Objects.isNull(userId)) { + return true; + } + return buildLoginUserByToken(token) != null; + } + + /** + * 获得用户编号 + *

+ * 虽然方法名获得的是 username,实际对应到项目中是用户编号 + * + * @param token JmReport 前端传递的 token + * @return 用户编号 + */ + @Override + public String getUsername(String token) { + Long userId = SecurityFrameworkUtils.getLoginUserId(); + if (ObjectUtil.isNotNull(userId)) { + return String.valueOf(userId); + } + LoginUser user = buildLoginUserByToken(token); + return user == null ? null : String.valueOf(user.getId()); + } + + /** + * 基于 token 构建登录用户 + * + * @param token token + * @return 返回 token 对应的用户信息 + */ + private LoginUser buildLoginUserByToken(String token) { if (StrUtil.isEmpty(token)) { - return false; + return null; } // TODO 如下的实现不算特别优雅,主要咱是不想搞的太复杂,所以参考对应的 Filter 先实现了 @@ -41,7 +109,7 @@ public class JmReportTokenServiceImpl implements JmReportTokenServiceI { try { OAuth2AccessTokenCheckRespDTO accessToken = oauth2TokenApi.checkAccessToken(token); if (accessToken == null) { - return false; + return null; } user = new LoginUser().setId(accessToken.getUserId()).setUserType(accessToken.getUserType()) .setTenantId(accessToken.getTenantId()).setScopes(accessToken.getScopes()); @@ -49,7 +117,7 @@ public class JmReportTokenServiceImpl implements JmReportTokenServiceI { // do nothing:如果报错,说明认证失败,则返回 false 即可 } if (user == null) { - return false; + return null; } SecurityFrameworkUtils.setLoginUser(user, WebFrameworkUtils.getRequest()); @@ -57,21 +125,7 @@ public class JmReportTokenServiceImpl implements JmReportTokenServiceI { // 目的:基于 LoginUser 获得到的租户编号,设置到 Tenant 上下文,避免查询数据库时的报错 TenantContextHolder.setIgnore(false); TenantContextHolder.setTenantId(user.getTenantId()); - return true; - } - - /** - * 获得用户编号 - * - * 虽然方法名获得的是 username,实际对应到项目中是用户编号 - * - * @param token JmReport 前端传递的 token - * @return 用户编号 - */ - @Override - public String getUsername(String token) { - Long userId = SecurityFrameworkUtils.getLoginUserId(); - return userId != null ? String.valueOf(userId) : null; + return user; } } diff --git a/yudao-ui-admin-vue3/README.md b/yudao-ui-admin-vue3/README.md index 73561ec9b..79a9505ac 100644 --- a/yudao-ui-admin-vue3/README.md +++ b/yudao-ui-admin-vue3/README.md @@ -34,7 +34,7 @@ | [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 的超集 | 4.9.4 | | [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.0.28 | | [vueuse](https://vueuse.org/) | 常用工具集 | 9.10.0 | -| [vxe-table](https://vxetable.cn/) | vue 最强表单 | 4.3.7 | +| [vxe-table](https://vxetable.cn/) | vue 最强表单 | 4.3.9 | | [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.2.2 | | [vue-router](https://router.vuejs.org/) | vue 路由 | 4.1.6 | | [windicss](https://cn.windicss.org/) | 下一代工具优先的 CSS 框架 | 3.5.6 | diff --git a/yudao-ui-admin-vue3/package.json b/yudao-ui-admin-vue3/package.json index ac2e72ded..20f02859f 100644 --- a/yudao-ui-admin-vue3/package.json +++ b/yudao-ui-admin-vue3/package.json @@ -1,6 +1,6 @@ { "name": "yudao-ui-admin-vue3", - "version": "1.6.6-snapshot.1901", + "version": "1.6.6-snapshot.1911", "description": "基于vue3、vite4、element-plus、typesScript", "author": "xingyu", "private": false, @@ -50,14 +50,14 @@ "vue-i18n": "9.2.2", "vue-router": "^4.1.6", "vue-types": "^5.0.2", - "vxe-table": "^4.3.7", + "vxe-table": "^4.3.9", "web-storage-cache": "^1.1.1", "xe-utils": "^3.5.7" }, "devDependencies": { - "@commitlint/cli": "^17.4.0", + "@commitlint/cli": "^17.4.1", "@commitlint/config-conventional": "^17.4.0", - "@iconify/json": "^2.2.2", + "@iconify/json": "^2.2.5", "@intlify/unplugin-vue-i18n": "^0.8.1", "@purge-icons/generated": "^0.9.0", "@types/intro.js": "^5.1.0", @@ -66,8 +66,8 @@ "@types/nprogress": "^0.2.0", "@types/qrcode": "^1.5.0", "@types/qs": "^6.9.7", - "@typescript-eslint/eslint-plugin": "^5.48.0", - "@typescript-eslint/parser": "^5.48.0", + "@typescript-eslint/eslint-plugin": "^5.48.1", + "@typescript-eslint/parser": "^5.48.1", "@vitejs/plugin-legacy": "^3.0.1", "@vitejs/plugin-vue": "^4.0.0", "@vitejs/plugin-vue-jsx": "^3.0.0", @@ -75,14 +75,14 @@ "consola": "^2.15.3", "eslint": "^8.31.0", "eslint-config-prettier": "^8.6.0", - "eslint-define-config": "^1.13.0", + "eslint-define-config": "^1.14.0", "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-vue": "^9.8.0", "lint-staged": "^13.1.0", - "postcss": "^8.4.20", + "postcss": "^8.4.21", "postcss-html": "^1.5.0", "postcss-scss": "^4.0.6", - "prettier": "^2.8.1", + "prettier": "^2.8.2", "rimraf": "^3.0.2", "rollup": "^3.9.1", "sass": "^1.57.1", @@ -91,7 +91,7 @@ "stylelint-config-prettier": "^9.0.4", "stylelint-config-recommended": "^9.0.0", "stylelint-config-standard": "^29.0.0", - "stylelint-order": "^5.0.0", + "stylelint-order": "^6.0.1", "terser": "^5.16.1", "typescript": "4.9.4", "vite": "4.0.4", @@ -104,7 +104,7 @@ "vite-plugin-svg-icons": "^2.0.1", "vite-plugin-vue-setup-extend": "^0.4.0", "vite-plugin-windicss": "^1.8.10", - "vue-tsc": "^1.0.22", + "vue-tsc": "^1.0.24", "windicss": "^3.5.6" }, "engines": { diff --git a/yudao-ui-admin-vue3/pnpm-lock.yaml b/yudao-ui-admin-vue3/pnpm-lock.yaml index cb31c2c89..af51c2bc8 100644 --- a/yudao-ui-admin-vue3/pnpm-lock.yaml +++ b/yudao-ui-admin-vue3/pnpm-lock.yaml @@ -1,10 +1,10 @@ lockfileVersion: 5.4 specifiers: - '@commitlint/cli': ^17.4.0 + '@commitlint/cli': ^17.4.1 '@commitlint/config-conventional': ^17.4.0 '@iconify/iconify': ^3.0.1 - '@iconify/json': ^2.2.2 + '@iconify/json': ^2.2.5 '@intlify/unplugin-vue-i18n': ^0.8.1 '@purge-icons/generated': ^0.9.0 '@types/intro.js': ^5.1.0 @@ -13,8 +13,8 @@ specifiers: '@types/nprogress': ^0.2.0 '@types/qrcode': ^1.5.0 '@types/qs': ^6.9.7 - '@typescript-eslint/eslint-plugin': ^5.48.0 - '@typescript-eslint/parser': ^5.48.0 + '@typescript-eslint/eslint-plugin': ^5.48.1 + '@typescript-eslint/parser': ^5.48.1 '@vitejs/plugin-legacy': ^3.0.1 '@vitejs/plugin-vue': ^4.0.0 '@vitejs/plugin-vue-jsx': ^3.0.0 @@ -34,7 +34,7 @@ specifiers: element-plus: 2.2.28 eslint: ^8.31.0 eslint-config-prettier: ^8.6.0 - eslint-define-config: ^1.13.0 + eslint-define-config: ^1.14.0 eslint-plugin-prettier: ^4.2.1 eslint-plugin-vue: ^9.8.0 intro.js: ^6.0.0 @@ -44,10 +44,10 @@ specifiers: mitt: ^3.0.0 nprogress: ^0.2.0 pinia: ^2.0.28 - postcss: ^8.4.20 + postcss: ^8.4.21 postcss-html: ^1.5.0 postcss-scss: ^4.0.6 - prettier: ^2.8.1 + prettier: ^2.8.2 qrcode: ^1.5.1 qs: ^6.11.0 rimraf: ^3.0.2 @@ -58,7 +58,7 @@ specifiers: stylelint-config-prettier: ^9.0.4 stylelint-config-recommended: ^9.0.0 stylelint-config-standard: ^29.0.0 - stylelint-order: ^5.0.0 + stylelint-order: ^6.0.1 terser: ^5.16.1 typescript: 4.9.4 url: ^0.11.0 @@ -75,9 +75,9 @@ specifiers: vue: 3.2.45 vue-i18n: 9.2.2 vue-router: ^4.1.6 - vue-tsc: ^1.0.22 + vue-tsc: ^1.0.24 vue-types: ^5.0.2 - vxe-table: ^4.3.7 + vxe-table: ^4.3.9 web-storage-cache: ^1.1.1 windicss: ^3.5.6 xe-utils: ^3.5.7 @@ -109,14 +109,14 @@ dependencies: vue-i18n: 9.2.2_vue@3.2.45 vue-router: 4.1.6_vue@3.2.45 vue-types: 5.0.2_vue@3.2.45 - vxe-table: 4.3.7_vue@3.2.45+xe-utils@3.5.7 + vxe-table: 4.3.9_vue@3.2.45+xe-utils@3.5.7 web-storage-cache: 1.1.1 xe-utils: 3.5.7 devDependencies: - '@commitlint/cli': 17.4.0_@types+node@18.11.18 + '@commitlint/cli': 17.4.1 '@commitlint/config-conventional': 17.4.0 - '@iconify/json': 2.2.2 + '@iconify/json': 2.2.5 '@intlify/unplugin-vue-i18n': 0.8.1_vue-i18n@9.2.2 '@purge-icons/generated': 0.9.0 '@types/intro.js': 5.1.0 @@ -125,23 +125,23 @@ devDependencies: '@types/nprogress': 0.2.0 '@types/qrcode': 1.5.0 '@types/qs': 6.9.7 - '@typescript-eslint/eslint-plugin': 5.48.0_k73wpmdolxikpyqun3p36akaaq - '@typescript-eslint/parser': 5.48.0_iukboom6ndih5an6iafl45j2fe + '@typescript-eslint/eslint-plugin': 5.48.1_3jon24igvnqaqexgwtxk6nkpse + '@typescript-eslint/parser': 5.48.1_iukboom6ndih5an6iafl45j2fe '@vitejs/plugin-legacy': 3.0.1_terser@5.16.1+vite@4.0.4 '@vitejs/plugin-vue': 4.0.0_vite@4.0.4+vue@3.2.45 '@vitejs/plugin-vue-jsx': 3.0.0_vite@4.0.4+vue@3.2.45 - autoprefixer: 10.4.13_postcss@8.4.20 + autoprefixer: 10.4.13_postcss@8.4.21 consola: 2.15.3 eslint: 8.31.0 eslint-config-prettier: 8.6.0_eslint@8.31.0 - eslint-define-config: 1.13.0 - eslint-plugin-prettier: 4.2.1_32m5uc2milwdw3tnkcq5del26y + eslint-define-config: 1.14.0 + eslint-plugin-prettier: 4.2.1_iu5s7nk6dw7o3tajefwfiqfmge eslint-plugin-vue: 9.8.0_eslint@8.31.0 lint-staged: 13.1.0 - postcss: 8.4.20 + postcss: 8.4.21 postcss-html: 1.5.0 - postcss-scss: 4.0.6_postcss@8.4.20 - prettier: 2.8.1 + postcss-scss: 4.0.6_postcss@8.4.21 + prettier: 2.8.2 rimraf: 3.0.2 rollup: 3.9.1 sass: 1.57.1 @@ -150,7 +150,7 @@ devDependencies: stylelint-config-prettier: 9.0.4_stylelint@14.16.1 stylelint-config-recommended: 9.0.0_stylelint@14.16.1 stylelint-config-standard: 29.0.0_stylelint@14.16.1 - stylelint-order: 5.0.0_stylelint@14.16.1 + stylelint-order: 6.0.1_stylelint@14.16.1 terser: 5.16.1 typescript: 4.9.4 vite: 4.0.4_zxbrnrc4iyldik6mikh3pswz4i @@ -163,7 +163,7 @@ devDependencies: vite-plugin-svg-icons: 2.0.1_vite@4.0.4 vite-plugin-vue-setup-extend: 0.4.0_vite@4.0.4 vite-plugin-windicss: 1.8.10_vite@4.0.4 - vue-tsc: 1.0.22_typescript@4.9.4 + vue-tsc: 1.0.24_typescript@4.9.4 windicss: 3.5.6 packages: @@ -506,14 +506,14 @@ packages: '@babel/helper-validator-identifier': 7.19.1 to-fast-properties: 2.0.0 - /@commitlint/cli/17.4.0_@types+node@18.11.18: - resolution: {integrity: sha512-SEY4sYe8yVlgxPP7X0wJb96DBAGBPsCsy6QbqJt/UECbIAjDeDV5xXBV4jnS7T/qMC10sk6Ub9kDhEX0VWvblw==} + /@commitlint/cli/17.4.1: + resolution: {integrity: sha512-W8OJwz+izY+fVwyUt1HveCDmABMZNRVZHSVPw/Bh9Y62tp11SmmQaycgbsYLMiMy7JGn4mAJqEGlSHS9Uti9ZQ==} engines: {node: '>=v14'} hasBin: true dependencies: '@commitlint/format': 17.4.0 '@commitlint/lint': 17.4.0 - '@commitlint/load': 17.4.0_@types+node@18.11.18 + '@commitlint/load': 17.4.1 '@commitlint/read': 17.4.0 '@commitlint/types': 17.4.0 execa: 5.1.1 @@ -524,7 +524,6 @@ packages: transitivePeerDependencies: - '@swc/core' - '@swc/wasm' - - '@types/node' dev: true /@commitlint/config-conventional/17.4.0: @@ -585,14 +584,15 @@ packages: '@commitlint/types': 17.4.0 dev: true - /@commitlint/load/17.4.0_@types+node@18.11.18: - resolution: {integrity: sha512-wDKNvAJqukqZqKmhRlf3KNo/12QGo1AQcd80EbV01SxtGvyHOsJ/g+/IbrZpopZv8rvzmEVktcpfDYH6ITepFA==} + /@commitlint/load/17.4.1: + resolution: {integrity: sha512-6A7/LhIaQpL4ieciIDcVvK2d5z/UI1GBrtDaHm6sQSCL0265clB2/F7XKQNTJHXv9yG4LByT2r+QCpM4GugIfw==} engines: {node: '>=v14'} dependencies: '@commitlint/config-validator': 17.4.0 '@commitlint/execute-rule': 17.4.0 '@commitlint/resolve-extends': 17.4.0 '@commitlint/types': 17.4.0 + '@types/node': 18.11.18 chalk: 4.1.2 cosmiconfig: 8.0.0 cosmiconfig-typescript-loader: 4.2.0_bxtyj3et3xbsdyxhh3oblnfbj4 @@ -605,7 +605,6 @@ packages: transitivePeerDependencies: - '@swc/core' - '@swc/wasm' - - '@types/node' dev: true /@commitlint/message/17.4.0: @@ -682,14 +681,14 @@ packages: '@jridgewell/trace-mapping': 0.3.9 dev: true - /@csstools/selector-specificity/2.0.2_2xshye3abirqjlplmebvmaxyna: + /@csstools/selector-specificity/2.0.2_wajs5nedgkikc5pcuwett7legi: resolution: {integrity: sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==} engines: {node: ^12 || ^14 || >=16} peerDependencies: postcss: ^8.2 postcss-selector-parser: ^6.0.10 dependencies: - postcss: 8.4.20 + postcss: 8.4.21 postcss-selector-parser: 6.0.11 dev: true @@ -964,8 +963,8 @@ packages: dependencies: '@iconify/types': 2.0.0 - /@iconify/json/2.2.2: - resolution: {integrity: sha512-G9HVJz3uvQGNEirk9oI7xYnWb7ygEfTUZ+PVp81qgNp8bu5UOtXaxjTGw78NyNAC2OlryH5tSEp95Dqbt4LLQQ==} + /@iconify/json/2.2.5: + resolution: {integrity: sha512-AIbJTRF9HJz7FJ8t7058huwDXHaFEY4a4f6uuPtctEQ8/I3ybrX66iZMgoLD1kLaamU4tzZPlZ6tSpA3pM8LZg==} dependencies: '@iconify/types': 2.0.0 pathe: 1.0.0 @@ -986,8 +985,8 @@ packages: vue-i18n: optional: true dependencies: - '@intlify/message-compiler': 9.3.0-beta.12 - '@intlify/shared': 9.3.0-beta.12 + '@intlify/message-compiler': 9.3.0-beta.14 + '@intlify/shared': 9.3.0-beta.14 jsonc-eslint-parser: 1.4.1 source-map: 0.6.1 vue-i18n: 9.2.2_vue@3.2.45 @@ -1016,11 +1015,11 @@ packages: '@intlify/shared': 9.2.2 source-map: 0.6.1 - /@intlify/message-compiler/9.3.0-beta.12: - resolution: {integrity: sha512-A8/s7pb3v8nf6HG77qFPJntxgQKI9GXxGnkn7aO+b03/X/GkF/4WceDSAIk3i+yLeIgszeBn9GZ23tSg4sTEHA==} + /@intlify/message-compiler/9.3.0-beta.14: + resolution: {integrity: sha512-PlZ3pl+YYuql54Nq+26wv6ohIa8Ig6ALrvQI+f2zZKUtkupb49M4wyVN3bDQbFlgYVE7/u3n19BJSY8lEuX5Eg==} engines: {node: '>= 14'} dependencies: - '@intlify/shared': 9.3.0-beta.11 + '@intlify/shared': 9.3.0-beta.14 source-map: 0.6.1 dev: true @@ -1028,13 +1027,8 @@ packages: resolution: {integrity: sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==} engines: {node: '>= 14'} - /@intlify/shared/9.3.0-beta.11: - resolution: {integrity: sha512-CtbotesxTRiC3bRyXyv1NG39fkqJ790f8z8xFaeIXSZpOdiyxoh5BIyypCzSFQZDGLwz0Q9gyWbW1XpxQJm68Q==} - engines: {node: '>= 14'} - dev: true - - /@intlify/shared/9.3.0-beta.12: - resolution: {integrity: sha512-WsmaS54sA8xuwezPKpa/OMoaX1v2VF2fCgAmYS6prDr2ir0CkUFWPm9A8ilmxzv4nkS61/v8+vf4lGGkn5uBdA==} + /@intlify/shared/9.3.0-beta.14: + resolution: {integrity: sha512-mJ/rFan+4uVsBAQSCAJnpQaPvSjQ49mJMNmGelTUbTDAmgf0oexYxwqtKOlFFyY3hmQ8lUDYaGQKuYrFgRuHnA==} engines: {node: '>= 14'} dev: true @@ -1054,7 +1048,7 @@ packages: optional: true dependencies: '@intlify/bundle-utils': 3.4.0_vue-i18n@9.2.2 - '@intlify/shared': 9.3.0-beta.12 + '@intlify/shared': 9.3.0-beta.14 '@rollup/pluginutils': 4.2.1 '@vue/compiler-sfc': 3.2.45 debug: 4.3.4 @@ -1285,8 +1279,8 @@ packages: resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} dev: false - /@typescript-eslint/eslint-plugin/5.48.0_k73wpmdolxikpyqun3p36akaaq: - resolution: {integrity: sha512-SVLafp0NXpoJY7ut6VFVUU9I+YeFsDzeQwtK0WZ+xbRN3mtxJ08je+6Oi2N89qDn087COdO0u3blKZNv9VetRQ==} + /@typescript-eslint/eslint-plugin/5.48.1_3jon24igvnqaqexgwtxk6nkpse: + resolution: {integrity: sha512-9nY5K1Rp2ppmpb9s9S2aBiF3xo5uExCehMDmYmmFqqyxgenbHJ3qbarcLt4ITgaD6r/2ypdlcFRdcuVPnks+fQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: '@typescript-eslint/parser': ^5.0.0 @@ -1296,10 +1290,10 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.48.0_iukboom6ndih5an6iafl45j2fe - '@typescript-eslint/scope-manager': 5.48.0 - '@typescript-eslint/type-utils': 5.48.0_iukboom6ndih5an6iafl45j2fe - '@typescript-eslint/utils': 5.48.0_iukboom6ndih5an6iafl45j2fe + '@typescript-eslint/parser': 5.48.1_iukboom6ndih5an6iafl45j2fe + '@typescript-eslint/scope-manager': 5.48.1 + '@typescript-eslint/type-utils': 5.48.1_iukboom6ndih5an6iafl45j2fe + '@typescript-eslint/utils': 5.48.1_iukboom6ndih5an6iafl45j2fe debug: 4.3.4 eslint: 8.31.0 ignore: 5.2.1 @@ -1312,8 +1306,8 @@ packages: - supports-color dev: true - /@typescript-eslint/parser/5.48.0_iukboom6ndih5an6iafl45j2fe: - resolution: {integrity: sha512-1mxNA8qfgxX8kBvRDIHEzrRGrKHQfQlbW6iHyfHYS0Q4X1af+S6mkLNtgCOsGVl8+/LUPrqdHMssAemkrQ01qg==} + /@typescript-eslint/parser/5.48.1_iukboom6ndih5an6iafl45j2fe: + resolution: {integrity: sha512-4yg+FJR/V1M9Xoq56SF9Iygqm+r5LMXvheo6DQ7/yUWynQ4YfCRnsKuRgqH4EQ5Ya76rVwlEpw4Xu+TgWQUcdA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -1322,9 +1316,9 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.48.0 - '@typescript-eslint/types': 5.48.0 - '@typescript-eslint/typescript-estree': 5.48.0_typescript@4.9.4 + '@typescript-eslint/scope-manager': 5.48.1 + '@typescript-eslint/types': 5.48.1 + '@typescript-eslint/typescript-estree': 5.48.1_typescript@4.9.4 debug: 4.3.4 eslint: 8.31.0 typescript: 4.9.4 @@ -1332,16 +1326,16 @@ packages: - supports-color dev: true - /@typescript-eslint/scope-manager/5.48.0: - resolution: {integrity: sha512-0AA4LviDtVtZqlyUQnZMVHydDATpD9SAX/RC5qh6cBd3xmyWvmXYF+WT1oOmxkeMnWDlUVTwdODeucUnjz3gow==} + /@typescript-eslint/scope-manager/5.48.1: + resolution: {integrity: sha512-S035ueRrbxRMKvSTv9vJKIWgr86BD8s3RqoRZmsSh/s8HhIs90g6UlK8ZabUSjUZQkhVxt7nmZ63VJ9dcZhtDQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.48.0 - '@typescript-eslint/visitor-keys': 5.48.0 + '@typescript-eslint/types': 5.48.1 + '@typescript-eslint/visitor-keys': 5.48.1 dev: true - /@typescript-eslint/type-utils/5.48.0_iukboom6ndih5an6iafl45j2fe: - resolution: {integrity: sha512-vbtPO5sJyFjtHkGlGK4Sthmta0Bbls4Onv0bEqOGm7hP9h8UpRsHJwsrCiWtCUndTRNQO/qe6Ijz9rnT/DB+7g==} + /@typescript-eslint/type-utils/5.48.1_iukboom6ndih5an6iafl45j2fe: + resolution: {integrity: sha512-Hyr8HU8Alcuva1ppmqSYtM/Gp0q4JOp1F+/JH5D1IZm/bUBrV0edoewQZiEc1r6I8L4JL21broddxK8HAcZiqQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '*' @@ -1350,8 +1344,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.48.0_typescript@4.9.4 - '@typescript-eslint/utils': 5.48.0_iukboom6ndih5an6iafl45j2fe + '@typescript-eslint/typescript-estree': 5.48.1_typescript@4.9.4 + '@typescript-eslint/utils': 5.48.1_iukboom6ndih5an6iafl45j2fe debug: 4.3.4 eslint: 8.31.0 tsutils: 3.21.0_typescript@4.9.4 @@ -1360,13 +1354,13 @@ packages: - supports-color dev: true - /@typescript-eslint/types/5.48.0: - resolution: {integrity: sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==} + /@typescript-eslint/types/5.48.1: + resolution: {integrity: sha512-xHyDLU6MSuEEdIlzrrAerCGS3T7AA/L8Hggd0RCYBi0w3JMvGYxlLlXHeg50JI9Tfg5MrtsfuNxbS/3zF1/ATg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree/5.48.0_typescript@4.9.4: - resolution: {integrity: sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw==} + /@typescript-eslint/typescript-estree/5.48.1_typescript@4.9.4: + resolution: {integrity: sha512-Hut+Osk5FYr+sgFh8J/FHjqX6HFcDzTlWLrFqGoK5kVUN3VBHF/QzZmAsIXCQ8T/W9nQNBTqalxi1P3LSqWnRA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' @@ -1374,8 +1368,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.48.0 - '@typescript-eslint/visitor-keys': 5.48.0 + '@typescript-eslint/types': 5.48.1 + '@typescript-eslint/visitor-keys': 5.48.1 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -1386,17 +1380,17 @@ packages: - supports-color dev: true - /@typescript-eslint/utils/5.48.0_iukboom6ndih5an6iafl45j2fe: - resolution: {integrity: sha512-x2jrMcPaMfsHRRIkL+x96++xdzvrdBCnYRd5QiW5Wgo1OB4kDYPbC1XjWP/TNqlfK93K/lUL92erq5zPLgFScQ==} + /@typescript-eslint/utils/5.48.1_iukboom6ndih5an6iafl45j2fe: + resolution: {integrity: sha512-SmQuSrCGUOdmGMwivW14Z0Lj8dxG1mOFZ7soeJ0TQZEJcs3n5Ndgkg0A4bcMFzBELqLJ6GTHnEU+iIoaD6hFGA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: '@types/json-schema': 7.0.11 '@types/semver': 7.3.13 - '@typescript-eslint/scope-manager': 5.48.0 - '@typescript-eslint/types': 5.48.0 - '@typescript-eslint/typescript-estree': 5.48.0_typescript@4.9.4 + '@typescript-eslint/scope-manager': 5.48.1 + '@typescript-eslint/types': 5.48.1 + '@typescript-eslint/typescript-estree': 5.48.1_typescript@4.9.4 eslint: 8.31.0 eslint-scope: 5.1.1 eslint-utils: 3.0.0_eslint@8.31.0 @@ -1406,11 +1400,11 @@ packages: - typescript dev: true - /@typescript-eslint/visitor-keys/5.48.0: - resolution: {integrity: sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==} + /@typescript-eslint/visitor-keys/5.48.1: + resolution: {integrity: sha512-Ns0XBwmfuX7ZknznfXozgnydyR8F6ev/KEGePP4i74uL3ArsKbEhJ7raeKr1JSa997DBDwol/4a0Y+At82c9dA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.48.0 + '@typescript-eslint/types': 5.48.1 eslint-visitor-keys: 3.3.0 dev: true @@ -1498,30 +1492,30 @@ packages: vue: 3.2.45 dev: true - /@volar/language-core/1.0.22: - resolution: {integrity: sha512-hiJeCOqxNdtG/04FRGLGI9H9DVz2l6cTqPDBzwqplHXAWfMxjzUaGUrn9sfTG7YMFNZUgK4EYxJnRfhqdtbSFQ==} + /@volar/language-core/1.0.24: + resolution: {integrity: sha512-vTN+alJiWwK0Pax6POqrmevbtFW2dXhjwWiW/MW4f48eDYPLdyURWcr8TixO7EN/nHsUBj2udT7igFKPtjyAKg==} dependencies: - '@volar/source-map': 1.0.22 + '@volar/source-map': 1.0.24 muggle-string: 0.1.0 dev: true - /@volar/source-map/1.0.22: - resolution: {integrity: sha512-cv4gypHSP4MWVR82ed/+1IpI6794qAl0Q0+KJ+VGMVF8rVugsiF9QbyMCgjel9wNRsssQsazzsf6txOR9vHQiw==} + /@volar/source-map/1.0.24: + resolution: {integrity: sha512-Qsv/tkplx18pgBr8lKAbM1vcDqgkGKQzbChg6NW+v0CZc3G7FLmK+WrqEPzKlN7Cwdc6XVL559Nod8WKAfKr4A==} dependencies: muggle-string: 0.1.0 dev: true - /@volar/typescript/1.0.22: - resolution: {integrity: sha512-VPyEicealSD4gqlE5/UQ1j3ietsO6Hfat40KtUEh/K+XEZ7h02b1KgFV64YEuBkBOaZ5hgvRW/WXKtQgXCl7Iw==} + /@volar/typescript/1.0.24: + resolution: {integrity: sha512-f8hCSk+PfKR1/RQHxZ79V1NpDImHoivqoizK+mstphm25tn/YJ/JnKNjZHB+o21fuW0yKlI26NV3jkVb2Cc/7A==} dependencies: - '@volar/language-core': 1.0.22 + '@volar/language-core': 1.0.24 dev: true - /@volar/vue-language-core/1.0.22: - resolution: {integrity: sha512-Ki0G/ZdBj2/GLw+/VVH3n9XR/JL6krMIth02EekFn6JV4PGN3mNxbvoh6lOPSDZLR6biOU5nJPnnjpKy8nuXhw==} + /@volar/vue-language-core/1.0.24: + resolution: {integrity: sha512-2NTJzSgrwKu6uYwPqLiTMuAzi7fAY3yFy5PJ255bGJc82If0Xr+cW8pC80vpjG0D/aVLmlwAdO4+Ya2BI8GdDg==} dependencies: - '@volar/language-core': 1.0.22 - '@volar/source-map': 1.0.22 + '@volar/language-core': 1.0.24 + '@volar/source-map': 1.0.24 '@vue/compiler-dom': 3.2.45 '@vue/compiler-sfc': 3.2.45 '@vue/reactivity': 3.2.45 @@ -1530,11 +1524,11 @@ packages: vue-template-compiler: 2.7.14 dev: true - /@volar/vue-typescript/1.0.22: - resolution: {integrity: sha512-2T1o5z86PAev31OMtVOv/qp4P3ZVl9ln/2KTmykQE8Fh4A5F+868MW4nf5J7XQ6RNyx7RH9LhzgjvbqJpAfiYw==} + /@volar/vue-typescript/1.0.24: + resolution: {integrity: sha512-9a25oHDvGaNC0okRS47uqJI6FxY4hUQZUsxeOUFHcqVxZEv8s17LPuP/pMMXyz7jPygrZubB/qXqHY5jEu/akA==} dependencies: - '@volar/typescript': 1.0.22 - '@volar/vue-language-core': 1.0.22 + '@volar/typescript': 1.0.24 + '@volar/vue-language-core': 1.0.24 dev: true /@vue/babel-helper-vue-transform-on/1.0.2: @@ -1583,7 +1577,7 @@ packages: '@vue/shared': 3.2.45 estree-walker: 2.0.2 magic-string: 0.25.9 - postcss: 8.4.20 + postcss: 8.4.21 source-map: 0.6.1 /@vue/compiler-ssr/3.2.45: @@ -2066,7 +2060,7 @@ packages: hasBin: true dev: true - /autoprefixer/10.4.13_postcss@8.4.20: + /autoprefixer/10.4.13_postcss@8.4.21: resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==} engines: {node: ^10 || ^12 || >=14} hasBin: true @@ -2078,7 +2072,7 @@ packages: fraction.js: 4.2.0 normalize-range: 0.1.2 picocolors: 1.0.0 - postcss: 8.4.20 + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: true @@ -3013,12 +3007,12 @@ packages: eslint: 8.31.0 dev: true - /eslint-define-config/1.13.0: - resolution: {integrity: sha512-d0BfmPGBcMusfiz6QY/piAhWaEyJriJtvk9SHfuJzI7am9k4ce07SfmPkpcR0ckXNyu4FBons10akOO2Tx+X+Q==} + /eslint-define-config/1.14.0: + resolution: {integrity: sha512-NREt5SzMwKmLAY28YdaqIiTSJxfPpuZ+1ZLJxY2Wbj02dYF4QX81z0q9MPMjZB8C+SlCu66qAhcPpFJyhXOiuA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0, npm: '>=6.14.13', pnpm: '>= 7.0.0'} dev: true - /eslint-plugin-prettier/4.2.1_32m5uc2milwdw3tnkcq5del26y: + /eslint-plugin-prettier/4.2.1_iu5s7nk6dw7o3tajefwfiqfmge: resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -3031,7 +3025,7 @@ packages: dependencies: eslint: 8.31.0 eslint-config-prettier: 8.6.0_eslint@8.31.0 - prettier: 2.8.1 + prettier: 2.8.2 prettier-linter-helpers: 1.0.0 dev: true @@ -4506,7 +4500,7 @@ packages: dev: false /nanoid/3.3.4: - resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/nanoid/-/nanoid-3.3.4.tgz} + resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -4848,8 +4842,8 @@ packages: dependencies: htmlparser2: 8.0.1 js-tokens: 8.0.0 - postcss: 8.4.20 - postcss-safe-parser: 6.0.0_postcss@8.4.20 + postcss: 8.4.21 + postcss-safe-parser: 6.0.0_postcss@8.4.21 dev: true /postcss-media-query-parser/0.2.3: @@ -4868,22 +4862,22 @@ packages: resolution: {integrity: sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==} dev: true - /postcss-safe-parser/6.0.0_postcss@8.4.20: + /postcss-safe-parser/6.0.0_postcss@8.4.21: resolution: {integrity: sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==} engines: {node: '>=12.0'} peerDependencies: postcss: ^8.3.3 dependencies: - postcss: 8.4.20 + postcss: 8.4.21 dev: true - /postcss-scss/4.0.6_postcss@8.4.20: + /postcss-scss/4.0.6_postcss@8.4.21: resolution: {integrity: sha512-rLDPhJY4z/i4nVFZ27j9GqLxj1pwxE80eAzUNRMXtcpipFYIeowerzBgG3yJhMtObGEXidtIgbUpQ3eLDsf5OQ==} engines: {node: '>=12.0'} peerDependencies: postcss: ^8.4.19 dependencies: - postcss: 8.4.20 + postcss: 8.4.21 dev: true /postcss-selector-parser/6.0.10: @@ -4902,12 +4896,12 @@ packages: util-deprecate: 1.0.2 dev: true - /postcss-sorting/7.0.1_postcss@8.4.20: - resolution: {integrity: sha512-iLBFYz6VRYyLJEJsBJ8M3TCqNcckVzz4wFounSc5Oez35ogE/X+aoC5fFu103Ot7NyvjU3/xqIXn93Gp3kJk4g==} + /postcss-sorting/8.0.1_postcss@8.4.21: + resolution: {integrity: sha512-go9Zoxx7KQH+uLrJ9xa5wRErFeXu01ydA6O8m7koPXkmAN7Ts//eRcIqjo0stBR4+Nir2gMYDOWAOx7O5EPUZA==} peerDependencies: - postcss: ^8.3.9 + postcss: ^8.4.20 dependencies: - postcss: 8.4.20 + postcss: 8.4.21 dev: true /postcss-value-parser/4.2.0: @@ -4924,8 +4918,8 @@ packages: supports-color: 3.2.3 dev: true - /postcss/8.4.20: - resolution: {integrity: sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/postcss/-/postcss-8.4.20.tgz} + /postcss/8.4.21: + resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==} engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.4 @@ -4983,8 +4977,8 @@ packages: fast-diff: 1.2.0 dev: true - /prettier/2.8.1: - resolution: {integrity: sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==} + /prettier/2.8.2: + resolution: {integrity: sha512-BtRV9BcncDyI2tsuS19zzhzoxD8Dh8LiCx7j7tHzrkz8GFXAexeWFdi22mjE1d16dftH2qNaytVxqiRTGlMfpw==} engines: {node: '>=10.13.0'} hasBin: true dev: true @@ -5428,7 +5422,7 @@ packages: dev: true /source-map-js/1.0.2: - resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/source-map-js/-/source-map-js-1.0.2.tgz} + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} /source-map-resolve/0.5.3: @@ -5636,13 +5630,13 @@ packages: stylelint-config-recommended: 9.0.0_stylelint@14.16.1 dev: true - /stylelint-order/5.0.0_stylelint@14.16.1: - resolution: {integrity: sha512-OWQ7pmicXufDw5BlRqzdz3fkGKJPgLyDwD1rFY3AIEfIH/LQY38Vu/85v8/up0I+VPiuGRwbc2Hg3zLAsJaiyw==} + /stylelint-order/6.0.1_stylelint@14.16.1: + resolution: {integrity: sha512-C9gJDZArRBZvn+4MPgggwYTp7dK49WPnYa5+6tBEkZnW/YWj4xBVNJdQjIik14w5orlF9RqFpYDHN0FPWIFOSQ==} peerDependencies: stylelint: ^14.0.0 dependencies: - postcss: 8.4.20 - postcss-sorting: 7.0.1_postcss@8.4.20 + postcss: 8.4.21 + postcss-sorting: 8.0.1_postcss@8.4.21 stylelint: 14.16.1 dev: true @@ -5651,7 +5645,7 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} hasBin: true dependencies: - '@csstools/selector-specificity': 2.0.2_2xshye3abirqjlplmebvmaxyna + '@csstools/selector-specificity': 2.0.2_wajs5nedgkikc5pcuwett7legi balanced-match: 2.0.0 colord: 2.9.3 cosmiconfig: 7.1.0 @@ -5674,10 +5668,10 @@ packages: micromatch: 4.0.5 normalize-path: 3.0.0 picocolors: 1.0.0 - postcss: 8.4.20 + postcss: 8.4.21 postcss-media-query-parser: 0.2.3 postcss-resolve-nested-selector: 0.1.1 - postcss-safe-parser: 6.0.0_postcss@8.4.20 + postcss-safe-parser: 6.0.0_postcss@8.4.21 postcss-selector-parser: 6.0.11 postcss-value-parser: 4.2.0 resolve-from: 5.0.0 @@ -6211,7 +6205,7 @@ packages: dependencies: '@types/node': 18.11.18 esbuild: 0.16.5 - postcss: 8.4.20 + postcss: 8.4.21 resolve: 1.22.1 rollup: 3.9.1 sass: 1.57.1 @@ -6281,14 +6275,14 @@ packages: he: 1.2.0 dev: true - /vue-tsc/1.0.22_typescript@4.9.4: - resolution: {integrity: sha512-xSxwgWR3czhv7sLKHWu6lzj9Xq6AtsCURVL45AY4TLGFszv2L2YlMgygXvqslyCM5bz9cyoIKSaZnzHqHTHjzA==} + /vue-tsc/1.0.24_typescript@4.9.4: + resolution: {integrity: sha512-mmU1s5SAqE1nByQAiQnao9oU4vX+mSdsgI8H57SfKH6UVzq/jP9+Dbi2GaV+0b4Cn361d2ln8m6xeU60ApiEXg==} hasBin: true peerDependencies: typescript: '*' dependencies: - '@volar/vue-language-core': 1.0.22 - '@volar/vue-typescript': 1.0.22 + '@volar/vue-language-core': 1.0.24 + '@volar/vue-typescript': 1.0.24 typescript: 4.9.4 dev: true @@ -6314,8 +6308,8 @@ packages: '@vue/server-renderer': 3.2.45_vue@3.2.45 '@vue/shared': 3.2.45 - /vxe-table/4.3.7_vue@3.2.45+xe-utils@3.5.7: - resolution: {integrity: sha512-v+d7eEQ5uqtVTQCts4xkW0S15LZcIuEukYHGXI53SdoUj2gLFggPYAxQr1y659CM/ESRWPz9LNVHpd97KkjGHw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/vxe-table/-/vxe-table-4.3.7.tgz} + /vxe-table/4.3.9_vue@3.2.45+xe-utils@3.5.7: + resolution: {integrity: sha512-Ns7Ooa7lOHBpks90i0k0BMNyxfMpUo39ryxTgKE41X3xVnI9tGQs2U6+klfDlsuqYfmG3ibyzHN3OCrWbbKo4Q==} peerDependencies: vue: ^3.2.28 xe-utils: ^3.5.0 diff --git a/yudao-ui-admin/src/styles/index.scss b/yudao-ui-admin/src/styles/index.scss index c659c11f3..3d4566183 100644 --- a/yudao-ui-admin/src/styles/index.scss +++ b/yudao-ui-admin/src/styles/index.scss @@ -129,7 +129,7 @@ input, textarea{ } .el-scrollbar__view{ - overflow-x: hidden; +// overflow-x: hidden; } .el-rate{ diff --git a/yudao-ui-admin/src/views/infra/redis/index.vue b/yudao-ui-admin/src/views/infra/redis/index.vue index 0cbca999d..63be640bc 100644 --- a/yudao-ui-admin/src/views/infra/redis/index.vue +++ b/yudao-ui-admin/src/views/infra/redis/index.vue @@ -136,8 +136,8 @@