unseal channel subject in webapp

This commit is contained in:
Roland Osborne 2022-12-13 14:25:35 -08:00
parent 5cf74e9793
commit 76ce83f0c0
7 changed files with 83 additions and 12 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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;

View File

@ -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);
},

View File

@ -116,7 +116,7 @@ export function AccountAccess() {
)}
{ state.sealMode === 'unlocking' && (
<div class="sealPassword">
<Input placeholder="Password" spellCheck="false" onChange={(e) => actions.setSealUnlock(e.target.value)}
<Input.Password placeholder="Password" spellCheck="false" onChange={(e) => actions.setSealUnlock(e.target.value)}
prefix={<LockOutlined />} />
</div>
)}

View File

@ -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 }) {
<Logo url={item.logo} width={32} height={32} radius={8} />
</div>
<div class="details">
<div class="subject">{ item.subject }</div>
<div class="subject">
{ item.locked && !item.unlocked && (
<LockFilled style={{ paddingRight: 8 }}/>
)}
{ item.locked && item.unlocked && (
<UnlockOutlined style={{ paddingRight: 8 }}/>
)}
<span>{ item.subject }</span>
</div>
<div class="message">{ item.message }</div>
</div>
{ item.updated && (
@ -46,7 +54,15 @@ export function ChannelItem({ item, openChannel, active }) {
<AppstoreFilled />
</div>
<div class="details">
<div class="subject">{ item.subject }</div>
<div class="subject">
{ item.locked && !item.unlocked && (
<LockFilled style={{ paddingRight: 8 }}/>
)}
{ item.locked && item.unlocked && (
<UnlockOutlined style={{ paddingRight: 8 }}/>
)}
<span>{ item.subject }</span>
</div>
<div class="message">{ item.message }</div>
</div>
{ item.updated && (

View File

@ -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 });