mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Add Support Grist page and nudge
Summary: Adds a new Support Grist page (accessible only in grist-core), containing options to opt in to telemetry and sponsor Grist Labs on GitHub. A nudge is also shown in the doc menu, which can be collapsed or permanently dismissed. Test Plan: Browser and server tests. Reviewers: paulfitz, dsagal Reviewed By: paulfitz Subscribers: jarek, dsagal Differential Revision: https://phab.getgrist.com/D3926
This commit is contained in:
@@ -5,6 +5,7 @@ import {encodeUrl, getSlugIfNeeded, GristDeploymentType, GristDeploymentTypes,
|
||||
GristLoadConfig, IGristUrlState, isOrgInPathOnly, parseSubdomain,
|
||||
sanitizePathTail} from 'app/common/gristUrls';
|
||||
import {getOrgUrlInfo} from 'app/common/gristUrls';
|
||||
import {InstallProperties} from 'app/common/InstallAPI';
|
||||
import {UserProfile} from 'app/common/LoginSessionAPI';
|
||||
import {tbind} from 'app/common/tbind';
|
||||
import * as version from 'app/common/version';
|
||||
@@ -50,14 +51,15 @@ import {getAppPathTo, getAppRoot, getUnpackedAppRoot} from 'app/server/lib/place
|
||||
import {addPluginEndpoints, limitToPlugins} from 'app/server/lib/PluginEndpoint';
|
||||
import {PluginManager} from 'app/server/lib/PluginManager';
|
||||
import * as ProcessMonitor from 'app/server/lib/ProcessMonitor';
|
||||
import {adaptServerUrl, getOrgUrl, getOriginUrl, getScope, optStringParam,
|
||||
RequestWithGristInfo, stringParam, TEST_HTTPS_OFFSET, trustOrigin} from 'app/server/lib/requestUtils';
|
||||
import {adaptServerUrl, getOrgUrl, getOriginUrl, getScope, isDefaultUser, optStringParam,
|
||||
RequestWithGristInfo, sendOkReply, stringParam, TEST_HTTPS_OFFSET,
|
||||
trustOrigin} from 'app/server/lib/requestUtils';
|
||||
import {ISendAppPageOptions, makeGristConfig, makeMessagePage, makeSendAppPage} from 'app/server/lib/sendAppPage';
|
||||
import {getDatabaseUrl, listenPromise} from 'app/server/lib/serverUtils';
|
||||
import {Sessions} from 'app/server/lib/Sessions';
|
||||
import * as shutdown from 'app/server/lib/shutdown';
|
||||
import {TagChecker} from 'app/server/lib/TagChecker';
|
||||
import {ITelemetry} from 'app/server/lib/Telemetry';
|
||||
import {getTelemetryPrefs, ITelemetry} from 'app/server/lib/Telemetry';
|
||||
import {startTestingHooks} from 'app/server/lib/TestingHooks';
|
||||
import {getTestLoginSystem} from 'app/server/lib/TestLogin';
|
||||
import {addUploadRoute} from 'app/server/lib/uploads';
|
||||
@@ -706,11 +708,17 @@ export class FlexServer implements GristServer {
|
||||
});
|
||||
}
|
||||
|
||||
public addTelemetry() {
|
||||
public async addTelemetry() {
|
||||
if (this._check('telemetry', 'homedb', 'json', 'api-mw')) { return; }
|
||||
|
||||
this._telemetry = this.create.Telemetry(this._dbManager, this);
|
||||
this._telemetry.addEndpoints(this.app);
|
||||
this._telemetry.addPages(this.app, [
|
||||
this._redirectToHostMiddleware,
|
||||
this._userIdMiddleware,
|
||||
this._redirectToLoginWithoutExceptionsMiddleware,
|
||||
]);
|
||||
await this._telemetry.start();
|
||||
|
||||
// Start up a monitor for memory and cpu usage.
|
||||
this._processMonitorStop = ProcessMonitor.start(this._telemetry);
|
||||
@@ -1198,7 +1206,7 @@ export class FlexServer implements GristServer {
|
||||
];
|
||||
|
||||
this.app.get('/account', ...middleware, expressWrap(async (req, resp) => {
|
||||
return this._sendAppPage(req, resp, {path: 'account.html', status: 200, config: {}});
|
||||
return this._sendAppPage(req, resp, {path: 'app.html', status: 200, config: {}});
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -1460,6 +1468,43 @@ export class FlexServer implements GristServer {
|
||||
addGoogleAuthEndpoint(this.app, messagePage);
|
||||
}
|
||||
|
||||
public addInstallEndpoints() {
|
||||
if (this._check('install')) { return; }
|
||||
|
||||
const isManager = expressWrap(
|
||||
(req: express.Request, _res: express.Response, next: express.NextFunction) => {
|
||||
if (!isDefaultUser(req)) { throw new ApiError('Access denied', 403); }
|
||||
|
||||
next();
|
||||
}
|
||||
);
|
||||
|
||||
this.app.get('/api/install/prefs', expressWrap(async (_req, resp) => {
|
||||
const activation = await this._activations.current();
|
||||
|
||||
return sendOkReply(null, resp, {
|
||||
telemetry: await getTelemetryPrefs(this._dbManager, activation),
|
||||
});
|
||||
}));
|
||||
|
||||
this.app.patch('/api/install/prefs', isManager, expressWrap(async (req, resp) => {
|
||||
const props = {prefs: req.body};
|
||||
const activation = await this._activations.current();
|
||||
activation.checkProperties(props);
|
||||
activation.updateFromProperties(props);
|
||||
await activation.save();
|
||||
|
||||
if ((props as Partial<InstallProperties>).prefs?.telemetry) {
|
||||
// Make sure the Telemetry singleton picks up the changes to telemetry preferences.
|
||||
// TODO: if there are multiple home server instances, notify them all of changes to
|
||||
// preferences (via Redis Pub/Sub).
|
||||
await this._telemetry.fetchTelemetryPrefs();
|
||||
}
|
||||
|
||||
return resp.status(200).send();
|
||||
}));
|
||||
}
|
||||
|
||||
// Get the HTML template sent for document pages.
|
||||
public async getDocTemplate(): Promise<DocTemplate> {
|
||||
const page = await fse.readFile(path.join(getAppPathTo(this.appRoot, 'static'),
|
||||
|
||||
Reference in New Issue
Block a user