|
|
|
const { checkLogin } = require("../util-server");
|
|
|
|
const { log } = require("../../src/util");
|
|
|
|
const { R } = require("redbean-node");
|
|
|
|
const { nanoid } = require("nanoid");
|
|
|
|
const passwordHash = require("../password-hash");
|
|
|
|
const apicache = require("../modules/apicache");
|
|
|
|
const APIKey = require("../model/api_key");
|
|
|
|
const { Settings } = require("../settings");
|
|
|
|
const { sendAPIKeyList } = require("../client");
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handlers for API keys
|
|
|
|
* @param {Socket} socket Socket.io instance
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
module.exports.apiKeySocketHandler = (socket) => {
|
|
|
|
// Add a new api key
|
|
|
|
socket.on("addAPIKey", async (key, callback) => {
|
|
|
|
try {
|
|
|
|
await checkLogin(socket);
|
|
|
|
|
|
|
|
let clearKey = nanoid(40);
|
|
|
|
let hashedKey = passwordHash.generate(clearKey);
|
|
|
|
key["key"] = hashedKey;
|
|
|
|
let bean = await APIKey.save(key, socket.userID);
|
|
|
|
|
|
|
|
log.debug("apikeys", "Added API Key");
|
|
|
|
log.debug("apikeys", key);
|
|
|
|
|
|
|
|
// Append key ID and prefix to start of key seperated by _, used to get
|
|
|
|
// correct hash when validating key.
|
|
|
|
let formattedKey = "uk" + bean.id + "_" + clearKey;
|
|
|
|
await sendAPIKeyList(socket);
|
|
|
|
|
|
|
|
// Enable API auth if the user creates a key, otherwise only basic
|
|
|
|
// auth will be used for API.
|
|
|
|
await Settings.set("apiKeysEnabled", true);
|
|
|
|
|
|
|
|
callback({
|
|
|
|
ok: true,
|
|
|
|
msg: "successAdded",
|
|
|
|
msgi18n: true,
|
|
|
|
key: formattedKey,
|
|
|
|
keyID: bean.id,
|
|
|
|
});
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
callback({
|
|
|
|
ok: false,
|
|
|
|
msg: e.message,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
socket.on("getAPIKeyList", async (callback) => {
|
|
|
|
try {
|
|
|
|
await checkLogin(socket);
|
|
|
|
await sendAPIKeyList(socket);
|
|
|
|
callback({
|
|
|
|
ok: true,
|
|
|
|
});
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
callback({
|
|
|
|
ok: false,
|
|
|
|
msg: e.message,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
socket.on("deleteAPIKey", async (keyID, callback) => {
|
|
|
|
try {
|
|
|
|
await checkLogin(socket);
|
|
|
|
|
|
|
|
log.debug("apikeys", `Deleted API Key: ${keyID} User ID: ${socket.userID}`);
|
|
|
|
|
|
|
|
await R.exec("DELETE FROM api_key WHERE id = ? ", [ keyID ]);
|
|
|
|
|
|
|
|
apicache.clear();
|
|
|
|
|
|
|
|
callback({
|
|
|
|
ok: true,
|
|
|
|
msg: "successDeleted",
|
|
|
|
msgi18n: true,
|
|
|
|
});
|
|
|
|
|
|
|
|
await sendAPIKeyList(socket);
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
callback({
|
|
|
|
ok: false,
|
|
|
|
msg: e.message,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
socket.on("disableAPIKey", async (keyID, callback) => {
|
|
|
|
try {
|
|
|
|
await checkLogin(socket);
|
|
|
|
|
|
|
|
log.debug("apikeys", `Disabled Key: ${keyID} User ID: ${socket.userID}`);
|
|
|
|
|
|
|
|
await R.exec("UPDATE api_key SET active = 0 WHERE id = ? ", [
|
|
|
|
keyID,
|
|
|
|
]);
|
|
|
|
|
|
|
|
apicache.clear();
|
|
|
|
|
|
|
|
callback({
|
|
|
|
ok: true,
|
|
|
|
msg: "successDisabled",
|
|
|
|
msgi18n: true,
|
|
|
|
});
|
|
|
|
|
|
|
|
await sendAPIKeyList(socket);
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
callback({
|
|
|
|
ok: false,
|
|
|
|
msg: e.message,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
socket.on("enableAPIKey", async (keyID, callback) => {
|
|
|
|
try {
|
|
|
|
await checkLogin(socket);
|
|
|
|
|
|
|
|
log.debug("apikeys", `Enabled Key: ${keyID} User ID: ${socket.userID}`);
|
|
|
|
|
|
|
|
await R.exec("UPDATE api_key SET active = 1 WHERE id = ? ", [
|
|
|
|
keyID,
|
|
|
|
]);
|
|
|
|
|
|
|
|
apicache.clear();
|
|
|
|
|
|
|
|
callback({
|
|
|
|
ok: true,
|
|
|
|
msg: "successEnabled",
|
|
|
|
msgi18n: true,
|
|
|
|
});
|
|
|
|
|
|
|
|
await sendAPIKeyList(socket);
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
callback({
|
|
|
|
ok: false,
|
|
|
|
msg: e.message,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|