2018-12-19 10:54:33 -08:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
exports = module.exports = {
|
2021-05-01 11:21:09 -07:00
|
|
|
createTicket,
|
2018-12-19 11:47:15 -08:00
|
|
|
|
2021-05-01 11:21:09 -07:00
|
|
|
getRemoteSupport,
|
|
|
|
|
enableRemoteSupport,
|
2020-02-05 14:30:56 -08:00
|
|
|
|
2023-08-02 22:21:30 +05:30
|
|
|
getConfig,
|
|
|
|
|
|
2021-05-01 11:21:09 -07:00
|
|
|
canCreateTicket,
|
|
|
|
|
canEnableRemoteSupport
|
2018-12-19 10:54:33 -08:00
|
|
|
};
|
|
|
|
|
|
2021-08-18 15:54:53 -07:00
|
|
|
const appstore = require('../appstore.js'),
|
2018-12-19 10:54:33 -08:00
|
|
|
assert = require('assert'),
|
2021-09-30 09:50:30 -07:00
|
|
|
AuditSource = require('../auditsource.js'),
|
2023-08-02 22:21:30 +05:30
|
|
|
BoxError = require('../boxerror.js'),
|
2020-02-04 13:07:26 -08:00
|
|
|
constants = require('../constants.js'),
|
2018-12-19 10:54:33 -08:00
|
|
|
HttpError = require('connect-lastmile').HttpError,
|
|
|
|
|
HttpSuccess = require('connect-lastmile').HttpSuccess,
|
2021-08-18 15:54:53 -07:00
|
|
|
safe = require('safetydance'),
|
2023-05-25 11:27:23 +02:00
|
|
|
support = require('../support.js');
|
2018-12-19 10:54:33 -08:00
|
|
|
|
2023-08-02 22:21:30 +05:30
|
|
|
async function getConfig(req, res, next) {
|
|
|
|
|
const [error, supportConfig] = await safe(support.getConfig());
|
|
|
|
|
if (error) return next(BoxError.toHttpError(error));
|
|
|
|
|
|
|
|
|
|
next(new HttpSuccess(200, supportConfig));
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-18 15:54:53 -07:00
|
|
|
async function canCreateTicket(req, res, next) {
|
2023-08-02 22:21:30 +05:30
|
|
|
const [error, supportConfig] = await safe(support.getConfig());
|
2021-08-18 15:54:53 -07:00
|
|
|
if (error) return next(new HttpError(503, error.message));
|
2020-02-05 14:30:56 -08:00
|
|
|
|
2021-08-18 15:54:53 -07:00
|
|
|
if (!supportConfig.submitTickets) return next(new HttpError(405, 'feature disabled by admin'));
|
2020-02-05 14:30:56 -08:00
|
|
|
|
2021-08-18 15:54:53 -07:00
|
|
|
next();
|
2020-02-05 14:30:56 -08:00
|
|
|
}
|
|
|
|
|
|
2021-08-18 15:54:53 -07:00
|
|
|
async function createTicket(req, res, next) {
|
2018-12-19 10:54:33 -08:00
|
|
|
assert.strictEqual(typeof req.user, 'object');
|
|
|
|
|
|
2023-08-25 12:08:44 +02:00
|
|
|
const VALID_TYPES = [ 'feedback', 'ticket', 'app_missing', 'app_error', 'upgrade_request', 'email_error', 'billing' ];
|
2018-12-19 10:54:33 -08:00
|
|
|
|
|
|
|
|
if (typeof req.body.type !== 'string' || !req.body.type) return next(new HttpError(400, 'type must be string'));
|
|
|
|
|
if (VALID_TYPES.indexOf(req.body.type) === -1) return next(new HttpError(400, 'unknown type'));
|
|
|
|
|
if (typeof req.body.subject !== 'string' || !req.body.subject) return next(new HttpError(400, 'subject must be string'));
|
|
|
|
|
if (typeof req.body.description !== 'string' || !req.body.description) return next(new HttpError(400, 'description must be string'));
|
|
|
|
|
if (req.body.appId && typeof req.body.appId !== 'string') return next(new HttpError(400, 'appId must be string'));
|
2019-10-15 11:39:44 -07:00
|
|
|
if (req.body.altEmail && typeof req.body.altEmail !== 'string') return next(new HttpError(400, 'altEmail must be string'));
|
2020-10-05 15:20:14 +02:00
|
|
|
if (req.body.enableSshSupport && typeof req.body.enableSshSupport !== 'boolean') return next(new HttpError(400, 'enableSshSupport must be a boolean'));
|
2018-12-19 10:54:33 -08:00
|
|
|
|
2023-08-02 22:21:30 +05:30
|
|
|
const [error, supportConfig] = await safe(support.getConfig());
|
2021-08-18 15:54:53 -07:00
|
|
|
if (error) return next(new HttpError(503, `Error getting support config: ${error.message}`));
|
|
|
|
|
if (supportConfig.email !== constants.SUPPORT_EMAIL) return next(new HttpError(503, 'Sending to non-cloudron email not implemented yet'));
|
2020-02-05 14:30:56 -08:00
|
|
|
|
2023-05-25 11:27:23 +02:00
|
|
|
const [ticketError, result] = await safe(appstore.createTicket(Object.assign({ }, req.body, { email: req.user.email, displayName: req.user.displayName }), AuditSource.fromRequest(req)));
|
2023-01-31 11:29:55 +01:00
|
|
|
if (ticketError) return next(new HttpError(503, `Error contacting cloudron.io: ${ticketError.message}. Please email ${constants.SUPPORT_EMAIL}`));
|
2020-02-05 14:30:56 -08:00
|
|
|
|
2021-08-18 15:54:53 -07:00
|
|
|
next(new HttpSuccess(201, result));
|
2020-02-05 14:30:56 -08:00
|
|
|
}
|
|
|
|
|
|
2021-08-18 15:54:53 -07:00
|
|
|
async function canEnableRemoteSupport(req, res, next) {
|
2023-08-02 22:21:30 +05:30
|
|
|
const [error, supportConfig] = await safe(support.getConfig());
|
2021-08-18 15:54:53 -07:00
|
|
|
if (error) return next(new HttpError(503, error.message));
|
2020-02-05 14:30:56 -08:00
|
|
|
|
2021-08-18 15:54:53 -07:00
|
|
|
if (!supportConfig.remoteSupport) return next(new HttpError(405, 'feature disabled by admin'));
|
2018-12-19 10:54:33 -08:00
|
|
|
|
2021-08-18 15:54:53 -07:00
|
|
|
next();
|
2018-12-19 10:54:33 -08:00
|
|
|
}
|
2018-12-19 11:47:15 -08:00
|
|
|
|
2021-08-18 15:54:53 -07:00
|
|
|
async function enableRemoteSupport(req, res, next) {
|
2018-12-19 11:47:15 -08:00
|
|
|
assert.strictEqual(typeof req.body, 'object');
|
|
|
|
|
|
|
|
|
|
if (typeof req.body.enable !== 'boolean') return next(new HttpError(400, 'enabled is required'));
|
|
|
|
|
|
2021-09-30 09:50:30 -07:00
|
|
|
const [error] = await safe(support.enableRemoteSupport(req.body.enable, AuditSource.fromRequest(req)));
|
2021-08-18 15:54:53 -07:00
|
|
|
if (error) return next(new HttpError(503, 'Error enabling remote support. Try running "cloudron-support --enable-ssh" on the server'));
|
2018-12-19 11:47:15 -08:00
|
|
|
|
2021-08-18 15:54:53 -07:00
|
|
|
next(new HttpSuccess(202, {}));
|
2018-12-19 11:47:15 -08:00
|
|
|
}
|
|
|
|
|
|
2021-08-18 15:54:53 -07:00
|
|
|
async function getRemoteSupport(req, res, next) {
|
|
|
|
|
const [error, enabled] = await safe(support.getRemoteSupport());
|
|
|
|
|
if (error) return next(new HttpError(500, error));
|
2018-12-19 11:47:15 -08:00
|
|
|
|
2021-08-18 15:54:53 -07:00
|
|
|
next(new HttpSuccess(200, { enabled }));
|
2018-12-19 11:47:15 -08:00
|
|
|
}
|