mirror of
https://github.com/balzack/databag.git
synced 2025-04-21 00:55:16 +00:00
support editing sealed messages in webapp
This commit is contained in:
parent
b43a26b240
commit
8a6411ff21
@ -1,9 +1,9 @@
|
||||
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||
|
||||
export async function setChannelTopicSubject(token, channelId, topicId, data) {
|
||||
export async function setChannelTopicSubject(token, channelId, topicId, datatype, data) {
|
||||
let subject = { data: JSON.stringify(data, (key, value) => {
|
||||
if (value !== null) return value
|
||||
}), datatype: 'superbasictopic' };
|
||||
}), datatype };
|
||||
|
||||
let channel = await fetchWithTimeout(`/content/channels/${channelId}/topics/${topicId}/subject?agent=${token}&confirm=true`,
|
||||
{ method: 'PUT', body: JSON.stringify(subject) });
|
||||
|
@ -278,22 +278,24 @@ export function useCardContext() {
|
||||
const channel = card.channels.get(channelId);
|
||||
|
||||
const { subjectEncrypted, subjectIv, seals } = JSON.parse(channel.data.channelDetail.data);
|
||||
seals.forEach(seal => {
|
||||
if (seal.publicKey === sealKey.public) {
|
||||
let crypto = new JSEncrypt();
|
||||
crypto.setPrivateKey(sealKey.private);
|
||||
const unsealedKey = crypto.decrypt(seal.sealedKey);
|
||||
const iv = CryptoJS.enc.Hex.parse(subjectIv);
|
||||
const key = CryptoJS.enc.Hex.parse(unsealedKey);
|
||||
const enc = CryptoJS.enc.Base64.parse(subjectEncrypted);
|
||||
let cipher = CryptoJS.lib.CipherParams.create({ ciphertext: enc, iv: iv });
|
||||
const dec = CryptoJS.AES.decrypt(cipher, key, { iv: iv });
|
||||
channel.data.unsealedChannel = JSON.parse(dec.toString(CryptoJS.enc.Utf8));
|
||||
card.channels.set(channel.id, { ...channel });
|
||||
cards.current.set(cardId, { ...card });
|
||||
updateState({ cards: cards.current });
|
||||
}
|
||||
});
|
||||
if (seals?.length) {
|
||||
seals.forEach(seal => {
|
||||
if (seal.publicKey === sealKey.public) {
|
||||
let crypto = new JSEncrypt();
|
||||
crypto.setPrivateKey(sealKey.private);
|
||||
const unsealedKey = crypto.decrypt(seal.sealedKey);
|
||||
const iv = CryptoJS.enc.Hex.parse(subjectIv);
|
||||
const key = CryptoJS.enc.Hex.parse(unsealedKey);
|
||||
const enc = CryptoJS.enc.Base64.parse(subjectEncrypted);
|
||||
let cipher = CryptoJS.lib.CipherParams.create({ ciphertext: enc, iv: iv });
|
||||
const dec = CryptoJS.AES.decrypt(cipher, key, { iv: iv });
|
||||
channel.data.unsealedChannel = JSON.parse(dec.toString(CryptoJS.enc.Utf8));
|
||||
card.channels.set(channel.id, { ...channel });
|
||||
cards.current.set(cardId, { ...card });
|
||||
updateState({ cards: cards.current });
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
removeChannel: async (cardId, channelId) => {
|
||||
let { cardProfile, cardDetail } = cards.current.get(cardId).data;
|
||||
@ -318,7 +320,27 @@ export function useCardContext() {
|
||||
let { cardProfile, cardDetail } = cards.current.get(cardId).data;
|
||||
let token = cardProfile.guid + '.' + cardDetail.token;
|
||||
let node = cardProfile.node;
|
||||
await setContactChannelTopicSubject(node, token, channelId, topicId, data);
|
||||
await setContactChannelTopicSubject(node, token, channelId, topicId, 'superbasictopic', data);
|
||||
try {
|
||||
resync.current.push(cardId);
|
||||
await setCards(null);
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
},
|
||||
setSealedChannelTopicSubject: async (cardId, channelId, topicId, data, sealKey) => {
|
||||
console.log("SETTING:", data, sealKey);
|
||||
|
||||
let { cardProfile, cardDetail } = cards.current.get(cardId).data;
|
||||
let token = cardProfile.guid + '.' + cardDetail.token;
|
||||
let node = cardProfile.node;
|
||||
const iv = CryptoJS.lib.WordArray.random(128 / 8);
|
||||
const key = CryptoJS.enc.Hex.parse(sealKey);
|
||||
const encrypted = CryptoJS.AES.encrypt(JSON.stringify(data), key, { iv: iv });
|
||||
const messageEncrypted = encrypted.ciphertext.toString(CryptoJS.enc.Base64)
|
||||
const messageIv = iv.toString();
|
||||
await setContactChannelTopicSubject(node, token, channelId, topicId, 'sealedtopic', { messageEncrypted, messageIv });
|
||||
try {
|
||||
resync.current.push(cardId);
|
||||
await setCards(null);
|
||||
|
@ -134,21 +134,23 @@ export function useChannelContext() {
|
||||
const channel = channels.current.get(channelId);
|
||||
|
||||
const { subjectEncrypted, subjectIv, seals } = JSON.parse(channel.data.channelDetail.data);
|
||||
seals.forEach(seal => {
|
||||
if (seal.publicKey === sealKey.public) {
|
||||
let crypto = new JSEncrypt();
|
||||
crypto.setPrivateKey(sealKey.private);
|
||||
const unsealedKey = crypto.decrypt(seal.sealedKey);
|
||||
const iv = CryptoJS.enc.Hex.parse(subjectIv);
|
||||
const key = CryptoJS.enc.Hex.parse(unsealedKey);
|
||||
const enc = CryptoJS.enc.Base64.parse(subjectEncrypted);
|
||||
let cipher = CryptoJS.lib.CipherParams.create({ ciphertext: enc, iv: iv });
|
||||
const dec = CryptoJS.AES.decrypt(cipher, key, { iv: iv });
|
||||
channel.data.unsealedChannel = JSON.parse(dec.toString(CryptoJS.enc.Utf8));
|
||||
channels.current.set(channel.id, { ...channel });
|
||||
updateState({ channels: channels.current });
|
||||
}
|
||||
});
|
||||
if (seals?.length) {
|
||||
seals.forEach(seal => {
|
||||
if (seal.publicKey === sealKey.public) {
|
||||
let crypto = new JSEncrypt();
|
||||
crypto.setPrivateKey(sealKey.private);
|
||||
const unsealedKey = crypto.decrypt(seal.sealedKey);
|
||||
const iv = CryptoJS.enc.Hex.parse(subjectIv);
|
||||
const key = CryptoJS.enc.Hex.parse(unsealedKey);
|
||||
const enc = CryptoJS.enc.Base64.parse(subjectEncrypted);
|
||||
let cipher = CryptoJS.lib.CipherParams.create({ ciphertext: enc, iv: iv });
|
||||
const dec = CryptoJS.AES.decrypt(cipher, key, { iv: iv });
|
||||
channel.data.unsealedChannel = JSON.parse(dec.toString(CryptoJS.enc.Utf8));
|
||||
channels.current.set(channel.id, { ...channel });
|
||||
updateState({ channels: channels.current });
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
setChannelSubject: async (channelId, subject) => {
|
||||
return await setChannelSubject(access.current, channelId, 'superbasic', { subject });
|
||||
@ -157,19 +159,21 @@ export function useChannelContext() {
|
||||
const channel = channels.current.get(channelId);
|
||||
|
||||
let { seals, subjectEncrypted, subjectIv } = JSON.parse(channel.data.channelDetail.data);
|
||||
seals.forEach(seal => {
|
||||
if (seal.publicKey === sealKey.public) {
|
||||
let crypto = new JSEncrypt();
|
||||
crypto.setPrivateKey(sealKey.private);
|
||||
const unsealedKey = crypto.decrypt(seal.sealedKey);
|
||||
const key = CryptoJS.enc.Hex.parse(unsealedKey);
|
||||
if (seals?.length) {
|
||||
seals.forEach(seal => {
|
||||
if (seal.publicKey === sealKey.public) {
|
||||
let crypto = new JSEncrypt();
|
||||
crypto.setPrivateKey(sealKey.private);
|
||||
const unsealedKey = crypto.decrypt(seal.sealedKey);
|
||||
const key = CryptoJS.enc.Hex.parse(unsealedKey);
|
||||
|
||||
const iv = CryptoJS.lib.WordArray.random(128 / 8);
|
||||
const encrypted = CryptoJS.AES.encrypt(JSON.stringify({ subject }), key, { iv: iv });
|
||||
subjectEncrypted = encrypted.ciphertext.toString(CryptoJS.enc.Base64)
|
||||
subjectIv = iv.toString();
|
||||
}
|
||||
});
|
||||
const iv = CryptoJS.lib.WordArray.random(128 / 8);
|
||||
const encrypted = CryptoJS.AES.encrypt(JSON.stringify({ subject }), key, { iv: iv });
|
||||
subjectEncrypted = encrypted.ciphertext.toString(CryptoJS.enc.Base64)
|
||||
subjectIv = iv.toString();
|
||||
}
|
||||
});
|
||||
}
|
||||
const data = { subjectEncrypted, subjectIv, seals };
|
||||
return await setChannelSubject(access.current, channelId, 'sealed', data);
|
||||
},
|
||||
@ -192,7 +196,21 @@ export function useChannelContext() {
|
||||
}
|
||||
},
|
||||
setChannelTopicSubject: async (channelId, topicId, data) => {
|
||||
await setChannelTopicSubject(access.current, channelId, topicId, data);
|
||||
await setChannelTopicSubject(access.current, channelId, topicId, 'superbasictopic', data);
|
||||
try {
|
||||
await setChannels(null);
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
},
|
||||
setSealedChannelTopicSubject: async (channelId, topicId, data, sealKey) => {
|
||||
const iv = CryptoJS.lib.WordArray.random(128 / 8);
|
||||
const key = CryptoJS.enc.Hex.parse(sealKey);
|
||||
const encrypted = CryptoJS.AES.encrypt(JSON.stringify({ message: data }), key, { iv: iv });
|
||||
const messageEncrypted = encrypted.ciphertext.toString(CryptoJS.enc.Base64)
|
||||
const messageIv = iv.toString();
|
||||
await setChannelTopicSubject(access.current, channelId, topicId, 'sealedtopic', { messageEncrypted, messageIv });
|
||||
try {
|
||||
await setChannels(null);
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ export function useConversationContext() {
|
||||
|
||||
const getSeals = (conversation) => {
|
||||
try {
|
||||
if (conversation.data.channelDetail.dataType === 'sealed') {
|
||||
if (conversation?.data.channelDetail.dataType === 'sealed') {
|
||||
return JSON.parse(conversation.data.channelDetail.data).seals;
|
||||
}
|
||||
}
|
||||
@ -226,10 +226,11 @@ export function useConversationContext() {
|
||||
|
||||
if (curView === view.current) {
|
||||
let chan = getChannel();
|
||||
|
||||
let contacts = getContacts(chan);
|
||||
let subject = getSubject(chan);
|
||||
let members = getMembers(chan);
|
||||
const seals = getSeals(chan);
|
||||
let seals = getSeals(chan);
|
||||
const enableImage = chan?.data?.channelDetail?.enableImage;
|
||||
const enableAudio = chan?.data?.channelDetail?.enableAudio;
|
||||
const enableVideo = chan?.data?.channelDetail?.enableVideo;
|
||||
@ -391,6 +392,15 @@ export function useConversationContext() {
|
||||
return await channel.actions.setChannelTopicSubject(channelId, topicId, data);
|
||||
}
|
||||
},
|
||||
setSealedTopicSubject: async (topicId, data, sealKey) => {
|
||||
const { cardId, channelId } = channelView.current;
|
||||
if (cardId) {
|
||||
return await card.actions.setSealedChannelTopicSubject(cardId, channelId, topicId, data, sealKey);
|
||||
}
|
||||
else {
|
||||
return await channel.actions.setSealedChannelTopicSubject(channelId, topicId, data, sealKey);
|
||||
}
|
||||
},
|
||||
resync: () => {
|
||||
updateState({ error: false });
|
||||
events.current.push({ type: EVENT_RESYNC });
|
||||
|
@ -200,7 +200,7 @@ export function useChannels() {
|
||||
}
|
||||
|
||||
const setMessage = (chan) => {
|
||||
let message = "";
|
||||
let message;
|
||||
if (chan.data.channelSummary?.lastTopic?.dataType === 'superbasictopic') {
|
||||
try {
|
||||
message = JSON.parse(chan.data.channelSummary.lastTopic.data).text;
|
||||
@ -210,7 +210,9 @@ export function useChannels() {
|
||||
}
|
||||
}
|
||||
|
||||
chan.message = message;
|
||||
if (typeof message === 'string') {
|
||||
chan.message = message;
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -14,7 +14,7 @@ export function Conversation({ closeConversation, openDetails, cardId, channelId
|
||||
const thread = useRef(null);
|
||||
|
||||
const topicRenderer = (topic) => {
|
||||
return (<TopicItem host={cardId == null} topic={topic} sealKey={state.sealKey} />)
|
||||
return (<TopicItem host={cardId == null} topic={topic} sealed={state.sealed} sealKey={state.sealKey} />)
|
||||
}
|
||||
|
||||
// an unfortunate cludge for the mobile browser
|
||||
|
@ -8,9 +8,9 @@ import { Space, Skeleton, Button, Modal, Input } from 'antd';
|
||||
import { ExclamationCircleOutlined, DeleteOutlined, EditOutlined, FireOutlined, PictureOutlined } from '@ant-design/icons';
|
||||
import { Carousel } from 'carousel/Carousel';
|
||||
|
||||
export function TopicItem({ host, topic, sealKey }) {
|
||||
export function TopicItem({ host, topic, sealed, sealKey }) {
|
||||
|
||||
const { state, actions } = useTopicItem(topic, sealKey);
|
||||
const { state, actions } = useTopicItem(topic, sealed, sealKey);
|
||||
|
||||
let name = state.name ? state.name : state.handle;
|
||||
let nameClass = state.name ? 'set' : 'unset';
|
||||
|
@ -3,7 +3,7 @@ import { ConversationContext } from 'context/ConversationContext';
|
||||
import { ProfileContext } from 'context/ProfileContext';
|
||||
import { CardContext } from 'context/CardContext';
|
||||
|
||||
export function useTopicItem(topic, sealKey) {
|
||||
export function useTopicItem(topic, sealed, sealKey) {
|
||||
|
||||
const [state, setState] = useState({
|
||||
init: false,
|
||||
@ -60,7 +60,9 @@ export function useTopicItem(topic, sealKey) {
|
||||
if (dataType === 'superbasictopic') {
|
||||
try {
|
||||
message = JSON.parse(data);
|
||||
text = message.text;
|
||||
if (typeof message.text === 'string') {
|
||||
text = message.text;
|
||||
}
|
||||
if (message.textColor != null) {
|
||||
textColor = message.textColor;
|
||||
}
|
||||
@ -84,7 +86,9 @@ export function useTopicItem(topic, sealKey) {
|
||||
}
|
||||
else if (dataType === 'sealedtopic') {
|
||||
if (topic.data.unsealedMessage) {
|
||||
text = topic.data.unsealedMessage.message.text;
|
||||
console.log("UNSEALED MESSAGE", topic.data.unsealedMessage);
|
||||
|
||||
text = topic.data.unsealedMessage.message?.text;
|
||||
sealed = false;
|
||||
}
|
||||
else {
|
||||
@ -141,8 +145,15 @@ export function useTopicItem(topic, sealKey) {
|
||||
if (!state.busy) {
|
||||
updateState({ busy: true });
|
||||
try {
|
||||
await conversation.actions.setTopicSubject(topic.id,
|
||||
if (sealed) {
|
||||
console.log("SET SEALED");
|
||||
await conversation.actions.setSealedTopicSubject(topic.id, {...state.message, text: editMessage.current }, sealKey);
|
||||
}
|
||||
else {
|
||||
console.log("SET UNSEALED");
|
||||
await conversation.actions.setTopicSubject(topic.id,
|
||||
{ ...state.message, text: editMessage.current, assets: state.assets });
|
||||
}
|
||||
updateState({ editing: false });
|
||||
}
|
||||
catch (err) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user