mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
more card context refactor for mobile app
This commit is contained in:
parent
1d419c05fa
commit
56b181d798
197
app/mobile/src/context/sealUtil.js
Normal file
197
app/mobile/src/context/sealUtil.js
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
import CryptoJS from 'crypto-js';
|
||||||
|
import { RSA } from 'react-native-rsa-native';
|
||||||
|
import { JSEncrypt } from 'jsencrypt'
|
||||||
|
|
||||||
|
export function getChannelSeals(subject) {
|
||||||
|
const { seals } = JSON.parse(subject);
|
||||||
|
return seals;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isUnsealed(seals, sealKey) {
|
||||||
|
for (let i = 0; i < seals?.length; i++) {
|
||||||
|
if (seals[i].publicKey === sealKey?.public) {
|
||||||
|
return sealKey?.private != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getContentKey(seals, sealKey) {
|
||||||
|
for (let i = 0; i < seals?.length; i++) {
|
||||||
|
if (seals[i].publicKey === sealKey.public) {
|
||||||
|
const seal = seals[i];
|
||||||
|
const begin = '-----BEGIN RSA PRIVATE KEY-----\n';
|
||||||
|
const end = '\n-----END RSA PRIVATE KEY-----';
|
||||||
|
const key = `${begin}${sealKey.private}${end}`;
|
||||||
|
return await RSA.decrypt(seal.sealedKey, key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Error("unsealKey not available");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function encryptChannelSubject(subject, publicKeys) {
|
||||||
|
const key = CryptoJS.lib.WordArray.random(256 / 8);
|
||||||
|
const iv = CryptoJS.lib.WordArray.random(128 / 8);
|
||||||
|
const encrypted = CryptoJS.AES.encrypt(JSON.stringify({ subject }), key, { iv: iv });
|
||||||
|
const subjectEncrypted = encrypted.ciphertext.toString(CryptoJS.enc.Base64)
|
||||||
|
const subjectIv = iv.toString();
|
||||||
|
const keyHex = key.toString();
|
||||||
|
|
||||||
|
let seals = [];
|
||||||
|
let crypto = new JSEncrypt();
|
||||||
|
publicKeys.forEach(publicKey => {
|
||||||
|
crypto.setPublicKey(publicKey);
|
||||||
|
const sealedKey = crypto.encrypt(keyHex);
|
||||||
|
seals.push({ publicKey, sealedKey });
|
||||||
|
});
|
||||||
|
|
||||||
|
return { subjectEncrypted, subjectIv, seals };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateChannelSubject(subject, contentKey) {
|
||||||
|
const key = CryptoJS.enc.Hex.parse(contentKey);
|
||||||
|
const iv = CryptoJS.lib.WordArray.random(128 / 8);
|
||||||
|
const encrypted = CryptoJS.AES.encrypt(JSON.stringify({ subject }), key, { iv: iv });
|
||||||
|
const subjectEncrypted = encrypted.ciphertext.toString(CryptoJS.enc.Base64)
|
||||||
|
const subjectIv = iv.toString();
|
||||||
|
|
||||||
|
return { subjectEncrypted, subjectIv };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function decryptChannelSubject(subject, contentKey) {
|
||||||
|
const { subjectEncrypted, subjectIv } = JSON.parse(subject);
|
||||||
|
const iv = CryptoJS.enc.Hex.parse(subjectIv);
|
||||||
|
const key = CryptoJS.enc.Hex.parse(contentKey);
|
||||||
|
const enc = CryptoJS.enc.Base64.parse(subjectEncrypted);
|
||||||
|
const cipher = CryptoJS.lib.CipherParams.create({ ciphertext: enc, iv: iv });
|
||||||
|
const dec = CryptoJS.AES.decrypt(cipher, key, { iv: iv });
|
||||||
|
const str = dec.toString(CryptoJS.enc.Utf8);
|
||||||
|
if (!str) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return JSON.parse(dec.toString(CryptoJS.enc.Utf8));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function encryptTopicSubject(subject, contentKey) {
|
||||||
|
const iv = CryptoJS.lib.WordArray.random(128 / 8);
|
||||||
|
const key = CryptoJS.enc.Hex.parse(contentKey);
|
||||||
|
const encrypted = CryptoJS.AES.encrypt(JSON.stringify(subject), key, { iv: iv });
|
||||||
|
const messageEncrypted = encrypted.ciphertext.toString(CryptoJS.enc.Base64)
|
||||||
|
const messageIv = iv.toString();
|
||||||
|
return { messageEncrypted, messageIv };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function decryptTopicSubject(subject, contentKey) {
|
||||||
|
const { messageEncrypted, messageIv } = JSON.parse(subject);
|
||||||
|
const iv = CryptoJS.enc.Hex.parse(messageIv);
|
||||||
|
const key = CryptoJS.enc.Hex.parse(contentKey);
|
||||||
|
const enc = CryptoJS.enc.Base64.parse(messageEncrypted);
|
||||||
|
let cipher = CryptoJS.lib.CipherParams.create({ ciphertext: enc, iv: iv });
|
||||||
|
const dec = CryptoJS.AES.decrypt(cipher, key, { iv: iv });
|
||||||
|
return JSON.parse(dec.toString(CryptoJS.enc.Utf8));
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertPem(pem) {
|
||||||
|
var lines = pem.split('\n');
|
||||||
|
var encoded = '';
|
||||||
|
for(var i = 0;i < lines.length;i++){
|
||||||
|
if (lines[i].trim().length > 0 &&
|
||||||
|
lines[i].indexOf('-BEGIN RSA PRIVATE KEY-') < 0 &&
|
||||||
|
lines[i].indexOf('-BEGIN RSA PUBLIC KEY-') < 0 &&
|
||||||
|
lines[i].indexOf('-BEGIN PUBLIC KEY-') < 0 &&
|
||||||
|
lines[i].indexOf('-END PUBLIC KEY-') < 0 &&
|
||||||
|
lines[i].indexOf('-END RSA PRIVATE KEY-') < 0 &&
|
||||||
|
lines[i].indexOf('-END RSA PUBLIC KEY-') < 0) {
|
||||||
|
encoded += lines[i].trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return encoded
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function generateSeal(password) {
|
||||||
|
|
||||||
|
// generate key to encrypt private key
|
||||||
|
const salt = CryptoJS.lib.WordArray.random(128 / 8);
|
||||||
|
const aes = CryptoJS.PBKDF2(password, salt, {
|
||||||
|
keySize: 256 / 32,
|
||||||
|
iterations: 1024,
|
||||||
|
});
|
||||||
|
|
||||||
|
// generate rsa key for sealing channel, delay for activity indicators
|
||||||
|
await new Promise(r => setTimeout(r, 1000));
|
||||||
|
const crypto = new JSEncrypt({ default_key_size: 2048 });
|
||||||
|
crypto.getKey();
|
||||||
|
|
||||||
|
// encrypt private key
|
||||||
|
const iv = CryptoJS.lib.WordArray.random(128 / 8);
|
||||||
|
const privateKey = convertPem(crypto.getPrivateKey());
|
||||||
|
const enc = CryptoJS.AES.encrypt(privateKey, aes, { iv: iv });
|
||||||
|
const publicKey = convertPem(crypto.getPublicKey());
|
||||||
|
|
||||||
|
// update account
|
||||||
|
const seal = {
|
||||||
|
passwordSalt: salt.toString(),
|
||||||
|
privateKeyIv: iv.toString(),
|
||||||
|
privateKeyEncrypted: enc.ciphertext.toString(CryptoJS.enc.Base64),
|
||||||
|
publicKey: publicKey,
|
||||||
|
}
|
||||||
|
const sealKey = {
|
||||||
|
public: publicKey,
|
||||||
|
private: privateKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
return { seal, sealKey };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function unlockSeal(seal, password) {
|
||||||
|
|
||||||
|
// generate key to encrypt private key
|
||||||
|
const salt = CryptoJS.enc.Hex.parse(seal.passwordSalt);
|
||||||
|
const aes = CryptoJS.PBKDF2(password, salt, {
|
||||||
|
keySize: 256 / 32,
|
||||||
|
iterations: 1024,
|
||||||
|
});
|
||||||
|
|
||||||
|
// decrypt private key
|
||||||
|
const iv = CryptoJS.enc.Hex.parse(seal.privateKeyIv);
|
||||||
|
const enc = CryptoJS.enc.Base64.parse(seal.privateKeyEncrypted)
|
||||||
|
|
||||||
|
let cipherParams = CryptoJS.lib.CipherParams.create({
|
||||||
|
ciphertext: enc,
|
||||||
|
iv: iv
|
||||||
|
});
|
||||||
|
const dec = CryptoJS.AES.decrypt(cipherParams, aes, { iv: iv });
|
||||||
|
const privateKey = dec.toString(CryptoJS.enc.Utf8)
|
||||||
|
|
||||||
|
// store ke
|
||||||
|
const sealKey = {
|
||||||
|
public: seal.publicKey,
|
||||||
|
private: privateKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
return sealKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateSeal(seal, sealKey, password) {
|
||||||
|
|
||||||
|
// generate key to encrypt private key
|
||||||
|
const salt = CryptoJS.lib.WordArray.random(128 / 8);
|
||||||
|
const aes = CryptoJS.PBKDF2(password, salt, {
|
||||||
|
keySize: 256 / 32,
|
||||||
|
iterations: 1024,
|
||||||
|
});
|
||||||
|
|
||||||
|
// encrypt private key
|
||||||
|
const iv = CryptoJS.lib.WordArray.random(128 / 8);
|
||||||
|
const enc = CryptoJS.AES.encrypt(sealKey.private, aes, { iv: iv });
|
||||||
|
|
||||||
|
// update account
|
||||||
|
const updated = {
|
||||||
|
passwordSalt: salt.toString(),
|
||||||
|
privateKeyIv: iv.toString(),
|
||||||
|
privateKeyEncrypted: enc.ciphertext.toString(CryptoJS.enc.Base64),
|
||||||
|
publicKey: seal.publicKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
return { seal: updated, sealKey };
|
||||||
|
}
|
@ -33,6 +33,7 @@ export function useCardContext() {
|
|||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
offsync: false,
|
offsync: false,
|
||||||
cards: new Map(),
|
cards: new Map(),
|
||||||
|
viewRevision: null,
|
||||||
});
|
});
|
||||||
const upload = useContext(UploadContext);
|
const upload = useContext(UploadContext);
|
||||||
const access = useRef(null);
|
const access = useRef(null);
|
||||||
@ -47,6 +48,75 @@ export function useCardContext() {
|
|||||||
setState((s) => ({ ...s, ...value }))
|
setState((s) => ({ ...s, ...value }))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const setCardItem = (card) => {
|
||||||
|
return {
|
||||||
|
cardId: card.id,
|
||||||
|
revision: card.revision,
|
||||||
|
detailRevision: card.data?.detailRevision,
|
||||||
|
profileRevision: card.data?.profileRevision,
|
||||||
|
detail: card.data?.cardDetail,
|
||||||
|
profile: card.data?.cardProfile,
|
||||||
|
notifiedView: card.data?.notifiedView,
|
||||||
|
notifiedProfile: card.data?.notifiedProfile,
|
||||||
|
notifiedArticle: card.data?.notifiedArticle,
|
||||||
|
notifiedChannel: card.data?.notifiedChannel,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const setCardField = (cardId, field, value) => {
|
||||||
|
const card = cards.current.get(cardId);
|
||||||
|
if (card) {
|
||||||
|
card[field] = value;
|
||||||
|
cards.set(cardId, { ...card });
|
||||||
|
updateState({ cards: cards.current });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const setCardChannelField = (cardId, channelId, field, value) => {
|
||||||
|
const card = cards.current.get(cardId);
|
||||||
|
if (card) {
|
||||||
|
const channel = card.channels.get(channelId);
|
||||||
|
if (channel) {
|
||||||
|
channel[field] = value;
|
||||||
|
card.channels.set(channelId, { ...channel });
|
||||||
|
cards.current.set(cardId, { ...card });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const resync = async () => {
|
||||||
|
try {
|
||||||
|
force.current = true;
|
||||||
|
await sync();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const resyncCard = async (cardId) => {
|
||||||
|
if (!syncing.current) {
|
||||||
|
syncing.current = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { token } = access.current;
|
||||||
|
const card = cards.current.get(cardId) || {};
|
||||||
|
|
||||||
|
if (card.detail?.status === 'connected') {
|
||||||
|
await syncCard(token, card);
|
||||||
|
}
|
||||||
|
card.offsync = false;
|
||||||
|
cards.current.set(cardId, card);
|
||||||
|
updateState({ cards: cards.current });
|
||||||
|
}
|
||||||
|
catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
syncing.current = false;
|
||||||
|
await sync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -249,17 +319,54 @@ export function useCardContext() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const sync = async () => {
|
const sync = async () => {
|
||||||
if (!syncing.current && (setRevision.current !== curRevision.current || resync.current.length > 0)) {
|
if (!syncing.current && (setRevision.current !== curRevision.current || force.current)) {
|
||||||
syncing.current = true;
|
syncing.current = true;
|
||||||
const { server, appToken, guid } = session.current;
|
force.current = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const { server, token, guid } = session.current;
|
||||||
const revision = curRevision.current;
|
const revision = curRevision.current;
|
||||||
|
const delta = await getCards(server, token, setRevision.current);
|
||||||
// get and store
|
|
||||||
const delta = await getCards(server, appToken, setRevision.current);
|
|
||||||
for (let card of delta) {
|
for (let card of delta) {
|
||||||
if (card.data) {
|
if (card.data) {
|
||||||
|
const item = setCardItem(card);
|
||||||
|
const { profileRevision, profile, detailRevision, detail } = cards.current.get(card.id) || {};
|
||||||
|
|
||||||
|
if (item.profileRevision !== profileRevision) {
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
item.profileRevision = profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.detailRevision !== detailRevision) {
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
item.detailRevision = detail;
|
||||||
|
]
|
||||||
|
|
||||||
|
await store.actions.setCardItem(guid, card);
|
||||||
|
cards.current.set(card.cardId,
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
await store.actions.clearCardChannelItems(guid, card.id);
|
||||||
|
await store.actions.clearCardItem(guid, card.id);
|
||||||
|
cards.current.delete(card.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
syncing.current = false;
|
||||||
|
updateState({ offsync: true });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
syncing.current = false;
|
||||||
|
await sync();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
if (card.data.cardDetail && card.data.cardProfile) {
|
if (card.data.cardDetail && card.data.cardProfile) {
|
||||||
await store.actions.setCardItem(guid, card);
|
await store.actions.setCardItem(guid, card);
|
||||||
setCard(card.id, card);
|
setCard(card.id, card);
|
||||||
@ -293,9 +400,6 @@ export function useCardContext() {
|
|||||||
await syncCard(card);
|
await syncCard(card);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
await store.actions.clearCardChannelItems(guid, card.id);
|
|
||||||
await store.actions.clearCardItem(guid, card.id);
|
|
||||||
cards.current.delete(card.id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,10 +538,12 @@ export function useCardContext() {
|
|||||||
card.channels.set(card.channelId, cardChannel);
|
card.channels.set(card.channelId, cardChannel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const status = await store.actions.getCardRequestStatus(guid);
|
||||||
|
|
||||||
const revision = await store.actions.getCardRevision(session.guid);
|
const revision = await store.actions.getCardRevision(session.guid);
|
||||||
curRevision.current = revision;
|
curRevision.current = revision;
|
||||||
setRevision.current = revision;
|
setRevision.current = revision;
|
||||||
setState({ offsync: false, channels: channels.current });
|
setState({ offsync: false, viewRevision: status?.revision, channels: channels.current });
|
||||||
},
|
},
|
||||||
clearSession: () => {
|
clearSession: () => {
|
||||||
access.current = null;
|
access.current = null;
|
||||||
@ -482,245 +588,24 @@ export function useCardContext() {
|
|||||||
setCardCloseMessage: async (server, message) => {
|
setCardCloseMessage: async (server, message) => {
|
||||||
return await setCardCloseMessage(server, message);
|
return await setCardCloseMessage(server, message);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
getCardImageUrl: (cardId) => {
|
getCardImageUrl: (cardId) => {
|
||||||
|
const { server, token } = access.current;
|
||||||
|
return getCardImageUrl(server, token, cardId, revision);
|
||||||
},
|
},
|
||||||
removeChannel: async (cardId, channelId) => {
|
removeChannel: async (cardId, channelId) => {
|
||||||
|
const { detail, profile } = cards.current.get(cardId) || {};
|
||||||
|
const cardToken = `${profile?.guid}.${detail?.token}`;
|
||||||
|
return await removeContactChannel(profile?.node, cardToken, channelId);
|
||||||
},
|
},
|
||||||
addTopic: async (cardId, channelId, type, message, files) => {
|
addTopic: async (cardId, channelId, type, type, message, files) => {
|
||||||
},
|
const { detail, profile } = cards.current.get(cardId) || {};
|
||||||
removeTopic: async (cardId, channelId, topicId) => {
|
const cardToken = `${profile?.guid}.${detail?.token}`;
|
||||||
},
|
const node = profile?.node;
|
||||||
setTopicSubject: async (cardId, channelId, topicId, type, subject) => {
|
|
||||||
},
|
|
||||||
getTopicAssetUrl: (cardId, channelId, topicId, assetId) => {
|
|
||||||
},
|
|
||||||
getTopics: async (cardId, channelId, revision, count, begin, end) => {
|
|
||||||
},
|
|
||||||
getTopic: async (cardId, channelId, topicId) => {
|
|
||||||
},
|
|
||||||
resync: async () => {
|
|
||||||
},
|
|
||||||
resyncCard: async (cardId) => {
|
|
||||||
},
|
|
||||||
|
|
||||||
setContactRevision: async (cardId, revision) => {
|
|
||||||
},
|
|
||||||
setCardFlag: async (cardId) => {
|
|
||||||
},
|
|
||||||
clearCardFlag: async (cardId) => {
|
|
||||||
},
|
|
||||||
setChannelReadRevision: async (cardId, channelId, revision) => {
|
|
||||||
},
|
|
||||||
setChannelSyncRevision: async (cardId, channelId, revision) => {
|
|
||||||
},
|
|
||||||
setChannelTopicMarker: async (cardId, channelId, marker) => {
|
|
||||||
},
|
|
||||||
addChannelAlert: async (cardId, channelId) => {
|
|
||||||
},
|
|
||||||
setChannelFlag: async (cardId, channelId) => {
|
|
||||||
},
|
|
||||||
clearChannelFlag: async (cardId, channelId) => {
|
|
||||||
},
|
|
||||||
getChannelNotifications: async (cardId, channelId) => {
|
|
||||||
},
|
|
||||||
setChannelNotifications: async (cardId, channelId, notify) => {
|
|
||||||
},
|
|
||||||
addTopicAlert: async (cardId, channelId, topicId) => {
|
|
||||||
},
|
|
||||||
setTopicFlag: async (cardId, channelId, topicId) => {
|
|
||||||
},
|
|
||||||
clearTopicFlag: async (cardId, channelId, topicId) => {
|
|
||||||
},
|
|
||||||
|
|
||||||
getTopicItems: async (cardId, channelId, revision, count, begin, end) => {
|
|
||||||
},
|
|
||||||
getTopicItem: async (cardId, channelId, topicId) => {
|
|
||||||
},
|
|
||||||
setTopicItem: async (cardId, channelId, topic) => {
|
|
||||||
},
|
|
||||||
clearTopicItem: async (cardId, channelId) => {
|
|
||||||
},
|
|
||||||
|
|
||||||
setUnsealedChannelSubject: async (cardId, channelId, revision, unsealed) => {
|
|
||||||
},
|
|
||||||
setUnsealedChannelSummary: async (cardId, channelId, revision, unsealed) => {
|
|
||||||
},
|
|
||||||
setUnsealedTopicSubject: async (cardId, channelId, topicId, revision, unsealed) => {
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
//setSession: async (access) => {
|
|
||||||
const { guid, server, appToken } = access;
|
|
||||||
cards.current = new Map();
|
|
||||||
const status = await store.actions.getCardRequestStatus(guid);
|
|
||||||
updateState({ requestRevision: status.revision });
|
|
||||||
const cardItems = await store.actions.getCardItems(guid);
|
|
||||||
for (item of cardItems) {
|
|
||||||
cards.current.set(item.cardId, { ...item, channels: new Map() });
|
|
||||||
}
|
|
||||||
const cardChannelItems = await store.actions.getCardChannelItems(guid);
|
|
||||||
for (item of cardChannelItems) {
|
|
||||||
setCardChannelItem(item.cardId, item);
|
|
||||||
}
|
|
||||||
const revision = await store.actions.getCardRevision(guid);
|
|
||||||
updateState({ cards: cards.current });
|
|
||||||
setRevision.current = revision;
|
|
||||||
curRevision.current = revision;
|
|
||||||
session.current = access;
|
|
||||||
},
|
|
||||||
setRequestRevision: async (revision) => {
|
|
||||||
const { guid } = session.current
|
|
||||||
await store.actions.setCardRequestStatus(guid, { revision });
|
|
||||||
updateState({ requestRevision: revision });
|
|
||||||
},
|
|
||||||
//clearSession: () => {
|
|
||||||
session.current = {};
|
|
||||||
updateState({ account: null });
|
|
||||||
},
|
|
||||||
setRevision: (rev) => {
|
|
||||||
curRevision.current = rev;
|
|
||||||
sync();
|
|
||||||
},
|
|
||||||
setChannelReadRevision: async (cardId, channelId, rev) => {
|
|
||||||
await store.actions.setCardChannelItemReadRevision(session.current.guid, cardId, channelId, rev);
|
|
||||||
setCardChannelReadRevision(cardId, channelId, rev);
|
|
||||||
updateState({ cards: cards.current });
|
|
||||||
},
|
|
||||||
getCardLogo: (cardId, revision) => {
|
|
||||||
const { server, appToken } = session.current;
|
|
||||||
return getCardImageUrl(server, appToken, cardId, revision);
|
|
||||||
},
|
|
||||||
getByGuid: (guid) => {
|
|
||||||
let card;
|
|
||||||
cards.current.forEach((value, key, map) => {
|
|
||||||
if (value?.profile?.guid === guid) {
|
|
||||||
card = value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return card;
|
|
||||||
},
|
|
||||||
//addCard: async (message) => {
|
|
||||||
const { server, appToken } = session.current;
|
|
||||||
return await addCard(server, appToken, message);
|
|
||||||
},
|
|
||||||
//removeCard: async (cardId) => {
|
|
||||||
const { server, appToken } = session.current;
|
|
||||||
return await removeCard(server, appToken, cardId);
|
|
||||||
},
|
|
||||||
//setCardConnecting: async (cardId) => {
|
|
||||||
const { server, appToken } = session.current;
|
|
||||||
return await setCardConnecting(server, appToken, cardId);
|
|
||||||
},
|
|
||||||
//setCardConnected: async (cardId, token, rev) => {
|
|
||||||
const { server, appToken } = session.current;
|
|
||||||
return await setCardConnected(server, appToken, cardId, token,
|
|
||||||
rev.viewRevision, rev.articleRevision, rev.channelRevision, rev.profileRevision);
|
|
||||||
},
|
|
||||||
//setCardConfirmed: async (cardId) => {
|
|
||||||
const { server, appToken } = session.current;
|
|
||||||
return await setCardConfirmed(server, appToken, cardId);
|
|
||||||
},
|
|
||||||
//getCardOpenMessage: async (cardId) => {
|
|
||||||
const { server, appToken } = session.current;
|
|
||||||
return await getCardOpenMessage(server, appToken, cardId);
|
|
||||||
},
|
|
||||||
//setCardOpenMessage: async (server, message) => {
|
|
||||||
return await setCardOpenMessage(server, message);
|
|
||||||
},
|
|
||||||
//getCardCloseMessage: async (cardId) => {
|
|
||||||
const { server, appToken } = session.current;
|
|
||||||
return await getCardCloseMessage(server, appToken, cardId);
|
|
||||||
},
|
|
||||||
//setCardCloseMessage: async (server, message) => {
|
|
||||||
return await setCardCloseMessage(server, message);
|
|
||||||
},
|
|
||||||
setCardBlocked: async (cardId) => {
|
|
||||||
const { guid } = session.current;
|
|
||||||
setCardBlocked(cardId, true);
|
|
||||||
await store.actions.setCardItemBlocked(guid, cardId);
|
|
||||||
updateState({ cards: cards.current });
|
|
||||||
},
|
|
||||||
clearCardBlocked: async (cardId) => {
|
|
||||||
const { guid } = session.current;
|
|
||||||
setCardBlocked(cardId, false);
|
|
||||||
await store.actions.clearCardItemBlocked(guid, cardId);
|
|
||||||
updateState({ cards: cards.current });
|
|
||||||
},
|
|
||||||
setSyncRevision: async (cardId, channelId, revision) => {
|
|
||||||
const { guid } = session.current;
|
|
||||||
await store.actions.setCardChannelItemSyncRevision(guid, cardId, channelId, revision);
|
|
||||||
setCardChannelSyncRevision(cardId, channelId, revision);
|
|
||||||
updateState({ cards: cards.current });
|
|
||||||
},
|
|
||||||
setTopicMarker: async (cardId, channelId, marker) => {
|
|
||||||
const { guid } = session.current;
|
|
||||||
await store.actions.setCardChannelItemTopicMarker(guid, cardId, channelId, marker);
|
|
||||||
setCardChannelTopicMarker(cardId, channelId, marker);
|
|
||||||
updateState({ cards: cards.current });
|
|
||||||
},
|
|
||||||
setChannelBlocked: async (cardId, channelId) => {
|
|
||||||
const { guid } = session.current;
|
|
||||||
await store.actions.setCardChannelItemBlocked(guid, cardId, channelId);
|
|
||||||
setCardChannelBlocked(cardId, channelId, true);
|
|
||||||
updateState({ cards: cards.current });
|
|
||||||
},
|
|
||||||
clearChannelBlocked: async (cardId, channelId) => {
|
|
||||||
const { guid } = session.current;
|
|
||||||
await store.actions.clearCardChannelItemBlocked(guid, cardId, channelId);
|
|
||||||
setCardChannelBlocked(cardId, channelId, false);
|
|
||||||
updateState({ cards: cards.current });
|
|
||||||
},
|
|
||||||
setChannelTopicBlocked: async (cardId, channelId, topicId) => {
|
|
||||||
const { guid } = session.current;
|
|
||||||
await store.actions.setCardChannelTopicBlocked(guid, cardId, channelId, topicId, true);
|
|
||||||
},
|
|
||||||
clearChannelTopicBlocked: async (cardId, channelId, topicId) => {
|
|
||||||
const { guid } = session.current;
|
|
||||||
await store.actions.setCardChannelTopicBlocked(guid, cardId, channelId, topicId, false);
|
|
||||||
},
|
|
||||||
getChannelTopicBlocked: async () => {
|
|
||||||
const { guid } = session.current;
|
|
||||||
return await store.actions.getCardChannelTopicBlocked(guid);
|
|
||||||
},
|
|
||||||
getChannelTopicItems: async (cardId, channelId) => {
|
|
||||||
const { guid } = session.current;
|
|
||||||
return await store.actions.getCardChannelTopicItems(guid, cardId, channelId);
|
|
||||||
},
|
|
||||||
setChannelTopicItem: async (cardId, channelId, topicId, topic) => {
|
|
||||||
const { guid } = session.current;
|
|
||||||
return await store.actions.setCardChannelTopicItem(guid, cardId, channelId, topicId, topic);
|
|
||||||
},
|
|
||||||
clearChannelTopicItem: async (cardId, channelId, topicId) => {
|
|
||||||
const { guid } = session.current;
|
|
||||||
return await store.actions.clearCardChannelTopicItem(guid, cardId, channelId, topicId);
|
|
||||||
},
|
|
||||||
clearChannelTopicItems: async (cardId, channelId) => {
|
|
||||||
const { guid } = session.current;
|
|
||||||
return await store.actions.clearCardChannelTopicItems(guid, cardId, channelId);
|
|
||||||
},
|
|
||||||
getChannelTopic: async (cardId, channelId, topicId) => {
|
|
||||||
const { detail, profile } = getCardEntry(cardId);
|
|
||||||
return await getContactChannelTopic(profile.node, `${profile.guid}.${detail.token}`, channelId, topicId);
|
|
||||||
},
|
|
||||||
getChannelTopics: async (cardId, channelId, revision, count, begin, end) => {
|
|
||||||
const { detail, profile } = getCardEntry(cardId);
|
|
||||||
return await getContactChannelTopics(profile.node, `${profile.guid}.${detail.token}`, channelId, revision, count, begin, end);
|
|
||||||
},
|
|
||||||
getChannelTopicAssetUrl: (cardId, channelId, topicId, assetId) => {
|
|
||||||
const { detail, profile } = getCardEntry(cardId);
|
|
||||||
return getContactChannelTopicAssetUrl(profile.node, `${profile.guid}.${detail.token}`, channelId, topicId, assetId);
|
|
||||||
},
|
|
||||||
addChannelTopic: async (cardId, channelId, message, files) => {
|
|
||||||
const { detail, profile } = getCardEntry(cardId);
|
|
||||||
const node = profile.node;
|
|
||||||
const token = `${profile.guid}.${detail.token}`;
|
|
||||||
if (files?.length > 0) {
|
if (files?.length > 0) {
|
||||||
const topicId = await addContactChannelTopic(node, token, channelId, null, null, null);
|
const topicId = await addContactChannelTopic(node, token, channelId, null, null, null);
|
||||||
upload.actions.addContactTopic(node, token, cardId, channelId, topicId, files, async (assets) => {
|
upload.actions.addContactTopic(node, token, cardId, channelId, topicId, files, async (assets) => {
|
||||||
message.assets = assets;
|
const subject = message(assets);
|
||||||
await setContactChannelTopicSubject(node, token, channelId, topicId, 'superbasictopic', message);
|
await setContactChannelTopicSubject(node, token, channelId, topicId, type, subject);
|
||||||
}, async () => {
|
}, async () => {
|
||||||
try {
|
try {
|
||||||
await removeContactChannelTopic(node, token, channelId, topicId);
|
await removeContactChannelTopic(node, token, channelId, topicId);
|
||||||
@ -731,108 +616,137 @@ export function useCardContext() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
await addContactChannelTopic(node, token, channelId, 'superbasictopic', message, []);
|
const subject = message([]);
|
||||||
|
await addContactChannelTopic(node, token, channelId, type, subject, []);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addSealedChannelTopic: async (cardId, channelId, message, sealKey) => {
|
removeTopic: async (cardId, channelId, topicId) => {
|
||||||
const { detail, profile } = getCardEntry(cardId);
|
const { detail, profile } = cards.current.get(cardId) || {};
|
||||||
const node = profile.node;
|
const cardToken = `${profile?.guid}.${detail?.token}`;
|
||||||
const token = `${profile.guid}.${detail.token}`;
|
return await removeContactChannelTopic(profile?.node, cardToken, channelId, topicId);
|
||||||
const iv = CryptoJS.lib.WordArray.random(128 / 8);
|
|
||||||
const key = CryptoJS.enc.Hex.parse(sealKey);
|
|
||||||
const encrypted = CryptoJS.AES.encrypt(JSON.stringify({ message }), key, { iv: iv });
|
|
||||||
const messageEncrypted = encrypted.ciphertext.toString(CryptoJS.enc.Base64)
|
|
||||||
const messageIv = iv.toString();
|
|
||||||
await addContactChannelTopic(node, token, channelId, 'sealedtopic', { messageEncrypted, messageIv });
|
|
||||||
},
|
},
|
||||||
setChannelTopicSubject: async (cardId, channelId, topicId, dataType, data) => {
|
setTopicSubject: async (cardId, channelId, topicId, type, subject) => {
|
||||||
const { detail, profile } = getCardEntry(cardId);
|
const { detail, profile } = cards.current.get(cardId) || {};
|
||||||
return await setContactChannelTopicSubject(profile.node, `${profile.guid}.${detail.token}`, channelId, topicId, dataType, data);
|
const cardToken = `${profile?.guid}.${detail?.token}`;
|
||||||
|
return await setContactChannelTopicSubject(profile?.node, cardToken, channelId, topicId, type, subject);
|
||||||
},
|
},
|
||||||
setChannelTopicUnsealedDetail: async (cardId, channelId, topicId, revision, unsealed) => {
|
getTopicAssetUrl: (cardId, channelId, topicId, assetId) => {
|
||||||
const { guid } = session.current;
|
const { detail, profile } = cards.current.get(cardId) || {};
|
||||||
await store.actions.setCardChannelTopicItemUnsealedDetail(guid, cardId, channelId, topicId, revision, unsealed);
|
const cardToken = `${profile?.guid}.${detail?.token}`;
|
||||||
|
return getContactChannelTopicAssetUrl(profile?.node, cardToken, channelId, topicId, assetId);
|
||||||
},
|
},
|
||||||
removeChannel: async (cardId, channelId) => {
|
getTopics: async (cardId, channelId, revision, count, begin, end) => {
|
||||||
const { detail, profile } = getCardEntry(cardId);
|
const { detail, profile } = cards.current.get(cardId) || {};
|
||||||
return await removeContactChannel(profile.node, `${profile.guid}.${detail.token}`, channelId);
|
const cardToken = `${profile?.guid}.${detail?.token}`;
|
||||||
|
return await store.actions.getCardChannelTopicItems(guid, cardId, channelId);
|
||||||
},
|
},
|
||||||
removeChannelTopic: async (cardId, channelId, topicId) => {
|
getChannelTopic: async (cardId, channelId, topicId) => {
|
||||||
const { detail, profile } = getCardEntry(cardId);
|
const { detail, profile } = cards.current.get(cardId) || {};
|
||||||
return await removeContactChannelTopic(profile.node, `${profile.guid}.${detail.token}`, channelId, topicId);
|
const cardToken = `${profile?.guid}.${detail?.token}`;
|
||||||
|
return await getContactChannelTopic(profile?.node, cardToken, channelId, topicId);
|
||||||
},
|
},
|
||||||
addChannelReport: async (cardId, channelId) => {
|
setContactRevision: async (cardId, revision) => {
|
||||||
const { detail, profile } = getCardEntry(cardId);
|
const { guid } = acccess.current
|
||||||
return await addFlag(profile.node, profile.guid, channelId);
|
await store.actions.setCardRequestStatus(guid, { revision });
|
||||||
|
updateState({ viewRevision: revision });
|
||||||
},
|
},
|
||||||
addChannelTopicReport: async (cardId, channelId, topicId) => {
|
setChannelReadRevision: async (cardId, channelId, revision) => {
|
||||||
const { detail, profile } = getCardEntry(cardId);
|
const { guid } = access.current;
|
||||||
return await addFlag(profile.node, profile.guid, channelId, topicId);
|
await store.actions.setCardChannelItemReadRevision(guid, cardId, channelId, revision);
|
||||||
|
setCardField(cardId, 'readRevision', revision);
|
||||||
},
|
},
|
||||||
|
setChannelSyncRevision: async (cardId, channelId, revision) => {
|
||||||
|
const { guid } = access.current;
|
||||||
|
await store.actions.setCardChannelItemSyncRevision(guid, cardId, channelId, revision);
|
||||||
|
setCardField(cardId, 'syncRevision', revision);
|
||||||
|
},
|
||||||
|
setChannelTopicMarker: async (cardId, channelId, marker) => {
|
||||||
|
const { guid } = access.current;
|
||||||
|
await store.actions.setCardChannelItemTopicMarker(guid, cardId, channelId, marker);
|
||||||
|
setCardField(cardId, 'topicMarker', marker);
|
||||||
|
},
|
||||||
|
setCardFlag: async (cardId) => {
|
||||||
|
const { guid } = acccess.current;
|
||||||
|
await store.actions.setCardItemBlocked(guid, cardId);
|
||||||
|
setCardField(cardId, 'blocked', true);
|
||||||
|
},
|
||||||
|
clearCardFlag: async (cardId) => {
|
||||||
|
const { guid } = acccess.current;
|
||||||
|
await store.actions.clearCardItemBlocked(guid, cardId);
|
||||||
|
setCardField(cardId, 'blocked', false);
|
||||||
|
},
|
||||||
|
setChannelFlag: async (cardId, channelId) => {
|
||||||
|
const { guid } = access.current;
|
||||||
|
await store.actions.setCardChannelItemBlocked(guid, cardId, channelId);
|
||||||
|
setCardChannelField(cardId, channelId, 'blocked', true);
|
||||||
|
},
|
||||||
|
clearChannelFlag: async (cardId, channelId) => {
|
||||||
|
const { guid } = access.current;
|
||||||
|
await store.actions.setCardChannelItemBlocked(guid, cardId, channelId);
|
||||||
|
setCardChannelField(cardId, channelId, 'blocked', false);
|
||||||
|
},
|
||||||
|
setTopicFlag: async (cardId, channelId, topicId) => {
|
||||||
|
const { guid } = access.current;
|
||||||
|
await store.actions.setCardChannelTopicBlocked(guid, cardId, channelId, topicId, true);
|
||||||
|
},
|
||||||
|
clearTopicFlag: async (cardId, channelId, topicId) => {
|
||||||
|
const { guid } = access.current;
|
||||||
|
await store.actions.setCardChannelTopicBlocked(guid, cardId, channelId, topicId, false);
|
||||||
|
},
|
||||||
|
addChannelAlert: async (cardId, channelId) => {
|
||||||
|
const { profile } = cards.current.get(cardId) || {};
|
||||||
|
return await addFlag(profile?.node, profile?.guid, channelId);
|
||||||
|
},
|
||||||
|
addTopicAlert: async (cardId, channelId, topicId) => {
|
||||||
|
const { detail, profile } = cards.current.get(cardId) || {};
|
||||||
|
return await addFlag(profile?.node, profile?.guid, channelId, topicId);
|
||||||
|
},
|
||||||
|
|
||||||
getChannelNotifications: async (cardId, channelId) => {
|
getChannelNotifications: async (cardId, channelId) => {
|
||||||
const { detail, profile } = getCardEntry(cardId);
|
const { detail, profile } = cards.current.get(cardId) || {};
|
||||||
return await getContactChannelNotifications(profile.node, `${profile.guid}.${detail.token}`, channelId);
|
const token = `${profile?.guid}.${detail?.token}`;
|
||||||
|
return await getContactChannelNotifications(profile?.node, token, channelId);
|
||||||
},
|
},
|
||||||
setChannelNotifications: async (cardId, channelId, notify) => {
|
setChannelNotifications: async (cardId, channelId, notify) => {
|
||||||
const { detail, profile } = getCardEntry(cardId);
|
const { detail, profile } = cards.current.get(cardId) || {};
|
||||||
return await setContactChannelNotifications(profile.node, `${profile.guid}.${detail.token}`, channelId, notify);
|
const token = `${profile?.guid}.${detail?.token}`;
|
||||||
|
return await setContactChannelNotifications(profile?.node, token, channelId, notify);
|
||||||
},
|
},
|
||||||
unsealChannelSubject: async (cardId, channelId, revision, sealKey) => {
|
|
||||||
try {
|
getTopicItems: async (cardId, channelId) => {
|
||||||
const { guid } = session.current;
|
const { guid } = access.current;
|
||||||
const card = cards.current.get(cardId);
|
return await store.actions.getCardChannelTopicItems(guid, cardId, channelId);
|
||||||
const channel = card.channels.get(channelId);
|
|
||||||
const { subjectEncrypted, subjectIv, seals } = JSON.parse(channel.detail.data);
|
|
||||||
const unsealedKey = await unsealKey(seals, sealKey);
|
|
||||||
if (unsealedKey) {
|
|
||||||
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 });
|
|
||||||
if (revision === channel.detailRevision) {
|
|
||||||
channel.unsealedDetail = JSON.parse(dec.toString(CryptoJS.enc.Utf8));
|
|
||||||
await store.actions.setCardChannelItemUnsealedDetail(guid, cardId, channelId, revision, channel.unsealedDetail);
|
|
||||||
card.channels.set(channelId, { ...channel });
|
|
||||||
cards.current.set(cardId, { ...card });
|
|
||||||
updateState({ cards: cards.current });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(err) {
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
unsealChannelSummary: async (cardId, channelId, revision, sealKey) => {
|
setChannelTopicItem: async (cardId, channelId, topicId, topic) => {
|
||||||
try {
|
const { guid } = access.current;
|
||||||
const { guid } = session.current;
|
return await store.actions.setCardChannelTopicItem(guid, cardId, channelId, topicId, topic);
|
||||||
const card = cards.current.get(cardId);
|
|
||||||
const channel = card.channels.get(channelId);
|
|
||||||
const { seals } = JSON.parse(channel.detail.data);
|
|
||||||
const { messageEncrypted, messageIv } = JSON.parse(channel.summary.lastTopic.data);
|
|
||||||
const unsealedKey = await unsealKey(seals, sealKey);
|
|
||||||
if (unsealedKey) {
|
|
||||||
const iv = CryptoJS.enc.Hex.parse(messageIv);
|
|
||||||
const key = CryptoJS.enc.Hex.parse(unsealedKey);
|
|
||||||
const enc = CryptoJS.enc.Base64.parse(messageEncrypted);
|
|
||||||
let cipher = CryptoJS.lib.CipherParams.create({ ciphertext: enc, iv: iv });
|
|
||||||
const dec = CryptoJS.AES.decrypt(cipher, key, { iv: iv });
|
|
||||||
if (revision === channel.topicRevision) {
|
|
||||||
channel.unsealedSummary = JSON.parse(dec.toString(CryptoJS.enc.Utf8));
|
|
||||||
await store.actions.setCardChannelItemUnsealedSummary(guid, cardId, channelId, revision, channel.unsealedSummary);
|
|
||||||
card.channels.set(channelId, { ...channel });
|
|
||||||
cards.current.set(cardId, { ...card });
|
|
||||||
updateState({ cards: cards.current });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(err) {
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
resync: (cardId) => {
|
clearChannelTopicItem: async (cardId, channelId, topicId) => {
|
||||||
resync.current.push(cardId);
|
const { guid } = access.current;
|
||||||
sync();
|
return await store.actions.clearCardChannelTopicItem(guid, cardId, channelId, topicId);
|
||||||
|
},
|
||||||
|
clearChannelTopicItems: async (cardId, channelId) => {
|
||||||
|
const { guid } = access.current;
|
||||||
|
return await store.actions.clearCardChannelTopicItems(guid, cardId, channelId);
|
||||||
|
},
|
||||||
|
|
||||||
|
setUnsealedChannelSubject: async (cardId, channelId, revision, unsealed) => {
|
||||||
|
const { guid } = access.current;
|
||||||
|
await store.actions.setCardChannelItemUnsealedDetail(guid, cardId, channelId, revision, unsealed);
|
||||||
|
},
|
||||||
|
setUnsealedChannelSummary: async (cardId, channelId, revision, unsealed) => {
|
||||||
|
const { guid } = session.current;
|
||||||
|
await store.actions.setCardChannelItemUnsealedSummary(guid, cardId, channelId, revision, unsealed);
|
||||||
|
},
|
||||||
|
setUnsealedTopicSubject: async (cardId, channelId, topicId, revision, unsealed) => {
|
||||||
|
const { guid } = access.current;
|
||||||
|
await store.actions.setCardChannelTopicItemUnsealedDetail(guid, cardId, channelId, topicId, revision, unsealed);
|
||||||
|
},
|
||||||
|
resync: async () => {
|
||||||
|
await resync();
|
||||||
|
},
|
||||||
|
resyncCard: async (cardId) => {
|
||||||
|
await resyncCard(cardId);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +172,6 @@ export function useChannelContext() {
|
|||||||
if (files?.length > 0) {
|
if (files?.length > 0) {
|
||||||
const topicId = await addChannelTopic(server, token, channelId, null, null, null);
|
const topicId = await addChannelTopic(server, token, channelId, null, null, null);
|
||||||
upload.actions.addTopic(server, token, channelId, topicId, files, async (assets) => {
|
upload.actions.addTopic(server, token, channelId, topicId, files, async (assets) => {
|
||||||
message.assets = assets;
|
|
||||||
const subject = message(assets);
|
const subject = message(assets);
|
||||||
await setChannelTopicSubject(server, token, channelId, topicId, type, sbuject);
|
await setChannelTopicSubject(server, token, channelId, topicId, type, sbuject);
|
||||||
}, async () => {
|
}, async () => {
|
||||||
@ -201,12 +200,14 @@ export function useChannelContext() {
|
|||||||
const { server, token } = access.current;
|
const { server, token } = access.current;
|
||||||
getChannelTopicAssetUrl(server, token, channelId, topicId, assetId);
|
getChannelTopicAssetUrl(server, token, channelId, topicId, assetId);
|
||||||
},
|
},
|
||||||
|
|
||||||
getTopics: async (channelId) => {
|
getTopics: async (channelId) => {
|
||||||
const { guid } = session.current;
|
const { server, token } = access.current;
|
||||||
return await store.actions.getChannelTopicItems(guid, channelId);
|
return await getChannelTopics(server, token, channelId, revision, count, begin, end);
|
||||||
|
},
|
||||||
|
getTopic: async (channelId, topicId) => {
|
||||||
|
const { server, token } = access.current;
|
||||||
|
return await getChannelTopic(server, token, channelId, topicId);
|
||||||
},
|
},
|
||||||
|
|
||||||
resync: async () => {
|
resync: async () => {
|
||||||
await resync();
|
await resync();
|
||||||
},
|
},
|
||||||
@ -262,12 +263,8 @@ export function useChannelContext() {
|
|||||||
return await addFlag(server, guid, channelId, topicId);
|
return await addFlag(server, guid, channelId, topicId);
|
||||||
},
|
},
|
||||||
getTopicItems: async (channelId, revision, count, begin, end) => {
|
getTopicItems: async (channelId, revision, count, begin, end) => {
|
||||||
const { server, token } = session.current;
|
const { guid } = session.current;
|
||||||
return await getChannelTopics(server, token, channelId, revision, count, begin, end);
|
return await store.actions.getChannelTopicItems(guid, channelId);
|
||||||
},
|
|
||||||
getTopicItem: async (channelId, topicId) => {
|
|
||||||
const { server, token } = session.current;
|
|
||||||
return await getChannelTopic(server, token, channelId, topicId);
|
|
||||||
},
|
},
|
||||||
setTopicItem: async (channelId, topic) => {
|
setTopicItem: async (channelId, topic) => {
|
||||||
const { guid } = session.current;
|
const { guid } = session.current;
|
||||||
|
Loading…
Reference in New Issue
Block a user