Compare commits

...

10 commits

Author SHA1 Message Date
4f7835ccbe
adding subscribe to event act, todo: passthrough remote 2024-02-25 13:41:04 +01:00
4393a2b226
small fixes 2024-02-25 13:40:35 +01:00
255b3fd215
bug fix: client push 2024-02-23 23:17:43 +01:00
2eea58808b
bug fix 2024-02-22 21:26:13 +01:00
b0d949b350
npm update 2023-04-06 23:47:45 +02:00
4ffb09e2b8
change warn color to orange 2023-04-06 23:17:27 +02:00
39475fdb47
recover Account 2023-04-06 14:10:05 +02:00
b70527032e
getAccounts added delete time 2023-04-06 14:02:43 +02:00
76d314ec00
auto delete accounts after set time 2023-04-06 13:55:21 +02:00
10760e77f2
fix data error 2023-04-05 19:28:41 +02:00
21 changed files with 679 additions and 688 deletions

1008
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -3,4 +3,5 @@ export * from "./acts/client.js"
export * from "./acts/admin.js"
export * from "./acts/rooms.js"
export * from "./acts/server.js"
export * from "./acts/roomContent.js"
export * from "./acts/roomContent.js"
export * from "./acts/subscribe.js"

View file

@ -17,6 +17,7 @@ export const getAccounts: Act = {
accounts.name,
accounts.viewable,
accounts.deleted,
accounts.deletedTime,
accounts.maxRooms,
accounts.maxRoomSize,
accounts.maxUsersPerRoom
@ -28,11 +29,12 @@ export const getAccounts: Act = {
let name = d[accounts.name];
let viewable = d[accounts.viewable] ? true : false;
let deleted = d[accounts.deleted] ? true : false;
let deletedTime = Number(d[accounts.deletedTime]);
let maxRooms = d[accounts.maxRooms];
let maxRoomSize = d[accounts.maxRoomSize];
let maxUsersPerRoom = d[accounts.maxUsersPerRoom];
if (accID != null && rights != null && name != null && viewable != null && deleted != null && maxRooms != null && maxRoomSize != null && maxUsersPerRoom != null) {
return { accID, rights, name, viewable, deleted, maxRooms, maxRoomSize, maxUsersPerRoom };
if (accID != null && rights != null && name != null && viewable != null && deleted != null && maxRooms != null && maxRoomSize != null && maxUsersPerRoom != null && deletedTime != null) {
return { accID, rights, name, viewable, deleted, deletedTime, maxRooms, maxRoomSize, maxUsersPerRoom };
}
return null;
});
@ -40,6 +42,23 @@ export const getAccounts: Act = {
}
};
export const recoverAccount: Act = {
state: STATE.client,
right: PERMISSIONS.CAN_USE_API | PERMISSIONS.EDIT_USERS,
data: {
accID: "number"
},
func: async (client: Client, data: any, aws: (code: string, data: any) => void) => {
let req = await update(accounts)
.set(accounts.deleted, false)
.set(accounts.deletedTime, 0)
.where(eq(accounts.accID, data.accID))
.query(db);
if(req.affectedRows > 0) aws("ok", "");
else aws("error", act_error.ACCOUNT_NOT_EXISTS)
}
}
export const setPermissions: Act = {
state: STATE.client,
right: PERMISSIONS.CAN_USE_API | PERMISSIONS.EDIT_RIGHTS,
@ -150,7 +169,7 @@ export const addOTA: Act = { // or change it, primary key is the token
let resp = await insert(signupOTA.token, signupOTA.expires, signupOTA.usesLeft)
.add(data.token, data.expires, data.usesLeft)
.query(db);
if(resp.affectedRows == 0) throw new Error("insertion fail");
if (resp.affectedRows == 0) throw new Error("insertion fail");
} catch (error) {
await update(signupOTA)
.set(signupOTA.expires, data.expires)

View file

@ -18,6 +18,7 @@ export const deleteAccount: Act = {
client.state = STATE.no;
await update(accounts)
.set(accounts.deleted, 1)
.set(accounts.deletedTime, uts())
.where(eq(accounts.accID, client.accID))
.query(db);
aws("ok", "");

View file

@ -6,6 +6,8 @@ import { isCategoryInRoom, isItemInRoom, isProductInRoom, isRoomDataFull } from
import { ROOM_RIGHTS } from "../../server/permissions.js";
import { act_error } from "../../server/errors.js";
import { uts } from "../../sys/tools.js";
import { sendRoomListeners } from "../listener.js";
import { LISTENER_ACTION, LISTENER_TYPE } from "../../server/listener.js";
export const getCategories: Act = {
state: STATE.client | STATE.remote,
@ -128,10 +130,12 @@ export const addCategory: Act = {
.where(eq(listCategories.roomID, roomID))
.limit(1)
).query(db);
if (req.affectedRows > 0) aws("ok", {
catID: Number(req.insertId)
});
else aws("error", act_error.ADD_CAT);
if (req.affectedRows > 0) {
aws("ok", {
catID: Number(req.insertId)
});
sendRoomListeners(roomID, LISTENER_TYPE.CATEGORIES, LISTENER_ACTION.ADD, [req.insertId]);
} else aws("error", act_error.ADD_CAT);
}
};
@ -165,8 +169,10 @@ export const changeCategory: Act = {
eq(listCategories.listCatID, data.listCatID)
))
.query(db);
if (req.affectedRows > 0) aws("ok", "");
else aws("error", act_error.CAT_NOT_EXISTS);
if (req.affectedRows > 0) {
aws("ok", "");
sendRoomListeners(roomID, LISTENER_TYPE.CATEGORIES, LISTENER_ACTION.CHANGE, [data.listCatID]);
} else aws("error", act_error.CAT_NOT_EXISTS);
}
};
@ -202,8 +208,10 @@ export const changeCategoriesOrder: Act = {
.query(db);
affacted += req.affectedRows;
}
if (affacted > 0) aws("ok", "");
else aws("error", act_error.CAT_NOT_EXISTS);
if (affacted > 0) {
aws("ok", "");
sendRoomListeners(roomID, LISTENER_TYPE.CATEGORIES, LISTENER_ACTION.CHANGE, data.listCatIDs);
} else aws("error", act_error.CAT_NOT_EXISTS);
}
};
@ -233,8 +241,10 @@ export const deleteCategory: Act = {
eq(listCategories.listCatID, data.listCatID)
))
.query(db);
if (req.affectedRows > 0) aws("ok", "");
else aws("error", act_error.CAT_NOT_EXISTS);
if (req.affectedRows > 0) {
aws("ok", "");
sendRoomListeners(roomID, LISTENER_TYPE.CATEGORIES, LISTENER_ACTION.DELETE, [data.listCatID]);
} else aws("error", act_error.CAT_NOT_EXISTS);
}
};
@ -383,10 +393,12 @@ export const addProduct: Act = {
data.ean,
data.parent != null ? data.parent : null,
).query(db);
if (req.affectedRows > 0) aws("ok", {
listProdID: Number(req.insertId)
});
else aws("error", act_error.ADD_PROD);
if (req.affectedRows > 0) {
aws("ok", {
listProdID: Number(req.insertId)
});
sendRoomListeners(roomID, LISTENER_TYPE.PRODUCTS, LISTENER_ACTION.ADD, [req.insertId]);
} else aws("error", act_error.ADD_PROD);
}
};
@ -434,8 +446,10 @@ export const changeProduct: Act = {
eq(listProducts.roomID, roomID),
))
.query(db);
if (req.affectedRows > 0) aws("ok", "");
else aws("error", act_error.PROD_NOT_EXISTS);
if (req.affectedRows > 0) {
aws("ok", "");
sendRoomListeners(roomID, LISTENER_TYPE.PRODUCTS, LISTENER_ACTION.CHANGE, [data.listProdID]);
} else aws("error", act_error.PROD_NOT_EXISTS);
}
};
@ -465,8 +479,10 @@ export const deleteProduct: Act = {
eq(listProducts.listProdID, data.listProdID),
eq(listProducts.roomID, roomID),
)).query(db);
if (req.affectedRows > 0) aws("ok", "");
else aws("error", act_error.PROD_NOT_EXISTS);
if (req.affectedRows > 0) {
aws("ok", "");
sendRoomListeners(roomID, LISTENER_TYPE.PRODUCTS, LISTENER_ACTION.DELETE, [data.listProdID]);
} else aws("error", act_error.PROD_NOT_EXISTS);
}
};
@ -559,7 +575,7 @@ export const getItem: Act = {
], listItems)
.where(and(
eq(listItems.listItemID, data.listItemID),
eq(listItems.roomID, data.roomID)
eq(listItems.roomID, roomID)
))
.query(db);
if (req.length > 0) {
@ -634,12 +650,14 @@ export const addItem: Act = {
data.listCatID != null ? data.listCatID : null,
data.unit,
data.value,
data.listProdID != null ? data.parent : null,
data.listProdID != null ? data.listProdID : null,
).query(db);
if (req.affectedRows > 0) aws("ok", {
listItemID: Number(req.insertId)
});
else aws("error", act_error.ADD_ITEM);
if (req.affectedRows > 0) {
aws("ok", {
listItemID: Number(req.insertId)
});
sendRoomListeners(roomID, LISTENER_TYPE.ITEMS, LISTENER_ACTION.ADD, [req.insertId]);
} else aws("error", act_error.ADD_ITEM);
}
};
@ -684,11 +702,13 @@ export const changeItem: Act = {
.set(listItems.link, data.listProdID != null ? data.listProdID : null)
.where(and(
eq(listItems.listItemID, data.listItemID),
eq(listItems.roomID, data.roomID)
eq(listItems.roomID, roomID)
))
.query(db);
if (req.affectedRows > 0) aws("ok", "");
else aws("error", act_error.ITEM_NOT_EXISTS);
if (req.affectedRows > 0) {
aws("ok", "");
sendRoomListeners(roomID, LISTENER_TYPE.ITEMS, LISTENER_ACTION.CHANGE, [data.listItemID]);
} else aws("error", act_error.ITEM_NOT_EXISTS);
}
};
@ -723,8 +743,10 @@ export const changeItemState: Act = {
eq(listItems.roomID, roomID)
))
.query(db);
if (req.affectedRows > 0) aws("ok", "");
else aws("error", act_error.ITEM_NOT_EXISTS);
if (req.affectedRows > 0) {
aws("ok", "");
sendRoomListeners(roomID, LISTENER_TYPE.ITEMS, LISTENER_ACTION.CHANGE, [data.listItemID]);
} else aws("error", act_error.ITEM_NOT_EXISTS);
}
};
@ -753,7 +775,12 @@ export const changeItemStates: Act = {
if (
data.listItemIDs.length != data.changedTimes.length
|| data.changedTimes.length != data.states.length
) return void aws("error", "data");
) return void aws("error", act_error.DATA);
for (let i = 0; i < data.listItemIDs.length; i++) {
let id = data.listItemIDs[i];
if (typeof id != "number" || id < 0)
return void aws("error", act_error.DATA);
}
for (let i = 0; i < data.listItemIDs.length; i++) {
let id = data.listItemIDs[i];
let time = data.changedTimes[i];
@ -769,6 +796,7 @@ export const changeItemStates: Act = {
.query(db);
}
aws("ok", "");
sendRoomListeners(roomID, LISTENER_TYPE.ITEMS, LISTENER_ACTION.CHANGE, data.listItemIDs);
}
};
@ -797,8 +825,10 @@ export const deleteItem: Act = {
eq(listItems.listItemID, data.listItemID),
eq(listItems.roomID, roomID)
)).query(db);
if (req.affectedRows > 0) aws("ok", "");
else aws("error", act_error.ITEM_NOT_EXISTS);
if (req.affectedRows > 0) {
aws("ok", "");
sendRoomListeners(roomID, LISTENER_TYPE.ITEMS, LISTENER_ACTION.DELETE, [data.listItemID]);
} else aws("error", act_error.ITEM_NOT_EXISTS);
}
};
export const deleteItemByState: Act = {
@ -827,5 +857,6 @@ export const deleteItemByState: Act = {
eq(listItems.roomID, roomID)
)).query(db);
aws("ok", "");
sendRoomListeners(roomID, LISTENER_TYPE.ITEMS, LISTENER_ACTION.DELETE, []);
}
}

