• api-key-socket-handler.js
  • 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 {
                checkLogin(socket);
    
                let clearKey = nanoid(40);
                let hashedKey = await 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 {
                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 {
                checkLogin(socket);
    
                log.debug("apikeys", `Deleted API Key: ${keyID} User ID: ${socket.userID}`);
    
                await R.exec("DELETE FROM api_key WHERE id = ? AND user_id = ? ", [
                    keyID,
                    socket.userID,
                ]);
    
                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 {
                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 {
                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,
                });
            }
        });
    };