tests
This commit is contained in:
parent
869f1503c2
commit
694dff14fc
13 changed files with 288 additions and 18 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -4,3 +4,5 @@ config.juml
|
||||||
.vscode
|
.vscode
|
||||||
test
|
test
|
||||||
build
|
build
|
||||||
|
testLocal.juml
|
||||||
|
openssl
|
|
@ -10,6 +10,12 @@ pipeline:
|
||||||
- mkdir build
|
- mkdir build
|
||||||
- npm run prepublish
|
- npm run prepublish
|
||||||
- npm run bundleRelease
|
- npm run bundleRelease
|
||||||
|
test:
|
||||||
|
image: node:18-alpine
|
||||||
|
commands:
|
||||||
|
- apk add openssl
|
||||||
|
- sh genSelfSignedCert.sh
|
||||||
|
- node tests/tester.js ci
|
||||||
buildBin:
|
buildBin:
|
||||||
image: node:18
|
image: node:18
|
||||||
commands:
|
commands:
|
||||||
|
@ -35,3 +41,12 @@ pipeline:
|
||||||
when:
|
when:
|
||||||
event: tag
|
event: tag
|
||||||
secrets: [ gitea_token, api_url ]
|
secrets: [ gitea_token, api_url ]
|
||||||
|
|
||||||
|
|
||||||
|
services:
|
||||||
|
database:
|
||||||
|
image: mysql
|
||||||
|
environment:
|
||||||
|
- MYSQL_DATABASE=outbag
|
||||||
|
- MYSQL_USER=outbag
|
||||||
|
- MYSQL_PASSWORD=12345678
|
3
genSelfSignedCert.sh
Normal file
3
genSelfSignedCert.sh
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
mkdir -p openssl
|
||||||
|
openssl req -nodes -new -x509 -keyout openssl/server.key -out openssl/server.cert -subj '/CN=localhost'
|
||||||
|
touch openssl/server.chain
|
|
@ -45,22 +45,29 @@ export const signup: Act = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let salt = get64(16);
|
let salt = get64(16);
|
||||||
let req = await insert(accounts.name, accounts.rights, accounts.accountKey, accounts.accountKeySalt)
|
try {
|
||||||
.add(data.name, userNum == 0 ? PERMISSIONS.ALL : PERMISSIONS.DEFAULT, sha256(salt + data.accountKey), salt)
|
let req = await insert(accounts.name, accounts.rights, accounts.accountKey, accounts.accountKeySalt)
|
||||||
.query(db);
|
.add(data.name, userNum == 0 ? PERMISSIONS.ALL : PERMISSIONS.DEFAULT, sha256(salt + data.accountKey), salt)
|
||||||
if (req.affectedRows > 0) {
|
.query(db);
|
||||||
let accID = Number(req.insertId);
|
if (req.affectedRows > 0) {
|
||||||
if (!isNaN(accID)) {
|
let accID = Number(req.insertId);
|
||||||
aws("ok", "");
|
if (!isNaN(accID)) {
|
||||||
client.state = STATE.client;
|
aws("ok", "");
|
||||||
client.accID = accID;
|
client.state = STATE.client;
|
||||||
client.name = data.name;
|
client.accID = accID;
|
||||||
client.server = new outbagServer(data.server, oConf.get("System", "URL") + "", oConf.get("System", "PATHexposed") + "", oConf.get("System", "PORTexposed") + "");
|
client.name = data.name;
|
||||||
|
client.server = new outbagServer(data.server, oConf.get("System", "URL") + "", oConf.get("System", "PATHexposed") + "", oConf.get("System", "PORTexposed") + "");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
client.suspect();
|
||||||
|
aws("error", "existence");
|
||||||
}
|
}
|
||||||
} else {
|
} catch (error) {
|
||||||
client.suspect();
|
client.suspect();
|
||||||
aws("error", "existence");
|
aws("error", "existence");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -369,4 +369,4 @@ export const roomMeta: Act = {
|
||||||
.query(db);
|
.query(db);
|
||||||
aws("ok", "");
|
aws("ok", "");
|
||||||
}
|
}
|
||||||
}
|
};
|
|
@ -37,6 +37,9 @@ program
|
||||||
.action(({ config, debug, setup }) => {
|
.action(({ config, debug, setup }) => {
|
||||||
let dofullSetup = false;
|
let dofullSetup = false;
|
||||||
global.debug = debug != null;
|
global.debug = debug != null;
|
||||||
|
if(global.debug){
|
||||||
|
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0";
|
||||||
|
}
|
||||||
if (config) {
|
if (config) {
|
||||||
log("System", "Starting with config:", config);
|
log("System", "Starting with config:", config);
|
||||||
if (!oConf.connect(config)) dofullSetup = true;
|
if (!oConf.connect(config)) dofullSetup = true;
|
||||||
|
@ -75,7 +78,9 @@ async function startServer() {
|
||||||
log("Server", "SSL Enabled");
|
log("Server", "SSL Enabled");
|
||||||
oConf.readPathes(oConf.get("ssl", "privkey"), oConf.get("ssl", "cert"), oConf.get("ssl", "chain"))
|
oConf.readPathes(oConf.get("ssl", "privkey"), oConf.get("ssl", "cert"), oConf.get("ssl", "chain"))
|
||||||
.then(([privkey, cert, chain]: any) => {
|
.then(([privkey, cert, chain]: any) => {
|
||||||
const HTTPserver = https.createServer({ key: privkey, cert: cert, ca: chain }, server);
|
const HTTPserver = chain != "" ?
|
||||||
|
https.createServer({ key: privkey, cert: cert, ca: chain }, server) :
|
||||||
|
https.createServer({ key: privkey, cert: cert }, server);
|
||||||
const wssServer = new WebSocketServer({ server: HTTPserver });
|
const wssServer = new WebSocketServer({ server: HTTPserver });
|
||||||
wssServer.on('connection', wsOnConnection);
|
wssServer.on('connection', wsOnConnection);
|
||||||
serverclose = HTTPserver.listen(oConf.get("System", "PORT"), () => {
|
serverclose = HTTPserver.listen(oConf.get("System", "PORT"), () => {
|
||||||
|
@ -101,7 +106,7 @@ async function complete_loaded() {
|
||||||
startUpdateCert();
|
startUpdateCert();
|
||||||
await wait(500);
|
await wait(500);
|
||||||
let succ = await generateTag();
|
let succ = await generateTag();
|
||||||
if(!succ) error("Outbag", "Could not check own Server Tag. Remote-Auth may not work! Check if the Server is reachable and the config ist correct!");
|
if (!succ) error("Outbag", "Could not check own Server Tag. Remote-Auth may not work! Check if the Server is reachable and the config ist correct!");
|
||||||
activatePost();
|
activatePost();
|
||||||
activateWS();
|
activateWS();
|
||||||
log("Server", 'Listening...');
|
log("Server", 'Listening...');
|
||||||
|
|
|
@ -46,7 +46,7 @@ nMan.addShutdownTask(db.close, 3000, 10);
|
||||||
export const accounts = db.newTable("accounts");
|
export const accounts = db.newTable("accounts");
|
||||||
accounts.addAttributes({
|
accounts.addAttributes({
|
||||||
accID: { type: INT, primaryKey: true, autoIncrement: true },
|
accID: { type: INT, primaryKey: true, autoIncrement: true },
|
||||||
name: { type: VARCHAR(100), default: PERMISSIONS.DEFAULT },
|
name: { type: VARCHAR(100), unique: true, default: PERMISSIONS.DEFAULT },
|
||||||
|
|
||||||
rights: { type: INT, default: PERMISSIONS.DEFAULT },
|
rights: { type: INT, default: PERMISSIONS.DEFAULT },
|
||||||
|
|
||||||
|
|
27
test.juml
Normal file
27
test.juml
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
|
||||||
|
[System]
|
||||||
|
#The Server will listen on this Port!
|
||||||
|
PORT=7224
|
||||||
|
PORTexposed=7224
|
||||||
|
PATHexposed=/
|
||||||
|
URL=localhost
|
||||||
|
CertLiveSec=2592000
|
||||||
|
|
||||||
|
[ssl]
|
||||||
|
enable=true
|
||||||
|
privkey=openssl/server.key
|
||||||
|
cert=openssl/server.cert
|
||||||
|
chain=openssl/server.chain
|
||||||
|
|
||||||
|
[Database]
|
||||||
|
host=database
|
||||||
|
port=3306
|
||||||
|
user=root
|
||||||
|
password=12345678
|
||||||
|
database=outbag
|
||||||
|
|
||||||
|
[Settings]
|
||||||
|
maxUsers=2
|
||||||
|
defaultMaxRooms=3
|
||||||
|
defaultMaxRoomSize=10
|
||||||
|
defaultMaxUsersPerRoom=2
|
3
tests/post.js
Normal file
3
tests/post.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export async function postTester(){
|
||||||
|
|
||||||
|
}
|
43
tests/tester.js
Normal file
43
tests/tester.js
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import { spawn } from "child_process";
|
||||||
|
import { postTester } from "./post.js";
|
||||||
|
import { wsTester } from "./ws.js";
|
||||||
|
|
||||||
|
let inCI = process.argv.includes("ci");
|
||||||
|
|
||||||
|
const ls = spawn('node', ['.', '-c', inCI ? 'test.juml' : 'testLocal.juml', '-d']);
|
||||||
|
|
||||||
|
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;
|
||||||
|
|
||||||
|
ls.stdout.on('data', (data) => {
|
||||||
|
process.stdout.write(data);
|
||||||
|
if(data.includes("Listening...")) test();
|
||||||
|
});
|
||||||
|
|
||||||
|
ls.stderr.on('data', (data) => {
|
||||||
|
console.error(`stderr: ${data}`);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
ls.on('close', (code) => {
|
||||||
|
console.log(`child process exited with code ${code}`);
|
||||||
|
process.exit(code);
|
||||||
|
});
|
||||||
|
|
||||||
|
function kill() {
|
||||||
|
ls.kill('SIGINT');
|
||||||
|
}
|
||||||
|
|
||||||
|
let startet = false;
|
||||||
|
|
||||||
|
async function test() {
|
||||||
|
if(startet) return;
|
||||||
|
startet = true;
|
||||||
|
console.log("Start testing");
|
||||||
|
let url = "localhost:7224";
|
||||||
|
await wsTester("wss://" + url + "/", kill);
|
||||||
|
await postTester("https://" + url + "/", kill);
|
||||||
|
kill();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
132
tests/ws.js
Normal file
132
tests/ws.js
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
import WebSocket from 'ws';
|
||||||
|
import { generateSigningKey, sign } from '../dist/sys/crypto.js';
|
||||||
|
import { uts, wait } from '../dist/sys/tools.js';
|
||||||
|
import * as ws from "./ws/ws.js"
|
||||||
|
|
||||||
|
function conn(url) {
|
||||||
|
const ws = new WebSocket(url);
|
||||||
|
|
||||||
|
ws.on('close', function open() {
|
||||||
|
wsOpen = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
let wsOpen = true;
|
||||||
|
|
||||||
|
var list = [];
|
||||||
|
var c = 0;
|
||||||
|
|
||||||
|
ws.on('message', function message(data) {
|
||||||
|
data = data.toString();
|
||||||
|
if (data == "error") return void console.log("Server error");
|
||||||
|
var json = JSON.parse(data);
|
||||||
|
for (let i = 0; i < list.length; i++) {
|
||||||
|
const e = list[i];
|
||||||
|
if (e[0] == json.id) {
|
||||||
|
e[2]({ state: json.state, data: json.data });
|
||||||
|
list.splice(i, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.close = function () {
|
||||||
|
ws.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
for (let i = 0; i < list.length; i++) {
|
||||||
|
const e = list[i];
|
||||||
|
if (e[1] + 5 < uts()) {
|
||||||
|
e[2]("timeout");
|
||||||
|
list.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
function req(act, data) {
|
||||||
|
return new Promise((res, rej) => {
|
||||||
|
if (!wsOpen) {
|
||||||
|
console.error("WebSocket is closed");
|
||||||
|
rej("WebSocket is closed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var id = ++c;
|
||||||
|
list.push([id, uts(), res, rej]);
|
||||||
|
ws.send(JSON.stringify({
|
||||||
|
id,
|
||||||
|
act,
|
||||||
|
data
|
||||||
|
}));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.req = req;
|
||||||
|
};
|
||||||
|
|
||||||
|
function shallowEqual(object1, object2) {
|
||||||
|
const keys1 = Object.keys(object1);
|
||||||
|
const keys2 = Object.keys(object2);
|
||||||
|
if (keys1.length < keys2.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (let key of keys1) {
|
||||||
|
if (object1[key] != object2[key]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export async function wsTester(url, kill) {
|
||||||
|
async function test(conn, act, data, expState, expData) {
|
||||||
|
console.log("Testing Act:", act, "with Data:", data);
|
||||||
|
let resp = await conn.req(act, data);
|
||||||
|
if (resp.state != expState) {
|
||||||
|
console.error(`Expected state: '${expState}', but got: '${resp.state}'`);
|
||||||
|
kill();
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
if (typeof expData == "object" && expData != null) {
|
||||||
|
if (!shallowEqual(expData, resp.data)) {
|
||||||
|
console.error(`Expected data: '${expData}', but got: '${resp.data}'`);
|
||||||
|
kill();
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (expData != resp.data) {
|
||||||
|
console.error(`Expected data: '${expData}', but got: '${resp.data}'`);
|
||||||
|
kill();
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const k in ws) {
|
||||||
|
console.log(`Testing '${k}':`);
|
||||||
|
const handler = [new conn(url)];
|
||||||
|
await wait(100);
|
||||||
|
const currTest = ws[k];
|
||||||
|
let resp = true;
|
||||||
|
try {
|
||||||
|
resp = await currTest(handler[0], test, async ()=>{
|
||||||
|
let h = new conn(url);
|
||||||
|
await wait(100);
|
||||||
|
handler.push(h);
|
||||||
|
return h;
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Test Error: ", error);
|
||||||
|
kill();
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
handler.forEach(h=>h.close());
|
||||||
|
if (resp === false) {
|
||||||
|
console.log("Test respond with error indication!");
|
||||||
|
kill();
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
32
tests/ws/login.js
Normal file
32
tests/ws/login.js
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
let name1 = "testUser1";
|
||||||
|
let name2 = "testUser2";
|
||||||
|
let name3 = "testUser3";
|
||||||
|
let accountKey = "123456789";
|
||||||
|
|
||||||
|
export const signup = async (handler, req, newHandler) => {
|
||||||
|
await req(handler, "signup", {
|
||||||
|
name: name1,
|
||||||
|
server: "localhost:7224",
|
||||||
|
accountKey
|
||||||
|
}, "ok", "");
|
||||||
|
await req(handler, "signup", {
|
||||||
|
name: name1,
|
||||||
|
server: "localhost:7224",
|
||||||
|
accountKey
|
||||||
|
}, "error", "wrongstate");
|
||||||
|
await req(await newHandler(), "signup", {
|
||||||
|
name: name1,
|
||||||
|
server: "localhost:7224",
|
||||||
|
accountKey
|
||||||
|
}, "error", "existence");
|
||||||
|
await req(await newHandler(), "signup", {
|
||||||
|
name: name2,
|
||||||
|
server: "localhost:7224",
|
||||||
|
accountKey
|
||||||
|
}, "ok", "");
|
||||||
|
await req(await newHandler(), "signup", {
|
||||||
|
name: name2,
|
||||||
|
server: "localhost:7224",
|
||||||
|
accountKey
|
||||||
|
}, "error", "config");
|
||||||
|
};
|
1
tests/ws/ws.js
Normal file
1
tests/ws/ws.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export * from "./login.js";
|
Loading…
Reference in a new issue