Compare commits

...
13 changed files with 12890 additions and 920 deletions

26
.gitignore vendored
View file

@ -1,29 +1,5 @@
.DS_Store .DS_Store
/node_modules /node_modules
/.log /out
crash.log
# local env files
.env.local
.env.*.local
.env
# Log files
npm-debug.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# Dist
*.app
*.sublime-workspace *.sublime-workspace
*.sublime-project

2
.npmrc
View file

@ -1,2 +1,2 @@
@crimata:registry=https://gitlab.com/api/v4/projects/28849281/packages/npm/ @crimata:registry=https://gitlab.com/api/v4/projects/28849281/packages/npm/
//gitlab.com/api/v4/projects/28849281/packages/npm/:_authToken=${API_TOKEN} //gitlab.com/api/v4/projects/28849281/packages/npm

View file

@ -1,62 +0,0 @@
# crimata-electron
## Project setup
```
yarn install
```
### Compiles and hot-reloads for development
```
yarn electron:serve
```
### Compiles and minifies for production
```
yarn electron:build
```
<!-- ### Run your unit tests
```
yarn test:unit
```
### Lints and fixes files
```
yarn lint
``` -->
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
## Sign and Notarize
Prerequisites:
* Apple Developer Account ($99)
* Valid Apple Developer ID Application Certificate on keychain
Sign and Notarize:
node notarize.js
Debug electron-osx-sign:
export DEBUG=electron-osx-sign*
### Some things to note:
Notarize only when distributing outside the Mac App Store.
#### Gatekeeper Assess
Electron-osx-sign seems to have a bug where the sign will fail if "gatekeeper-assess" is true (default).
#### Entitlements.plist
Not to be confused with Info.plist, this file specifies entitlements the app can have in hardened runtime (e.g. Can I use the microphone?). Only including the ones Electron reccommends seems to work (including audio of course and omitting allow-unsigned-executable-memory).
#### The Benifit of Electron OSX Sign
Without this package, we would have to manually go in and figure out how to sign each level of the app. While it didn't work out of the box (gatekeeper-assess) it seems to be good otherwise. However, there is a bug where it puts multiple runtime flags on each command - not catastrophic though.
#### Apple Password
This must be an app specific password, not your normal Apple ID password.
#### --Signiture-Flags OSX Sign
Not exactly sure what this does or why its important, but Electron includes it.

8
electron.sublime-project Normal file
View file

@ -0,0 +1,8 @@
{
"folders":
[
{
"path": "."
}
]
}

View file

@ -1,52 +0,0 @@
const exec = require('child_process').exec;
const sign = require("electron-osx-sign").signAsync;
const notarize = require("electron-notarize").notarize;
const app = "Crimata.app";
const dir = `${app}/Contents/Resources/app`;
const runShellCommand = (cmd) => (new Promise((resolve, reject) => {
exec(cmd, (error, stdout, stderr) => {
error ? reject(stderr) : resolve(stdout);
});
}));
const signConfig = {
"app": app,
"hardened-runtime": true,
"gatekeeper-assess": false,
"signature-flags": "library",
"entitlements": "entitlements.plist",
"entitlements-inherit": "entitlements.plist",
};
const notarizeConfig = {
appPath: app,
appleId: "[email protected]",
appBundleId: "com.crimata.CrimataMessenger",
appleIdPassword: process.env["AC_PASSWORD"]
};
(async function () {
try
{
console.log("Building...");
await runShellCommand(`rm -rf ${dir} && mkdir ${dir} && cp -r {package.json,src,node_modules} ${dir}
`);
console.log("Cleaning...");
await runShellCommand(`xattr -cr ${app}`);
console.log("Signing...");
await sign(signConfig);
console.log("Notarizing...");
await notarize(notarizeConfig);
}
catch (e)
{
console.log(e);
}
})();

