diff --git a/README.md b/README.md
index 3b18c4e88a..313118682f 100755
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-
-
+
+
@@ -14,7 +14,7 @@
-官网
+官网
文档
社区
Gitee
@@ -26,7 +26,7 @@
## 快速开始
```bash
-docker run -it -d --name halo -p 8090:8090 -v ~/.halo2:/root/.halo2 halohub/halo:2.11
+docker run -it -d --name halo -p 8090:8090 -v ~/.halo2:/root/.halo2 halohub/halo:2.12
```
以上仅作为体验使用,详细部署文档请查阅:
@@ -40,8 +40,7 @@ docker run -it -d --name halo -p 8090:8090 -v ~/.halo2:/root/.halo2 halohub/halo
## 生态
-可访问 [官方应用市场](https://halo.run/store/apps) 或 [awesome-halo 仓库](https://github.com/halo-sigs/awesome-halo) 查看已经适用于 Halo 2.x 的主题和插件,以及适用于 Halo
-1.x 的相关仓库。
+可访问 [官方应用市场](https://www.halo.run/store/apps) 或 [awesome-halo 仓库](https://github.com/halo-sigs/awesome-halo) 查看适用于 Halo 2.x 的主题和插件。
## 许可证
diff --git a/application/src/main/java/run/halo/app/notification/endpoint/UserNotificationPreferencesEndpoint.java b/application/src/main/java/run/halo/app/notification/endpoint/UserNotificationPreferencesEndpoint.java
index 90948904d0..9916d90ed5 100644
--- a/application/src/main/java/run/halo/app/notification/endpoint/UserNotificationPreferencesEndpoint.java
+++ b/application/src/main/java/run/halo/app/notification/endpoint/UserNotificationPreferencesEndpoint.java
@@ -5,17 +5,20 @@
import static org.springdoc.core.fn.builders.parameter.Builder.parameterBuilder;
import static org.springdoc.core.fn.builders.requestbody.Builder.requestBodyBuilder;
+import com.fasterxml.jackson.core.type.TypeReference;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Supplier;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.experimental.Accessors;
+import org.apache.commons.lang3.StringUtils;
import org.springdoc.webflux.core.fn.SpringdocRouteBuilder;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
@@ -25,12 +28,15 @@
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
import reactor.util.function.Tuples;
+import run.halo.app.core.extension.Role;
import run.halo.app.core.extension.endpoint.CustomEndpoint;
import run.halo.app.core.extension.notification.NotifierDescriptor;
import run.halo.app.core.extension.notification.ReasonType;
import run.halo.app.extension.Comparators;
import run.halo.app.extension.GroupVersion;
+import run.halo.app.extension.MetadataUtil;
import run.halo.app.extension.ReactiveExtensionClient;
+import run.halo.app.infra.utils.JsonUtils;
import run.halo.app.notification.UserNotificationPreference;
import run.halo.app.notification.UserNotificationPreferenceService;
@@ -135,10 +141,7 @@ private static Map toNameIndexMap(List collection,
Mono listReasonTypeNotifierMatrix(String username) {
return client.list(ReasonType.class, null, Comparators.defaultComparator())
- .map(reasonType -> new ReasonTypeInfo(reasonType.getMetadata().getName(),
- reasonType.getSpec().getDisplayName(),
- reasonType.getSpec().getDescription())
- )
+ .map(ReasonTypeInfo::from)
.collectList()
.flatMap(reasonTypes -> client.list(NotifierDescriptor.class, null,
Comparators.defaultComparator())
@@ -188,7 +191,23 @@ static class ReasonTypeNotifierMatrix {
private boolean[][] stateMatrix;
}
- record ReasonTypeInfo(String name, String displayName, String description) {
+ record ReasonTypeInfo(String name, String displayName, String description,
+ Set uiPermissions) {
+
+ public static ReasonTypeInfo from(ReasonType reasonType) {
+ var uiPermissions = Optional.of(MetadataUtil.nullSafeAnnotations(reasonType))
+ .map(annotations -> annotations.get(Role.UI_PERMISSIONS_ANNO))
+ .filter(StringUtils::isNotBlank)
+ .map(uiPermissionStr -> JsonUtils.jsonToObject(uiPermissionStr,
+ new TypeReference>() {
+ })
+ )
+ .orElse(Set.of());
+ return new ReasonTypeInfo(reasonType.getMetadata().getName(),
+ reasonType.getSpec().getDisplayName(),
+ reasonType.getSpec().getDescription(),
+ uiPermissions);
+ }
}
record NotifierInfo(String name, String displayName, String description) {
diff --git a/application/src/main/resources/extensions/notification.yaml b/application/src/main/resources/extensions/notification.yaml
index 23429a95ad..3fd11c9195 100644
--- a/application/src/main/resources/extensions/notification.yaml
+++ b/application/src/main/resources/extensions/notification.yaml
@@ -64,6 +64,9 @@ apiVersion: notification.halo.run/v1alpha1
kind: ReasonType
metadata:
name: new-comment-on-post
+ annotations:
+ rbac.authorization.halo.run/ui-permissions: |
+ [ "uc:posts:publish" ]
spec:
displayName: "我的文章收到新评论"
description: "如果有读者在你的文章下方留下了新的评论,你将会收到一条通知,告诉你有新的评论。
@@ -90,6 +93,9 @@ apiVersion: notification.halo.run/v1alpha1
kind: ReasonType
metadata:
name: new-comment-on-single-page
+ annotations:
+ rbac.authorization.halo.run/ui-permissions: |
+ [ "system:singlepages:manage" ]
spec:
displayName: "我的自定义页面收到新评论"
description: "当你创建的自定义页面收到新评论时,你将会收到一条通知,告诉你有新的评论。"
diff --git a/application/src/main/resources/extensions/role-template-authenticated.yaml b/application/src/main/resources/extensions/role-template-authenticated.yaml
index 03055e067d..2c2bf3bd54 100644
--- a/application/src/main/resources/extensions/role-template-authenticated.yaml
+++ b/application/src/main/resources/extensions/role-template-authenticated.yaml
@@ -127,7 +127,7 @@ metadata:
halo.run/hidden: "true"
rules:
- apiGroups: [ "api.security.halo.run" ]
- resources: [ "authentications", "authentications/totp" ]
+ resources: [ "authentications", "authentications/totp", "authentications/settings" ]
verbs: [ "*" ]
---
apiVersion: v1alpha1
diff --git a/console/packages/api-client/package.json b/console/packages/api-client/package.json
index a40dc7f91f..b84c70009f 100644
--- a/console/packages/api-client/package.json
+++ b/console/packages/api-client/package.json
@@ -1,6 +1,6 @@
{
"name": "@halo-dev/api-client",
- "version": "2.12.0",
+ "version": "2.13.0",
"description": "",
"scripts": {
"build": "unbuild",
diff --git a/console/packages/api-client/src/models/post-status.ts b/console/packages/api-client/src/models/post-status.ts
index dbc5bd93ad..b59635bcce 100644
--- a/console/packages/api-client/src/models/post-status.ts
+++ b/console/packages/api-client/src/models/post-status.ts
@@ -58,6 +58,12 @@ export interface PostStatus {
* @memberof PostStatus
*/
lastModifyTime?: string;
+ /**
+ *
+ * @type {number}
+ * @memberof PostStatus
+ */
+ observedVersion?: number;
/**
*
* @type {string}
diff --git a/console/packages/api-client/src/models/reason-type-info.ts b/console/packages/api-client/src/models/reason-type-info.ts
index 1008af2c5e..422b2cabdc 100644
--- a/console/packages/api-client/src/models/reason-type-info.ts
+++ b/console/packages/api-client/src/models/reason-type-info.ts
@@ -36,4 +36,10 @@ export interface ReasonTypeInfo {
* @memberof ReasonTypeInfo
*/
name?: string;
+ /**
+ *
+ * @type {Array}
+ * @memberof ReasonTypeInfo
+ */
+ uiPermissions?: Array;
}
diff --git a/console/packages/api-client/src/models/single-page-status.ts b/console/packages/api-client/src/models/single-page-status.ts
index 29c74e3594..6972c42374 100644
--- a/console/packages/api-client/src/models/single-page-status.ts
+++ b/console/packages/api-client/src/models/single-page-status.ts
@@ -58,6 +58,12 @@ export interface SinglePageStatus {
* @memberof SinglePageStatus
*/
lastModifyTime?: string;
+ /**
+ *
+ * @type {number}
+ * @memberof SinglePageStatus
+ */
+ observedVersion?: number;
/**
*
* @type {string}
diff --git a/console/packages/components/package.json b/console/packages/components/package.json
index 73795bee39..8eabb6dfa6 100644
--- a/console/packages/components/package.json
+++ b/console/packages/components/package.json
@@ -1,6 +1,6 @@
{
"name": "@halo-dev/components",
- "version": "2.12.0",
+ "version": "2.13.0",
"description": "",
"files": [
"dist"
diff --git a/console/packages/editor/package.json b/console/packages/editor/package.json
index dbdc069546..18a20617e8 100644
--- a/console/packages/editor/package.json
+++ b/console/packages/editor/package.json
@@ -1,6 +1,6 @@
{
"name": "@halo-dev/richtext-editor",
- "version": "2.12.0",
+ "version": "2.13.0",
"description": "Default editor for Halo",
"homepage": "https://github.com/halo-dev/halo/tree/main/console/packages/editor#readme",
"bugs": {
diff --git a/console/packages/editor/src/dev/App.vue b/console/packages/editor/src/dev/App.vue
index a8f26cd8f3..a9509019ad 100644
--- a/console/packages/editor/src/dev/App.vue
+++ b/console/packages/editor/src/dev/App.vue
@@ -112,6 +112,9 @@ const editor = useEditor({
ExtensionListKeymap,
ExtensionSearchAndReplace,
],
+ parseOptions: {
+ preserveWhitespace: true,
+ },
onUpdate: () => {
content.value = editor.value?.getHTML() + "";
},
diff --git a/console/packages/shared/package.json b/console/packages/shared/package.json
index 6269ac5fc3..10ba3b5ed7 100644
--- a/console/packages/shared/package.json
+++ b/console/packages/shared/package.json
@@ -1,6 +1,6 @@
{
"name": "@halo-dev/console-shared",
- "version": "2.12.0",
+ "version": "2.13.0",
"description": "",
"files": [
"dist"
diff --git a/console/packages/ui-plugin-bundler-kit/package.json b/console/packages/ui-plugin-bundler-kit/package.json
index d88d7409a8..b961b485d9 100644
--- a/console/packages/ui-plugin-bundler-kit/package.json
+++ b/console/packages/ui-plugin-bundler-kit/package.json
@@ -1,6 +1,6 @@
{
"name": "@halo-dev/ui-plugin-bundler-kit",
- "version": "2.12.0",
+ "version": "2.13.0",
"homepage": "https://github.com/halo-dev/halo/tree/main/console/packages/ui-plugin-bundler-kit#readme",
"bugs": {
"url": "https://github.com/halo-dev/halo/issues"
diff --git a/console/src/components/editor/DefaultEditor.vue b/console/src/components/editor/DefaultEditor.vue
index cd4dfed201..cbead8137d 100644
--- a/console/src/components/editor/DefaultEditor.vue
+++ b/console/src/components/editor/DefaultEditor.vue
@@ -392,6 +392,9 @@ onMounted(() => {
ExtensionSearchAndReplace,
],
autofocus: "start",
+ parseOptions: {
+ preserveWhitespace: true,
+ },
onUpdate: () => {
debounceOnUpdate();
},
diff --git a/console/src/constants/labels.ts b/console/src/constants/labels.ts
index 1cb0ac071b..63939483ca 100644
--- a/console/src/constants/labels.ts
+++ b/console/src/constants/labels.ts
@@ -6,6 +6,7 @@ export enum pluginLabels {
// role
export enum roleLabels {
TEMPLATE = "halo.run/role-template",
+ HIDDEN = "halo.run/hidden",
SYSTEM_RESERVED = "rbac.authorization.halo.run/system-reserved",
}
diff --git a/console/uc-src/modules/profile/components/PersonalAccessTokenCreationModal.vue b/console/uc-src/modules/profile/components/PersonalAccessTokenCreationModal.vue
index dee7ab2d23..e868a29cab 100644
--- a/console/uc-src/modules/profile/components/PersonalAccessTokenCreationModal.vue
+++ b/console/uc-src/modules/profile/components/PersonalAccessTokenCreationModal.vue
@@ -7,11 +7,11 @@ import { Dialog, Toast, VButton, VModal, VSpace } from "@halo-dev/components";
import { useMutation, useQueryClient } from "@tanstack/vue-query";
import { useClipboard } from "@vueuse/core";
import type { PatSpec, PersonalAccessToken } from "@halo-dev/api-client";
-import { ref } from "vue";
+import { computed, ref } from "vue";
import { useRoleTemplateSelection } from "@/composables/use-role";
import { useRoleStore } from "@/stores/role";
-import { toRefs } from "vue";
import { useI18n } from "vue-i18n";
+import { roleLabels } from "@/constants/labels";
const queryClient = useQueryClient();
const { t } = useI18n();
@@ -45,8 +45,17 @@ const formState = ref<
const { permissions } = useRoleStore();
+const availableRoleTemplates = computed(() => {
+ return permissions.permissions.filter((role) => {
+ return (
+ role.metadata.labels?.[roleLabels.TEMPLATE] === "true" &&
+ role.metadata.labels?.[roleLabels.HIDDEN] !== "true"
+ );
+ });
+});
+
const { roleTemplateGroups, handleRoleTemplateSelect, selectedRoleTemplates } =
- useRoleTemplateSelection(toRefs(permissions).permissions);
+ useRoleTemplateSelection(availableRoleTemplates);
const { copy } = useClipboard({
legacy: true,
diff --git a/console/uc-src/modules/profile/tabs/NotificationPreferences.vue b/console/uc-src/modules/profile/tabs/NotificationPreferences.vue
index 9d96635543..32b3d457ca 100644
--- a/console/uc-src/modules/profile/tabs/NotificationPreferences.vue
+++ b/console/uc-src/modules/profile/tabs/NotificationPreferences.vue
@@ -8,6 +8,7 @@ import { computed } from "vue";
import { inject } from "vue";
import { cloneDeep } from "lodash-es";
import type { ReasonTypeNotifierRequest } from "@halo-dev/api-client";
+import HasPermission from "@/components/permission/HasPermission.vue";
const queryClient = useQueryClient();
@@ -114,37 +115,41 @@ const {
-
-
- {{ reasonType.displayName }}
- |
-
-
- |
-
+
+
+
+ {{ reasonType.displayName }}
+ |
+
+
+ |
+
+
+
diff --git a/gradle.properties b/gradle.properties
index c7eda50352..352c7aad1f 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1 +1 @@
-version=2.12.0-SNAPSHOT
+version=2.13.0-SNAPSHOT