diff --git a/net/web/src/api/getChannels.js b/net/web/src/api/getChannels.js index 168cdb94..0dafc671 100644 --- a/net/web/src/api/getChannels.js +++ b/net/web/src/api/getChannels.js @@ -5,7 +5,7 @@ export async function getChannels(token, revision) { if (revision != null) { param += `&channelRevision=${revision}` } - let types = encodeURIComponent(JSON.stringify([ 'superbasic' ])); + let types = encodeURIComponent(JSON.stringify([ 'sealed', 'superbasic' ])); param += `&types=${types}` let channels = await fetchWithTimeout('/content/channels' + param, { method: 'GET' }); checkResponse(channels) diff --git a/net/web/src/api/getContactChannels.js b/net/web/src/api/getContactChannels.js index b2f144f9..579385ed 100644 --- a/net/web/src/api/getContactChannels.js +++ b/net/web/src/api/getContactChannels.js @@ -13,7 +13,7 @@ export async function getContactChannels(server, token, viewRevision, channelRev if (channelRevision != null) { param += '&channelRevision=' + channelRevision } - let types = encodeURIComponent(JSON.stringify([ 'superbasic' ])); + let types = encodeURIComponent(JSON.stringify([ 'sealed', 'superbasic' ])); param += `&types=${types}` let channels = await fetchWithTimeout(`${host}/content/channels${param}`, { method: 'GET' }); checkResponse(channels) diff --git a/net/web/src/context/useCardContext.hook.js b/net/web/src/context/useCardContext.hook.js index 984b7d82..6dbca521 100644 --- a/net/web/src/context/useCardContext.hook.js +++ b/net/web/src/context/useCardContext.hook.js @@ -23,6 +23,8 @@ import { getContactChannelTopicAssetUrl } from 'api/getContactChannelTopicAssetU import { addCard } from 'api/addCard'; import { removeCard } from 'api/removeCard'; import { UploadContext } from 'context/UploadContext'; +import CryptoJS from 'crypto-js'; +import { JSEncrypt } from 'jsencrypt' export function useCardContext() { const [state, setState] = useState({ @@ -271,6 +273,28 @@ export function useCardContext() { } return card.data.cardProfile.name; }, + unsealChannelSubject: (cardId, channelId, sealKey) => { + const card = cards.current.get(cardId); + 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 }); + } + }); + }, removeChannel: async (cardId, channelId) => { let { cardProfile, cardDetail } = cards.current.get(cardId).data; let token = cardProfile.guid + '.' + cardDetail.token; diff --git a/net/web/src/context/useChannelContext.hook.js b/net/web/src/context/useChannelContext.hook.js index cdaa62b5..ce327476 100644 --- a/net/web/src/context/useChannelContext.hook.js +++ b/net/web/src/context/useChannelContext.hook.js @@ -43,10 +43,12 @@ export function useChannelContext() { if (cur.data.detailRevision !== channel.data.detailRevision) { if (channel.data.channelDetail != null) { cur.data.channelDetail = channel.data.channelDetail; + cur.data.unsealedSubject = null; } else { let detail = await getChannelDetail(access.current, channel.id); cur.data.channelDetail = detail; + cur.data.unsealedSubject = null; } cur.data.detailRevision = channel.data.detailRevision; } @@ -128,6 +130,11 @@ export function useChannelContext() { const data = { subjectEncrypted, subjectIv, seals }; return await addChannel(access.current, 'sealed', cards, data); }, + unsealChannelSubject: (channelId, sealKey) => { + console.log("unseal: ", channelId); + let sealed = channels.current.get(channelId); + console.log(sealed); + }, setChannelSubject: async (channelId, subject) => { return await setChannelSubject(access.current, channelId, subject); }, diff --git a/net/web/src/session/accountAccess/AccountAccess.jsx b/net/web/src/session/accountAccess/AccountAccess.jsx index 3556e4ee..09b32753 100644 --- a/net/web/src/session/accountAccess/AccountAccess.jsx +++ b/net/web/src/session/accountAccess/AccountAccess.jsx @@ -116,7 +116,7 @@ export function AccountAccess() { )} { state.sealMode === 'unlocking' && (
- actions.setSealUnlock(e.target.value)} + actions.setSealUnlock(e.target.value)} prefix={} />
)} diff --git a/net/web/src/session/channels/channelItem/ChannelItem.jsx b/net/web/src/session/channels/channelItem/ChannelItem.jsx index 8fadbcc8..dc78bcf2 100644 --- a/net/web/src/session/channels/channelItem/ChannelItem.jsx +++ b/net/web/src/session/channels/channelItem/ChannelItem.jsx @@ -1,7 +1,7 @@ import { Tooltip } from 'antd'; import { ChannelItemWrapper, Markup } from './ChannelItem.styled'; import { Logo } from 'logo/Logo'; -import { AppstoreFilled, SolutionOutlined } from '@ant-design/icons'; +import { AppstoreFilled, SolutionOutlined, UnlockOutlined, LockFilled } from '@ant-design/icons'; export function ChannelItem({ item, openChannel, active }) { @@ -32,7 +32,15 @@ export function ChannelItem({ item, openChannel, active }) {
-
{ item.subject }
+
+ { item.locked && !item.unlocked && ( + + )} + { item.locked && item.unlocked && ( + + )} + { item.subject } +
{ item.message }
{ item.updated && ( @@ -46,7 +54,15 @@ export function ChannelItem({ item, openChannel, active }) {
-
{ item.subject }
+
+ { item.locked && !item.unlocked && ( + + )} + { item.locked && item.unlocked && ( + + )} + { item.subject } +
{ item.message }
{ item.updated && ( diff --git a/net/web/src/session/channels/useChannels.hook.js b/net/web/src/session/channels/useChannels.hook.js index 8d34770d..ebffd744 100644 --- a/net/web/src/session/channels/useChannels.hook.js +++ b/net/web/src/session/channels/useChannels.hook.js @@ -153,12 +153,36 @@ export function useChannels() { const setSubject = (chan) => { let subject = ""; - if (chan.data.channelDetail?.data) { - try { - subject = JSON.parse(chan.data.channelDetail?.data).subject; + if (chan.data.channelDetail.dataType === 'sealed') { + chan.locked = chan.data.channelDetail.dataType === 'sealed' + if (state.sealable) { + try { + if (chan.data.unsealedChannel == null) { + if (chan.cardId) { + card.actions.unsealChannelSubject(chan.cardId, chan.id, account.state.sealKey); + } + else { + channel.actions.unsealChannelSubject(chan.id, account.state.sealKey); + } + } + else { + chan.unlocked = true; + subject = chan.data.unsealedChannel.subject; + } + } + catch (err) { + console.log(err) + } } - catch (err) { - console.log(err); + } + else { + if (chan.data.channelDetail?.data) { + try { + subject = JSON.parse(chan.data.channelDetail?.data).subject; + } + catch (err) { + console.log(err); + } } } if (!subject) { @@ -223,7 +247,7 @@ export function useChannels() { updateState({ channels: filtered }); // eslint-disable-next-line - }, [channel, card, store, filter]); + }, [channel, card, store, filter, state.sealable]); useEffect(() => { updateState({ display: viewport.state.display });