Fix jamid.node path in server

Add npm script in server to generate keys.
Improve dockerfile to generate server keys.
Add dotenv and dotenv-cli dependencies to server

Change-Id: Ibcb21578b4cb59d3bc9a99fa0e832d3b30cfb01a
diff --git a/server/.gitignore b/server/.gitignore
index 54fcf25..efc99e0 100644
--- a/server/.gitignore
+++ b/server/.gitignore
@@ -1,2 +1 @@
 creds.json
-*.pem
diff --git a/server/misc/gen_key_pair.sh b/server/misc/gen_key_pair.sh
deleted file mode 100755
index ea60e05..0000000
--- a/server/misc/gen_key_pair.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-set -ex
-
-# Generate PEM-encoded PKCS#8 private key and PEM-encoded SPKI public key
-
-if command -v openssl; then
-  # -algorithm RSA -pkeyopt rsa_keygen_bits:2048
-  # ES256: -algorithm EC -pkeyopt ec_paramgen_curve:P-256
-  gen_pkcs8() { openssl genpkey -algorithm ed25519; }
-  pkcs8_to_spki() { openssl pkey -pubout; }
-else
-  printf 'No tools known\n' >&2 && exit 1
-fi
-
-gen_pkcs8 | tee ./privkey.pem | pkcs8_to_spki >./pubkey.pem
diff --git a/server/package.json b/server/package.json
index 6d17ce8..b11c92d 100644
--- a/server/package.json
+++ b/server/package.json
@@ -9,13 +9,16 @@
     "lint": "eslint src",
     "lint:fix": "eslint --fix src",
     "format": "prettier --write src",
-    "format:check": "prettier --check src"
+    "format:check": "prettier --check src",
+    "prepare": "npm run genkeys",
+    "genkeys": "sh scripts/genkeys.sh"
   },
   "devDependencies": {
     "@types/express": "^4.17.14",
     "@types/node": "^18.8.3",
     "@types/whatwg-url": "^11.0.0",
     "@types/ws": "^8.5.3",
+    "dotenv-cli": "^6.0.0",
     "nodemon": "^2.0.20",
     "npm-check-updates": "^16.3.3",
     "ts-node": "^10.9.1",
@@ -24,6 +27,7 @@
   },
   "dependencies": {
     "argon2": "^0.29.1",
+    "dotenv": "^16.0.3",
     "express": "^4.18.2",
     "express-async-handler": "^1.2.0",
     "helmet": "^6.0.0",
diff --git a/server/scripts/genkeys.sh b/server/scripts/genkeys.sh
new file mode 100755
index 0000000..18f1bdf
--- /dev/null
+++ b/server/scripts/genkeys.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+set -e
+
+if ! command -v dotenv; then
+  printf 'Missing "dotenv". Please run "npm install"\n' >&2 && exit 1
+fi
+
+if [ "$(dotenv -p PRIVATE_KEY)" ] && [ "$(dotenv -p PUBLIC_KEY)" ]; then
+  printf 'Public and private keys are already defined. Exiting...\n' >&2 && exit 0
+fi
+
+# Generate PEM-encoded PKCS#8 private key and PEM-encoded SPKI public key
+
+if command -v openssl; then
+  # -algorithm RSA -pkeyopt rsa_keygen_bits:2048
+  # ES256: -algorithm EC -pkeyopt ec_paramgen_curve:P-256
+  gen_pkcs8() { openssl genpkey -algorithm ed25519; }
+  pkcs8_to_spki() { openssl pkey -pubout; }
+else
+  printf 'No tools known\n' >&2 && exit 1
+fi
+
+private_key=$(gen_pkcs8)
+public_key=$(echo "${private_key}" | pkcs8_to_spki)
+
+echo "PRIVATE_KEY=\"${private_key}\"" >> .env
+echo "PUBLIC_KEY=\"${public_key}\"" >> .env
diff --git a/server/src/index.ts b/server/src/index.ts
index ec7067e..d00f78b 100644
--- a/server/src/index.ts
+++ b/server/src/index.ts
@@ -17,6 +17,9 @@
  */
 import 'reflect-metadata';
 
+import * as dotenv from 'dotenv';
+dotenv.config();
+
 import { createServer } from 'node:http';
 
 import log from 'loglevel';
diff --git a/server/src/jamid/jamid.ts b/server/src/jamid/jamid.ts
index 51394eb..48c20f2 100644
--- a/server/src/jamid/jamid.ts
+++ b/server/src/jamid/jamid.ts
@@ -38,7 +38,7 @@
 
   constructor() {
     // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
-    this.jamiSwig = require('../../jamid.node') as JamiSwig;
+    this.jamiSwig = require('../../jamid.node') as JamiSwig; // TODO: we should put the path in the .env
 
     const handlers: Record<string, unknown> = {};
     const handler = (sig: string) => {
diff --git a/server/src/vault.ts b/server/src/vault.ts
index 45548db..07e2914 100644
--- a/server/src/vault.ts
+++ b/server/src/vault.ts
@@ -15,8 +15,6 @@
  * License along with this program.  If not, see
  * <https://www.gnu.org/licenses/>.
  */
-import { readFile } from 'node:fs/promises';
-
 import { importPKCS8, importSPKI, KeyLike } from 'jose';
 import { Service } from 'typedi';
 
@@ -25,13 +23,16 @@
   privateKey!: KeyLike;
   publicKey!: KeyLike;
 
-  // TODO: Convert to environment variables and check if defined
   async build() {
-    const privateKeyBuffer = await readFile('privkey.pem');
-    this.privateKey = await importPKCS8(privateKeyBuffer.toString(), 'EdDSA');
+    const privatekey = process.env.PRIVATE_KEY;
+    const publicKey = process.env.PUBLIC_KEY;
 
-    const publicKeyBuffer = await readFile('pubkey.pem');
-    this.publicKey = await importSPKI(publicKeyBuffer.toString(), 'EdDSA');
+    if (!privatekey || !publicKey) {
+      throw new Error('Missing private or public key environment variables. Try running "npm run genkeys"');
+    }
+
+    this.privateKey = await importPKCS8(privatekey, 'EdDSA');
+    this.publicKey = await importSPKI(publicKey, 'EdDSA');
 
     return this;
   }