Logger & server
This commit is contained in:
parent
88f6a29aa9
commit
cf5b1a2ce2
|
@ -1,8 +1,12 @@
|
||||||
export enum Permissions {
|
export enum Permissions {
|
||||||
ALL = "*",
|
ALL = "*",
|
||||||
VIEW_PROFILE = "view_profile",
|
VIEW = "view",
|
||||||
ADD_PROFILE = "add_profile",
|
ADD_PROFILE = "add_profile",
|
||||||
MANAGE_PERMISSIONS = "manage_permissions"
|
REMOVE_PROFILE = "remove_profile",
|
||||||
|
VIEW_USERS = "view_users",
|
||||||
|
ADD_USER = "add_user",
|
||||||
|
EDIT_USER = "edit_user",
|
||||||
|
REMOVE_USER = "remove_user"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
109
src/server.ts
109
src/server.ts
|
@ -8,10 +8,17 @@ import { hash } from "bcrypt";
|
||||||
import { log } from "./logger";
|
import { log } from "./logger";
|
||||||
import { Permissions } from "./lib/permissions";
|
import { Permissions } from "./lib/permissions";
|
||||||
|
|
||||||
const { PORT, NODE_ENV, DB_USERNAME, DB_PASSWORD, DB_URL, DB_NAME, API_KEY } =
|
export const {
|
||||||
process.env;
|
PORT,
|
||||||
|
NODE_ENV,
|
||||||
|
DB_USERNAME,
|
||||||
|
DB_PASSWORD,
|
||||||
|
DB_URL,
|
||||||
|
DB_NAME,
|
||||||
|
API_KEY
|
||||||
|
} = process.env;
|
||||||
const dev = NODE_ENV === "development";
|
const dev = NODE_ENV === "development";
|
||||||
const db = arangojs({
|
export const db = arangojs({
|
||||||
auth: {
|
auth: {
|
||||||
username: DB_USERNAME || "root",
|
username: DB_USERNAME || "root",
|
||||||
password: DB_PASSWORD
|
password: DB_PASSWORD
|
||||||
|
@ -19,34 +26,83 @@ const db = arangojs({
|
||||||
url: DB_URL || "http://127.0.0.1:8529",
|
url: DB_URL || "http://127.0.0.1:8529",
|
||||||
databaseName: DB_NAME || "sbdatatracker"
|
databaseName: DB_NAME || "sbdatatracker"
|
||||||
});
|
});
|
||||||
const saltRounds = 10;
|
export const saltRounds = 9;
|
||||||
|
export const accessTokenExpire = 1000 * 60 * 20;
|
||||||
|
export const refreshTokenExpire = 1000 * 60 * 60 * 24 * 7;
|
||||||
const delay = 3 * 60 * 1000;
|
const delay = 3 * 60 * 1000;
|
||||||
|
|
||||||
const intervalFunc = async (db: Database) => {
|
const intervalFunc = async (db: Database) => {
|
||||||
const cnf = db.collection("config");
|
const cnf = db.collection("config");
|
||||||
const users = db.collection("users");
|
const users = db.collection("users");
|
||||||
|
const sessions = db.collection("sessions");
|
||||||
if (!(await cnf.exists())) {
|
if (!(await cnf.exists())) {
|
||||||
await cnf.create();
|
await cnf.create({
|
||||||
|
schema: {
|
||||||
|
rule: {
|
||||||
|
properties: {
|
||||||
|
type: { type: "string" },
|
||||||
|
data: { type: "object" }
|
||||||
|
},
|
||||||
|
required: ["type", "data"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (!(await users.exists())) {
|
if (!(await users.exists())) {
|
||||||
await users.create();
|
await users.create({
|
||||||
|
schema: {
|
||||||
|
rule: {
|
||||||
|
properties: {
|
||||||
|
username: { type: "string" },
|
||||||
|
password: { type: "string" },
|
||||||
|
permissions: {
|
||||||
|
type: "array",
|
||||||
|
items: { type: "string" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
required: ["username", "permissions"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
await users.save({
|
await users.save({
|
||||||
username: DB_USERNAME,
|
username: DB_USERNAME || "root",
|
||||||
password: await hash(DB_PASSWORD || "SBDataTracker", saltRounds),
|
password: await hash(DB_PASSWORD || "SBDataTracker", saltRounds),
|
||||||
forceChangePassword: true,
|
|
||||||
permissions: [Permissions.ALL]
|
permissions: [Permissions.ALL]
|
||||||
});
|
});
|
||||||
await users.save({
|
await users.save({
|
||||||
username: "_guest",
|
username: "_guest",
|
||||||
permissions: [Permissions.VIEW_PROFILE]
|
permissions: [Permissions.VIEW]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (!(await sessions.exists())) {
|
||||||
|
await sessions.create({
|
||||||
|
schema: {
|
||||||
|
rule: {
|
||||||
|
properties: {
|
||||||
|
token: { type: "string" },
|
||||||
|
exp: { type: "number" },
|
||||||
|
type: { type: "string" },
|
||||||
|
user: { type: "string" }
|
||||||
|
},
|
||||||
|
required: ["token", "exp", "type", "user"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete expired sessions
|
||||||
|
const now = Date.now();
|
||||||
|
await db.query(aql`
|
||||||
|
FOR doc in ${sessions}
|
||||||
|
FILTER doc.exp <= ${now}
|
||||||
|
REMOVE doc in ${sessions}
|
||||||
|
`);
|
||||||
|
|
||||||
const cursor = await db.query(
|
const cursor = await db.query(
|
||||||
aql`
|
aql`
|
||||||
FOR doc IN ${cnf}
|
FOR doc IN ${cnf}
|
||||||
FILTER doc.type == "tracker"
|
FILTER doc.type == "tracker"
|
||||||
RETURN doc
|
RETURN { _key: doc._key }
|
||||||
`,
|
`,
|
||||||
{
|
{
|
||||||
count: true
|
count: true
|
||||||
|
@ -65,28 +121,29 @@ const intervalFunc = async (db: Database) => {
|
||||||
let counter = 0;
|
let counter = 0;
|
||||||
let interval: NodeJS.Timeout;
|
let interval: NodeJS.Timeout;
|
||||||
const iterate = async () => {
|
const iterate = async () => {
|
||||||
if (++counter >= (cursor.count as number)) clearInterval(interval);
|
try {
|
||||||
|
if (++counter >= cursor.count!) clearInterval(interval);
|
||||||
|
|
||||||
const { _key, profile } = await cursor.next();
|
const { _key: profile } = await cursor.next();
|
||||||
if (profile) {
|
if (profile) {
|
||||||
const col = db.collection(`c${profile}`);
|
const col = db.collection(`c${profile}`);
|
||||||
if (!(await col.exists())) col.create();
|
if (!(await col.exists())) col.create();
|
||||||
|
console.log(`${new Date()}\tLogging '${profile}'`);
|
||||||
await col.save(await log(API_KEY || "", profile));
|
await col.save(await log(API_KEY || "", profile));
|
||||||
} else {
|
} else {
|
||||||
console.warn(
|
console.warn(
|
||||||
`Configuration entry '${_key}' with type 'tracker' has no "profile" value`
|
`Configuration entry '${profile}' with type 'tracker' has no "profile" value`
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// Separated into setInterval and a setTimeout so when the script is started,
|
// Separated into setInterval and a setTimeout so when the script is started,
|
||||||
// immediately at least one profile is logged. This is useful for debugging
|
// immediately at least one profile is logged. This is useful for debugging
|
||||||
// since you don't have to wait for up to 3 minutes to pass.
|
// since you don't have to wait for up to 3 minutes to pass.
|
||||||
if ((cursor.count as number) > 1)
|
if (cursor.count! > 1)
|
||||||
interval = setInterval(
|
interval = setInterval(iterate, delay / (cursor.count! - 1));
|
||||||
iterate,
|
|
||||||
delay / ((cursor.count as number) - 1)
|
|
||||||
);
|
|
||||||
setTimeout(iterate);
|
setTimeout(iterate);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue