Compare commits

...

12 Commits

Author SHA1 Message Date
jmxd
e1cdccaa5e update 2025-06-06 07:06:41 +08:00
jmxd
5433962fa0 更新前端 2025-06-06 06:54:06 +08:00
jmxd
7d324d184a 修订版本号 2025-06-06 06:52:01 +08:00
jmxd
9a22c3b0f5 修订版本号 2025-06-06 06:51:00 +08:00
jmxd
407d71349e fix 2025-06-05 07:33:14 +08:00
jmxd
2648cb33bf 单表API主键取消强制String类型 2025-05-31 08:33:14 +08:00
jmxd
9106fcfbcb 兼容springdoc2.8 2025-05-31 08:32:39 +08:00
小东
a7b3e189f7
!92 保存接口请求加密:Base64+ROT13
Merge pull request !92 from toss/ROT13-encrypt
2025-05-25 02:38:50 +00:00
小东
21afc951cf
!93 fix:空指针异常
Merge pull request !93 from 他化天/master
2025-05-22 06:03:53 +00:00
chenweiqing
4b7d8494b6 fix:空指针异常 2025-05-22 13:53:19 +08:00
txk
4e39ce468f 解密逻辑移到save接口 2025-05-21 10:21:07 +08:00
txk
f67b357059 保存接口请求加密:Base64+ROT13 2025-05-20 15:10:23 +08:00
30 changed files with 185 additions and 65 deletions

View File

