update system messages
This commit is contained in:
@@ -1,9 +1,8 @@
|
|||||||
import { useDatabase } from "@/app/providers/DatabaseProvider/useDatabase";
|
import { useDatabase } from "@/app/providers/DatabaseProvider/useDatabase";
|
||||||
import { createContext, useEffect } from "react";
|
import { createContext } from "react";
|
||||||
import { useSystemAccount } from "./useSystemAccount";
|
import { useSystemAccount } from "./useSystemAccount";
|
||||||
import { usePublicKey } from "../AccountProvider/usePublicKey";
|
import { usePublicKey } from "../AccountProvider/usePublicKey";
|
||||||
import { usePrivatePlain } from "../AccountProvider/usePrivatePlain";
|
import { usePrivatePlain } from "../AccountProvider/usePrivatePlain";
|
||||||
import { APP_VERSION, RELEASE_NOTICE } from "@/app/version";
|
|
||||||
import { chacha20Encrypt, encodeWithPassword, encrypt } from "@/app/crypto/crypto";
|
import { chacha20Encrypt, encodeWithPassword, encrypt } from "@/app/crypto/crypto";
|
||||||
import { generateRandomKey } from "@/app/utils/utils";
|
import { generateRandomKey } from "@/app/utils/utils";
|
||||||
import { DeliveredMessageState } from "../DialogProvider/DialogProvider";
|
import { DeliveredMessageState } from "../DialogProvider/DialogProvider";
|
||||||
@@ -11,7 +10,11 @@ import { UserInformation } from "../InformationProvider/InformationProvider";
|
|||||||
import { useNotification } from "@/app/hooks/useNotification";
|
import { useNotification } from "@/app/hooks/useNotification";
|
||||||
import { useDialogsList } from "../DialogListProvider/useDialogsList";
|
import { useDialogsList } from "../DialogListProvider/useDialogsList";
|
||||||
|
|
||||||
export const SystemAccountContext = createContext(null);
|
export interface SystemAccountContextValue {
|
||||||
|
sendMessageFromSystemAccount: (accountUsername: string, message: string) => Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SystemAccountContext = createContext<SystemAccountContextValue | null>(null);
|
||||||
|
|
||||||
export interface SystemUserInformation extends UserInformation {
|
export interface SystemUserInformation extends UserInformation {
|
||||||
avatar: string;
|
avatar: string;
|
||||||
@@ -23,49 +26,37 @@ interface SystemAccountProviderProps {
|
|||||||
|
|
||||||
export function SystemAccountProvider(props : SystemAccountProviderProps) {
|
export function SystemAccountProvider(props : SystemAccountProviderProps) {
|
||||||
const {runQuery} = useDatabase();
|
const {runQuery} = useDatabase();
|
||||||
const lastNoticeVersion = localStorage.getItem("lastNoticeVersion") || "0.0.0";
|
|
||||||
const updateAccount = useSystemAccount("updates");
|
|
||||||
const publicKey = usePublicKey();
|
const publicKey = usePublicKey();
|
||||||
const privatePlain = usePrivatePlain();
|
const privatePlain = usePrivatePlain();
|
||||||
const {updateDialog} = useDialogsList();
|
const {updateDialog} = useDialogsList();
|
||||||
const notify = useNotification();
|
const notify = useNotification();
|
||||||
|
|
||||||
useEffect(() => {
|
const sendMessageFromSystemAccount = async (accountUsername: string, message: string) => {
|
||||||
if(publicKey == ""){
|
const account = useSystemAccount(accountUsername);
|
||||||
return;
|
if(!account){
|
||||||
|
throw new Error("System account not found");
|
||||||
}
|
}
|
||||||
if(lastNoticeVersion !== APP_VERSION){
|
const chachaEncrypted : any = await chacha20Encrypt(message.trim());
|
||||||
sendReleaseNoticeFromUpdatesAccount();
|
|
||||||
localStorage.setItem("lastNoticeVersion", APP_VERSION);
|
|
||||||
}
|
|
||||||
}, [lastNoticeVersion, publicKey]);
|
|
||||||
|
|
||||||
const sendReleaseNoticeFromUpdatesAccount = async () => {
|
|
||||||
const message = RELEASE_NOTICE;
|
|
||||||
if(message.trim() == ""){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const cahchaEncrypted = await chacha20Encrypt(message.trim());
|
|
||||||
const key = Buffer.concat([
|
const key = Buffer.concat([
|
||||||
Buffer.from(cahchaEncrypted.key, "hex"),
|
Buffer.from(chachaEncrypted.key, "hex"),
|
||||||
Buffer.from(cahchaEncrypted.nonce, "hex")]);
|
Buffer.from(chachaEncrypted.nonce, "hex")]);
|
||||||
const encryptedKey = await encrypt(key.toString('binary'), publicKey);
|
const encryptedKey = await encrypt(key.toString('binary'), publicKey);
|
||||||
const messageId = generateRandomKey(16);
|
const messageId = generateRandomKey(16);
|
||||||
const plainMessage = await encodeWithPassword(privatePlain, message.trim());
|
const plainMessage = await encodeWithPassword(privatePlain, message.trim());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
await runQuery(`
|
await runQuery(`
|
||||||
INSERT INTO messages
|
INSERT INTO messages
|
||||||
(from_public_key, to_public_key, content, timestamp, read, chacha_key, from_me, plain_message, account, message_id, delivered, attachments) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
(from_public_key, to_public_key, content, timestamp, read, chacha_key, from_me, plain_message, account, message_id, delivered, attachments) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
`, [updateAccount!.publicKey, publicKey, cahchaEncrypted.ciphertext, Date.now(), 0, encryptedKey, 0, plainMessage, publicKey, messageId, DeliveredMessageState.DELIVERED, JSON.stringify([])]);
|
`, [account.publicKey, publicKey, chachaEncrypted.ciphertext, Date.now(), 0, encryptedKey, 0, plainMessage, publicKey, messageId, DeliveredMessageState.DELIVERED, JSON.stringify([])]);
|
||||||
updateDialog(updateAccount!.publicKey);
|
updateDialog(account.publicKey);
|
||||||
notify("New message", "You have a new message");
|
notify("New message", "You have a new message");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SystemAccountContext.Provider value={null}>
|
<SystemAccountContext.Provider value={{
|
||||||
|
sendMessageFromSystemAccount
|
||||||
|
}}>
|
||||||
{props.children}
|
{props.children}
|
||||||
</SystemAccountContext.Provider>
|
</SystemAccountContext.Provider>
|
||||||
)
|
)
|
||||||
|
|||||||
BIN
app/providers/SystemAccountsProvider/avatars/safe.png
Normal file
BIN
app/providers/SystemAccountsProvider/avatars/safe.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 91 KiB |
21
app/providers/SystemAccountsProvider/useSendSystemMessage.ts
Normal file
21
app/providers/SystemAccountsProvider/useSendSystemMessage.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { useContext } from "react";
|
||||||
|
import { SystemAccountContext } from "./SystemAccountsProvider";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает функцию для отправки системного сообщения от имени указанного системного аккаунта
|
||||||
|
*
|
||||||
|
* ВАЖНО! Данный хук отправляет сообщение в текущий залогиненный аккаунт.
|
||||||
|
* @param accountUsername имя системного аккаунта от которого необходимо отправить сообщение
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function useSendSystemMessage(accountUsername : string) {
|
||||||
|
const context = useContext(SystemAccountContext);
|
||||||
|
if(!context){
|
||||||
|
throw new Error("useSystemSend must be used within a SystemAccountProvider");
|
||||||
|
}
|
||||||
|
const send = (message: string) => {
|
||||||
|
return context.sendMessageFromSystemAccount(accountUsername, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return send;
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { OnlineState } from "@/app/providers/ProtocolProvider/protocol/packets/packet.onlinestate";
|
import { OnlineState } from "@/app/providers/ProtocolProvider/protocol/packets/packet.onlinestate";
|
||||||
import { SystemUserInformation } from "./SystemAccountsProvider";
|
import { SystemUserInformation } from "./SystemAccountsProvider";
|
||||||
import updates from './avatars/updates.png';
|
import updates from './avatars/updates.png';
|
||||||
|
import safe from './avatars/safe.png';
|
||||||
|
|
||||||
export function useSystemAccounts() : SystemUserInformation[] {
|
export function useSystemAccounts() : SystemUserInformation[] {
|
||||||
const accounts : SystemUserInformation[] = [
|
const accounts : SystemUserInformation[] = [
|
||||||
@@ -11,6 +12,14 @@ export function useSystemAccounts() : SystemUserInformation[] {
|
|||||||
username: "updates",
|
username: "updates",
|
||||||
online: OnlineState.OFFLINE,
|
online: OnlineState.OFFLINE,
|
||||||
avatar: updates
|
avatar: updates
|
||||||
|
},
|
||||||
|
{
|
||||||
|
publicKey: "0x000000000000000000000000000000000000000002",
|
||||||
|
verified: 1,
|
||||||
|
title: "Safe",
|
||||||
|
username: "safe",
|
||||||
|
online: OnlineState.OFFLINE,
|
||||||
|
avatar: safe
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
30
app/providers/SystemProvider/useSystemInformation.ts
Normal file
30
app/providers/SystemProvider/useSystemInformation.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { useContext } from "react";
|
||||||
|
import { SystemProviderContext } from "./SystemProvider";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Информация о системе и устройстве
|
||||||
|
*/
|
||||||
|
export interface SystemInformation {
|
||||||
|
/**
|
||||||
|
* Уникальный обезличенный идентификатор устройства
|
||||||
|
*/
|
||||||
|
id: string;
|
||||||
|
/**
|
||||||
|
* Имя устройства
|
||||||
|
*/
|
||||||
|
name: string;
|
||||||
|
/**
|
||||||
|
* Операционная система устройства
|
||||||
|
*/
|
||||||
|
os: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useSystemInformation() : SystemInformation {
|
||||||
|
const context = useContext(SystemProviderContext);
|
||||||
|
|
||||||
|
if(!context) {
|
||||||
|
throw new Error("useSystemInformation must be used within a SystemProvider");
|
||||||
|
}
|
||||||
|
|
||||||
|
return context as SystemInformation;
|
||||||
|
}
|
||||||
@@ -27,13 +27,32 @@ import { useDatabase } from "@/app/providers/DatabaseProvider/useDatabase";
|
|||||||
import { useMemoryClean } from "@/app/providers/MemoryProvider/useMemoryClean";
|
import { useMemoryClean } from "@/app/providers/MemoryProvider/useMemoryClean";
|
||||||
import { useAccountProvider } from "@/app/providers/AccountProvider/useAccountProvider";
|
import { useAccountProvider } from "@/app/providers/AccountProvider/useAccountProvider";
|
||||||
import { useLogout } from "@/app/providers/AccountProvider/useLogout";
|
import { useLogout } from "@/app/providers/AccountProvider/useLogout";
|
||||||
|
import { useUpdateMessage } from "@/app/hooks/useUpdateMessage";
|
||||||
|
import { useDeviceMessage } from "@/app/hooks/useDeviceMessage";
|
||||||
|
|
||||||
export function Main() {
|
export function Main() {
|
||||||
const { mainColor, borderColor } = useRosettaColors();
|
const { mainColor, borderColor } = useRosettaColors();
|
||||||
const { lg } = useRosettaBreakpoints();
|
const { lg } = useRosettaBreakpoints();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const [viewState, setViewState] = useViewPanelsState();
|
const [viewState, setViewState] = useViewPanelsState();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Слушаем диалоги в пассивном режиме
|
||||||
|
*/
|
||||||
useDialogFiber();
|
useDialogFiber();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Отправляем сообщение об обновлении,
|
||||||
|
* если версия приложения изменилась
|
||||||
|
*/
|
||||||
|
useUpdateMessage();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Слушаем все сообщения на присоединение новых устройств
|
||||||
|
* к нашему аккаунту
|
||||||
|
*/
|
||||||
|
useDeviceMessage();
|
||||||
|
|
||||||
const { setSize, setResizeble } = useWindow();
|
const { setSize, setResizeble } = useWindow();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user