admin, client Acts
This commit is contained in:
parent
a394dbe437
commit
ed4b74362e
8 changed files with 313 additions and 22 deletions
|
@ -1 +1,3 @@
|
|||
export * from "./acts/login.js"
|
||||
export * from "./acts/login.js";
|
||||
export * from "./acts/client.js"
|
||||
export * from "./acts/admin.js"
|
171
src/api/acts/admin.ts
Normal file
171
src/api/acts/admin.ts
Normal file
|
@ -0,0 +1,171 @@
|
|||
import { eq, insert, le, or, remove, select, update } from "dblang";
|
||||
import { PERMISSIONS } from "../../server/permissions.js";
|
||||
import { sha256 } from "../../sys/crypto.js";
|
||||
import { accounts, db, signupOTA } from "../../sys/db.js";
|
||||
import { get64, uts } from "../../sys/tools.js";
|
||||
import { Client, STATE } from "../user.js";
|
||||
|
||||
export const getAccounts = {
|
||||
state: STATE.client,
|
||||
right: PERMISSIONS.CAN_USE_API | PERMISSIONS.SHOW_USERS_AND_LISTS,
|
||||
data: {},
|
||||
func: async (client: Client, data: any, aws: (code: string, data: any) => void) => {
|
||||
let query = await select([
|
||||
accounts.accID,
|
||||
accounts.rights,
|
||||
accounts.name,
|
||||
accounts.viewable,
|
||||
accounts.deleted,
|
||||
accounts.maxRooms,
|
||||
accounts.maxRoomSize,
|
||||
accounts.maxUsersPerRoom
|
||||
], accounts)
|
||||
.query(db);
|
||||
var out = query.map(d => {
|
||||
let accID = d[accounts.accID];
|
||||
let rights = d[accounts.rights];
|
||||
let name = d[accounts.name];
|
||||
let viewable = d[accounts.viewable];
|
||||
let deleted = d[accounts.deleted];
|
||||
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 };
|
||||
}
|
||||
return null;
|
||||
});
|
||||
aws("ok", out.filter(d => d != null));
|
||||
}
|
||||
};
|
||||
|
||||
export const setPermissions = {
|
||||
state: STATE.client,
|
||||
right: PERMISSIONS.CAN_USE_API | PERMISSIONS.EDIT_RIGHTS,
|
||||
data: {
|
||||
accID: "number",
|
||||
rights: "number"
|
||||
},
|
||||
func: async (client: Client, data: any, aws: (code: string, data: any) => void) => {
|
||||
let query = await update(accounts)
|
||||
.set(accounts.rights, data.rights)
|
||||
.where(eq(accounts.accID, data.accID))
|
||||
.query(db);
|
||||
if (query.affectedRows > 0) {
|
||||
aws("ok", "");
|
||||
} else {
|
||||
client.suspect();
|
||||
aws("error", "existence");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const resetPassword = {
|
||||
state: STATE.client,
|
||||
right: PERMISSIONS.CAN_USE_API | PERMISSIONS.EDIT_USERS,
|
||||
data: {
|
||||
accID: "number",
|
||||
accountKey: "string"
|
||||
},
|
||||
func: async (client: Client, data: any, aws: (code: string, data: any) => void) => {
|
||||
var salt = get64(16);
|
||||
let req = await update(accounts)
|
||||
.set(accounts.accountKey, sha256(salt + data.accountKey))
|
||||
.set(accounts.accountKeySalt, salt)
|
||||
.where(eq(accounts.accID, data.accID))
|
||||
.query(db);
|
||||
if (req.affectedRows > 0) {
|
||||
aws("ok", "");
|
||||
} else {
|
||||
client.suspect();
|
||||
aws("error", "existence");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const setMaxValues = {
|
||||
state: STATE.client,
|
||||
right: PERMISSIONS.CAN_USE_API | PERMISSIONS.EDIT_USERS,
|
||||
data: {
|
||||
accID: "number",
|
||||
maxRooms: "number",
|
||||
maxRoomSize: "number",
|
||||
maxUsersPerRoom: "number",
|
||||
},
|
||||
func: async (client: Client, data: any, aws: (code: string, data: any) => void) => {
|
||||
let req = await update(accounts)
|
||||
.set(accounts.maxRooms, data.maxRooms)
|
||||
.set(accounts.maxRoomSize, data.maxRoomSize)
|
||||
.set(accounts.maxUsersPerRoom, data.maxUsersPerRoom)
|
||||
.where(eq(accounts.accID, data.accID))
|
||||
.query(db);
|
||||
if (req.affectedRows > 0) {
|
||||
aws("ok", "");
|
||||
} else {
|
||||
client.suspect();
|
||||
aws("error", "existence");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const getOTAs = {
|
||||
state: STATE.client,
|
||||
right: PERMISSIONS.CAN_USE_API | PERMISSIONS.MANAGE_OTA_TOKENS,
|
||||
data: {},
|
||||
func: async (client: Client, data: any, aws: (code: string, data: any) => void) => {
|
||||
await remove(signupOTA)
|
||||
.where(or(
|
||||
eq(signupOTA.usesLeft, 0),
|
||||
le(signupOTA.expires, uts())
|
||||
))
|
||||
.query(db);
|
||||
let req = await select([
|
||||
signupOTA.token,
|
||||
signupOTA.expires,
|
||||
signupOTA.usesLeft,
|
||||
], signupOTA)
|
||||
.query(db);
|
||||
aws("ok", req.map(d => ({
|
||||
token: d[signupOTA.token],
|
||||
expires: d[signupOTA.expires],
|
||||
usesLeft: d[signupOTA.usesLeft]
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
||||
export const addOTA = {
|
||||
state: STATE.client,
|
||||
right: PERMISSIONS.CAN_USE_API | PERMISSIONS.MANAGE_OTA_TOKENS,
|
||||
data: {
|
||||
token: "string-255",
|
||||
expires: "number", //uts in sec.
|
||||
usesLeft: "number"
|
||||
},
|
||||
func: async (client: Client, data: any, aws: (code: string, data: any) => void) => {
|
||||
try {
|
||||
await insert(signupOTA.token, signupOTA.expires, signupOTA.usesLeft)
|
||||
.add(data.token, data.expires, data. usesLeft)
|
||||
.query(db);
|
||||
} catch (error) {
|
||||
await update(signupOTA)
|
||||
.set(signupOTA.expires, data.expires)
|
||||
.set(signupOTA.usesLeft, data.usesLeft)
|
||||
.where(eq(signupOTA.token, data.token))
|
||||
.query(db);
|
||||
}
|
||||
aws("ok", "");
|
||||
}
|
||||
}
|
||||
export const deleteOTA = {
|
||||
state: STATE.client,
|
||||
right: PERMISSIONS.CAN_USE_API | PERMISSIONS.MANAGE_OTA_TOKENS,
|
||||
data: {
|
||||
token: "string"
|
||||
},
|
||||
func: async (client: Client, data: any, aws: (code: string, data: any) => void) => {
|
||||
await remove(signupOTA)
|
||||
.where(eq(signupOTA.token, data.token))
|
||||
.query(db);
|
||||
aws("ok", "");
|
||||
}
|
||||
}
|
92
src/api/acts/client.ts
Normal file
92
src/api/acts/client.ts
Normal file
|
@ -0,0 +1,92 @@
|
|||
import { eq, select, update } from "dblang";
|
||||
import { outbagURLshort } from "../../server/outbagURL.js";
|
||||
import { PERMISSIONS } from "../../server/permissions.js";
|
||||
import { oConf } from "../../sys/config.js";
|
||||
import { sha256, sign } from "../../sys/crypto.js";
|
||||
import { accounts, db } from "../../sys/db.js";
|
||||
import { getSettings, SETTINGS } from "../../sys/settings.js";
|
||||
import { get64 } from "../../sys/tools.js";
|
||||
import { Client, STATE } from "../user.js";
|
||||
|
||||
|
||||
export const deleteAccount = {
|
||||
state: STATE.client,
|
||||
right: 0,
|
||||
data: {},
|
||||
func: async (client: Client, data: any, aws: (code: string, data: any) => void) => {
|
||||
client.state = STATE.no;
|
||||
await update(accounts)
|
||||
.set(accounts.deleted, 1)
|
||||
.where(eq(accounts.accID, client.accID))
|
||||
.query(db);
|
||||
aws("ok", "");
|
||||
}
|
||||
};
|
||||
|
||||
export const createSignature = {
|
||||
state: STATE.client,
|
||||
right: PERMISSIONS.CAN_USE_API | PERMISSIONS.PROVIDE_CERT,
|
||||
data: {
|
||||
publicKey: "string"
|
||||
},
|
||||
func: async (client: Client, data: any, aws: (code: string, data: any) => void) => {
|
||||
const server = await outbagURLshort(oConf.get("System", "URL") + ":" + oConf.get("System", "PORTexposed"));
|
||||
const tag = client.name + "@" + server + "-" + data.publicKey;
|
||||
var signature = await sign(tag, await getSettings(SETTINGS.privateKey));
|
||||
aws("ok", signature);
|
||||
}
|
||||
};
|
||||
|
||||
export const getMyAccount = {
|
||||
state: STATE.client,
|
||||
right: 0,
|
||||
data: {},
|
||||
func: async (client: Client, data: any, aws: (code: string, data: any) => void) => {
|
||||
let query = await select([
|
||||
accounts.rights,
|
||||
accounts.name,
|
||||
accounts.viewable,
|
||||
accounts.maxRooms,
|
||||
accounts.maxRoomSize,
|
||||
accounts.maxUsersPerRoom,
|
||||
], accounts)
|
||||
.where(eq(accounts.accID, client.accID))
|
||||
.query(db);
|
||||
if (query.length > 0) {
|
||||
let rights = query[0][accounts.rights];
|
||||
let name = query[0][accounts.name];
|
||||
let viewable = query[0][accounts.viewable];
|
||||
let maxRooms = query[0][accounts.maxRooms];
|
||||
let maxRoomSize = query[0][accounts.maxRoomSize];
|
||||
let maxUsersPerRoom = query[0][accounts.maxUsersPerRoom];
|
||||
if (rights != null && name != null && viewable != null && maxRooms != null && maxRoomSize != null && maxUsersPerRoom != null) {
|
||||
aws("ok", { rights, name, viewable, maxRooms, maxRoomSize, maxUsersPerRoom });
|
||||
return;
|
||||
}
|
||||
}
|
||||
client.suspect();
|
||||
aws("error", "existence");
|
||||
}
|
||||
};
|
||||
|
||||
export const changePassword = {
|
||||
state: STATE.client,
|
||||
right: PERMISSIONS.CAN_USE_API,
|
||||
data: {
|
||||
accountKey: "string"
|
||||
},
|
||||
func: async (client: Client, data: any, aws: (code: string, data: any) => void) => {
|
||||
var salt = get64(16);
|
||||
let req = await update(accounts)
|
||||
.set(accounts.accountKey, sha256(salt + data.accountKey))
|
||||
.set(accounts.accountKeySalt, salt)
|
||||
.where(eq(accounts.accID, client.accID))
|
||||
.query(db);
|
||||
if (req.affectedRows > 0) {
|
||||
aws("ok", "");
|
||||
} else {
|
||||
client.suspect();
|
||||
aws("error", "existence");
|
||||
}
|
||||
}
|
||||
};
|
|
@ -27,10 +27,10 @@ export const signup: Act = {
|
|||
}
|
||||
let salt = get64(16);
|
||||
let req = await insert(accounts.name, accounts.rights, accounts.accountKey, accounts.accountKeySalt)
|
||||
.add(data.name, userNum == 0 ? PERMISSIONS.ALL : PERMISSIONS.DEFAULT, sha256(salt + data.accountKey))
|
||||
.add(data.name, userNum == 0 ? PERMISSIONS.ALL : PERMISSIONS.DEFAULT, sha256(salt + data.accountKey), salt)
|
||||
.query(db);
|
||||
if (req.affectedRows > 0) {
|
||||
let accID = req.insertId;
|
||||
let accID = Number(req.insertId);
|
||||
if (!isNaN(accID)) {
|
||||
aws("ok", "");
|
||||
client.state = STATE.client;
|
||||
|
@ -69,10 +69,10 @@ export const signupOTA = {
|
|||
}
|
||||
let salt = get64(16);
|
||||
let req = await insert(accounts.name, accounts.rights, accounts.accountKey, accounts.accountKeySalt)
|
||||
.add(data.name, PERMISSIONS.DEFAULT, sha256(salt + data.accountKey))
|
||||
.add(data.name, PERMISSIONS.DEFAULT, sha256(salt + data.accountKey), salt)
|
||||
.query(db);
|
||||
if (req.affectedRows > 0) {
|
||||
let accID = req.insertId;
|
||||
let accID = Number(req.insertId);
|
||||
if (!isNaN(accID)) {
|
||||
aws("ok", "");
|
||||
client.state = STATE.client;
|
||||
|
@ -101,12 +101,12 @@ export const signin = {
|
|||
eq(accounts.deleted, 0)
|
||||
))
|
||||
.query(db);
|
||||
if (query.length == 0 || query[0].accountKey != sha256((query[0].accountKeySalt ?? '') + data.accountKey)) {
|
||||
if (query.length == 0 || query[0][accounts.accountKey] != sha256((query[0][accounts.accountKeySalt] ?? '') + data.accountKey)) {
|
||||
client.suspect();
|
||||
aws("error", "auth");
|
||||
return;
|
||||
}
|
||||
var accID = query[0].ID;
|
||||
var accID = query[0][accounts.accID];
|
||||
if (!isNaN(accID)) {
|
||||
aws("ok", "");
|
||||
client.state = STATE.client;
|
||||
|
|
|
@ -20,7 +20,7 @@ export const outbagURL = (url: string, prefix = "https") => new Promise((res, re
|
|||
})
|
||||
.catch(_ => {
|
||||
if (uri.port == '') {
|
||||
uri.port = DEFAULT_PORT+"";
|
||||
uri.port = DEFAULT_PORT + "";
|
||||
outbagURL(uri.toString(), prefix)
|
||||
.then(url => res(url))
|
||||
.catch(_ => rej());
|
||||
|
@ -29,6 +29,7 @@ export const outbagURL = (url: string, prefix = "https") => new Promise((res, re
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
export const outbagURLshort = (url: string) => new Promise((res, rej) => {
|
||||
let uri: URL;
|
||||
try {
|
||||
|
@ -47,7 +48,7 @@ export const outbagURLshort = (url: string) => new Promise((res, rej) => {
|
|||
})
|
||||
.catch(_ => {
|
||||
if (uri.port == '') {
|
||||
uri.port = DEFAULT_PORT+"";
|
||||
uri.port = DEFAULT_PORT + "";
|
||||
outbagURLshort(uri.toString())
|
||||
.then(url => res(url))
|
||||
.catch(_ => rej());
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
import { eq, select, update } from "dblang";
|
||||
import { accounts, db } from "../sys/db.js";
|
||||
|
||||
export const PERMISSIONS = {
|
||||
NONE: 0b0000000000000000, // equal to no account or blocked account
|
||||
|
||||
|
@ -17,3 +14,13 @@ export const PERMISSIONS = {
|
|||
EDIT_USERS: 0b1000000000000000,
|
||||
ALL: 0b1111111111111111,
|
||||
};
|
||||
|
||||
export const ROOM_RIGHTS = { //when changing, look in main (db defaults)
|
||||
ADD_ARTICLES: 0b0000001, //change or add articles
|
||||
REMOVE_ARTICLES: 0b0000010,
|
||||
LIST_GROUPS_ITEMS: 0b0000100, //edit room intern listGroups and listItems
|
||||
CHANGE_META: 0b0001000,
|
||||
OTA: 0b0010000, //edit otas
|
||||
CHANGE_SETTINGS: 0b0100000,
|
||||
MANAGE_MEMBERS: 0b1000000,
|
||||
};
|
||||
|
|
|
@ -45,7 +45,7 @@ nMan.addShutdownTask(db.close, 3000, 10);
|
|||
export const accounts = db.newTable("accounts");
|
||||
accounts.addAttributes({
|
||||
accID: { type: INT, primaryKey: true, autoIncrement: true },
|
||||
name: { type: VARCHAR(255), default: PERMISSIONS.DEFAULT },
|
||||
name: { type: VARCHAR(100), default: PERMISSIONS.DEFAULT },
|
||||
|
||||
rights: { type: BIGINT, default: PERMISSIONS.DEFAULT },
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
export const debug = (name: string, ...args: any[]) => {
|
||||
if(!global.debug)return;
|
||||
if (!global.debug) return;
|
||||
consorArgs(args);
|
||||
console.log(
|
||||
"\x1b[33m%s\x1b[0m"+
|
||||
"\x1b[33m%s\x1b[0m" +
|
||||
"\x1b[1m\x1b[32m%s\x1b[0m",
|
||||
(new Date()).toLocaleString(),
|
||||
` [${name}]:`,
|
||||
|
@ -10,8 +11,9 @@ export const debug = (name: string, ...args: any[]) => {
|
|||
};
|
||||
|
||||
export const log = (name: string, ...args: string[]) => {
|
||||
consorArgs(args);
|
||||
console.log(
|
||||
"\x1b[33m%s\x1b[0m"+
|
||||
"\x1b[33m%s\x1b[0m" +
|
||||
"\x1b[1m\x1b[36m%s\x1b[0m",
|
||||
(new Date()).toLocaleString(),
|
||||
` [${name}]:`,
|
||||
|
@ -20,8 +22,9 @@ export const log = (name: string, ...args: string[]) => {
|
|||
};
|
||||
|
||||
export const warn = (name: string, ...args: any[]) => {
|
||||
consorArgs(args);
|
||||
console.warn(
|
||||
"\x1b[33m%s\x1b[0m"+
|
||||
"\x1b[33m%s\x1b[0m" +
|
||||
"\x1b[1m\x1b[36m%s\x1b[0m",
|
||||
(new Date()).toLocaleString(),
|
||||
` [${name}]:`,
|
||||
|
@ -30,12 +33,27 @@ export const warn = (name: string, ...args: any[]) => {
|
|||
};
|
||||
|
||||
export const error = (name: string, ...args: any[]) => {
|
||||
consorArgs(args);
|
||||
console.error(
|
||||
"\x1b[33m%s\x1b[0m"+
|
||||
"\x1b[33m%s\x1b[0m" +
|
||||
"\x1b[1m\x1b[41m%s\x1b[0m\x1b[41m",
|
||||
(new Date()).toLocaleString()+" ",
|
||||
(new Date()).toLocaleString() + " ",
|
||||
`[${name}]:`,
|
||||
...args,
|
||||
"\x1b[0m"
|
||||
);
|
||||
};
|
||||
|
||||
const consorArgs = (args: any[]) => {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const arg = args[i];
|
||||
censorLogArg(arg);
|
||||
}
|
||||
}
|
||||
const censorLogArg = (arg: any) => {
|
||||
if (typeof arg != "object") return;
|
||||
for (let key in arg) {
|
||||
if (key == "accountKey") arg[key] = new Array(arg[key].length).fill("*").join("");
|
||||
censorLogArg(arg[key]);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue