Skip to content

Commit

Permalink
Fix bugs! (#49)
Browse files Browse the repository at this point in the history
* make things work!

* version 013

* do not install CLI on startup

* add cli instructions

* fix main

* fix readme

* remove dead code
  • Loading branch information
arvid220u authored Jul 15, 2022
1 parent 25d2f2b commit d0d91b0
Show file tree
Hide file tree
Showing 13 changed files with 147 additions and 73 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,17 @@ For the gui, run:
```bash
./wrap2.sh ./gui/start.sh
```

## Installing the CLI

Run:

```bash
sudo mkdir -p /usr/local/bin
sudo ln -sf /Applications/Anysphere.app/Contents/Resources/bin/anysphere /usr/local/bin/anysphere
cat << EOF >> ~/.zprofile
export PATH="\$PATH:/usr/local/bin"
EOF
```

Replace `.zprofile` with `.bash_profile` if you use bash instead.
2 changes: 1 addition & 1 deletion daemon/crypto/constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ constexpr auto DEFAULT_ROUND_DELAY_SECONDS = 60;
constexpr auto DEFAULT_SERVER_ADDRESS = "server1.anysphere.co:443";

// this commit hash will be automatically updated by gui/package.json.
constexpr auto RELEASE_COMMIT_HASH = "276f09d7735dac0ce030cbebcff57863715db831";
constexpr auto RELEASE_COMMIT_HASH = "92a11656e89a471e4380afd45237a2b757edb44f";

// this is the number of friends that will be received from in each round
// (ideally, they can all be received in a single PIR request using batch PIR)
Expand Down
4 changes: 2 additions & 2 deletions gui/release/app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion gui/release/app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "anysphere",
"version": "0.1.1",
"version": "0.1.3",
"author": "Anysphere, Inc.",
"description": "The world's first completely private messenger.",
"main": "./dist/main/main.js",
Expand Down
8 changes: 4 additions & 4 deletions gui/src/preload.d.ts → gui/src/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
import { Daemon } from "./main/daemon";

declare global {
interface Window {
// eslint-disable-next-line no-var
var logger: Console;

interface Window extends Daemon {
copyToClipboard(s: string): void;
isPlatformMac(): boolean;

daemon: Daemon;
}
}

export {};
2 changes: 1 addition & 1 deletion gui/src/main/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { exit } from "process";
import path from "path";

// this commit hash will be automatically updated by gui/package.json.
export const RELEASE_COMMIT_HASH = "276f09d7735dac0ce030cbebcff57863715db831";
export const RELEASE_COMMIT_HASH = "92a11656e89a471e4380afd45237a2b757edb44f";

export const PLIST_PATH = () => {
if (process.platform === "darwin" && process.env.HOME) {
Expand Down
88 changes: 52 additions & 36 deletions gui/src/main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import * as daemon_pb from "../daemon/schema/daemon_pb";
import { PLIST_CONTENTS, PLIST_PATH, RELEASE_COMMIT_HASH } from "./constants";
import { exit } from "process";
import fs from "fs";
import { Console } from "console";

const daemon = new DaemonImpl();

Expand All @@ -27,7 +28,32 @@ const isDevelopment =

if (process.env["NODE_ENV"] === "production") {
const sourceMapSupport = require("source-map-support");
sourcemapsupport.install();
sourceMapSupport.install();
}

function setupLogger(): void {
let logPath = "";
if (process.env["XDG_CACHE_HOME"] !== undefined) {
logPath = path.join(process.env["XDG_CACHE_HOME"], "anysphere", "logs");
} else if (process.env["HOME"] !== undefined) {
logPath = path.join(process.env["HOME"], ".anysphere", "cache", "logs");
} else {
process.stderr.write(
"$HOME or $XDG_CACHE_HOME not set! Cannot create log path, aborting :("
);
exit(1);
}
app.setAppLogsPath(logPath);

// in debug mode, use console.log. in production, use the log file.
if (isDevelopment) {
global.logger = console;
} else {
global.logger = new Console({
stdout: fs.createWriteStream(path.join(logPath, "anysphere-gui.log")),
stderr: fs.createWriteStream(path.join(logPath, "anysphere-gui.err")),
});
}
}

async function startDaemonIfNeeded(pkgPath: string): Promise<void> {
Expand All @@ -38,27 +64,19 @@ async function startDaemonIfNeeded(pkgPath: string): Promise<void> {
throw new Error("incorrect release hash");
}
// daemon is running, correct version, nothing to do
logger.log("Daemon is running, with the correct version!");
return;
} catch (e) {
// if development, we don't want to start the daemon (want to do it manually)
if (isDevelopment) {
process.stdout.write(
logger.log(
`Daemon is either not running or running the wrong version. Please start it; we're not doing anything because we're in DEV mode. Error: ${e}.`
);
return;
}

// first copy the CLI
const cliPath = path.join(pkgPath, "bin", "anysphere");
// ln -sf link it!
// TODO(arvid): just add to PATH instead, because not everyone has /usr/local/bin in their PATH
const mkdir = await exec(`mkdir -p /usr/local/bin`);
if (mkdir.stderr) {
process.stderr.write(mkdir.stderr);
}
const clilink = await exec(`ln -sf ${cliPath} /usr/local/bin/anysphere`);
if (clilink.stderr) {
process.stderr.write(clilink.stderr);
} else {
logger.log(
`Daemon is either not running or running the wrong version. Error: ${e}.`
);
}

// TODO(arvid): handle windows and linux too
Expand All @@ -68,45 +86,39 @@ async function startDaemonIfNeeded(pkgPath: string): Promise<void> {
// 0: create the directory
const mkdirPlist = await exec(`mkdir -p ${path.dirname(plistPath)}`);
if (mkdirPlist.stderr) {
process.stderr.write(mkdirPlist.stderr);
logger.error(mkdirPlist.stderr);
}
logger.log("Successfully created the plist directory.");
// 1: unload plist
await exec("launchctl unload " + plistPath); // we don't care if it fails or not!
let logPath = "";
if (process.env["XDG_CACHE_HOME"] !== undefined) {
logPath = path.join(process.env["XDG_CACHE_HOME"], "anysphere", "logs");
} else if (process.env["HOME"] !== undefined) {
logPath = path.join(process.env["HOME"], ".anysphere", "cache", "logs");
} else {
process.stderr.write(
"$HOME or $XDG_CACHE_HOME not set! Cannot create daemon, aborting :("
);
exit(1);
}
const logPath = app.getPath("logs");
const contents = PLIST_CONTENTS(pkgPath, logPath);
logger.log("Successfully unloaded the plist.");
// 2: write plist
await fs.promises.writeFile(plistPath, contents);
logger.log("Successfully wrote the new plist.");
// 3: load plist
const response = await exec("launchctl load " + plistPath);
if (response.stderr) {
process.stderr.write(response.stderr);
logger.error(response.stderr);
exit(1);
}
logger.log("Successfully loaded the new plist.");
}
}

const installExtensions = async () => {
async function installExtensions(): Promise<void> {
const installer = require("electron-devtools-installer");
const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
const forceDownload = !!process.env["UPGRADE_EXTENSIONS"];
const extensions = ["REACT_DEVELOPER_TOOLS"];

return installer
.default(
extensions.map((name) => installer[name]),
forceDownload
)
.catch(console.log);
};
.catch(logger.log);
}

const createWindow = async () => {
if (isDevelopment) {
Expand Down Expand Up @@ -140,9 +152,6 @@ const createWindow = async () => {
mainWindow.loadURL(resolveHtmlPath("index.html"));

mainWindow.on("ready-to-show", () => {
if (!mainWindow) {
throw new Error('"mainWindow" is not defined');
}
if (process.env["START_MINIMIZED"] === "true") {
mainWindow.minimize();
} else {
Expand All @@ -155,12 +164,17 @@ const createWindow = async () => {

// Don't allow ANY requests to any origin! This means that the app will
// only not be able to communicate with the internet at all, which is PERFECT.
session.defaultSession.enableNetworkEmulation({
offline: true,
});
session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
callback({
responseHeaders: {
...details.responseHeaders,
// eslint-disable-next-line @typescript-eslint/naming-convention
"Content-Security-Policy": [
"default-src 'self' style-src 'self' 'unsafe-inline'",
"default-src 'self'; style-src 'self' 'unsafe-inline'", // required for tailwind
// "default-src 'self'",
],
},
});
Expand Down Expand Up @@ -207,6 +221,8 @@ function registerForNotifications(): () => void {
app
.whenReady()
.then(() => {
setupLogger();

autoUpdater.checkForUpdatesAndNotify();

startDaemonIfNeeded(path.dirname(app.getAppPath()));
Expand Down
17 changes: 8 additions & 9 deletions gui/src/main/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@ contextBridge.exposeInMainWorld("isPlatformMac", () => {
});

const daemonI = new DaemonImpl();
const classToObject = (theClass) => {
const originalClass = theClass || {};
const keys = Object.getOwnPropertyNames(Object.getPrototypeOf(originalClass));
return keys.reduce((classAsObj, key) => {
classAsObj[key] = originalClass[key];
return classAsObj;
}, {});
};
contextBridge.exposeInMainWorld("daemon", classToObject(daemonI));
const methods = Object.getOwnPropertyNames(
Object.getPrototypeOf(daemonI)
).filter((x) => x !== "constructor");
for (const method of methods) {
contextBridge.exposeInMainWorld(method, (...args) => {
return daemonI[method](...args);
});
}
53 changes: 50 additions & 3 deletions gui/src/renderer/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { StatusHandler, StatusContext } from "./components/Status";
import { SideBar } from "./components/SideBar/SideBar";
import { SideBarButton } from "./components/SideBar/SideBarProps";
import AddFriend from "./components/AddFriend/AddFriend";
import Modal from "./components/Modal";

const defaultTabs: Tab[] = [
{ type: TabType.New, name: "New", data: null, unclosable: true, id: "new" },
Expand Down Expand Up @@ -62,7 +63,7 @@ function Main(): JSX.Element {
return;
}
}
window.daemon.messageSeen({ id: message.uid }).catch(console.error);
window.messageSeen({ id: message.uid }).catch(console.error);
let title = "";
if ("fromDisplayName" in message) {
title = `${truncate(message.message, 10)} - ${message.fromDisplayName}`;
Expand Down Expand Up @@ -194,15 +195,15 @@ function Main(): JSX.Element {
}

React.useEffect(() => {
window.daemon
window
.hasRegistered()
.then((registered: boolean) => {
if (!registered) {
setModal(
<RegisterModal
onClose={() => {}} // should not be able to close modal by clicking outside
onRegister={(username: string, key: string) => {
window.daemon
window
.registerUser({ name: username, betaKey: key })
.then(() => {
closeModal();
Expand Down Expand Up @@ -336,6 +337,52 @@ function Main(): JSX.Element {
shortcut: ["h"],
keywords: "help",
},
{
id: "install-cli",
name: "Install 'anysphere' command",
keywords: "install, cli, command",
perform: () => {
setModal(
<Modal
onClose={() => {
closeModal();
}}
>
<div className="relative h-full w-full">
<h1 className="absolute top-4 left-0 right-0 text-center text-sm font-bold">
Install 'anysphere' command
</h1>
<div className="absolute top-8 bottom-0 left-0 right-0 grid place-content-center">
<div className="grid h-full w-full gap-2 p-2 text-sm">
<p>
Run the following sequence of commands in your terminal:
</p>
<div className="overflow-scroll bg-asbeige p-1">
<code className="whitespace-pre text-[11px]">
{`sudo mkdir -p /usr/local/bin
sudo ln -sf /Applications/Anysphere.app/Contents/Resources/bin/anysphere /usr/local/bin/anysphere
cat << EOF >> ~/.zprofile
export PATH="\$PATH:/usr/local/bin"
EOF`}
</code>
</div>
<div className="unselectable pt-1 text-xs text-asbrown-300">
Replace `.zprofile` with `.bash_profile` or something else
if you use a different shell.
</div>
<div className="unselectable pt-1 text-xs text-asbrown-300">
Why do we ask you to run this yourself? Administrator
privileges are needed to install the command, and we don't
want to ask you for your password without you seeing exactly
what is being run.
</div>
</div>
</div>
</div>
</Modal>
);
},
},
// {
// id: "quit",
// name: "Quit",
Expand Down
4 changes: 2 additions & 2 deletions gui/src/renderer/components/AddFriend/AddFriend.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default function AddFriend({
onClose={onClose}
setStatus={setStatus}
chooseInperson={() => {
window.daemon
window
.getMyPublicID()
.then((publicID) => {
setStory(publicID.story);
Expand All @@ -48,7 +48,7 @@ export default function AddFriend({
});
}}
chooseRemote={() => {
window.daemon
window
.getMyPublicID()
.then((publicID) => {
setPublicID(publicID.publicId);
Expand Down
Loading

0 comments on commit d0d91b0

Please sign in to comment.