provide binary attachement restriction in admin config

This commit is contained in:
Roland Osborne 2024-05-04 22:33:30 -07:00
parent 0bcb289833
commit 380bc0d8a4
18 changed files with 102 additions and 48 deletions

View File

@ -91,5 +91,6 @@ func AddChannel(w http.ResponseWriter, r *http.Request) {
video := getBoolConfigValue(CNFEnableVideo, true);
audio := getBoolConfigValue(CNFEnableAudio, true);
image := getBoolConfigValue(CNFEnableImage, true);
WriteResponse(w, getChannelModel(slot, true, true, image, audio, video))
binary := getBoolConfigValue(CNFEnableBinary, true);
WriteResponse(w, getChannelModel(slot, true, true, image, audio, video, binary))
}

View File

@ -93,5 +93,6 @@ func ClearChannelCard(w http.ResponseWriter, r *http.Request) {
video := getBoolConfigValue(CNFEnableVideo, true);
audio := getBoolConfigValue(CNFEnableAudio, true);
image := getBoolConfigValue(CNFEnableImage, true);
WriteResponse(w, getChannelModel(&channelSlot, true, true, image, audio, video))
binary := getBoolConfigValue(CNFEnableBinary, true);
WriteResponse(w, getChannelModel(&channelSlot, true, true, image, audio, video, binary))
}

View File

@ -87,5 +87,6 @@ func ClearChannelGroup(w http.ResponseWriter, r *http.Request) {
video := getBoolConfigValue(CNFEnableVideo, true);
audio := getBoolConfigValue(CNFEnableAudio, true);
image := getBoolConfigValue(CNFEnableImage, true);
WriteResponse(w, getChannelModel(&channelSlot, true, true, image, audio, video))
binary := getBoolConfigValue(CNFEnableBinary, true);
WriteResponse(w, getChannelModel(&channelSlot, true, true, image, audio, video, binary))
}

View File

@ -52,16 +52,17 @@ func GetChannelDetail(w http.ResponseWriter, r *http.Request) {
video := getBoolConfigValue(CNFEnableVideo, true);
audio := getBoolConfigValue(CNFEnableAudio, true);
image := getBoolConfigValue(CNFEnableImage, true);
binary := getBoolConfigValue(CNFEnableBinary, true);
// return model data
if guid != "" {
if isChannelShared(guid, slot.Channel) {
WriteResponse(w, getChannelDetailModel(&slot, false, image, audio, video))
WriteResponse(w, getChannelDetailModel(&slot, false, image, audio, video, binary))
} else {
ErrResponse(w, http.StatusNotFound, errors.New("channel not shared with requestor"))
return
}
} else {
WriteResponse(w, getChannelDetailModel(&slot, true, image, audio, video))
WriteResponse(w, getChannelDetailModel(&slot, true, image, audio, video, binary))
}
}

View File

@ -83,7 +83,8 @@ func GetChannels(w http.ResponseWriter, r *http.Request) {
video := getBoolConfigValue(CNFEnableVideo, true);
audio := getBoolConfigValue(CNFEnableAudio, true);
image := getBoolConfigValue(CNFEnableImage, true);
response = append(response, getChannelModel(&slot, true, true, image, audio, video))
binary := getBoolConfigValue(CNFEnableBinary, true);
response = append(response, getChannelModel(&slot, true, true, image, audio, video, binary))
}
}
}
@ -130,7 +131,8 @@ func GetChannels(w http.ResponseWriter, r *http.Request) {
video := getBoolConfigValue(CNFEnableVideo, true);
audio := getBoolConfigValue(CNFEnableAudio, true);
image := getBoolConfigValue(CNFEnableImage, true);
response = append(response, getChannelModel(&slot, true, false, image, audio, video))
binary := getBoolConfigValue(CNFEnableBinary, true);
response = append(response, getChannelModel(&slot, true, false, image, audio, video, binary))
}
}
}

View File

