Client key
This commit is contained in:
@@ -12,7 +12,7 @@ pub struct Account {
|
|||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct AccountsFile {
|
pub struct AccountsFile {
|
||||||
pub active_account: Option<usize>,
|
pub active_account: usize,
|
||||||
pub accounts: Vec<Account>,
|
pub accounts: Vec<Account>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ pub fn get_accounts(app: AppHandle) -> Result<AccountsFile, String> {
|
|||||||
let path = accounts_file_path(&app)?;
|
let path = accounts_file_path(&app)?;
|
||||||
if !path.exists() {
|
if !path.exists() {
|
||||||
return Ok(AccountsFile {
|
return Ok(AccountsFile {
|
||||||
active_account: None,
|
active_account: 0,
|
||||||
accounts: Vec::new(),
|
accounts: Vec::new(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-2
@@ -1,23 +1,28 @@
|
|||||||
import { useRef } from "react";
|
import { useReducer, useRef } from "react";
|
||||||
import Enclave from "@/app/app";
|
import Enclave from "@/app/app";
|
||||||
import ServerList from "./components/view/serverList";
|
import ServerList from "./components/view/serverList";
|
||||||
import { NewProfilePage } from "./components/view/NewProfileView";
|
import { NewProfilePage } from "./components/view/NewProfileView";
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
const appRef = useRef<Enclave | null>(null);
|
const appRef = useRef<Enclave | null>(null);
|
||||||
|
const [, forceRender] = useReducer((x) => x + 1, 0);
|
||||||
if (!appRef.current) {
|
if (!appRef.current) {
|
||||||
appRef.current = new Enclave();
|
appRef.current = new Enclave();
|
||||||
|
|
||||||
|
appRef.current.forceRender = forceRender;
|
||||||
|
|
||||||
appRef.current
|
appRef.current
|
||||||
.init()
|
.init()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
console.log("Encalve initialized");
|
console.log("Encalve initialized");
|
||||||
|
forceRender();
|
||||||
})
|
})
|
||||||
.catch(console.error);
|
.catch(console.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="size-screen">
|
<main className="size-screen">
|
||||||
{!appRef.current.accounts ||
|
{appRef.current?.accounts &&
|
||||||
appRef.current.accounts.accounts.length === 0 ? (
|
appRef.current.accounts.accounts.length === 0 ? (
|
||||||
<NewProfilePage appRef={appRef} />
|
<NewProfilePage appRef={appRef} />
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
+23
-7
@@ -1,8 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
|
getHostname,
|
||||||
getHTTPUrl,
|
getHTTPUrl,
|
||||||
getServerList,
|
getServerList,
|
||||||
getWSUrl,
|
|
||||||
KnownServer,
|
|
||||||
ServerList,
|
ServerList,
|
||||||
} from "@/lib/serverList";
|
} from "@/lib/serverList";
|
||||||
import EnclaveServer from "./server";
|
import EnclaveServer from "./server";
|
||||||
@@ -29,16 +28,14 @@ ed.hashes.sha512 = sha512;
|
|||||||
* reach into `EnclaveServer` or `EnclaveWebSocket` directly.
|
* reach into `EnclaveServer` or `EnclaveWebSocket` directly.
|
||||||
*/
|
*/
|
||||||
export default class Enclave {
|
export default class Enclave {
|
||||||
private clientSecretKey: Uint8Array;
|
|
||||||
private clientPublicKey: Uint8Array;
|
|
||||||
public accounts?: AccountsFile;
|
public accounts?: AccountsFile;
|
||||||
public server?: EnclaveServer;
|
public server?: EnclaveServer;
|
||||||
public serverList: ServerList;
|
public serverList: ServerList;
|
||||||
|
public forceRender: () => void;
|
||||||
|
|
||||||
public constructor() {
|
public constructor() {
|
||||||
this.clientSecretKey = ed.utils.randomSecretKey();
|
|
||||||
this.clientPublicKey = ed.getPublicKey(this.clientSecretKey);
|
|
||||||
this.serverList = {};
|
this.serverList = {};
|
||||||
|
this.forceRender = () => {};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async init() {
|
public async init() {
|
||||||
@@ -51,7 +48,18 @@ export default class Enclave {
|
|||||||
this.server.disconnect();
|
this.server.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.server = new EnclaveServer(getWSUrl(hostname, isSecure));
|
this.server = new EnclaveServer(getHostname(hostname), isSecure);
|
||||||
|
|
||||||
|
const clientSecretKey = this.getClientSecretKey();
|
||||||
|
|
||||||
|
if (!clientSecretKey) {
|
||||||
|
console.error("Failed to get client key");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const clientPublicKey = ed.getPublicKey(clientSecretKey);
|
||||||
|
|
||||||
|
await this.server.connect(clientPublicKey, clientSecretKey);
|
||||||
|
|
||||||
if (!this.server.serverPublicKey) {
|
if (!this.server.serverPublicKey) {
|
||||||
console.error("Failed to get public key");
|
console.error("Failed to get public key");
|
||||||
@@ -68,4 +76,12 @@ export default class Enclave {
|
|||||||
publicKey: base58.encode(this.server.serverPublicKey),
|
publicKey: base58.encode(this.server.serverPublicKey),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getClientSecretKey() {
|
||||||
|
if (!this.accounts) return null;
|
||||||
|
|
||||||
|
const account = this.accounts?.accounts[this.accounts.activeAccount];
|
||||||
|
|
||||||
|
return account ? base58.decode(account.privateKey) : null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-2
@@ -2,6 +2,7 @@ import { base58 } from "@scure/base";
|
|||||||
import * as ed from "@noble/ed25519";
|
import * as ed from "@noble/ed25519";
|
||||||
import EnclaveWebSocket from "./ws";
|
import EnclaveWebSocket from "./ws";
|
||||||
import { sha512 } from "@noble/hashes/sha2.js";
|
import { sha512 } from "@noble/hashes/sha2.js";
|
||||||
|
import { getWSUrl } from "@/lib/serverList";
|
||||||
|
|
||||||
ed.hashes.sha512 = sha512;
|
ed.hashes.sha512 = sha512;
|
||||||
|
|
||||||
@@ -24,10 +25,12 @@ ed.hashes.sha512 = sha512;
|
|||||||
export default class EnclaveServer {
|
export default class EnclaveServer {
|
||||||
public serverPublicKey?: Uint8Array;
|
public serverPublicKey?: Uint8Array;
|
||||||
public hostname: string;
|
public hostname: string;
|
||||||
|
public isSecure: boolean;
|
||||||
public websocket?: EnclaveWebSocket;
|
public websocket?: EnclaveWebSocket;
|
||||||
|
|
||||||
public constructor(hostname: string) {
|
public constructor(hostname: string, isSecure: boolean) {
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
|
this.isSecure = isSecure;
|
||||||
}
|
}
|
||||||
|
|
||||||
public disconnect() {
|
public disconnect() {
|
||||||
@@ -39,7 +42,9 @@ export default class EnclaveServer {
|
|||||||
clientPublicKey: Uint8Array,
|
clientPublicKey: Uint8Array,
|
||||||
clientSecretKey: Uint8Array,
|
clientSecretKey: Uint8Array,
|
||||||
) {
|
) {
|
||||||
this.websocket = new EnclaveWebSocket(this.hostname);
|
this.websocket = new EnclaveWebSocket(
|
||||||
|
getWSUrl(this.hostname, this.isSecure),
|
||||||
|
);
|
||||||
|
|
||||||
const publicKeyString = base58.encode(clientPublicKey);
|
const publicKeyString = base58.encode(clientPublicKey);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@ export default class EnclaveWebSocket {
|
|||||||
public constructor(hostname: string) {
|
public constructor(hostname: string) {
|
||||||
this.onOpenQueue = new Array();
|
this.onOpenQueue = new Array();
|
||||||
|
|
||||||
this.websocket = new WebSocket("ws://" + hostname);
|
this.websocket = new WebSocket(hostname);
|
||||||
this.websocket.onopen = () => {
|
this.websocket.onopen = () => {
|
||||||
this.onOpenQueue.forEach((fun) => fun());
|
this.onOpenQueue.forEach((fun) => fun());
|
||||||
};
|
};
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ export interface Account {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AccountsFile {
|
export interface AccountsFile {
|
||||||
activeAccount: number | null;
|
activeAccount: number;
|
||||||
accounts: Account[];
|
accounts: Account[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,16 +18,13 @@ export async function getServerList(): Promise<ServerList> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getHTTPUrl(hostname: string, isSecure: boolean, path: string) {
|
export function getHTTPUrl(hostname: string, isSecure: boolean, path: string) {
|
||||||
return (
|
return (isSecure ? "https://" : "http://") + getHostname(hostname) + path;
|
||||||
(isSecure ? "https://" : "http://") +
|
|
||||||
(hostname.includes(":") ? hostname : hostname + ":3415") +
|
|
||||||
path
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getWSUrl(hostname: string, isSecure: boolean) {
|
export function getWSUrl(hostname: string, isSecure: boolean) {
|
||||||
return (
|
return (isSecure ? "wss://" : "ws://") + getHostname(hostname);
|
||||||
(isSecure ? "wss://" : "ws://") +
|
}
|
||||||
(hostname.includes(":") ? hostname : hostname + ":3415")
|
|
||||||
);
|
export function getHostname(hostname: string) {
|
||||||
|
return hostname.includes(":") ? hostname : hostname + ":3415";
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user