diff --git a/controller/message.go b/controller/message.go index d406542..6b2e5fe 100644 --- a/controller/message.go +++ b/controller/message.go @@ -133,7 +133,7 @@ func saveAndSendMessage(user *model.User, message *model.Message) error { message.URL = fmt.Sprintf("%s/message/%s", common.ServerAddress, message.Link) } success := false - if common.MessagePersistenceEnabled { + if common.MessagePersistenceEnabled || user.SaveMessageToDatabase == common.SaveMessageToDatabaseAllowed { defer func() { // Update the status of the message status := common.MessageSendStatusFailed diff --git a/model/user.go b/model/user.go index a6062b5..0a3f3d9 100644 --- a/model/user.go +++ b/model/user.go @@ -43,6 +43,7 @@ type User struct { TelegramChatId string `json:"telegram_chat_id"` DiscordWebhookURL string `json:"discord_webhook_url"` SendEmailToOthers int `json:"send_email_to_others" gorm:"type:int;default:0"` + SaveMessageToDatabase int `json:"save_message_to_database" gorm:"type:int;default:0"` } func GetMaxUserId() int { @@ -52,7 +53,7 @@ func GetMaxUserId() int { } func GetAllUsers(startIdx int, num int) (users []*User, err error) { - err = DB.Order("id desc").Limit(num).Offset(startIdx).Select([]string{"id", "username", "display_name", "role", "status", "email", "send_email_to_others"}).Find(&users).Error + err = DB.Order("id desc").Limit(num).Offset(startIdx).Select([]string{"id", "username", "display_name", "role", "status", "email", "send_email_to_others", "save_message_to_database"}).Find(&users).Error return users, err } @@ -79,7 +80,7 @@ func GetUserById(id int, selectAll bool) (*User, error) { "channel", "token", "wechat_test_account_id", "wechat_test_account_template_id", "wechat_test_account_open_id", "wechat_corp_account_id", "wechat_corp_account_agent_id", "wechat_corp_account_user_id", "wechat_corp_account_client_type", - "bark_server", "telegram_chat_id", + "bark_server", "telegram_chat_id", "save_message_to_database", }).First(&user, "id = ?", id).Error } return &user, err diff --git a/web/src/components/MessagesTable.js b/web/src/components/MessagesTable.js index d59943c..998b9e7 100644 --- a/web/src/components/MessagesTable.js +++ b/web/src/components/MessagesTable.js @@ -1,6 +1,6 @@ import React, { useEffect, useState } from 'react'; import { Button, Form, Label, Modal, Pagination, Table } from 'semantic-ui-react'; -import { API, openPage, showError, showSuccess } from '../helpers'; +import { API, openPage, showError, showSuccess, showWarning } from '../helpers'; import { ITEMS_PER_PAGE } from '../constants'; @@ -149,14 +149,36 @@ const MessagesTable = () => { })(); }; + const checkPermission = async () => { + // Check global permission + let res = await API.get('/api/status'); + const { success, data } = res.data; + if (success) { + if (data.message_persistence) { + return; + } + } + // Check user permission + { + let res = await API.get('/api/user/self'); + const { success, message, data } = res.data; + if (success) { + if (data.save_message_to_database !== 1) { + showWarning('您没有消息持久化的权限,消息未保存,请联系管理员。'); + } + } else { + showError(message); + } + } + } + useEffect(() => { - // TODO: Prompt the user if message persistence is disabled - // TODO: Allow set persistence permission for each user loadMessages(0) .then() .catch((reason) => { showError(reason); }); + checkPermission().then(); }, []); const viewMessage = async (id) => { diff --git a/web/src/components/UsersTable.js b/web/src/components/UsersTable.js index 1398fb9..f55d042 100644 --- a/web/src/components/UsersTable.js +++ b/web/src/components/UsersTable.js @@ -85,6 +85,7 @@ const UsersTable = () => { newUsers[realIdx].status = user.status; newUsers[realIdx].role = user.role; newUsers[realIdx].send_email_to_others = user.send_email_to_others; + newUsers[realIdx].save_message_to_database = user.save_message_to_database; } setUsers(newUsers); } else { @@ -295,6 +296,21 @@ const UsersTable = () => { ? '撤回发送任意邮件的权限' : '授予发送任意邮件的权限'} + { + manageUser( + user.username, + user.save_message_to_database === 1 + ? 'disallow_save_message_to_database' + : 'allow_save_message_to_database', + idx + ); + }} + > + {user.save_message_to_database === 1 + ? '撤回消息持久化的权限' + : '授予消息持久化的权限'} + diff --git a/web/src/constants/toast.constants.js b/web/src/constants/toast.constants.js index fc4e1d1..8b21235 100644 --- a/web/src/constants/toast.constants.js +++ b/web/src/constants/toast.constants.js @@ -2,5 +2,6 @@ export const toastConstants = { SUCCESS_TIMEOUT: 500, INFO_TIMEOUT: 3000, ERROR_TIMEOUT: 5000, + WARNING_TIMEOUT: 10000, NOTICE_TIMEOUT: 20000 }; diff --git a/web/src/helpers/utils.js b/web/src/helpers/utils.js index 6203392..9b1047a 100644 --- a/web/src/helpers/utils.js +++ b/web/src/helpers/utils.js @@ -31,6 +31,7 @@ export function isMobile() { } let showErrorOptions = { autoClose: toastConstants.ERROR_TIMEOUT }; +let showWarningOptions = { autoClose: toastConstants.WARNING_TIMEOUT }; let showSuccessOptions = { autoClose: toastConstants.SUCCESS_TIMEOUT }; let showInfoOptions = { autoClose: toastConstants.INFO_TIMEOUT }; let showNoticeOptions = { autoClose: false }; @@ -74,6 +75,10 @@ export function showError(error) { } } +export function showWarning(message) { + toast.warn(message, showWarningOptions); +} + export function showSuccess(message) { toast.success(message, showSuccessOptions); }