#### What type of PR is this?
/kind bug
/area core
/milestone 2.21.x
#### What this PR does / why we need it:
This PR fixes the always show of ghost user in post contributors.
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/7710
#### Does this PR introduce a user-facing change?
```release-note
修复文章贡献者中始终显示已删除用户的问题
```
#### What type of PR is this?
/kind improvement
/area plugin
/milestone 2.21.x
#### What this PR does / why we need it:
This PR restores context ClassLoader mangement during plugin lifecycle to prevent resource leak.
Meanwhile, it also fixes Class initialization error when starting plugins.
Superseds https://github.com/halo-dev/halo/pull/7725
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind bug
/area plugin
/milestone 2.21.x
#### What this PR does / why we need it:
This PR fixes the problem that loading resources from class path during static initialization doesn't work.
#### Does this PR introduce a user-facing change?
```release-note
修复部分场景下无法正常启动插件的问题
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.21.x
#### What this PR does / why we need it:
This PR allows ListResult to be deserialized with JSON. So we can resolve ListResult response of APIs correctly.
#### Does this PR introduce a user-facing change?
```release-note
None
```
* Add 'hidden' field to comment and reply requests
Signed-off-by: Ryan Wang <i@ryanc.cc>
* Add support for filtering comments with hidden
* Specify hidden=false and approved=true for anonymous users
* Set default hidden flag only if null in comments
* Add 'private reply' option to comment modals
* Add private tag for hidden comments and replies
* Allow hiding comments only
* Enhance comment visibility logic to allow owners to view hidden comments
* Remove hidden input for reply form
Signed-off-by: Ryan Wang <i@ryanc.cc>
* Refine i18n
Signed-off-by: Ryan Wang <i@ryanc.cc>
---------
Signed-off-by: Ryan Wang <i@ryanc.cc>
Co-authored-by: John Niang <johnniang@foxmail.com>
#### What type of PR is this?
/area core
/area ui
/milestone 2.21.x
/kind feature
#### What this PR does / why we need it:
Optimize comment notification template to support rich text rendering
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/area code
/milestone 2.21.x
/kind improvement
#### What this PR does / why we need it:
Comments are allowed to contain `s` tags and `code` tags with class attributes for the following reasons:
1. `s`: The comment component uses tiptap editor's [strikethrough extension](https://tiptap.dev/docs/editor/extensions/marks/strike#:~:text=while%20you%20type.-,Restrictions,-The%20extension%20will) which enforces the use of `s` tags for strikethrough text and cannot be changed.
2. `code[class]`: Used for code highlighting (class="language-*")
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind bug
/area core
/milestone 2.21.x
#### What this PR does / why we need it:
This PR replaces the dependency `thymeleaf-spring6` to apply the memory leak fix of <https://github.com/halo-dev/thymeleaf/pull/1>.
Please note that this is a temporary fix, and we would revert this PR after Thymeleaf official released a new version including my fix.
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/7289
#### Special notes for your reviewer:
1. Execute command ab -c 100 -n 1000 -H 'Accept: text/html' -H 'Cache-Control: no-cache' http://localhost:8090/ and then press Ctrl + C to stop the thread.
2. See logs in Halo
#### Does this PR introduce a user-facing change?
```release-note
修复在特定情况下模板引擎可能出现内存泄漏的问题
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.21.x
#### What this PR does / why we need it:
This PR checks if the contents of comment and reply are valid before persistence to prevent users from XSS attacks.
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/7675
#### Special notes for your reviewer:
Try to comment or reply with the contents from <https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html>.
#### Does this PR introduce a user-facing change?
```release-note
检测评论和回复内容是否合法以防止 XSS 攻击
```
#### What type of PR is this?
/area core
/kind improvement
/milestone 2.21.x
#### What this PR does / why we need it:
This PR optimizes SEO tag generation with the following changes:
1. Site description and keywords settings now only apply to the homepage and are no longer inserted on other pages.
2. Added meta description tags for category archive pages, using the category description as content.
3. Improved the help text descriptions for SEO options in system settings.
#### Which issue(s) this PR fixes:
Fixes#7662
#### Does this PR introduce a user-facing change?
```release-note
优化页面的 SEO 标签的生成
```
#### What type of PR is this?
/kind feature
/kind api-change
/area core
/milestone 2.21.x
#### What this PR does / why we need it:
This PR adds a new endpoint `POST /login/social/{auth_provider_name}?remember-me=true` to make the social login support remember-me mechanism.
#### Does this PR introduce a user-facing change?
```release-note
支持社交登录时选择是否保持登录
```
#### What type of PR is this?
/area core
/milestone 2.21.x
#### What this PR does / why we need it:
Bump all preset plugins and theme version
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.21.x
#### What this PR does / why we need it:
This PR refactors posts query to reduce database queries significantly.
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/7593
Supersedes https://github.com/halo-dev/halo/pull/7644
#### Does this PR introduce a user-facing change?
```release-note
优化首页、归档页加载速度
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.21.x
#### What this PR does / why we need it:
This PR sets timeout on notification trigger to make sure the procedure won't getting stuck forever.
#### Does this PR introduce a user-facing change?
```release-note
修复运行过程中通知器可能失效的问题
```
#### What type of PR is this?
/area ui
/kind feature
/milestone 2.21.x
#### What this PR does / why we need it:
Add thumbnail records viewing feature. The main goal is to keep track of failed thumbnail generations, making it easier to check if thumbnails were generated correctly and retry if needed.
<img width="1009" height="859" alt="image" src="https://github.com/user-attachments/assets/d968e416-0b88-45bf-a554-a0c1abcf97a0" />
<img width="1014" height="952" alt="image" src="https://github.com/user-attachments/assets/c5d1a11b-7acc-4ab5-a2da-cf9467cb6b70" />
#### Which issue(s) this PR fixes:
Fixes #
#### Special notes for your reviewer:
#### Does this PR introduce a user-facing change?
```release-note
支持查看附件缩略图记录
```
#### What type of PR is this?
/kind chore
/area editor
#### What this PR does / why we need it:
升级 tiptap 至 2.24.1
#### Does this PR introduce a user-facing change?
```release-note
升级 tiptap 至 2.24.1
```
What type of PR is this?
/kind bug
/area core
/milestone 2.21.x
What this PR does / why we need it:
Prevents published post view counts from being incorrectly increased when previewing posts in the admin panel.
Previously, the preview mode would load the tracking script, which resulted in inflated view counts. This PR adds a condition to detect preview mode and disables the tracking logic to avoid counting views for unpublished content.
Does this PR introduce user-facing changes?
```release-note
文章预览页面不再统计访问数据
```
#### What type of PR is this?
/kind cleanup
/area core
/milestone 2.21.x
#### What this PR does / why we need it:
This PR removes unused JPA dependency to reduce application size about 14.6% off.
```bash
# Before
❯ ll application/build/libs
total 123M
-rw-r--r--. 1 johnniang johnniang 123M Jun 13 15:37 halo-2.21.0-SNAPSHOT.jar
-rw-r--r--. 1 johnniang johnniang 64 Jun 13 15:37 halo-2.21.0-SNAPSHOT.jar.sha256
```
```bash
# After
❯ ll application/build/libs
total 105M
-rw-r--r--. 1 johnniang johnniang 105M Jun 13 15:36 halo-2.21.0-SNAPSHOT.jar
-rw-r--r--. 1 johnniang johnniang 64 Jun 13 15:36 halo-2.21.0-SNAPSHOT.jar.sha256
```
#### Does this PR introduce a user-facing change?
```release-note
移除无用的依赖,软件包的体积减少近 15%
```
#### What type of PR is this?
/kind cleanup
/area core
/milestone 2.21.x
#### What this PR does / why we need it:
This PR removes deprecated Subscritpion and Thumbnail migrations.
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/area ui
/kind improvement
/milestone 2.21.x
#### What this PR does / why we need it:
Update attachment policy form using new configMap API
#### Does this PR introduce a user-facing change?
```release-note
None
```
* Provide storage policy config APIs to make it easy to use
* Update api client
Signed-off-by: Ryan Wang <i@ryanc.cc>
---------
Signed-off-by: Ryan Wang <i@ryanc.cc>
Co-authored-by: Ryan Wang <i@ryanc.cc>
* Add support for configuring my preferences
* Update api client
Signed-off-by: Ryan Wang <i@ryanc.cc>
* Update api client
Signed-off-by: Ryan Wang <i@ryanc.cc>
---------
Signed-off-by: Ryan Wang <i@ryanc.cc>
Co-authored-by: Ryan Wang <i@ryanc.cc>
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.21.x
#### What this PR does / why we need it:
This PR allows users to set external URL at setup page without performing a restart.
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/7479
#### Special notes for your reviewer:
1. Try to start Halo instance with a fresh environment.
2. Request index page and you will be redirected to setup page.
3. Check if the external URL is equal to the base URL in your browser.
4. Try to change external URL and finish the setup process.
5. Login to console and check the external URL in overview page.
#### Does this PR introduce a user-facing change?
```release-note
支持在初始化页面设置外部访问地址
```
#### What type of PR is this?
/kind bug
/area core
/milestone 2.21.x
#### What this PR does / why we need it:
This PR fixes the problem of not working for relative permalink caused by <https://github.com/halo-dev/halo/pull/7459>.
#### Special notes for your reviewer:
1. Try to start Halo instance with `halo.use-absolute-permalink=false` and check the permalinks of posts and attachments.
1. Try to start Halo instance with `halo.use-absolute-permalink=true` and check the permalinks of posts and attachments.
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind cleanup
/area core
/milestone 2.21.x
#### What this PR does / why we need it:
This PR corrects location of LogoutHandler instead of in LogoutSuccessHandler. LogoutHanadler should be invoked before LogoutSuccessHandler.
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind improvement
#### What this PR does / why we need it:
This PR adds UserLoginEvent and UserLogoutEvent which are shared to plugins.
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/7436
#### Does this PR introduce a user-facing change?
```release-note
添加用户登录/登出事件
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.21.x
#### What this PR does / why we need it:
This PR bumps Spring Boot to [3.5.0](https://github.com/spring-projects/spring-boot/releases/tag/v3.5.0).
#### Does this PR introduce a user-facing change?
```release-note
升级依赖 Spring Boot 至 3.5.0
```
* Add support for configuring external URL online
* Fix the problem of timeout on external URL initialization
* Add external URL editing capability to overview page
Signed-off-by: Ryan Wang <i@ryanc.cc>
---------
Signed-off-by: Ryan Wang <i@ryanc.cc>
Co-authored-by: Ryan Wang <i@ryanc.cc>
#### What type of PR is this?
/kind bug
/area core
/milestone 2.21.x
#### What this PR does / why we need it:
This PR check if the locale is undetermined during resolving locale. Or it will cause the error below if locale is `und`:
```java
2025-05-21T17:28:45.953+08:00 ERROR 58760 --- [undedElastic-14] o.s.w.s.adapter.HttpWebHandlerAdapter : [c1824fa5-1] 500 Server Error for HTTP GET "/"
org.thymeleaf.exceptions.TemplateOutputException: An error happened during template rendering
at org.thymeleaf.engine.OutputTemplateHandler.handleText(OutputTemplateHandler.java:75) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.AbstractTemplateHandler.handleText(AbstractTemplateHandler.java:221) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.ProcessorTemplateHandler.handleText(ProcessorTemplateHandler.java:587) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.Text.beHandled(Text.java:97) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.Model.process(Model.java:300) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.GatheringModelProcessable.process(GatheringModelProcessable.java:78) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.ProcessorTemplateHandler.queueProcessable(ProcessorTemplateHandler.java:2106) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.ProcessorTemplateHandler.handleCloseElement(ProcessorTemplateHandler.java:1642) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.CloseElementTag.beHandled(CloseElementTag.java:139) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.Model.process(Model.java:300) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.OpenElementTagModelProcessable.process(OpenElementTagModelProcessable.java:110) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.ProcessorTemplateHandler.queueProcessable(ProcessorTemplateHandler.java:2106) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.ProcessorTemplateHandler.handleOpenElement(ProcessorTemplateHandler.java:1559) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.OpenElementTag.beHandled(OpenElementTag.java:205) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.TemplateModel.process(TemplateModel.java:155) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.ThrottledTemplateProcessor.process(ThrottledTemplateProcessor.java:235) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.ThrottledTemplateProcessor.process(ThrottledTemplateProcessor.java:200) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.spring6.SpringWebFluxTemplateEngine$StreamThrottledTemplateProcessor.process(SpringWebFluxTemplateEngine.java:720) ~[thymeleaf-spring6-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.spring6.SpringWebFluxTemplateEngine.lambda$createChunkedStream$2(SpringWebFluxTemplateEngine.java:269) ~[thymeleaf-spring6-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at reactor.core.publisher.FluxGenerate$GenerateSubscription.slowPath(FluxGenerate.java:271) ~[reactor-core-3.7.5.jar:3.7.5]
at reactor.core.publisher.FluxGenerate$GenerateSubscription.request(FluxGenerate.java:213) ~[reactor-core-3.7.5.jar:3.7.5]
at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.request(FluxPeekFuseable.java:144) ~[reactor-core-3.7.5.jar:3.7.5]
at reactor.core.publisher.FluxSubscribeOn$SubscribeOnSubscriber.requestUpstream(FluxSubscribeOn.java:131) ~[reactor-core-3.7.5.jar:3.7.5]
at reactor.core.publisher.FluxSubscribeOn$SubscribeOnSubscriber.onSubscribe(FluxSubscribeOn.java:124) ~[reactor-core-3.7.5.jar:3.7.5]
at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onSubscribe(FluxPeekFuseable.java:178) ~[reactor-core-3.7.5.jar:3.7.5]
at reactor.core.publisher.FluxGenerate.subscribe(FluxGenerate.java:85) ~[reactor-core-3.7.5.jar:3.7.5]
at reactor.core.publisher.InternalFluxOperator.subscribe(InternalFluxOperator.java:68) ~[reactor-core-3.7.5.jar:3.7.5]
at reactor.core.publisher.FluxSubscribeOn$SubscribeOnSubscriber.run(FluxSubscribeOn.java:194) ~[reactor-core-3.7.5.jar:3.7.5]
at reactor.core.scheduler.BoundedElasticThreadPerTaskScheduler$SchedulerTask.run(BoundedElasticThreadPerTaskScheduler.java:1013) ~[reactor-core-3.7.5.jar:3.7.5]
at java.base/java.lang.VirtualThread.run(VirtualThread.java:329) ~[na:na]
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Locale "" cannot be used as it does not specify a language. (template: "modules/layout" - line 12, col 49)
at org.thymeleaf.messageresolver.StandardMessageResolutionUtils.computeMessageResourceNamesFromBase(StandardMessageResolutionUtils.java:202) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.messageresolver.StandardMessageResolutionUtils.resolveMessagesForTemplate(StandardMessageResolutionUtils.java:69) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.messageresolver.StandardMessageResolver.resolveMessagesForTemplate(StandardMessageResolver.java:380) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.messageresolver.StandardMessageResolver.resolveMessage(StandardMessageResolver.java:282) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.messageresolver.StandardMessageResolver.resolveMessage(StandardMessageResolver.java:227) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.context.AbstractEngineContext.getMessage(AbstractEngineContext.java:134) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.standard.expression.MessageExpression.executeMessageExpression(MessageExpression.java:265) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.standard.expression.SimpleExpression.executeSimple(SimpleExpression.java:69) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.standard.expression.Expression.execute(Expression.java:109) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.standard.expression.Expression.execute(Expression.java:138) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.standard.processor.StandardUtextTagProcessor.doProcess(StandardUtextTagProcessor.java:87) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:74) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.processor.element.AbstractElementTagProcessor.process(AbstractElementTagProcessor.java:95) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.util.ProcessorConfigurationUtils$ElementTagProcessorWrapper.process(ProcessorConfigurationUtils.java:633) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.ProcessorTemplateHandler.handleOpenElement(ProcessorTemplateHandler.java:1314) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.OpenElementTag.beHandled(OpenElementTag.java:205) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.TemplateModel.process(TemplateModel.java:136) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.TemplateManager.process(TemplateManager.java:519) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.util.LazyProcessingCharSequence.writeUnresolved(LazyProcessingCharSequence.java:85) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.util.AbstractLazyCharSequence.write(AbstractLazyCharSequence.java:103) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.AbstractTextualTemplateEvent.writeContent(AbstractTextualTemplateEvent.java:224) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.Text.write(Text.java:78) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.thymeleaf.engine.OutputTemplateHandler.handleText(OutputTemplateHandler.java:71) ~[thymeleaf-3.1.3.RELEASE.jar:3.1.3.RELEASE]
... 29 common frames omitted
```
#### Does this PR introduce a user-facing change?
```release-note
修复因 Locale 解析错误导致无法访问页面的问题
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.21.x
#### What this PR does / why we need it:
This PR removes `/uploads/**` from static resources to make it protected by Halo security.
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.21.x
#### What this PR does / why we need it:
This PR sets Java 21 as minimal version. After doing that, Halo can only run on Java 21 or newer version.
Fortunately, all plugins and themes won't be affected by the restriction.
> https://docs.gradle.org/current/userguide/toolchains.html#sec:release-flag-toolchain
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/6867
#### Does this PR introduce a user-facing change?
```release-note
[Action Required] 更新最低运行环境为 Java 21
```