This commit is contained in:
Sam Hadow 2025-02-10 17:08:50 +01:00
parent 4827e6ae57
commit e5ffbac3ea
9 changed files with 102 additions and 9 deletions

View File

@ -2,7 +2,7 @@
run: clean build run: clean build
podman pod create --name=e2ee -p 3333:3333 podman pod create --name=e2ee -p 3333:3333
podman run -d --pod=e2ee -e POSTGRES_PASSWORD="password" -e POSTGRES_DB="e2ee" -e POSTGRES_USER="e2ee" -e POSTGRES_INITDB_ARGS="--encoding=UTF-8 --lc-collate=C --lc-ctype=C" --name=e2ee-db docker.io/library/postgres:15 podman run -d --pod=e2ee -e POSTGRES_PASSWORD="password" -e POSTGRES_DB="e2ee" -e POSTGRES_USER="e2ee" -e POSTGRES_INITDB_ARGS="--encoding=UTF-8 --lc-collate=C --lc-ctype=C" --name=e2ee-db docker.io/library/postgres:15
podman run -d --pod=e2ee -e POSTGRES_PASSWORD="password" -e POSTGRES_DB="e2ee" -e POSTGRES_USER="e2ee" --name=e2ee-app e2ee-messaging-service:latest podman run -d --pod=e2ee -e POSTGRES_PASSWORD="password" -e POSTGRES_DB="e2ee" -e POSTGRES_USER="e2ee" -e SHARED_SECRET="toto" --name=e2ee-app e2ee-messaging-service:latest
build: build:
podman build -t e2ee-messaging-service . podman build -t e2ee-messaging-service .
test: test:

View File

@ -6,6 +6,7 @@ app.set("port", port);
var io = require('socket.io')(http); var io = require('socket.io')(http);
const cookieParser = require('cookie-parser'); const cookieParser = require('cookie-parser');
app.use(cookieParser()); app.use(cookieParser());
app.use(express.json());
// bootstrap // bootstrap
app.use('/css', express.static(__dirname + '/node_modules/bootstrap/dist/css')); app.use('/css', express.static(__dirname + '/node_modules/bootstrap/dist/css'));

9
src/authentication.js Normal file
View File

@ -0,0 +1,9 @@
const sharedSecret = process.env.SHARED_SECRET;
const authentication = {
checkSharedSecret: (providedSecret) => {
return sharedSecret === providedSecret;
}
};
module.exports = authentication;

View File

@ -1,4 +1,6 @@
const crypto = require('crypto'); const crypto = require('crypto');
const database = require("../db");
const authentication = require("../authentication");
const accountController = { const accountController = {
getCookie: (req, res) => { getCookie: (req, res) => {
@ -18,6 +20,24 @@ const accountController = {
console.log("cookie set"); console.log("cookie set");
} }
res.redirect('/'); res.redirect('/');
},
register: async (req, res) => {
try {
const { sharedSecret, publicKey } = req.body;
if (!sharedSecret || !publicKey) {
return res.status(400).json({ error: "Missing sharedSecret or publicKey" });
}
console.log('Received data:', { sharedSecret, publicKey });
if (authentication.checkSharedSecret(sharedSecret)) {
database.addUser(publicKey);
} else {
return res.status(400).json({ error: "Wrong sharedSecret" });
}
return res.status(201).json({ message: "Registration successful" });
} catch (error) {
console.error("Error during registration:", error);
return res.status(500).json({ error: "Server error during registration" });
}
} }
}; };

View File

@ -83,6 +83,23 @@ const database = {
} }
}); });
}); });
},
addUser: async (pubkey) => {
if (!pubkey) {
console.error("Pubkey is required");
return;
}
try {
const result = await pool.query('SELECT NEXTVAL(\'uuid_sequence\') AS next_uuid');
const nextUuid = result.rows[0].next_uuid;
await pool.query(
'INSERT INTO "user" (uuid, pubkey) VALUES ($1, $2)',
[nextUuid, pubkey]
);
console.log(`Added user with the public key ${pubkey} .`);
} catch (err) {
console.error('Error adding user:', err);
}
} }
}; };

View File

