fix: 修复审查发现的安全与公开接口问题 - #17
Conversation
There was a problem hiding this comment.
Pull request overview
本 PR 聚焦于审查后安全与公开接口收敛:为微信后台相关接口补齐方法级权限、修复微信回调 NPE,并调整产品详情公开接口的返回模型与前端富文本渲染的 iframe 安全策略。
Changes:
- 为
mortise-wechat的管理/消息发送接口补齐方法级@PreAuthorize,并统一管理接口返回GlobalResult - 产品详情接口改为返回包含 SKU 目标映射的 VO,并在后端过滤仅启用 SKU/启用目标
- 前端富文本清洗新增 iframe HTTPS + 域名白名单校验,保留文章页受控
v-html使用;同时将临时 secrets 文件模式加入.gitignore
Reviewed changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| mortise-wechat/src/main/java/com/rymcu/mortise/wechat/handler/MsgHandler.java | 修复非文本消息回调 content 为空导致的 NPE,并改为日志记录异常 |
| mortise-wechat/src/main/java/com/rymcu/mortise/wechat/controller/WeChatMpManagementController.java | 管理接口补齐方法级权限并统一返回 GlobalResult |
| mortise-wechat/src/main/java/com/rymcu/mortise/wechat/controller/WeChatMessageController.java | 将消息发送接口收敛到后台控制器并补齐方法级权限 |
| mortise-product/mortise-product-application/src/main/java/com/rymcu/mortise/product/service/query/impl/ProductSkuTargetQueryServiceImpl.java | 新增 SKU 目标映射的 query service 实现,供 API 层组合数据 |
| mortise-product/mortise-product-application/src/main/java/com/rymcu/mortise/product/service/query/ProductSkuTargetQueryService.java | 新增 SKU 目标映射 query service 接口 |
| mortise-product/mortise-product-application/src/main/java/com/rymcu/mortise/product/service/impl/ProductSkuTargetServiceImpl.java | 新增 SKU 目标映射 service 与查询方法实现 |
| mortise-product/mortise-product-application/src/main/java/com/rymcu/mortise/product/service/ProductSkuTargetService.java | 新增 SKU 目标映射 service 接口定义 |
| mortise-product/mortise-product-api/src/main/java/com/rymcu/mortise/product/api/facade/impl/ProductCatalogApiFacadeImpl.java | 产品详情组装为 VO,并过滤仅启用 SKU/启用 target 映射 |
| mortise-product/mortise-product-api/src/main/java/com/rymcu/mortise/product/api/facade/ProductCatalogApiFacade.java | 产品详情 facade 返回类型调整为详情 VO |
| mortise-product/mortise-product-api/src/main/java/com/rymcu/mortise/product/api/dto/ApiProductModels.java | 新增对外 VO(产品详情 + SKU 目标映射) |
| mortise-product/mortise-product-api/src/main/java/com/rymcu/mortise/product/api/controller/ProductApiController.java | 产品详情接口返回类型更新为详情 VO |
| frontend/layers/base/composables/useSanitizedHtml.ts | DOMPurify 增加 iframe 白名单 + HTTPS 校验 hook |
| frontend/apps/site/app/pages/blog/[id].vue | 对受控 v-html 片段增加 eslint 局部豁免注释 |
| .gitignore | 忽略临时 secrets 文件模式 |
| @Operation(summary = "发送模板消息", description = "发送微信模板消息给指定用户") | ||
| @PostMapping("/template") | ||
| @PreAuthorize("hasAuthority('wechat:account:edit')") |
There was a problem hiding this comment.
/wechat/messages/* 发送消息接口当前复用 wechat:account:edit 权限;按权限标识规范(模块:资源:操作),该接口更符合 wechat:message:send(或 wechat:message:add)这类“message”资源的操作权限。建议新增独立的按钮/API 权限并在 Flyway 菜单初始化中补齐,避免把“账号编辑”权限扩大为“消息发送”权限,便于最小权限控制。
| @Data | ||
| @EqualsAndHashCode(callSuper = true) | ||
| public static class ProductDetailVO extends Product { | ||
|
|
||
| private List<SkuTargetVO> skuTargets; | ||
| } |
There was a problem hiding this comment.
ProductDetailVO 继承了 Product 实体类,会把 createdBy、delFlag 等领域/持久化字段一并暴露到公开接口返回值中,这与 PR 描述里“隐藏内部元数据、删除标记等字段”的目标相冲突,也容易造成不必要的数据泄露。建议改为独立的 DTO(只声明需要对外暴露的字段),或至少通过 @JsonIgnoreProperties/@JsonIgnore 明确屏蔽这些内部字段,而不是继承实体。
| private static final String ACTIVE_SKU_STATUS = "active"; | ||
| private static final Integer ENABLED_TARGET_STATUS = 1; |
There was a problem hiding this comment.
这里用 ENABLED_TARGET_STATUS = 1 属于硬编码魔法值;仓库里已有通用 Status 枚举(0=禁用/1=启用),并且同模块其他查询也使用了 Status.ENABLED.getCode()。建议改为复用 Status.ENABLED.getCode()(或同等常量)以避免状态语义漂移、提升可读性。
变更说明
GlobalResult。content为空导致的 NPE,并改用日志记录异常。iframe增加 HTTPS 白名单校验,并保留文章详情页的受控v-html使用。.gitignore。关联规范
.github/instructions/permission-conventions.instructions.md,.github/instructions/springboot.instructions.md,.github/instructions/frontend-nuxt-patterns.instructions.md范围说明
本 PR 只包含根仓库
rymcu/mortise的审查修复;商业子模块mortise-commerce、mortise-payment以及其他子模块改动没有纳入本次提交,需要按各自仓库独立提交和推送。自检清单
验证
git diff --cached --checkmvn -pl mortise-wechat,mortise-product/mortise-product-api -am clean compile -DskipTestspnpm --filter @mortise/site lintpnpm --filter @mortise/site typecheck