@ -21,6 +21,7 @@ func GetNodeConfig(w http.ResponseWriter, r *http.Request) {
config.EnableImage = getBoolConfigValue(CNFEnableImage, true)
config.EnableAudio = getBoolConfigValue(CNFEnableAudio, true)
config.EnableVideo = getBoolConfigValue(CNFEnableVideo, true)
config.EnableBinary = getBoolConfigValue(CNFEnableBinary, true)
config.KeyType = getStrConfigValue(CNFKeyType, APPRSA2048)
config.PushSupported = getBoolConfigValue(CNFPushSupported, true)
config.EnableIce = getBoolConfigValue(CNFEnableIce, false)

View File

@ -101,5 +101,6 @@ func SetChannelCard(w http.ResponseWriter, r *http.Request) {
video := getBoolConfigValue(CNFEnableVideo, true);
audio := getBoolConfigValue(CNFEnableAudio, true);
image := getBoolConfigValue(CNFEnableImage, true);
WriteResponse(w, getChannelModel(&channelSlot, true, true, image, audio, video))
binary := getBoolConfigValue(CNFEnableBinary, true);
WriteResponse(w, getChannelModel(&channelSlot, true, true, image, audio, video, binary))
}

View File

@ -87,5 +87,6 @@ func SetChannelGroup(w http.ResponseWriter, r *http.Request) {
video := getBoolConfigValue(CNFEnableVideo, true);
audio := getBoolConfigValue(CNFEnableAudio, true);
image := getBoolConfigValue(CNFEnableImage, true);
WriteResponse(w, getChannelModel(&channelSlot, true, true, image, audio, video))
binary := getBoolConfigValue(CNFEnableBinary, true);
WriteResponse(w, getChannelModel(&channelSlot, true, true, image, audio, video, binary))
}

View File

@ -86,5 +86,6 @@ func SetChannelSubject(w http.ResponseWriter, r *http.Request) {
video := getBoolConfigValue(CNFEnableVideo, true);
audio := getBoolConfigValue(CNFEnableAudio, true);
image := getBoolConfigValue(CNFEnableImage, true);
WriteResponse(w, getChannelModel(&slot, true, true, image, audio, video))
binary := getBoolConfigValue(CNFEnableBinary, true);
WriteResponse(w, getChannelModel(&slot, true, true, image, audio, video, binary))
}

View File

@ -69,6 +69,14 @@ func SetNodeConfig(w http.ResponseWriter, r *http.Request) {
return res
}
// upsert enable binary attachments
if res := tx.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "config_id"}},
DoUpdates: clause.AssignmentColumns([]string{"bool_value"}),
}).Create(&store.Config{ConfigID: CNFEnableBinary, BoolValue: config.EnableBinary}).Error; res != nil {
return res
}
// upsert allow unsealed channels
if res := tx.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "config_id"}},

View File

@ -33,7 +33,7 @@ const CNFAssetPath = "asset_path"
//CNFScriptPath specifies the path where transform scripts are found
const CNFScriptPath = "script_path"
//CNFEnableVideo specifies whether node can process video assets
//CNFAllowUnsealed specified if plantext channels can be created
const CNFAllowUnsealed = "allow_unsealed"
//CNFEnableImage specifies whether node can process image assets
@ -45,6 +45,9 @@ const CNFEnableAudio = "enable_audio"
//CNFEnableVideo specifies whether node can process video assets
const CNFEnableVideo = "enable_video"
//CNFEnableBinary specifies whether node can attach binary asset
const CNFEnableBinary = "enable_binary"
//CNFKeyType specifies the type of key to use for identity
const CNFKeyType = "key_type"

View File