@ -15,10 +15,6 @@ function exportedKeyToPem(key, type) {
async function genKey() { async function genKey() {
// Generate keys // Generate keys
const { publicKey, privateKey } = await crypto.subtle.generateKey( const { publicKey, privateKey } = await crypto.subtle.generateKey(
// {
// name: "ECDSA",
// namedCurve: "P-384",
// },
{ {
name: "Ed25519", name: "Ed25519",
}, },
@ -28,9 +24,11 @@ async function genKey() {
const exportedPubkey = await crypto.subtle.exportKey("spki", publicKey); const exportedPubkey = await crypto.subtle.exportKey("spki", publicKey);
const exportedPrivkey = await crypto.subtle.exportKey("pkcs8", privateKey); const exportedPrivkey = await crypto.subtle.exportKey("pkcs8", privateKey);
// const privkey = await crypto.subtle.wrapKey("pkcs8", privateKey, wrapkey, { name: "AES-KW" }); // const privkey = await crypto.subtle.wrapKey("pkcs8", privateKey, wrapkey, { name: "AES-KW" });
const key = {
console.log(`publicKey: ${exportedKeyToPem(exportedPubkey, publicKey.type)}`); privateKey: exportedPrivkey,
console.log(`privateKey: ${exportedKeyToPem(exportedPrivkey, privateKey.type)}`); publicKey: exportedPubkey
}
return key;
} }
async function test(data) { async function test(data) {

View File

@ -23,11 +23,12 @@
<div id="registerPopup" class="popup"> <div id="registerPopup" class="popup">
<div class="popup-content"> <div class="popup-content">
<div class="btn-group mr-2 w-100" role="group" aria-label="Add group"> <div class="btn-group mr-2 w-100" role="group" aria-label="Add group">
<input id="sharedsecret" type="text" class="form-control input-sm w-50" placeholder="shared secret" required> <input id="sharedsecret" type="password" class="form-control input-sm w-50" placeholder="shared secret" required>
<input id="publickey" type="text" class="form-control input-sm w-50" placeholder="public key"> <input id="publickey" type="text" class="form-control input-sm w-50" placeholder="public key">
<button id="registerconfirm" class="btn btn-secondary" type="button">register</button> <button id="registerconfirm" class="btn btn-secondary" type="button">register</button>
<button id="registercancel" class="btn btn-secondary" type="button">cancel</button> <button id="registercancel" class="btn btn-secondary" type="button">cancel</button>
</div> </div>
<div id="registerPopupText"></div>
</div> </div>
</div> </div>
<a href="./account/cookie" class="btn btn-primary">Get cookie</a> <a href="./account/cookie" class="btn btn-primary">Get cookie</a>

View File

@ -1,9 +1,12 @@
const currentUrl = window.location.href;
// close popups with escape key // close popups with escape key
document.addEventListener("keydown", (event) => { document.addEventListener("keydown", (event) => {
if (event.isComposing || event.key === 'Escape') { if (event.isComposing || event.key === 'Escape') {
Array.from(document.getElementsByClassName("popup")).forEach(function(x) { Array.from(document.getElementsByClassName("popup")).forEach(function(x) {
x.style.display = 'none'; x.style.display = 'none';
}); });
document.getElementById("registerPopupText").innerText = "";
} }
}); });
@ -14,4 +17,44 @@ document.getElementById("register").addEventListener("click", function () {
// cancel // cancel
document.getElementById("registercancel").addEventListener("click", function () { document.getElementById("registercancel").addEventListener("click", function () {
registerPopup.style.display = 'none'; registerPopup.style.display = 'none';
document.getElementById("registerPopupText").innerText = "";
});
// confirm
document.getElementById("registerconfirm").addEventListener("click", async function () {
const apiUrl = `${currentUrl}account/register`;
const inputFieldSharedSecret = document.getElementById("sharedsecret");
const inputFieldPublicKey = document.getElementById("publickey");
let pubkey = null;
if (!inputFieldPublicKey.value) {
const { privateKey, publicKey } = await genKey();
pubkey = exportedKeyToPem(publicKey, "public");
document.getElementById("registerPopupText").innerText = exportedKeyToPem(privateKey, "private");
} else {
pubkey = inputFieldPublicKey.value;
}
const postData = {
sharedSecret: inputFieldSharedSecret.value,
publicKey: pubkey
};
// clear input fields
inputFieldSharedSecret.value='';
inputFieldPublicKey.value='';
const requestOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(postData)
};
const response = await fetch(apiUrl, requestOptions)
.catch(error => {
console.error('Error during POST request:', error);
});
if (response.ok) {
console.log(response);
} else {
throw new Error('Error in server response');
}
}); });

View File

@ -6,4 +6,8 @@ router
.route("/cookie") .route("/cookie")
.get(accountController.getCookie); .get(accountController.getCookie);
router
.route("/register")
.post(accountController.register);
module.exports = router; module.exports = router;