@ -51,7 +51,7 @@ magic-api 是一个基于Java的接口快速开发框架编写接口将通过
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-spring-boot-starter</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
</dependency>
```
## 修改application.properties

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-plugins</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
</parent>
<artifactId>magic-api-plugin-cluster</artifactId>
<packaging>jar</packaging>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-plugins</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
</parent>
<artifactId>magic-api-plugin-component</artifactId>
<packaging>jar</packaging>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-plugins</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
</parent>
<artifactId>magic-api-plugin-elasticsearch</artifactId>
<packaging>jar</packaging>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-plugins</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
</parent>
<artifactId>magic-api-plugin-git</artifactId>
<packaging>jar</packaging>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-plugins</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
</parent>
<artifactId>magic-api-plugin-mongo</artifactId>
<packaging>jar</packaging>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-plugins</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
</parent>
<artifactId>magic-api-plugin-nebula</artifactId>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-plugins</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
</parent>
<artifactId>magic-api-plugin-redis</artifactId>
<packaging>jar</packaging>

View File

@ -6,14 +6,14 @@
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-plugins</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
</parent>
<artifactId>magic-api-plugin-springdoc</artifactId>
<packaging>jar</packaging>
<name>magic-api-plugin-springdoc</name>
<description>magic-api-plugin-springdoc</description>
<properties>
<springdoc.version>2.0.4</springdoc.version>
<springdoc.version>2.8.8</springdoc.version>
</properties>
<dependencies>
<dependency>

View File

@ -1,11 +1,15 @@
package org.ssssssss.magicapi.springdoc;
import jakarta.servlet.ServletContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springdoc.core.properties.AbstractSwaggerUiConfigProperties;
import org.springdoc.core.properties.SpringDocConfigProperties;
import org.springdoc.core.properties.SwaggerUiConfigParameters;
import org.springdoc.core.properties.SwaggerUiConfigProperties;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
@ -23,9 +27,10 @@ import org.ssssssss.magicapi.springdoc.entity.SwaggerEntity;
import org.ssssssss.magicapi.springdoc.entity.SwaggerProvider;
import org.ssssssss.magicapi.utils.Mapping;
import jakarta.servlet.ServletContext;
import java.util.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@Configuration
@EnableConfigurationProperties(SpringDocConfig.class)
@ -62,6 +67,34 @@ public class MagicSpringDocConfiguration implements MagicPluginConfiguration {
return new Plugin("SpringDoc");
}
@Bean
@Primary
@ConditionalOnMissingBean(SwaggerUiConfigParameters.class)
public SwaggerUiConfigProperties magicSwaggerUiConfigProperties(SwaggerUiConfigProperties swaggerUiConfigProperties, SpringDocConfigProperties springDocConfigProperties){
Set<AbstractSwaggerUiConfigProperties.SwaggerUrl> urls = swaggerUiConfigProperties.getUrls();
if (urls == null){
urls = new HashSet<>();
AbstractSwaggerUiConfigProperties.SwaggerUrl url = new AbstractSwaggerUiConfigProperties.SwaggerUrl("default", springDocConfigProperties.getApiDocs().getPath(), null);
urls.add(url);
}
urls.add(new AbstractSwaggerUiConfigProperties.SwaggerUrl(springDocConfig.getGroupName(), servletContext.getContextPath() + springDocConfig.getLocation(), null){
@Override
public String getUrl() {
try {
if (!createdMapping){
createdMapping = true;
createSwaggerProvider(requestMagicDynamicRegistryObjectProvider, magicResourceService, servletContext);
}
} catch (Exception e) {
logger.error("注册springdoc接口失败", e);
}
return super.getUrl();
}
});
swaggerUiConfigProperties.setUrls(urls);
return swaggerUiConfigProperties;
}
@Bean
@Primary
@Lazy

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-plugins</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
</parent>
<artifactId>magic-api-plugin-swagger</artifactId>
<packaging>jar</packaging>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-plugins</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
</parent>
<artifactId>magic-api-plugin-task</artifactId>
<packaging>jar</packaging>

View File

@ -6,10 +6,10 @@
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-parent</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
</parent>
<artifactId>magic-api-plugins</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
<packaging>pom</packaging>
<name>magic-api-plugins</name>
<description>auto generate http api</description>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-servlet</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
</parent>
<artifactId>magic-api-servlet-jakarta</artifactId>
<packaging>jar</packaging>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-servlet</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
</parent>
<artifactId>magic-api-servlet-javaee</artifactId>
<packaging>jar</packaging>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-parent</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
</parent>
<artifactId>magic-api-servlet</artifactId>
<packaging>pom</packaging>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-parent</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
</parent>
<artifactId>magic-api-spring-boot-starter</artifactId>
<packaging>jar</packaging>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-parent</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
</parent>
<artifactId>magic-api</artifactId>
<packaging>jar</packaging>

View File

@ -48,7 +48,7 @@ public class MagicBackupController extends MagicController implements MagicExcep
return new JsonBean<>(service.backupById(id));
}
@GetMapping("/backup/rollback")
@PostMapping("/backup/rollback")
@ResponseBody
public JsonBean<Boolean> rollback(String id, Long timestamp) throws IOException {
notNull(service, BACKUP_NOT_ENABLED);

View File

@ -12,8 +12,10 @@ import org.ssssssss.magicapi.core.service.MagicDynamicRegistry;
import org.ssssssss.magicapi.core.service.MagicResourceService;
import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest;
import org.ssssssss.magicapi.utils.IoUtils;
import org.ssssssss.magicapi.utils.ROT13Utils;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.function.Function;
@ -72,12 +74,14 @@ public class MagicResourceController extends MagicController implements MagicExc
@ResponseBody
public JsonBean<String> saveFile(@PathVariable("folder") String folder, String auto, MagicHttpServletRequest request) throws IOException {
byte[] bytes = IoUtils.bytes(request.getInputStream());
String encrypt = new String(bytes, StandardCharsets.UTF_8);
String decrypt = ROT13Utils.decrypt(encrypt);
MagicEntity entity = configuration.getMagicDynamicRegistries().stream()
.map(MagicDynamicRegistry::getMagicResourceStorage)
.filter(it -> Objects.equals(it.folder(), folder))
.findFirst()
.orElseThrow(() -> new InvalidArgumentException(GROUP_NOT_FOUND))
.read(bytes);
.read(decrypt.getBytes(StandardCharsets.UTF_8));
isTrue(allowVisit(request, Authorization.SAVE, entity), PERMISSION_INVALID);
// 自动保存的代码和旧版代码对比如果一致则不保存直接返回
if (entity ==null){

View File

@ -23,7 +23,7 @@ public class DefaultSqlInterceptor implements SQLInterceptor {
return "null";
}
if (it instanceof Object[]){
return "[" + Stream.of((Object[])it).map(x -> x + "(" + x.getClass().getSimpleName() + ")").collect(Collectors.joining(", ")) + "]";
return "[" + Stream.of((Object[]) it).map(x -> x == null ? "null" : (x + "(" + x.getClass().getSimpleName() + ")")).collect(Collectors.joining(", ")) + "]";
}
return it + "(" + it.getClass().getSimpleName() + ")";
}).collect(Collectors.joining(", "));

View File

@ -298,12 +298,12 @@ public class NamedTable extends Attributes<Object> {
if (data != null) {
data.forEach((key, value) -> this.columns.put(rowMapColumnMapper.apply(key), value));
}
String primaryValue = Objects.toString(this.columns.get(this.primary), "");
if (StringUtils.isBlank(primaryValue) && data != null) {
primaryValue = Objects.toString(data.get(this.primary), "");
Object primaryValue = this.columns.get(this.primary);
if (data != null && StringUtils.isBlank(Objects.toString(primaryValue, ""))) {
primaryValue = data.get(this.primary);
}
if (beforeQuery) {
if (StringUtils.isNotBlank(primaryValue)) {
if (primaryValue != null && StringUtils.isNotBlank(Objects.toString(primaryValue))) {
List<Object> params = new ArrayList<>();
params.add(primaryValue);
Integer count = sqlModule.selectInt(new BoundSql(runtimeContext, "select count(*) count from " + this.tableName + " where " + this.primary + " = ?", params, sqlModule));
@ -316,7 +316,7 @@ public class NamedTable extends Attributes<Object> {
}
}
if (StringUtils.isNotBlank(primaryValue)) {
if (primaryValue != null && StringUtils.isNotBlank(Objects.toString(primaryValue, ""))) {
return update(runtimeContext, data);
}
return insert(runtimeContext, data);
@ -425,7 +425,7 @@ public class NamedTable extends Attributes<Object> {
params.addAll(where.getParams());
} else if (primaryValue != null) {
builder.append(" where ").append(this.primary).append(" = ?");
params.add(String.valueOf(primaryValue));
params.add(primaryValue);
} else {
throw new MagicAPIException("主键值不能为空");
}

View File

@ -0,0 +1,84 @@
package org.ssssssss.magicapi.utils;
import java.util.Base64;
public class ROT13Utils {
/**
* ROT13 函数对给定字符串执行 ROT13 编码
* @param str - 要编码的字符串
* @return 编码后的字符串
*/
public static String rot13(String str) {
StringBuilder result = new StringBuilder();
for (char c : str.toCharArray()) {
if (c >= 'a' && c <= 'z') {
// 小写字母处理
c = (char) (((c - 'a' + 13) % 26) + 'a');
} else if (c >= 'A' && c <= 'Z') {
// 大写字母处理
c = (char) (((c - 'A' + 13) % 26) + 'A');
}
// 非字母字符保持不变
result.append(c);
}
return result.toString();
}
/**
* 加密流程
* 数据 -> Base64 编码 -> ROT13 替换
* @param str 要加密的字符串
* @return 加密后的字符串
*/
public static String encrypt(String str) {
try {
String encode = encode(str);
return rot13(encode);
} catch (Exception e) {
return str;
}
}
/**
* 解密流程
* ROT13 -> Base64 -> 数据对象
* @param encrypted 要解密的字符串
* @return 解密后的字符串
*/
public static String decrypt(String encrypted) {
try {
String encrypt = rot13(encrypted.replaceFirst("^\"", "").replaceAll("\"$", ""));
return decode(encrypt);
} catch (Exception e) {
return encrypted;
}
}
/**
* 对输入字符串进行 Base64 编码
*
* @param input 输入字符串
* @return 编码后的字符串
*/
public static String encode(String input) {
// 将字符串转换为字节数组
byte[] encodedBytes = Base64.getEncoder().encode(input.getBytes());
// 转换回字符串并返回
return new String(encodedBytes);
}
/**
* Base64 编码的字符串进行解码
*
* @param encodedString 已编码的字符串
* @return 解码后的原始字符串
*/
public static String decode(String encodedString) {
// 将字符串转换为字节数组
byte[] decodedBytes = Base64.getDecoder().decode(encodedString.getBytes());
// 转换回字符串并返回
return new String(decodedBytes);
}
}

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-parent</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
</parent>
<artifactId>magic-editor</artifactId>
<packaging>jar</packaging>

View File

@ -1 +1 @@
import"./app.b406e930.js";import"./vue.6f28a6f0.js";import"./axios.23e7b955.js";import"./vendor.f3cb29e6.js";const s=function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const e of document.querySelectorAll('link[rel="modulepreload"]'))i(e);new MutationObserver(e=>{for(const r of e)if(r.type==="childList")for(const o of r.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&i(o)}).observe(document,{childList:!0,subtree:!0});function n(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerpolicy&&(r.referrerPolicy=e.referrerpolicy),e.crossorigin==="use-credentials"?r.credentials="include":e.crossorigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function i(e){if(e.ep)return;e.ep=!0;const r=n(e);fetch(e.href,r)}};s();
import"./app.60f63c60.js";import"./vue.6f28a6f0.js";import"./axios.23e7b955.js";import"./vendor.295b3547.js";const s=function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const e of document.querySelectorAll('link[rel="modulepreload"]'))i(e);new MutationObserver(e=>{for(const r of e)if(r.type==="childList")for(const o of r.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&i(o)}).observe(document,{childList:!0,subtree:!0});function n(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerpolicy&&(r.referrerPolicy=e.referrerpolicy),e.crossorigin==="use-credentials"?r.credentials="include":e.crossorigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function i(e){if(e.ep)return;e.ep=!0;const r=n(e);fetch(e.href,r)}};s();

View File

@ -23,12 +23,12 @@
@keyframes stretch {0% {transform: scale(1);}25% {transform: scale(1.2);}50% {transform: scale(1);}100% {transform: scale(1);}}
@keyframes blink-loading {0% {opacity: 1;}50% {opacity: 0.5;}100% {opacity: 1;}}
</style>
<script type="module" crossorigin src="./assets/index.740a4e58.js"></script>
<script type="module" crossorigin src="./assets/index.8dc5e5af.js"></script>
<link rel="modulepreload" href="./assets/vue.6f28a6f0.js">
<link rel="modulepreload" href="./assets/axios.23e7b955.js">
<link rel="modulepreload" href="./assets/vendor.f3cb29e6.js">
<link rel="modulepreload" href="./assets/app.b406e930.js">
<link rel="stylesheet" href="./assets/style.75b77094.css">
<link rel="modulepreload" href="./assets/vendor.295b3547.js">
<link rel="modulepreload" href="./assets/app.60f63c60.js">
<link rel="stylesheet" href="./assets/style.5b6b651e.css">
</head>
<body>
<div class="magic-loading-wrapper" id="magic-loading-wrapper">
@ -49,7 +49,7 @@
function showMaLoadingText(){
let defaultConfig = {
title: 'magic-api',
version: '2.2.1'
version: '2.2.2'
}
defaultConfig = { ...defaultConfig, ...window.MAGIC_EDITOR_CONFIG }
let $dom = document.getElementById('magic-loading-text')

21
pom.xml
View File

@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-parent</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
<packaging>pom</packaging>
<name>magic-api-parent</name>
<description>auto generate http api</description>
@ -214,18 +214,17 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonatype.central</groupId>
<artifactId>central-publishing-maven-plugin</artifactId>
<version>0.7.0</version>
<extensions>true</extensions>
<configuration>
<publishingServerId>central</publishingServerId>
</configuration>
</plugin>
</plugins>
</build>
<distributionManagement>
<snapshotRepository>
<id>oss</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
<repository>
<id>oss</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2</url>
</repository>
</distributionManagement>
</profile>
</profiles>
</project>