static createShortcut (req, res) {
    // make sure all the necessary data is included in the post body
    if (!ArkimeUtil.isString(req.body.name)) {
      return res.serverError(403, 'Missing shortcut name');
    }
    if (!ArkimeUtil.isString(req.body.type)) {
      return res.serverError(403, 'Missing shortcut type');
    }
    if (!ArkimeUtil.isString(req.body.value)) {
      return res.serverError(403, 'Missing shortcut value');
    }

    if (req.body.roles !== undefined && !ArkimeUtil.isStringArray(req.body.roles)) {
      return res.serverError(403, 'Roles field must be an array of strings');
    }

    if (req.body.editRoles !== undefined && !ArkimeUtil.isStringArray(req.body.editRoles)) {
      return res.serverError(403, 'Edit roles field must be an array of strings');
    }

    if (req.body.users !== undefined && !ArkimeUtil.isString(req.body.users, 0)) {
      return res.serverError(403, 'Users field must be a string');
    }

    req.body.name = req.body.name.replace(/[^-a-zA-Z0-9_]/g, '');

    // return nothing if we can't find the user
    const user = req.settingUser;
    if (!user) { return res.send({}); }

    const query = {
      query: {
        bool: {
          filter: [
            { term: { name: req.body.name } }
          ]
        }
      }
    };

    ShortcutAPIs.#shortcutMutex.lock().then(async () => {
      try {
        const { body: { hits: shortcuts } } = await Db.searchShortcuts(query);

        // search for shortcut name collision
        for (const hit of shortcuts.hits) {
          const shortcut = hit._source;
          if (shortcut.name === req.body.name) {
            ShortcutAPIs.#shortcutMutex.unlock();
            return res.serverError(403, `A shortcut with the name, ${req.body.name}, already exists`);
          }
        }

        const newShortcut = req.body;
        newShortcut.userId = user.userId;

        const { type, values, invalidUsers } = await ShortcutAPIs.#normalizeShortcut(newShortcut);

        try {
          const { body: result } = await Db.createShortcut(newShortcut);
          newShortcut.id = result._id;
          newShortcut.type = type;
          newShortcut.value = values.join('\n');
          delete newShortcut.ip;
          delete newShortcut.string;
          delete newShortcut.number;
          ShortcutAPIs.#shortcutMutex.unlock();

          return res.send(JSON.stringify({
            invalidUsers,
            success: true,
            shortcut: newShortcut,
            text: 'Created new shortcut!'
          }));
        } catch (err) {
          ShortcutAPIs.#shortcutMutex.unlock();
          console.log(`ERROR - ${req.method} /api/shortcut (createShortcut)`, util.inspect(err, false, 50));
          return res.serverError(500, 'Error creating shortcut');
        }
      } catch (err) {
        ShortcutAPIs.#shortcutMutex.unlock();
        console.log(`ERROR - ${req.method} /api/shortcut (searchShortcuts)`, util.inspect(err, false, 50));
        return res.serverError(500, 'Error creating shortcut');
      }
    });
  }
POST - /api/shortcut

Creates a new shortcut.
@name /shortcut
@param {string} name - The name of the new shortcut.
@param {string} type - The type of the shortcut (number, ip, or string).
@param {string} value - The shortcut value.
@param {string} description - The optional description of this shortcut.
@param {string} users - A comma separated list of users that can view this shortcut.
@param {Array} roles - The roles that can view this shortcut.
@returns {Shortcut} shortcut - The new shortcut object.
@returns {boolean} success - Whether the create shortcut operation was successful.