View file

@ -8,6 +8,8 @@ import { isRoomFull } from "../helper.js";
import { fetchRemoteAsServer } from "../server.js";
import { Act, Client, STATE } from "../user.js";
import { act_error } from "../../server/errors.js";
import { sendRoomListeners } from "../listener.js";
import { LISTENER_ACTION, LISTENER_TYPE } from "../../server/listener.js";
export const listRooms: Act = {
state: STATE.client | STATE.remote,
@ -46,7 +48,7 @@ export const listRooms: Act = {
if (name != null && owner != null && rights != null && visibility != null && title != null && description != null && icon != null && confirmed != null) {
return { name, server, owner, rights, visibility, title, description, icon, debug: global.debug, confirmed };
}
console.log(name, server, owner, rights, visibility, title, description, icon, global.debug, confirmed)
//console.log(name, server, owner, rights, visibility, title, description, icon, global.debug, confirmed)
return null;
});
if (client.state == STATE.client) {
@ -608,6 +610,7 @@ export const setAdminStatus: Act = {
} else {
aws("error", act_error.MEMBER_NOT_EXISTS);
}
sendRoomListeners(roomID, LISTENER_TYPE.ROOMINFO, LISTENER_ACTION.CHANGE, []);
}
};
@ -617,6 +620,7 @@ export const leaveRoom: Act = {
data: {
room: "string",
server: "string",
// TODO: add force option for remote rooms
},
func: async (client: Client, data: any, aws: (code: string, data: any) => void) => {
if (!checkSelfTag(data.server)) {
@ -706,6 +710,7 @@ export const setRoomRight: Act = {
.where(eq(rooms.roomID, roomID))
.query(db);
aws("ok", "");
sendRoomListeners(roomID, LISTENER_TYPE.ROOMINFO, LISTENER_ACTION.CHANGE, []);
}
};
@ -735,5 +740,6 @@ export const changeRoomMeta: Act = {
.where(eq(rooms.roomID, roomID))
.query(db);
aws("ok", "");
sendRoomListeners(roomID, LISTENER_TYPE.ROOMINFO, LISTENER_ACTION.CHANGE, []);
}
};

68
src/api/acts/subscribe.ts Normal file
View file

@ -0,0 +1,68 @@
import { act_error } from "../../server/errors.js";
import { checkSelfTag } from "../../server/outbagURL.js";
import { Act, Client, STATE } from "../user.js";
import { wsClient } from "../ws.js";
export const subscribeRoom: Act = {
state: STATE.client | STATE.remote,
right: 0,
data: {
room: "name",
server: "string",
},
func: async (client: Client, data: any, aws: (code: string, data: any) => void) => {
if (!(client.connectionClient instanceof wsClient)) {
return void aws("error", act_error.CONNECTION);
}
if (!checkSelfTag(data.server)) {
throw new Error("Remote not yet implemented.");
return;
}
const roomID = await client.isInRoom(data.room);
if (roomID == -1) {
aws("error", act_error.NOT_IN_ROOM);
return;
}
client.connectionClient.listenRoom(roomID, data.room, data.server);
aws("ok", "");
}
};
export const unsubscribeRoom: Act = {
state: STATE.client | STATE.remote,
right: 0,
data: {
room: "name",
server: "string",
},
func: async (client: Client, data: any, aws: (code: string, data: any) => void) => {
if (!(client.connectionClient instanceof wsClient)) {
return void aws("error", act_error.CONNECTION);
}
if (!checkSelfTag(data.server)) {
throw new Error("Remote not yet implemented.");
return;
}
const roomID = await client.isInRoom(data.room);
if (roomID == -1) {
aws("error", act_error.NOT_IN_ROOM);
return;
}
client.connectionClient.unlistenRoom(roomID);
aws("ok", "");
}
};
export const unsubscribeAllRooms: Act = {
state: STATE.client | STATE.remote,
right: 0,
data: {},
func: async (client: Client, data: any, aws: (code: string, data: any) => void) => {
if (!(client.connectionClient instanceof wsClient)) {
return void aws("error", act_error.CONNECTION);
}
// TODO: When implemented close remote listeners
client.connectionClient.unlistenAllRooms();
aws("ok", "");
}
};

38
src/api/listener.ts Normal file
View file

@ -0,0 +1,38 @@
import { wsClient } from "./ws.js"
interface RoomListener {
client: wsClient;
room: string;
server: string;
}
let roomListeners: { [key: number]: RoomListener[] } = {};
export const sendRoomListeners = async (roomID: number, type: string | number, action: number, ids: number[]) => {
for (const listener of roomListeners[roomID] ?? []) {
listener.client.sendFromServer({
room: listener.room,
server: listener.server,
type,
action,
ids,
});
}
};
export const addRoomListener = (client: wsClient, roomID: number, room: string, server: string) => {
if (!Array.isArray(roomListeners[roomID])) roomListeners[roomID] = [];
const existingListener = roomListeners[roomID].find(listener => listener.client === client);
if (!existingListener) roomListeners[roomID].push({ client, room, server });
};
export const removeRoomListener = (client: wsClient, roomID: number | null = null) => {
let keys = roomID == null ? Object.keys(roomListeners) as any : [roomID];
for (const key of keys) {
roomListeners[key] = roomListeners[key].filter(listener => listener.client !== client);
if (roomListeners[key].length === 0) delete roomListeners[key];
}
};

View file

@ -116,7 +116,8 @@ export const addPostMethods = (server: express.Express) => {
export class postClient {
lastReq = uts();
client: Client;
constructor(ip: string, client = new Client(ip)) {
constructor(ip: string, client: Client | null = null) {
if (client === null) client = new Client(ip, this);
this.client = client;
}
async runAct(act: Act, json: any, aws: (state: string, data: any) => void) {

View file

@ -5,6 +5,8 @@ import { outbagServer, outbagURLfromTag } from "../server/outbagURL.js";
import { fetchRemoteAs } from "./server.js";
import { debug } from "../sys/log.js";
import { act_error } from "../server/errors.js";
import { wsClient } from "./ws.js";
import { postClient } from "./post.js";
export const STATE = {
no: 0b00001,
@ -39,8 +41,11 @@ export class Client {
accID: number = -1;
challenge: string = "";
remoteKey: string = "";
connectionClient: wsClient | postClient;
constructor(ip: string) {
constructor(ip: string, client: wsClient | postClient) {
this.connectionClient = client;
this.server = new outbagServer("", "", "", "");
this.ip = ip;
}

View file

@ -5,6 +5,7 @@ import { Act, checktype, Client } from "./user.js";
import { debug, error } from "../sys/log.js";
import * as importActs from "./acts.js"
import { act_error } from "../server/errors.js";
import { addRoomListener, removeRoomListener } from "./listener.js";
let acts = importActs as { [key: string]: Act };
@ -30,9 +31,11 @@ export class wsClient {
activeRequests = 0;
client: Client;
constructor(socket: ws.WebSocket, req: http.IncomingMessage) {
this.client = new Client(req.socket.remoteAddress ?? "");
this.client = new Client(req.socket.remoteAddress ?? "", this);
this.socket = socket;
clients.push(this);
socket.on("message", async (msg: any) => {
try {
this.activeRequests++;
@ -141,6 +144,7 @@ export class wsClient {
});
socket.on('close', () => {
this.unlistenAllRooms();
this.open = false;
var i = clients.indexOf(this);
delete clients[i];
@ -152,6 +156,7 @@ export class wsClient {
close(ms: number) {
return new Promise<void>(res => {
this.unlistenAllRooms();
if (this.activeRequests == 0) {
this.socket.close();
return void res();
@ -162,6 +167,34 @@ export class wsClient {
}, Math.max(100, ms));
});
}
sendFromServer(data: any): Promise<boolean> {
if (this.socket.readyState != WebSocket.OPEN) {
return Promise.resolve(false);
}
return new Promise((res, rej) => {
this.socket.send(JSON.stringify({
id: -1,
state: "server",
data: data
}), (err) => {
if(err) return void rej(false);
return void res(true);
});
});
}
listenRoom(roomID: number, room: string, server: string) {
addRoomListener(this, roomID, room, server);
}
unlistenRoom(roomID: number) {
removeRoomListener(this, roomID);
}
unlistenAllRooms() {
removeRoomListener(this);
}
}
export const closeWebSocket = async () => {

View file

@ -20,6 +20,7 @@ import { activatePost, addPostMethods } from "./api/post.js";
import { activateWS, closeWebSocket, wsOnConnection } from "./api/ws.js";
import { startUpdateCert } from "./server/serverCerts.js";
import { wait } from "./sys/tools.js";
import { startChecks } from "./server/checks.js";
global.provideLog = 10;
@ -70,6 +71,8 @@ nman.addShutdownTask(() => new Promise(async (res, rej) => {
if (serverclose != null) {
serverclose.keepAliveTimeout = 100;
serverclose.close(() => res());
} else {
res();
}
}), 10000);
@ -121,9 +124,10 @@ async function complete_loaded() {
await nman.shutdown();
process.exit(1);
}
warn("Outbag", "Keep running tue to debug Mode");
warn("Outbag", "Keep running due to debug Mode");
}
activatePost();
activateWS();
startChecks();
log("Server", 'Listening...');
}

17
src/server/checks.ts Normal file
View file

@ -0,0 +1,17 @@
import { and, le, remove } from "dblang";
import { addShutdownTask } from "nman";
import { accounts, db } from "../sys/db.js"
import { uts } from "../sys/tools.js";
import { oConf } from "../sys/config.js";
export function startChecks() {
let i1 = setInterval(async () => {
await remove(accounts)
.where(and(
accounts.deleted,
le(accounts.deletedTime, uts() - oConf.get("Settings", "deletedAccountKeepSec"))
)).query(db);
}, 60000);
addShutdownTask(() => clearInterval(i1), 500);
}

View file

@ -10,6 +10,7 @@ export const act_error = {
SERVER: "server", // uncaught error in server
RECURSION: "recursion", // not allowed due to suspected remote recursion, will only appear with miss configureation
REMOTE: "remote", // error while remote request (like could not contact the remote server)
CONNECTION: "connection", // the current connection type is not correct
CLIENT_NOT_EXISTS: "clientnotexists", // seems like your own account does not exists (client.ts acts)
ACCOUNT_NOT_EXISTS: "accountnotexists", // referred account does not exists (admin / client trennen? )

14
src/server/listener.ts Normal file
View file

@ -0,0 +1,14 @@
export const LISTENER_TYPE = {
ROOMINFO: 0,
ITEMS: 1,
CATEGORIES: 2,
PRODUCTS: 3,
}
export const LISTENER_ACTION = {
ADD: 0,
CHANGE: 1,
DELETE: 2,
}

View file

@ -256,8 +256,12 @@ const outbag = async () => {
name: "defaultViewable",
message: "Should outbag accounts be viewable by default?",
initial: oConf.get("Settings", "defaultViewable"),
},
}, {
type: "number",
name: "deletedAccountKeepSec",
message: "Please enter the number of days a deleted Account is being save until final deletion!",
initial: oConf.get("Settings", "deletedAccountKeepSec") / 60 / 60 / 24
}
]);
if (
resp.maxUsers == null
@ -265,6 +269,7 @@ const outbag = async () => {
|| resp.defaultMaxRoomSize == null
|| resp.defaultMaxUsersPerRoom == null
|| resp.defaultViewable == null
|| resp.deletedAccountKeepSec == null
) {
warn("Setup", "You have to provide all informations!");
return false;
@ -285,6 +290,7 @@ const outbag = async () => {
oConf.set("Settings", "defaultMaxRoomSize", resp.defaultMaxRoomSize);
oConf.set("Settings", "defaultMaxUsersPerRoom", resp.defaultMaxUsersPerRoom);
oConf.set("Settings", "defaultViewable", resp.defaultViewable);
oConf.set("Settings", "deletedAccountKeepSec", Math.round(resp.deletedAccountKeepSec * 60 * 60 * 24));
oConf.save();
return true;

View file

@ -26,7 +26,8 @@ const conf_struct = {
defaultMaxRooms: { type: "number", default: 3, env: "OUTBAG_DEFAULT_MAX_ROOMS" },//Infinity = -1
defaultMaxRoomSize: { type: "number", default: 10000, env: "OUTBAG_DEFAULT_MAX_ROOMS_SIZE" },//Infinity = -1
defaultMaxUsersPerRoom: { type: "number", default: 5, env: "OUTBAG_DEFAULT_MAX_USERS_PER_ROOM" },//Infinity = -1
defaultViewable: { type: "boolean", default: false, env: "OUTBAG_DEFAULT_VIEWABLE" }
defaultViewable: { type: "boolean", default: false, env: "OUTBAG_DEFAULT_VIEWABLE" },
deletedAccountKeepSec: { type: "number", default: 60 * 60 * 24 * 20, env: "OUTBAG_DEL_ACCOUNT_KEEP_SEC" },
}
};

View file

@ -58,6 +58,7 @@ accounts.addAttributes({
viewable: { type: BOOL, default: false },
deleted: { type: BOOL, default: false },
deletedTime: { type: BIGINT, default: 0 },
maxRooms: { type: INT },
maxRoomSize: { type: INT },
@ -117,7 +118,9 @@ rooms.addAttributes({
owner: {
type: INT,
foreignKey: {
link: accounts.accID
link: accounts.accID,
onDelete: onAction.cascade,
onUpdate: onAction.cascade
}
},
rights: { type: INT, default: 0b11111 },

View file

@ -37,10 +37,11 @@ export const warn = (name: string, ...args: any[]) => {
let dateString = (new Date()).toLocaleString();
console.warn(
"\x1b[33m%s\x1b[0m" +
"\x1b[1m\x1b[36m%s\x1b[0m",
dateString,
` [${name}]:`,
...args
"\x1b[1m\x1b[48;5;208m%s\x1b[0m\x1b[48;5;208m",
dateString+" ",
`[${name}]:`,
...args,
"\x1b[0m"
);
if (global.provideLog != 0) logList.push([logID++, "warn", dateString, name, args]);
};

View file

@ -25,4 +25,5 @@ maxUsers=2
defaultMaxRooms=2
defaultMaxRoomSize=10
defaultMaxUsersPerRoom=2
defaultViewable=true
defaultViewable=true
deletedAccountKeepSec=1728000

View file

@ -139,7 +139,7 @@ const list = [
name: name2,
server: "localhost:7224",
accountKey: accountKey + "lol"
}, "error",act_error.AUTH);
}, "error", act_error.AUTH);
}], ["admin", async (req) => {
let resp = await req({
"authorization": `Digest name=${name1} server=localhost:7224 accountKey=${accountKey}`
@ -150,6 +150,7 @@ const list = [
name: "testUser1",
viewable: true,
deleted: false,
deletedTime: 0,
maxRooms: 2,
maxRoomSize: 10,
maxUsersPerRoom: 2
@ -159,6 +160,7 @@ const list = [
name: "testUser2",
viewable: true,
deleted: true,
deletedTime: null,
maxRooms: 2,
maxRoomSize: 10,
maxUsersPerRoom: 2
@ -179,15 +181,17 @@ const list = [
name: "testUser1",
viewable: true,
deleted: false,
deletedTime: 0,
maxRooms: 2,
maxRoomSize: 10,
maxUsersPerRoom: 2
}, {
accID: null,
accID: 3,
rights: 5,
name: "testUser2",
viewable: true,
deleted: true,
deletedTime: null,
maxRooms: 2,
maxRoomSize: 10,
maxUsersPerRoom: 2