#### What type of PR is this?
/kind cleanup
/area core
/milestone 2.17.x
#### What this PR does / why we need it:
清理已经过时很久的 yaml extension 声明
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind bug
/area plugin
/milestone 2.17.x
#### What this PR does / why we need it:
修复当插件入口文件的缓存目录被系统清理后会导致一直无法加载的问题
原问题复现步骤:
1. 登录后刷新页面,此时缓存目录被创建
2. 删除缓存目录后就会提示文件不存在然后导致插件入口文件一致无法加载直到重启 Halo
#### Which issue(s) this PR fixes:
Fixes#6226
#### Does this PR introduce a user-facing change?
```release-note
修复当插件入口文件的缓存目录被系统清理后会导致一直无法加载的问题
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.17.0
#### What this PR does / why we need it:
This PR provides a configuration property to control whether two-factor authentication is disabled. e.g.:
```yaml
halo:
security:
two-factor-auth:
disabled: true | false # Default is false.
```
#### Which issue(s) this PR fixes:
Fixes#5640
#### Special notes for your reviewer:
1. Enable 2FA and configure TOTP
2. Disable 2FA by configuring property above
3. Restart Halo and try to login
#### Does this PR introduce a user-facing change?
```release-note
支持通过配置的方式全局禁用二步验证
```
#### What type of PR is this?
/kind feature
/area core
/milestone 2.17.x
#### What this PR does / why we need it:
提供对模板中 halo footer 标签内容的扩展点以支持扩展页脚内容
#### Which issue(s) this PR fixes:
Fixes#6189
#### Does this PR introduce a user-facing change?
```release-note
提供对模板中 halo footer 标签内容的扩展点以支持扩展页脚内容
```
#### What type of PR is this?
/kind feature
/area core
/area theme
/milestone 2.17.x
#### What this PR does / why we need it:
支持在主题中检查已启动的插件是否符合指定的版本要求,以便可以在某些功能可以正常工作时才渲染
示例
```html
<p th:if="${pluginFinder.available('plugin-search-widget', '>=2.3.0')}>
<!-- do something -->
</p>
```
#### Does this PR introduce a user-facing change?
```release-note
支持在主题中检查已启动的插件是否符合指定的版本要求
```
#### What type of PR is this?
/kind bug
/area core
/milestone 2.17.0
#### What this PR does / why we need it:
This PR adds missed type to HaloDocument while converting.
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/6235
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind feature
/kind api-change
/area core
/area plugin
/milestone 2.17.0
#### What this PR does / why we need it:
This PR creates a SearchService and makes it invokable for plugins.
#### Special notes for your reviewer:
1. Create a plugin
2. Publish all publication into Maven local repository by executing `./gradlew publishAllPublicationsToMavenLocalRepository`
3. Use `2.17.0-SNAPSHOT` as dependency version and refresh dependencies
4. Try to use the SearchService to search something.
#### Does this PR introduce a user-facing change?
```release-note
为插件提供全文搜索服务
```
#### What type of PR is this?
/kind feature
/area core
/milestone 2.17.x
#### What this PR does / why we need it:
This PR add support for allowing plugin to listen the event that the plugin has started. Below is an example of listening the event in plugin:
```java
@EventListener
void onPluginStartedEvent(PluginStartedEvent event) {
// do something.
}
```
See https://github.com/halo-dev/halo/issues/5339#issuecomment-2199220068 for more.
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/5339#issuecomment-2199220068
#### Special notes for your reviewer:
1. Create a plugin, add the listener above and write some logs
2. Build and install the plugin
3. Start plugin and see the logs you wrote
#### Does this PR introduce a user-facing change?
```release-note
支持在插件中监听已启动事件
```
#### What type of PR is this?
/area core
/milestone 2.17.x
#### What this PR does / why we need it:
由于2.17.0 修改了 listAll 的实现导致出现了不兼容 Sort 参数为 null 的情况,考虑到给开发者适应的时间因此先兼容并给出警告日志
see also #6219
#### Which issue(s) this PR fixes:
Fixes#6219
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.17.x
#### What this PR does / why we need it:
新增 LoginHandlerEnhancer 用于 Halo 扩展登录成功或失败后的处理逻辑如 RememberMe 和设备管理等
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/area core
/kind improvement
/milestone 2.17.x
#### What this PR does / why we need it:
更新预设插件的版本。
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind bug
/area core
/area plugin
/milestone 2.17.x
#### What this PR does / why we need it:
This PR makes sure the method `cache#put` is called before the event is published to avoid the event listener to fetch the old value from the cache.
The problem was introduced by <https://github.com/halo-dev/halo/pull/6141>.
#### Which issue(s) this PR fixes:
Fixes#6213
#### Does this PR introduce a user-facing change?
```release-note
修复在插件配置变更监听器中始终获取到旧数据的问题
```
#### What type of PR is this?
/kind improvement
/area core
/area plugin
#### What this PR does / why we need it:
修复当启动插件遇到 Error 级别的错误时会导致 API 被挂起无法终止的问题
```
- Throwable
- Error
- Exception
```
see #6192 for more details
#### Which issue(s) this PR fixes:
Fixes#6192
#### Does this PR introduce a user-facing change?
```release-note
修复当启动插件遇到 Error 级别的错误时会导致 API 被挂起无法终止的问题
```
#### What type of PR is this?
/kind bug
/area core
/milestone 2.17.x
#### What this PR does / why we need it:
修复文章关联或取消关联隐藏分类后显示不正确的问题
#### Which issue(s) this PR fixes:
Fixes#6194Fixes#6195
#### Does this PR introduce a user-facing change?
```release-note
修复文章关联或取消关联隐藏分类后显示不正确的问题
```
#### What type of PR is this?
/area core
/kind api-change
/milestone 2.17.x
#### What this PR does / why we need it:
移除内置的页面静态缓存功能,后续将由 https://github.com/halo-sigs/plugin-page-cache 插件提供。
#### Which issue(s) this PR fixes:
Fixes#5639
#### Special notes for your reviewer:
#### Does this PR introduce a user-facing change?
```release-note
移除内置的页面静态缓存功能,后续由 https://github.com/halo-sigs/plugin-page-cache 插件提供。
```
#### What type of PR is this?
/kind bug
/area core
/area theme
/milestone 2.17.x
#### What this PR does / why we need it:
修复获取隐藏分类的面包屑路径不正确的问题
#### Which issue(s) this PR fixes:
Fixes#6197
#### Does this PR introduce a user-facing change?
```release-note
修复获取隐藏分类的面包屑路径不正确的问题
```
#### What type of PR is this?
/kind bug
/area core
/milestone 2.17.x
#### What this PR does / why we need it:
In PR <https://github.com/halo-dev/halo/pull/6130>, I changed the api group of PAT and 2FA endpoints, but I forgot to change the corresponding role templates. So other users except admin will encounter 403 error like <https://github.com/halo-dev/halo/issues/6199>.
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/6199
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/area core
/kind improvement
/milestone 2.17.x
#### What this PR does / why we need it:
将扩展点定义和扩展点的描述文件改为简体中文。
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind cleanup
/area core
/milestone 2.17.x
#### What this PR does / why we need it:
In <https://github.com/halo-dev/halo/pull/5386>, I marked ExtensionComponentsFinder as deprecated. Four months have passed, it's time to remove it.
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind failing-test
/area core
/milestone 2.17.x
#### What this PR does / why we need it:
This PR allows retrying to operate on posts when optimistic locking errors occur.
#### Which issue(s) this PR fixes:
Fixes#6186
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.17.x
#### What this PR does / why we need it:
优化触发 Extension Watch 方法(onAdd/onUpdate/onDelete)时的参数始终为真实类型避免使用时进行类型转换
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind feature
/area core
/milestone 2.17.x
#### What this PR does / why we need it:
为分类 Finder 提供获取指定节点的面包屑路径方法
#### Which issue(s) this PR fixes:
Fixes#3374
#### Does this PR introduce a user-facing change?
```release-note
为分类 Finder 提供获取指定节点的面包屑路径方法
```
#### What type of PR is this?
/kind bug
/area core
/milestone 2.17.x
#### What this PR does / why we need it:
Some users encountered 2FA required issue after upgrading Halo 2.16, because they enabled 2FA but didn't configure TOTP before. The issue was introduced by <https://github.com/halo-dev/halo/pull/6005>.
This PR checks if TOTP configured to determine whether 2FA is required.
#### Does this PR introduce a user-facing change?
```release-note
修复在没有配置 TOTP 验证器的情况下仍被要求二步验证的问题
```
#### What type of PR is this?
/kind bug
/area core
/milestone 2.17.x
#### What this PR does / why we need it:
修复查询分类的排序条件拼写错误导致的错误
#### Which issue(s) this PR fixes:
Fixes#6171
#### Does this PR introduce a user-facing change?
```release-note
修复查询分类的排序条件拼写错误导致的错误
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.17.x
#### What this PR does / why we need it:
Use top-level interface `org.springframework.session.ReactiveFindByIndexNameSessionRepository` for being compatible with other session repositories.
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/6159
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind feature
/area plugin
/area core
/milestone 2.17.x
#### What this PR does / why we need it:
增强插件配置的缓存管理
1. 通过 SettingFetcher/ReactiveSettingFetcher 获取插件配置可以不在考虑获取数据的性能问题,当数据变更后会自动更新缓存
2. 现在你可以通过在插件中监听 `PluginConfigUpdatedEvent` 事件来做一些处理,它会在用户更改插件配置后被触发
#### Does this PR introduce a user-facing change?
```release-note
增强插件配置的缓存管理并支持通过监听 `PluginConfigUpdatedEvent` 事件做一些特殊处理
```
#### What type of PR is this?
/kind improvement
/kind api-change
/area core
#### What this PR does / why we need it:
This PR refactors ExtensionGetter implementation to add a support of enabling extension point(s). Here is an example of data field of `system` config map:
```json
{
"data": {
"extensionPointEnabled": "{ \"search-engine\": [\"search-engine-algolia\"]}"
},
```
> 1. The `search-engine` is a name of extension point definition.
> 2. The `search-engine-algolia` is a name of extension definition.
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind feature
/area core
/milestone 2.17.x
#### What this PR does / why we need it:
此次变更为文章分类引入了一个新的 `preventParentPostCascadeQuery` 布尔属性,用于控制分类及其子分类下的文章显示方式。具体变更包括:
- 在分类结构中增加了 `preventParentPostCascadeQuery` 属性。
- 当分类的 `preventParentPostCascadeQuery` 属性设置为 `true` 时,该分类的文章数量不会汇总到父分类中。
- 更新了树结构遍历逻辑,以支持对 `preventParentPostCascadeQuery` 属性的处理。
- 确保独立分类中的文章显示受控,不向上级分类进行聚合。
- 增加了相应的测试用例,以验证在不同树结构中 `preventParentPostCascadeQuery` 属性的功能性。
#### Which issue(s) this PR fixes:
Fixes#5663Fixes#4923
Fixes https://github.com/halo-dev/halo/issues/3418
#### Does this PR introduce a user-facing change?
```release-note
新增独立分类选项用于控制关联的子分类下的文章显示以提供更灵活的内容管理方式
```
#### What type of PR is this?
/kind feature
/area core
/milestone 2.17.x
#### What this PR does / why we need it:
This PR adds patch method for all extensions API.
Patch example:
```bash
http -a admin:admin PATCH http://localhost:8090/apis/plugin.halo.run/v1alpha1/plugins/app-store-integration \
Content-Type:application/json-patch+json \
--raw='[{"op": "replace", "path": "/spec/enabled", "value": false}]'
```
#### Which issue(s) this PR fixes:
Fixes#2311
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind feature
/area core
/milestone 2.17.x
#### What this PR does / why we need it:
支持在分类上为关联的文章统一设置渲染模板
现在文章的模板生效顺序为:
1. 文章关联的分类上设置的文章模板,如果有多个则选择第一个
2. 文章上设置的自定义模板
3. 文章的默认模板
#### Which issue(s) this PR fixes:
Fixes#6101
#### Does this PR introduce a user-facing change?
```release-note
支持在分类上为关联的文章统一设置渲染模板
```
#### What type of PR is this?
/kind bug
/area core
/milestone 2.17.x
#### What this PR does / why we need it:
修复已验证邮箱可以重复的问题
如果出现多个重复的已验证邮箱,则只保留一个其他的设置为未验证
#### Does this PR introduce a user-facing change?
```release-note
修复已验证邮箱可以重复的问题
```
#### What type of PR is this?
/kind feature
/area core
/area plugin
#### What this PR does / why we need it:
This PR enhance usage of SharedEvent annotation to add support for publishing events among plugins.
#### How to test?
1. Clone repository https://github.com/halo-dev/plugin-starter
2. Change build.gradle as following:
```gradle
dependencies {
implementation platform('run.halo.tools.platform:plugin:2.17.0-SNAPSHOT')
```
3. Change StarterPlugin as following:
```java
@Component
public class StarterPlugin extends BasePlugin {
private final ApplicationContext appContext;
public StarterPlugin(PluginContext pluginContext, ApplicationContext appContext) {
super(pluginContext);
this.appContext = appContext;
}
@Override
public void start() {
appContext.publishEvent(new PostDeletedEvent(this, "fake-plugin"));
}
@Override
public void stop() {
}
@EventListener(PostDeletedEvent.class)
public void onApplicationEvent(PostDeletedEvent event) {
System.out.println("Post deleted event received in plugin: " + event.getName());
}
}
```
4. Add a listener to Halo core
```java
@EventListener(PostDeletedEvent.class)
public void onApplicationEvent(PostDeletedEvent event) {
System.out.println("Post deleted event received in core: " + event.getName());
}
```
5. Build plugin and install plugin
6. Enable the plugin and see the result
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind regression
/area plugin
/milestone 2.17.x
#### What this PR does / why we need it:
This PR reverts changes of generating bundle resource version in <https://github.com/halo-dev/halo/pull/6028>.
Because the changes were adapted realtime change of bundle files for plugin developers in plugin development runtime mode, but I ignored it.
#### Special notes for your reviewer:
1. Try to start Halo in plugin development mode
2. Change and rebuild ui resources
3. Refresh console and check the result
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind bug
/area core
/milestone 2.17.x
#### What this PR does / why we need it:
When initialized for the first time, the folder `${halo.work-dir}/themes` does not exist, resulting in the `themes` path being ignored when invoking `themeRootResource.createRelative(themeName + "/templates/assets/");`. It works very well after restarting.
This PR fixes the problem by resolving theme resource directly rather than delegating to PathResourceResolver.
#### Which issue(s) this PR fixes:
Fixes#6048
#### Does this PR introduce a user-facing change?
```release-note
修复首次初始化后无法正常访问主题资源的问题
```
#### What type of PR is this?
/kind failing-test
/area core
/milestone 2.17.x
#### What this PR does / why we need it:
I wrongly invoked `Arraylist#add`(probes) method in multi threads. So the unit test was unstable and might encounter the problem as follows:
```java
Expected :1
Actual :0
<Click to see difference>
org.opentest4j.AssertionFailedError: expected: <1> but was: <0>
at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:151)
at org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:132)
at org.junit.jupiter.api.AssertEquals.failNotEqual(AssertEquals.java:197)
at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:166)
at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:161)
at org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:632)
at run.halo.app.core.extension.service.impl.PluginServiceImplTest$BundleCacheTest.concurrentComputeBundleFileIfAbsent(PluginServiceImplTest.java:460)
```
See https://github.com/halo-dev/halo/actions/runs/9382059472/job/25832681545 for more.
This PR moves the invocation outside thread tasks.
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind bug
/area core
/milestone 2.16.x
#### What this PR does / why we need it:
补充缺失的系统设置默认值。
#### Does this PR introduce a user-facing change?
```release-note
修复系统设置未保存导致无法正常注册的问题
```
#### What type of PR is this?
/kind bug
/area core
/area plugin
/milestone 2.16.0
#### What this PR does / why we need it:
Before the PR, any user can generate bundle files by providing random query param `v` while requesting bundle files.
This PR refactors the whole bundle file generation method.
1. Do nothing if users provide arbitrary bundle file version
2. Better lock for writing bundle files if not exist
#### Special notes for your reviewer:
1. Request `http://localhost:8090/apis/api.console.halo.run/v1alpha1/plugins/-/bundle.js?v=xyz`
2. Check if the file `xyz.js` in folder `$TMPDIR/halo-plugin-bundle**`
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind improvement
/area core
/kind milestone 2.16.x
#### What this PR does / why we need it:
使用索引机制来查询扩展点定义
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind improvement
/area core
#### What this PR does / why we need it:
This PR unifies cache control for static resources.
Example configuration of cache control:
```yaml
spring:
web:
resources:
cache:
cachecontrol:
no-cache: true
no-store: true
use-last-modified: false
```
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/6003
#### Special notes for your reviewer:
1. Run with `default` and `dev` profiles respectively.
2. See the difference of the `Cache-Control` header in HTTP response
#### Does this PR introduce a user-facing change?
```release-note
优化 HTTP 缓存控制
```