support: remove ssh manipulation routes

this is now moved entirely to cloudron-support --enable-remote-access.

this emphasizes more that users have to get ssh access to the server before
we can do anything about it. it's far too simple for people to click this
button.

we have now also added clear terms to understand what remote access entails.
(what happens if support personnel makes a mistake. who is liable? etc)
This commit is contained in:
Girish Ramakrishnan
2025-07-16 17:42:38 +02:00
parent d1dcbd97b7
commit 7214ce2ede
9 changed files with 2 additions and 229 deletions
-1
View File
@@ -28,7 +28,6 @@ exports = module.exports = {
provision: require('./provision.js'),
reverseProxy: require('./reverseproxy.js'),
services: require('./services.js'),
support: require('./support.js'),
system: require('./system.js'),
tasks: require('./tasks.js'),
tokens: require('./tokens.js'),
-31
View File
@@ -1,31 +0,0 @@
'use strict';
exports = module.exports = {
getRemoteSupport,
enableRemoteSupport,
};
const assert = require('assert'),
AuditSource = require('../auditsource.js'),
HttpError = require('@cloudron/connect-lastmile').HttpError,
HttpSuccess = require('@cloudron/connect-lastmile').HttpSuccess,
safe = require('safetydance'),
support = require('../support.js');
async function enableRemoteSupport(req, res, next) {
assert.strictEqual(typeof req.body, 'object');
if (typeof req.body.enabled !== 'boolean') return next(new HttpError(400, 'enabled is required'));
const [error] = await safe(support.enableRemoteSupport(req.body.enabled, AuditSource.fromRequest(req)));
if (error) return next(new HttpError(503, 'Error enabling remote support. Try running "cloudron-support --enable-remote-support" on the server'));
next(new HttpSuccess(202, {}));
}
async function getRemoteSupport(req, res, next) {
const [error, enabled] = await safe(support.getRemoteSupport());
if (error) return next(new HttpError(500, error));
next(new HttpSuccess(200, { enabled }));
}
-2
View File
@@ -14,7 +14,6 @@ const apps = require('../../apps.js'),
safe = require('safetydance'),
server = require('../../server.js'),
settings = require('../../settings.js'),
support = require('../../support.js'),
superagent = require('@cloudron/superagent'),
tasks = require('../../tasks.js'),
timers = require('timers/promises'),
@@ -127,7 +126,6 @@ async function setup() {
const owner = exports.owner, serverUrl = exports.serverUrl, user = exports.user, admin = exports.admin;
await setupServer();
await safe(fs.promises.unlink(support._sshInfo().filePath));
// setup
let response = await superagent.post(`${serverUrl}/api/v1/provision/setup`)
-86
View File
@@ -1,86 +0,0 @@
/* global it:false */
/* global describe:false */
/* global before:false */
/* global after:false */
'use strict';
const common = require('./common.js'),
expect = require('expect.js'),
fs = require('fs'),
nock = require('nock'),
support = require('../../support.js'),
superagent = require('@cloudron/superagent');
describe('Support API', function () {
const { setup, cleanup, serverUrl, owner, mockApiServerOrigin, appstoreToken, user, admin } = common;
before(setup);
before(() => { if (!nock.isActive()) nock.activate(); });
after(cleanup);
const authorizedKeysFile = support._sshInfo().filePath;
describe('remote support', function () {
it('get remote support', async function () {
const response = await superagent.get(`${serverUrl}/api/v1/support/remote_support`)
.query({ access_token: owner.token });
expect(response.status).to.equal(200);
expect(response.body.enabled).to.be(false);
});
it('enable remote support', async function () {
const response = await superagent.post(`${serverUrl}/api/v1/support/remote_support`)
.query({ access_token: owner.token })
.send({ enabled: true });
expect(response.status).to.equal(202);
let data = await fs.promises.readFile(authorizedKeysFile, 'utf8');
let count = (data.match(/support@cloudron.io/g) || []).length;
expect(count).to.be(1);
});
it('returns true when remote support enabled', async function () {
const response = await superagent.get(`${serverUrl}/api/v1/support/remote_support`)
.query({ access_token: owner.token });
expect(response.status).to.equal(200);
expect(response.body.enabled).to.be(true);
});
it('enable remote support (again)', async function () {
const response = await superagent.post(`${serverUrl}/api/v1/support/remote_support`)
.query({ access_token: owner.token })
.send({ enabled: true });
expect(response.status).to.equal(202);
let data = await fs.promises.readFile(authorizedKeysFile, 'utf8');
let count = (data.match(/support@cloudron.io/g) || []).length;
expect(count).to.be(1);
});
it('disable remote support', async function () {
const response = await superagent.post(`${serverUrl}/api/v1/support/remote_support`)
.query({ access_token: owner.token })
.send({ enabled: false });
expect(response.status).to.equal(202);
let data = await fs.promises.readFile(authorizedKeysFile, 'utf8');
let count = (data.match(/support@cloudron.io/g) || []).length;
expect(count).to.be(0);
});
it('disable remote support (again)', async function () {
const response = await superagent.post(`${serverUrl}/api/v1/support/remote_support`)
.query({ access_token: owner.token })
.send({ enabled: false });
expect(response.status).to.equal(202);
const data = await fs.promises.readFile(authorizedKeysFile, 'utf8');
const count = (data.match(/support@cloudron.io/g) || []).length;
expect(count).to.be(0);
});
});
});