@ -168,7 +168,7 @@ func getChannelRevisionModel(slot *store.ChannelSlot, showData bool) *Channel {
}
}
func getChannelDetailModel(slot *store.ChannelSlot, showList bool, image bool, audio bool, video bool) *ChannelDetail {
func getChannelDetailModel(slot *store.ChannelSlot, showList bool, image bool, audio bool, video bool, binary bool) *ChannelDetail {
if slot.Channel == nil {
return nil
@ -200,6 +200,7 @@ func getChannelDetailModel(slot *store.ChannelSlot, showList bool, image bool, a
EnableImage: image,
EnableAudio: audio,
EnableVideo: video,
EnableBinary: binary,
Contacts: contacts,
Members: members,
}
@ -226,7 +227,7 @@ func getChannelSummaryModel(slot *store.ChannelSlot) *ChannelSummary {
}
}
func getChannelModel(slot *store.ChannelSlot, showData bool, showList bool, image bool, audio bool, video bool) *Channel {
func getChannelModel(slot *store.ChannelSlot, showData bool, showList bool, image bool, audio bool, video bool, binary bool) *Channel {
if !showData || slot.Channel == nil {
return &Channel{
@ -241,7 +242,7 @@ func getChannelModel(slot *store.ChannelSlot, showData bool, showList bool, imag
Data: &ChannelData{
DetailRevision: slot.Channel.DetailRevision,
TopicRevision: slot.Channel.TopicRevision,
ChannelDetail: getChannelDetailModel(slot, showList, image, audio, video),
ChannelDetail: getChannelDetailModel(slot, showList, image, audio, video, binary),
ChannelSummary: getChannelSummaryModel(slot),
},
}

View File

@ -196,6 +196,8 @@ type ChannelDetail struct {
EnableVideo bool `json:"enableVideo"`
EnableBinary bool `json:"enableBinary"`
Contacts *ChannelContacts `json:"contacts,omitempty"`
Members []string `json:"members"`
@ -360,6 +362,8 @@ type NodeConfig struct {
EnableVideo bool `json:"enableVideo"`
EnableBinary bool `json:"enableBinary"`
EnableIce bool `json:"enableIce"`
IceUrl string `json:"iceUrl"`

View File

@ -65,7 +65,7 @@ export const en = {
password: 'Password',
newPassword: 'New Password',
confirmPassword: 'Confirm Password',
deleteKey: 'Type \'delete\' to remove key',
deleteKey: "Type 'delete' to remove key",
delete: 'delete',
remove: 'Delete',
username: 'Username',
@ -140,6 +140,8 @@ export const en = {
audioHint: 'Allow audio to be posted in topics',
enableVideo: 'Enable Video Queue',
videoHint: 'Allow video to be posted in topics',
enableBinary: 'Enable Binary Files',
binaryHint: 'Allow binary files to be posted in topics',
enableWeb: 'Enable WebRTC Calls',
webHint: 'Enable audio and video calls to contacts',
serverUrl: 'WebRTC Server URL',
@ -237,7 +239,7 @@ export const fr = {
node: 'Serveur',
location: 'Emplacement',
description: 'Description',
timeFormat: 'Format de l\'heure',
timeFormat: "Format de l'heure",
dateFormat: 'Format de la date',
theme: 'Thème',
language: 'Langue',
@ -255,10 +257,10 @@ export const fr = {
password: 'Mot de Passe',
newPassword: 'Nouveau Mot de Passe',
confirmPassword: 'Confirmer le Mot de Passe',
deleteKey: 'Tapez \'supprimer\' pour supprimer la clé',
deleteKey: "Tapez 'supprimer' pour supprimer la clé",
delete: 'supprimer',
remove: 'Supprimer',
username: 'Nom d\'Utilisateur',
username: "Nom d'Utilisateur",
updateProfile: 'Mettre à Jour le Profil',
syncError: 'Erreur de Synchronisation',
@ -290,13 +292,13 @@ export const fr = {
create: 'Créer',
createAccount: 'Créer un Compte',
accountLogin: 'Connexion au Compte',
toCreate: 'Les comptes sont créés via un lien généré depuis le tableau de bord d\'administration.',
toCreate: "Les comptes sont créés via un lien généré depuis le tableau de bord d'administration.",
admin: 'Administrateur',
loginError: 'Erreur de connexion',
loginMessage: 'Veuillez confirmer votre nom d\'utilisateur et votre mot de passe.',
loginMessage: "Veuillez confirmer votre nom d'utilisateur et votre mot de passe.",
createError: 'Erreur de création de compte',
createMessage: 'Veuillez vérifier auprès de votre administrateur.',
adminError: 'Erreur d\'Accès',
adminError: "Erreur d'Accès",
adminMessage: 'Veuillez confirmer votre mot de passe',
confirmDelete: 'Suppression de Compte',
@ -325,16 +327,18 @@ export const fr = {
allowUnsealed: 'Autoriser les Sujets non Sécurisés',
topicContent: 'Contenu du Sujet:',
enableImage: 'Activer les Images du Sujet',
imageHint: 'Autoriser la publication d\'images dans des sujets',
enableAudio: 'Activer l\'Audio du Suject',
audioHint: 'Autoriser la publication d\'audio dans des sujets',
imageHint: "Autoriser la publication d'images dans des sujets",
enableAudio: "Activer l'Audio du Suject",
audioHint: "Autoriser la publication d'audio dans des sujets",
enableVideo: 'Activer les Videos du Sujet',
videoHint: 'Autoriser la publication de video dans des sujets',
enableBinary: 'Activer les Fichiers Binaires du Sujet',
binaryHint: 'Autoriser la publication de fichiers binaires dans les sujets',
enableWeb: 'Activer les Appels WebRTC',
webHint: 'Autoriser les appels audio et vidéo aux contacts',
serverUrl: 'URL du Serveur WebRTC',
urlHint: 'turn:ip:port?transport=udp',
webUsername: 'Nom d\'Utilisateur WebRTC',
webUsername: "Nom d'Utilisateur WebRTC",
webPassword: 'Mot de Passe WebRTC',
failedLoad: 'Échec du Chargement',
limit: 'Limite',
@ -446,7 +450,7 @@ export const sp = {
password: 'Contraseña',
newPassword: 'Nueva Contraseña',
confirmPassword: 'Confirmar Contraseña',
deleteKey: 'Escribe \'borrar\' para Eliminar la Clave',
deleteKey: "Escribe 'borrar' para Eliminar la Clave",
delete: 'borrar',
remove: 'Eliminar',
username: 'Nombre de usuario',
@ -521,6 +525,8 @@ export const sp = {
audioHint: 'Permitir la publicación de audio en temas',
enableVideo: 'Activar videos en el tema',
videoHint: 'Permitir la publicación de videos en temas',
enableBinary: 'Activar archivos binarios en el tema',
binaryHint: 'Permitir que se publiquen archivos binarios en temas',
enableWeb: 'Activar llamadas WebRTC',
webHint: 'Permitir llamadas de audio y video a contactos',
serverUrl: 'URL del servidor WebRTC',
@ -567,7 +573,7 @@ export const sp = {
confirmRemove: '¿Estás seguro de que quieres eliminar el contacto?',
message: 'Mensaje',
sealedMessage: 'Mensaje Seguro',
}
};
export const pt = {
code: 'pt',
@ -636,7 +642,7 @@ export const pt = {
password: 'Senha',
newPassword: 'Nova senha',
confirmPassword: 'Confirmar senha',
deleteKey: 'Digite \'excluir\' para deletar a chave',
deleteKey: "Digite 'excluir' para deletar a chave",
delete: 'excluir',
remove: 'Remover',
username: 'Nome de usuário',
@ -711,6 +717,8 @@ export const pt = {
audioHint: 'Permitir a publicação de áudio em tópicos',
enableVideo: 'Ativar vídeos no tópico',
videoHint: 'Permitir a publicação de vídeos em tópicos',
enableBinary: 'Ativar arquivos binários no tópico',
binaryHint: 'Permitir que arquivos binários sejam postados em tópicos',
enableWeb: 'Ativar chamadas WebRTC',
webHint: 'Permitir chamadas de áudio e vídeo para contatos',
serverUrl: 'URL do servidor WebRTC',
@ -757,7 +765,7 @@ export const pt = {
confirmRemove: 'Tem certeza de que deseja remover o contato?',
message: 'Mensagem',
sealedMessage: 'Mensagem Segura',
}
};
export const de = {
code: 'de',
@ -826,7 +834,7 @@ export const de = {
password: 'Passwort',
newPassword: 'Neues Passwort',
confirmPassword: 'Passwort bestätigen',
deleteKey: '\'löschen\' eingeben, um den Schlüssel zu löschen',
deleteKey: "'löschen' eingeben, um den Schlüssel zu löschen",
delete: 'löschen',
remove: 'Entfernen',
username: 'Benutzername',
@ -901,6 +909,8 @@ export const de = {
audioHint: 'Veröffentlichung von Audio in Themen ermöglichen',
enableVideo: 'Videos im Thema aktivieren',
videoHint: 'Veröffentlichung von Videos in Themen ermöglichen',
enableBinary: 'Binärdateien im Betreff aktivieren',
binaryHint: 'Erlauben Sie die Veröffentlichung von Binärdateien in Themen',
enableWeb: 'WebRTC-Anrufe aktivieren',
webHint: 'Audio- und Videoanrufe an Kontakte zulassen',
serverUrl: 'URL des WebRTC-Servers',
@ -947,7 +957,7 @@ export const de = {
confirmRemove: 'Sind Sie sicher, dass Sie den Kontakt löschen möchten?',
message: 'Nachricht',
sealedMessage: 'Gesicherte Nachricht',
}
};
export const ru = {
code: 'ru',
@ -1016,7 +1026,7 @@ export const ru = {
password: 'Пароль',
newPassword: 'Новый пароль',
confirmPassword: 'Подтвердите пароль',
deleteKey: 'Введите \'удалить\', чтобы удалить ключ',
deleteKey: "Введите 'удалить', чтобы удалить ключ",
delete: 'удалить',
remove: 'Удалить',
username: 'Имя пользователя',
@ -1091,6 +1101,8 @@ export const ru = {
audioHint: 'Разрешить публикацию аудио в темах',
enableVideo: 'Включить видео тем',
videoHint: 'Разрешить публикацию видео в темах',
enableBinary: 'Включить двоичные файлы',
binaryHint: 'Разрешить публикацию двоичных файлов в темах',
enableWeb: 'Включить WebRTC-звонки',
webHint: 'Разрешить аудио- и видеозвонки контактам',
serverUrl: 'URL сервера WebRTC',
@ -1137,4 +1149,4 @@ export const ru = {
confirmRemove: 'Вы уверены, что хотите удалить контакт?',
message: 'Cообщение',
sealedMessage: 'Защищенное Cообщение',
}
};

View File

@ -164,6 +164,13 @@ export function Dashboard() {
defaultChecked={true} checked={state.enableVideo} />
</div>
</Tooltip>
<Tooltip placement="topLeft" title={state.strings.binaryHint}>
<div className="field">
<div>{state.strings.enableBinary}</div>
<Switch onChange={(e) => actions.setEnableBinary(e)} size="small"
defaultChecked={true} checked={state.enableBinary} />
</div>
</Tooltip>
<Tooltip placement="topLeft" title={state.strings.webHint}>
<div className="field label">
<div>{state.strings.enableWeb}</div>

View File

@ -20,6 +20,7 @@ export function useDashboard() {
enableImage: null,
enableAudio: null,
enableVideo: null,
enableBinary: null,
enableIce: null,
iceUrl: null,
iceUsername: null,
@ -108,6 +109,9 @@ export function useDashboard() {
setEnableVideo: (enableVideo) => {
updateState({ enableVideo });
},
setEnableBinary: (enableBinary) => {
updateState({ enableBinary });
},
setEnableIce: (enableIce) => {
updateState({ enableIce });
},
@ -140,9 +144,9 @@ export function useDashboard() {
if (!state.busy) {
updateState({ busy: true });
try {
const { domain, keyType, accountStorage, pushSupported, transformSupported, allowUnsealed, enableImage, enableAudio, enableVideo, enableIce, iceUrl, iceUsername, icePassword, enableOpenAccess, openAccessLimit } = state;
const { domain, keyType, accountStorage, pushSupported, transformSupported, allowUnsealed, enableImage, enableAudio, enableVideo, enableBinary, enableIce, iceUrl, iceUsername, icePassword, enableOpenAccess, openAccessLimit } = state;
const storage = accountStorage * 1073741824;
const config = { domain, accountStorage: storage, keyType, enableImage, enableAudio, enableVideo, pushSupported, transformSupported, allowUnsealed, enableIce, iceUrl, iceUsername, icePassword, enableOpenAccess, openAccessLimit };
const config = { domain, accountStorage: storage, keyType, enableImage, enableAudio, enableVideo, enableBinary, pushSupported, transformSupported, allowUnsealed, enableIce, iceUrl, iceUsername, icePassword, enableOpenAccess, openAccessLimit };
await setNodeConfig(app.state.adminToken, config);
updateState({ busy: false, showSettings: false });
}
@ -158,9 +162,9 @@ export function useDashboard() {
const syncConfig = async () => {
try {
const config = await getNodeConfig(app.state.adminToken);
const { accountStorage, domain, keyType, pushSupported, transformSupported, allowUnsealed, enableImage, enableAudio, enableVideo, enableIce, iceUrl, iceUsername, icePassword, enableOpenAccess, openAccessLimit } = config;
const { accountStorage, domain, keyType, pushSupported, transformSupported, allowUnsealed, enableImage, enableAudio, enableVideo, enableBinary, enableIce, iceUrl, iceUsername, icePassword, enableOpenAccess, openAccessLimit } = config;
const storage = Math.ceil(accountStorage / 1073741824);
updateState({ configError: false, domain, accountStorage: storage, keyType, enableImage, enableAudio, enableVideo, pushSupported, transformSupported, allowUnsealed, enableIce, iceUrl, iceUsername, icePassword, enableOpenAccess, openAccessLimit });
updateState({ configError: false, domain, accountStorage: storage, keyType, enableImage, enableAudio, enableVideo, enableBinary, pushSupported, transformSupported, allowUnsealed, enableIce, iceUrl, iceUsername, icePassword, enableOpenAccess, openAccessLimit });
}
catch(err) {
console.log(err);

View File

@ -152,12 +152,16 @@ export function AddTopic({ contentKey }) {
</div>
</Tooltip>
)}
{ state.enableBinary && (
<Tooltip placement="top" title={state.display === 'small' ? null : state.strings.attachFile}>
<div className="button space" onClick={() => attachBinary.current.click()}>
<FieldBinaryOutlined />
</div>
</Tooltip>
)}
{ (state.enableImage || state.enableAudio || state.enableVideo || state.enableBinary) && (
<div className="bar space" />
)}
<div className="button space">
<Tooltip placement="top" title={state.display === 'small' ? null : state.strings.fontColor}>
<Dropdown overlay={picker} overlayStyle={{ minWidth: 0 }} trigger={['click']} placement="top">

View File

@ -10,6 +10,7 @@ export function useAddTopic(contentKey) {
enableImage: null,
enableAudio: null,
enableVideo: null,
enableBinary: null,
assets: [],
messageText: null,
textColor: '#444444',
@ -70,8 +71,8 @@ export function useAddTopic(contentKey) {
}, [settings.state]);
useEffect(() => {
const { enableImage, enableAudio, enableVideo } = conversation.state.channel?.data?.channelDetail || {};
updateState({ enableImage, enableAudio, enableVideo });
const { enableImage, enableAudio, enableVideo, enableBinary } = conversation.state.channel?.data?.channelDetail || {};
updateState({ enableImage, enableAudio, enableVideo, enableBinary });
}, [conversation.state.channel?.data?.channelDetail]);
const loadFileData = (file) => {