Update ESLint and Prettier

This commit is contained in:
Zaid Abdulla committed 2020-07-27 20:30:13 -07:00
1 parent 5a9e03db2c
commit ac980116bd
110 files changed
+2993 -2794

No files matched your search

+30 -17
View File
@@ -26,8 +26,9 @@ import {
insertTasks,
watchTask,
connectionRequest,
deleteDevice
deleteDevice,
} from "../api-functions";
import { Task } from "../types";
async function deleteFault(id): Promise<void> {
const deviceId = id.split(":", 1)[0];
@@ -37,13 +38,16 @@ async function deleteFault(id): Promise<void> {
db.deleteFault(id),
channel.startsWith("task_")
? db.deleteTask(new ObjectID(channel.slice(5)))
: null
: null,
]);
await del(`${deviceId}_tasks_faults_operations`);
}
export async function deleteResource(resource, id): Promise<void> {
export async function deleteResource(
resource: string,
id: string
): Promise<void> {
switch (resource) {
case "devices":
await deleteDevice(id);
@@ -86,18 +90,18 @@ export async function deleteResource(resource, id): Promise<void> {
}
export async function postTasks(
deviceId,
tasks,
timeout,
device
deviceId: string,
tasks: Task[],
timeout: number,
device: Record<string, { value?: [boolean | number | string, string] }>
): Promise<{ connectionRequest: string; tasks: any[] }> {
for (const task of tasks) {
delete task._id;
task.device = deviceId;
task["device"] = deviceId;
}
tasks = await insertTasks(tasks);
const statuses = tasks.map(t => {
const statuses = tasks.map((t) => {
return { _id: t._id, status: "pending" };
});
@@ -106,9 +110,10 @@ export async function postTasks(
try {
await connectionRequest(deviceId, device);
} catch (err) {
for (const t of statuses) db.deleteTask(new ObjectID(t._id));
return {
connectionRequest: err.message,
tasks: statuses
tasks: statuses,
};
}
@@ -131,9 +136,9 @@ export async function postTasks(
r.status = "done";
} else if (res[i * 2 + 1].length === 1) {
r.status = "fault";
r.fault = res[i * 2 + 1][0];
r["fault"] = res[i * 2 + 1][0];
}
db.deleteTask(r._id);
db.deleteTask(new ObjectID(r._id));
}
return { connectionRequest: "OK", tasks: statuses };
@@ -149,7 +154,11 @@ interface PingResponse {
mdev: number;
}
export async function putResource(resource, id, data): Promise<void> {
export async function putResource(
resource: string,
id: string,
data: Record<string, unknown>
): Promise<void> {
if (resource === "presets") {
await db.putPreset(id, data);
} else if (resource === "provisions") {
@@ -161,21 +170,25 @@ export async function putResource(resource, id, data): Promise<void> {
} else if (resource === "permissions") {
await db.putPermission(id, data);
} else if (resource === "users") {
delete data.password;
delete data.salt;
delete data["password"];
delete data["salt"];
await db.putUser(id, data);
}
await del("presets_hash");
}
export function authLocal(snapshot, username, password): Promise<boolean> {
export function authLocal(
snapshot: string,
username: string,
password: string
): Promise<boolean> {
return new Promise((resolve, reject) => {
const users = getUsers(snapshot);
const user = users[username];
if (!user || !user.password) return void resolve(null);
hashPassword(password, user.salt)
.then(hash => {
.then((hash) => {
if (hash === user.password) resolve(true);
else resolve(false);
})
+41 -39
View File
@@ -53,7 +53,7 @@ const RESOURCE_IDS = {
permissions: "_id",
users: "_id",
faults: "_id",
tasks: "_id"
tasks: "_id",
};
const resources = {
@@ -66,21 +66,21 @@ const resources = {
permissions: 0 | RESOURCE_DELETE | RESOURCE_PUT,
users: 0 | RESOURCE_DELETE | RESOURCE_PUT,
faults: 0 | RESOURCE_DELETE,
tasks: 0
tasks: 0,
};
router.get(`/devices/:id.csv`, async ctx => {
router.get(`/devices/:id.csv`, async (ctx) => {
const authorizer: Authorizer = ctx.state.authorizer;
const log = {
message: "Query device (CSV)",
context: ctx,
id: ctx.params.id
id: ctx.params.id,
};
const filter = and(authorizer.getFilter("devices", 2), [
"=",
["PARAM", RESOURCE_IDS.devices],
ctx.params.id
ctx.params.id,
]);
if (!authorizer.hasAccess("devices", 2)) {
@@ -113,9 +113,9 @@ router.get(`/devices/:id.csv`, async ctx => {
p.writableTimestamp,
p.value != null ? `"${p.value[0].toString().replace(/"/g, '""')}"` : "",
p.value != null ? p.value[1] : "",
p.valueTimestamp
p.valueTimestamp,
];
ctx.body.write(row.map(r => (r != null ? r : "")).join(",") + "\n");
ctx.body.write(row.map((r) => (r != null ? r : "")).join(",") + "\n");
}
ctx.body.end();
logger.accessInfo(log);
@@ -132,7 +132,7 @@ for (const [resource, flags] of Object.entries(resources)) {
message: `Count ${resource}`,
context: ctx,
filter: ctx.request.query.filter,
count: null
count: null,
};
if (!authorizer.hasAccess(resource, 1)) {
@@ -144,7 +144,7 @@ for (const [resource, flags] of Object.entries(resources)) {
if (resource === "tasks" || resource === "faults") {
filter = and(filter, [
"NOT",
["<", ["PARAM", "expiry"], Date.now() + 60000]
["<", ["PARAM", "expiry"], Date.now() + 60000],
]);
}
@@ -180,7 +180,7 @@ for (const [resource, flags] of Object.entries(resources)) {
limit: options.limit,
skip: options.skip,
sort: options.sort,
projection: options.projection
projection: options.projection,
};
if (!authorizer.hasAccess(resource, 2)) {
@@ -192,7 +192,7 @@ for (const [resource, flags] of Object.entries(resources)) {
if (resource === "tasks" || resource === "faults") {
filter = and(filter, [
"NOT",
["<", ["PARAM", "expiry"], Date.now() + 60000]
["<", ["PARAM", "expiry"], Date.now() + 60000],
]);
}
@@ -201,7 +201,7 @@ for (const [resource, flags] of Object.entries(resources)) {
let c = 0;
ctx.body.write("[\n");
await db.query(resource, filter, options, obj => {
await db.query(resource, filter, options, (obj) => {
ctx.body.write((c++ ? "," : "") + JSON.stringify(obj) + "\n");
});
ctx.body.end("]");
@@ -227,7 +227,7 @@ for (const [resource, flags] of Object.entries(resources)) {
filter: ctx.request.query.filter,
limit: options.limit,
skip: options.skip,
sort: options.sort
sort: options.sort,
};
if (!authorizer.hasAccess(resource, 2)) {
@@ -235,7 +235,9 @@ for (const [resource, flags] of Object.entries(resources)) {
return void next();
}
const columns = JSON.parse(ctx.request.query.columns);
const columns: Record<string, Expression> = JSON.parse(
ctx.request.query.columns
);
const now = Date.now();
for (const [k, v] of Object.entries(columns)) {
@@ -249,7 +251,7 @@ for (const [resource, flags] of Object.entries(resources)) {
if (resource === "tasks" || resource === "faults") {
filter = and(filter, [
"NOT",
["<", ["PARAM", "expiry"], Date.now() + 60000]
["<", ["PARAM", "expiry"], Date.now() + 60000],
]);
}
@@ -260,11 +262,11 @@ for (const [resource, flags] of Object.entries(resources)) {
);
ctx.body.write(
Object.keys(columns).map(k => `"${k.replace(/"/, '""')}"`) + "\n"
Object.keys(columns).map((k) => `"${k.replace(/"/, '""')}"`) + "\n"
);
await db.query(resource, filter, options, obj => {
const arr = Object.values(columns).map(exp => {
const v = evaluate(exp, obj, null, e => {
await db.query(resource, filter, options, (obj) => {
const arr = Object.values(columns).map((exp) => {
const v = evaluate(exp, obj, null, (e) => {
if (Array.isArray(e)) {
if (e[0] === "PARAM") {
if (resource === "devices") {
@@ -303,13 +305,13 @@ for (const [resource, flags] of Object.entries(resources)) {
const log = {
message: `Count ${resource}`,
context: ctx,
filter: `${RESOURCE_IDS[resource]} = "${ctx.params.id}"`
filter: `${RESOURCE_IDS[resource]} = "${ctx.params.id}"`,
};
const filter = and(authorizer.getFilter(resource, 2), [
"=",
["PARAM", RESOURCE_IDS[resource]],
ctx.params.id
ctx.params.id,
]);
if (!authorizer.hasAccess(resource, 2)) {
logUnauthorizedWarning(log);
@@ -329,13 +331,13 @@ for (const [resource, flags] of Object.entries(resources)) {
const log = {
message: `Query ${resource}`,
context: ctx,
filter: `${RESOURCE_IDS[resource]} = "${ctx.params.id}"`
filter: `${RESOURCE_IDS[resource]} = "${ctx.params.id}"`,
};
const filter = and(authorizer.getFilter(resource, 2), [
"=",
["PARAM", RESOURCE_IDS[resource]],
ctx.params.id
ctx.params.id,
]);
if (!authorizer.hasAccess(resource, 2)) {
logUnauthorizedWarning(log);
@@ -356,13 +358,13 @@ for (const [resource, flags] of Object.entries(resources)) {
const log = {
message: `Delete ${resource}`,
context: ctx,
id: ctx.params.id
id: ctx.params.id,
};
const filter = and(authorizer.getFilter(resource, 3), [
"=",
["PARAM", RESOURCE_IDS[resource]],
ctx.params.id
ctx.params.id,
]);
if (!authorizer.hasAccess(resource, 3)) {
logUnauthorizedWarning(log);
@@ -393,7 +395,7 @@ for (const [resource, flags] of Object.entries(resources)) {
const log = {
message: `Put ${resource}`,
context: ctx,
id: id
id: id,
};
if (!authorizer.hasAccess(resource, 3)) {
@@ -434,7 +436,7 @@ router.put("/files/:id", async (ctx, next) => {
message: `Upload ${resource}`,
context: ctx,
id: id,
metadata: null
metadata: null,
};
if (!authorizer.hasAccess(resource, 3)) {
@@ -446,7 +448,7 @@ router.put("/files/:id", async (ctx, next) => {
fileType: ctx.request.headers["metadata.filetype"] || "",
oui: ctx.request.headers["metadata.oui"] || "",
productClass: ctx.request.headers["metadata.productclass"] || "",
version: ctx.request.headers["metadata.version"] || ""
version: ctx.request.headers["metadata.version"] || "",
};
const validate = authorizer.getValidator(resource, metadata);
@@ -474,13 +476,13 @@ router.post("/devices/:id/tasks", async (ctx, next) => {
message: "Commit tasks",
context: ctx,
deviceId: ctx.params.id,
tasks: null
tasks: null,
};
const filter = and(authorizer.getFilter("devices", 3), [
"=",
["PARAM", "DeviceID.ID"],
ctx.params.id
ctx.params.id,
]);
if (!authorizer.hasAccess("devices", 3)) {
logUnauthorizedWarning(log);
@@ -503,7 +505,7 @@ router.post("/devices/:id/tasks", async (ctx, next) => {
"cwmp.deviceOnlineThreshold",
{},
Date.now(),
exp => {
(exp) => {
if (!Array.isArray(exp)) return exp;
if (exp[0] === "PARAM") {
const p = device[exp[1]];
@@ -519,7 +521,7 @@ router.post("/devices/:id/tasks", async (ctx, next) => {
}
return exp;
}
);
) as number;
const res = await apiFunctions.postTasks(
ctx.params.id,
@@ -528,7 +530,7 @@ router.post("/devices/:id/tasks", async (ctx, next) => {
device
);
log.tasks = res.tasks.map(t => t._id).join(",");
log.tasks = res.tasks.map((t) => t._id).join(",");
logger.accessInfo(log);
@@ -542,13 +544,13 @@ router.post("/devices/:id/tags", async (ctx, next) => {
message: "Update tags",
context: ctx,
deviceId: ctx.params.id,
tags: ctx.request.body
tags: ctx.request.body,
};
const filter = and(authorizer.getFilter("devices", 3), [
"=",
["PARAM", "DeviceID.ID"],
ctx.params.id
ctx.params.id,
]);
if (!authorizer.hasAccess("devices", 3)) {
logUnauthorizedWarning(log);
@@ -577,8 +579,8 @@ router.post("/devices/:id/tags", async (ctx, next) => {
ctx.body = "";
});
router.get("/ping/:host", async ctx => {
return new Promise(resolve => {
router.get("/ping/:host", async (ctx) => {
return new Promise((resolve) => {
ping(ctx.params.host, (err, parsed) => {
if (parsed) {
ctx.body = parsed;
@@ -597,7 +599,7 @@ router.put("/users/:id/password", async (ctx, next) => {
const log = {
message: "Change password",
context: ctx,
username: username
username: username,
};
if (!ctx.state.user) {
@@ -622,7 +624,7 @@ router.put("/users/:id/password", async (ctx, next) => {
const filter = and(authorizer.getFilter("users", 3), [
"=",
["PARAM", RESOURCE_IDS.users],
username
username,
]);
const res = await db.query("users", filter);
if (!res.length) return void next();
+83 -50
View File
@@ -17,19 +17,20 @@
* along with GenieACS. If not, see <http://www.gnu.org/licenses/>.
*/
import { MongoClient, GridFSBucket } from "mongodb";
import { MongoClient, GridFSBucket, ObjectID } from "mongodb";
import { Script } from "vm";
import * as config from "../config";
import * as mongodbFunctions from "../mongodb-functions";
import * as expression from "../common/expression";
import { QueryOptions } from "../types";
import { QueryOptions, Expression } from "../types";
import { Readable } from "stream";
const CACHE_TTL = 300000;
let clientPromise: Promise<MongoClient>;
const RESOURCE_COLLECTION = {
files: "fs.files"
files: "fs.files",
};
function ensureIndexes(client): void {
@@ -58,27 +59,31 @@ function getClient(): Promise<MongoClient> {
return clientPromise;
}
export function cache<T>(key, valueGetter: () => Promise<T>, ttl): Promise<T> {
export function cache<T>(
key: string,
valueGetter: () => Promise<T>,
ttl: number
): Promise<T> {
return new Promise((resolve, reject) => {
getClient()
.then(client => {
.then((client) => {
const collection = client.db().collection("cache");
collection.findOne({ _id: key }, (err, doc) => {
if (err) return void reject(err);
if (doc != null) return void resolve(JSON.parse(doc.value) as T);
valueGetter()
.then(res => {
.then((res) => {
const expire = Date.now() + (ttl || CACHE_TTL);
const cacheDoc = {
_id: key,
value: JSON.stringify(res),
expire: new Date(expire)
expire: new Date(expire),
};
collection.updateOne(
{ _id: key },
{ $set: cacheDoc },
{ upsert: true },
err => {
(err) => {
if (err) reject(err);
else resolve(res);
}
@@ -92,8 +97,8 @@ export function cache<T>(key, valueGetter: () => Promise<T>, ttl): Promise<T> {
}
export function query(
resource,
filter,
resource: string,
filter: Expression,
options?: QueryOptions,
callback?: (doc: any) => void
): Promise<any[]> {
@@ -121,7 +126,7 @@ export function query(
}
return new Promise((resolve, reject) => {
getClient().then(client => {
getClient().then((client) => {
const collection = client
.db()
.collection(RESOURCE_COLLECTION[resource] || resource);
@@ -160,20 +165,20 @@ export function query(
cursor.toArray((err, docs) => {
if (err) return reject(err);
if (resource === "devices")
docs = docs.map(d => mongodbFunctions.flattenDevice(d));
docs = docs.map((d) => mongodbFunctions.flattenDevice(d));
else if (resource === "faults")
docs = docs.map(d => mongodbFunctions.flattenFault(d));
docs = docs.map((d) => mongodbFunctions.flattenFault(d));
else if (resource === "tasks")
docs = docs.map(d => mongodbFunctions.flattenTask(d));
docs = docs.map((d) => mongodbFunctions.flattenTask(d));
else if (resource === "presets")
docs = docs.map(d => mongodbFunctions.flattenPreset(d));
docs = docs.map((d) => mongodbFunctions.flattenPreset(d));
else if (resource === "files")
docs = docs.map(d => mongodbFunctions.flattenFile(d));
docs = docs.map((d) => mongodbFunctions.flattenFile(d));
return resolve(docs);
});
} else {
cursor.forEach(
doc => {
(doc) => {
if (resource === "devices")
doc = mongodbFunctions.flattenDevice(doc);
else if (resource === "faults")
@@ -186,7 +191,7 @@ export function query(
doc = mongodbFunctions.flattenFile(doc);
callback(doc);
},
err => {
(err) => {
if (err) reject(err);
else resolve();
}
@@ -196,7 +201,7 @@ export function query(
});
}
export function count(resource, filter): Promise<number> {
export function count(resource: string, filter: Expression): Promise<number> {
let q;
filter = expression.evaluate(filter, null, Date.now());
@@ -213,7 +218,7 @@ export function count(resource, filter): Promise<number> {
}
return new Promise((resolve, reject) => {
getClient().then(client => {
getClient().then((client) => {
const collection = client
.db()
.collection(RESOURCE_COLLECTION[resource] || resource);
@@ -225,7 +230,10 @@ export function count(resource, filter): Promise<number> {
});
}
export function updateDeviceTags(deviceId, tags): Promise<void> {
export function updateDeviceTags(
deviceId: string,
tags: Record<string, boolean>
): Promise<void> {
return new Promise((resolve, reject) => {
const add = [];
const pull = [];
@@ -242,13 +250,13 @@ export function updateDeviceTags(deviceId, tags): Promise<void> {
}
}
getClient()
.then(client => {
.then((client) => {
const collection = client.db().collection("devices");
const object = {};
if (add && add.length) object["$addToSet"] = { _tags: { $each: add } };
if (pull && pull.length) object["$pullAll"] = { _tags: pull };
collection.updateOne({ _id: deviceId }, object, err => {
collection.updateOne({ _id: deviceId }, object, (err) => {
if (err) return void reject(err);
resolve();
});
@@ -260,11 +268,11 @@ export function updateDeviceTags(deviceId, tags): Promise<void> {
function putResource(resource, id, object): Promise<void> {
return new Promise((resolve, reject) => {
getClient()
.then(client => {
.then((client) => {
const collection = client
.db()
.collection(RESOURCE_COLLECTION[resource] || resource);
collection.replaceOne({ _id: id }, object, { upsert: true }, err => {
collection.replaceOne({ _id: id }, object, { upsert: true }, (err) => {
if (err) return void reject(err);
resolve();
});
@@ -273,14 +281,17 @@ function putResource(resource, id, object): Promise<void> {
});
}
function deleteResource(resource, id): Promise<void> {
function deleteResource(
resource: string,
id: string | ObjectID
): Promise<void> {
return new Promise((resolve, reject) => {
getClient()
.then(client => {
.then((client) => {
const collection = client
.db()
.collection(RESOURCE_COLLECTION[resource] || resource);
collection.deleteOne({ _id: id }, err => {
collection.deleteOne({ _id: id }, (err) => {
if (err) return void reject(err);
resolve();
});
@@ -289,16 +300,22 @@ function deleteResource(resource, id): Promise<void> {
});
}
export function putPreset(id, object): Promise<void> {
export function putPreset(
id: string,
object: Record<string, unknown>
): Promise<void> {
object = mongodbFunctions.preProcessPreset(object);
return putResource("presets", id, object);
}
export function deletePreset(id): Promise<void> {
export function deletePreset(id: string): Promise<void> {
return deleteResource("presets", id);
}
export function putProvision(id, object): Promise<void> {
export function putProvision(
id: string,
object: Record<string, unknown>
): Promise<void> {
if (!object.script) object.script = "";
try {
new Script(`"use strict";(function(){\n${object.script}\n})();`);
@@ -308,11 +325,14 @@ export function putProvision(id, object): Promise<void> {
return putResource("provisions", id, object);
}
export function deleteProvision(id): Promise<void> {
export function deleteProvision(id: string): Promise<void> {
return deleteResource("provisions", id);
}
export function putVirtualParameter(id, object): Promise<void> {
export function putVirtualParameter(
id: string,
object: Record<string, unknown>
): Promise<void> {
if (!object.script) object.script = "";
try {
new Script(`"use strict";(function(){\n${object.script}\n})();`);
@@ -322,37 +342,46 @@ export function putVirtualParameter(id, object): Promise<void> {
return putResource("virtualParameters", id, object);
}
export function deleteVirtualParameter(id): Promise<void> {
export function deleteVirtualParameter(id: string): Promise<void> {
return deleteResource("virtualParameters", id);
}
export function putConfig(id, object): Promise<void> {
export function putConfig(
id: string,
object: Record<string, unknown>
): Promise<void> {
return putResource("config", id, object);
}
export function deleteConfig(id): Promise<void> {
export function deleteConfig(id: string): Promise<void> {
return deleteResource("config", id);
}
export function putPermission(id, object): Promise<void> {
export function putPermission(
id: string,
object: Record<string, unknown>
): Promise<void> {
return putResource("permissions", id, object);
}
export function deletePermission(id): Promise<void> {
export function deletePermission(id: string): Promise<void> {
return deleteResource("permissions", id);
}
export function putUser(id, object): Promise<void> {
export function putUser(
id: string,
object: Record<string, unknown>
): Promise<void> {
return new Promise((resolve, reject) => {
getClient()
.then(client => {
.then((client) => {
const collection = client.db().collection("users");
// update instead of replace to keep the password if not set by user
collection.updateOne(
{ _id: id },
{ $set: object },
{ upsert: true },
err => {
(err) => {
if (err) return void reject(err);
resolve();
}
@@ -362,17 +391,21 @@ export function putUser(id, object): Promise<void> {
});
}
export function deleteUser(id): Promise<void> {
export function deleteUser(id: string): Promise<void> {
return deleteResource("users", id);
}
export function putFile(filename, metadata, contentStream): Promise<void> {
export function putFile(
filename: string,
metadata: Record<string, string>,
contentStream: Readable
): Promise<void> {
return new Promise((resolve, reject) => {
getClient()
.then(client => {
.then((client) => {
const bucket = new GridFSBucket(client.db());
const uploadStream = bucket.openUploadStreamWithId(filename, filename, {
metadata: metadata
metadata: metadata,
});
uploadStream.on("error", reject);
contentStream.on("error", reject);
@@ -383,12 +416,12 @@ export function putFile(filename, metadata, contentStream): Promise<void> {
});
}
export function deleteFile(filename): Promise<void> {
export function deleteFile(filename: string): Promise<void> {
return new Promise((resolve, reject) => {
getClient()
.then(client => {
.then((client) => {
const bucket = new GridFSBucket(client.db());
bucket.delete(filename, err => {
bucket.delete(filename as any, (err) => {
if (err) return void reject(err);
resolve();
});
@@ -397,11 +430,11 @@ export function deleteFile(filename): Promise<void> {
});
}
export function deleteFault(id): Promise<void> {
export function deleteFault(id: string): Promise<void> {
return deleteResource("faults", id);
}
export function deleteTask(id): Promise<void> {
export function deleteTask(id: ObjectID): Promise<void> {
return deleteResource("tasks", id);
}