12612
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,25 +1,54 @@
{ {
"name": "Crimata", "name": "crimata",
"productName": "crimata-messenger",
"version": "1.0.0", "version": "1.0.0",
"private": true,
"description": "Cross-platform messenger app (Electron, Vue3)", "description": "Cross-platform messenger app (Electron, Vue3)",
"author": {
"name": "Andrew Gundersen"
},
"main": "src/main.js", "main": "src/main.js",
"scripts": { "scripts": {
"start": "electron ." "start": "electron-forge start",
"test": "echo \"Error: no test specified\" && exit 1",
"package": "electron-forge package",
"make": "electron-forge make"
},
"author": "Andrew Gundersen",
"license": "ISC",
"devDependencies": {
"@electron-forge/cli": "^6.0.0-beta.63",
"@electron-forge/maker-deb": "^6.0.0-beta.63",
"@electron-forge/maker-rpm": "^6.0.0-beta.63",
"@electron-forge/maker-squirrel": "^6.0.0-beta.63",
"@electron-forge/maker-zip": "^6.0.0-beta.63",
"electron": "^18.2.3"
}, },
"dependencies": { "dependencies": {
"@crimata/nodeaudio": "0.0.0",
"axios": "^0.21.1", "axios": "^0.21.1",
"base64-arraybuffer": "^1.0.1", "base64-arraybuffer": "^1.0.1",
"electron-store": "^8.0.0", "electron-store": "^8.0.0",
"ws": "^7.3.1" "ws": "^7.3.1",
"electron-squirrel-startup": "^1.0.0"
}, },
"devDependencies": { "config": {
"electron-notarize": "^1.1.1", "forge": {
"electron-osx-sign": "^0.6.0" "packagerConfig": {},
"makers": [
{
"name": "@electron-forge/maker-squirrel",
"config": {}
},
{
"name": "@electron-forge/maker-zip",
"platforms": [
"darwin"
]
},
{
"name": "@electron-forge/maker-deb",
"config": {}
},
{
"name": "@electron-forge/maker-rpm",
"config": {}
}
]
}
} }
} }

View file

@ -5,6 +5,8 @@ const store = require("./utils/store");
const { launchSession, endSession } = require("./session"); const { launchSession, endSession } = require("./session");
const { backgroundMitt, ipcEmit } = require("./utils/emitter"); const { backgroundMitt, ipcEmit } = require("./utils/emitter");
store.set("account", process.env.ACCOUNT);
async function auth(_e, creds) async function auth(_e, creds)
{ {
const { error, data } = await post("/auth", creds); const { error, data } = await post("/auth", creds);

View file

@ -2,10 +2,10 @@ const { app } = require("electron");
const DOMAIN = "crimata.com"; const DOMAIN = "crimata.com";
const prod = !process.defaultApp; /* If PROD env variable exists */
// const prod = true; const prod = process.env.PROD;
module.exports = { module.exports = {
PLATFORM: prod ? `https://app.${DOMAIN}` : `http://localhost:8760`, PLATFORM: prod ? `https://app.${DOMAIN}` : `http://localhost:5000`,
API: prod ? `https://${DOMAIN}/api` : `http://localhost:8761` API: prod ? `https://${DOMAIN}/api` : `http://localhost:5001`
} }

View file

@ -5,7 +5,7 @@ const store = require("./utils/store");
const { initTray } = require("./tray"); const { initTray } = require("./tray");
const { createWin } = require("./window"); const { createWin } = require("./window");
const { initAccount } = require("./account"); const { initAccount } = require("./account");
const { terminateAudio } = require("./audio"); // const { terminateAudio } = require("./audio");
// Assert a light theme // Assert a light theme
nativeTheme.themeSource = "light"; nativeTheme.themeSource = "light";
@ -17,19 +17,12 @@ app.on("ready", () =>
createWin(); createWin();
initAccount(); initAccount();
/* Check for an update every minunte */
setInterval(autoUpdater.checkForUpdates, 60000);
}); });
app.on("will-quit", terminateAudio); // app.on("will-quit", terminateAudio);
// When user clicks app icon (re-open) // When user clicks app icon (re-open)
app.on("activate", createWin); app.on("activate", createWin);
// Prevents app from quitting on window close event // Prevents app from quitting on window close event
app.on('window-all-closed', (e) => e.preventDefault()); app.on('window-all-closed', (e) => e.preventDefault());
// Update when a new update is downloaded.
autoUpdater.on("update-downloaded", update);

View file

@ -36,6 +36,7 @@ html, body {
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
height: 100vh; /* 100% for website */ height: 100vh; /* 100% for website */
width: 100vw; /* 100% for website */ width: 100vw; /* 100% for website */
/* Does not work on Linux */
border-radius: 15px; border-radius: 15px;
} }
@ -92,6 +93,8 @@ html, body {
margin-left: 20px; margin-left: 20px;
margin-top: 20px; margin-top: 20px;
z-index: 2; z-index: 2;
/* Needed for Linux even with higher Z index */
-webkit-app-region: no-drag;
} }
.header-menu-button { .header-menu-button {
@ -227,7 +230,6 @@ html, body {
border-radius: 50%; border-radius: 50%;
/* Set opacity here to not affect child. */ /* Set opacity here to not affect child. */
background-color: rgba(235, 235, 235, 0.75); background-color: rgba(235, 235, 235, 0.75);
cursor: pointer;
box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.15); box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.15);
} }
@ -294,10 +296,8 @@ html, body {
margin-top: 19px; margin-top: 19px;
z-index: 2; z-index: 2;
background-color: Transparent; background-color: Transparent;
} /* Needed for Linux */
-webkit-app-region: no-drag;
.settings-icon:hover {
cursor: pointer;
} }
.settings-account { .settings-account {
@ -314,10 +314,6 @@ html, body {
font-size: 14px; font-size: 14px;
} }
.settings-logout-button:hover {
cursor: pointer;
}
.settings-version { .settings-version {
position: absolute; position: absolute;
left: 50%; left: 50%;

View file

@ -3,7 +3,7 @@ const { Notification, ipcMain } = require("electron");
const store = require("./utils/store"); const store = require("./utils/store");
const { backgroundMitt, ipcEmit } = require("./utils/emitter"); const { backgroundMitt, ipcEmit } = require("./utils/emitter");
const { connectToPlatform, disconnectFromPlatform } = require("./io"); const { connectToPlatform, disconnectFromPlatform } = require("./io");
const { initAudio, terminateAudio, playback, streamState } = require("./audio"); // const { initAudio, terminateAudio, playback, streamState } = require("./audio");
const util = require('util'); const util = require('util');
@ -25,10 +25,12 @@ backgroundMitt.on("message", (message) => messageQueue.push(message));
function handleMessageQueue() function handleMessageQueue()
{ {
if (!streamState.pb && !streamState.rec) // if (!streamState.pb && !streamState.rec)
{ // {
const update = messageQueue.shift(); const update = messageQueue.shift();
console.log(update);
if (update) if (update)
{ {
if (update.person) if (update.person)
@ -67,30 +69,30 @@ function handleMessageQueue()
}).show(); }).show();
/* Ideally, we want a more native solution than this */ /* Ideally, we want a more native solution than this */
if (current.modifier == "ai" && content.category == "audio") // if (current.modifier == "ai" && content.category == "audio")
{ // {
playback(content.blob, current.id); // playback(content.blob, current.id);
} // }
return; return;
} }
ipcEmit("message", update); ipcEmit("message", update);
} }
} // }
} }
function launchSession(account) function launchSession(account)
{ {
connectToPlatform(account); connectToPlatform(account);
initAudio(); // initAudio();
processContentId = setInterval(handleMessageQueue, 100); processContentId = setInterval(handleMessageQueue, 100);
} }
function endSession() function endSession()
{ {
clearInterval(processContentId); clearInterval(processContentId);
terminateAudio(); // terminateAudio();
disconnectFromPlatform(); disconnectFromPlatform();
ui = null; ui = null;
} }

View file

@ -1,14 +0,0 @@
const { app, autoUpdater } = require("electron");
autoUpdater.setFeedURL({ "https://crimata.com" });
async function update()
{
await dialog.showMessageBox({
buttons: ["Ok"],
title: "App Update",
detail: "A new version of the app is available"
});
autoUpdater.quitAndInstall();
}