mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
153 lines
4.7 KiB
TypeScript
153 lines
4.7 KiB
TypeScript
/**
|
|
* Main entrypoint for grist-core server.
|
|
*
|
|
* By default, starts up on port 8484.
|
|
*/
|
|
|
|
import {commonUrls} from 'app/common/gristUrls';
|
|
import {isAffirmative} from 'app/common/gutil';
|
|
import {HomeDBManager} from 'app/gen-server/lib/homedb/HomeDBManager';
|
|
import {fixSiteProducts} from 'app/gen-server/lib/Housekeeper';
|
|
|
|
const debugging = isAffirmative(process.env.DEBUG) || isAffirmative(process.env.VERBOSE);
|
|
|
|
// Set log levels before importing anything.
|
|
if (!debugging) {
|
|
// Be a lot less noisy by default.
|
|
setDefaultEnv('GRIST_LOG_LEVEL', 'error');
|
|
setDefaultEnv('GRIST_LOG_SKIP_HTTP', 'true');
|
|
}
|
|
|
|
// Use a distinct cookie. Bump version to 2.
|
|
setDefaultEnv('GRIST_SESSION_COOKIE', 'grist_core2');
|
|
|
|
setDefaultEnv('GRIST_SERVE_SAME_ORIGIN', 'true');
|
|
setDefaultEnv('GRIST_SINGLE_PORT', 'true');
|
|
setDefaultEnv('GRIST_DEFAULT_PRODUCT', 'Free');
|
|
|
|
if (!process.env.GRIST_SINGLE_ORG) {
|
|
// org identifiers in domains are fiddly to configure right, so by
|
|
// default don't do that.
|
|
setDefaultEnv('GRIST_ORG_IN_PATH', 'true');
|
|
}
|
|
|
|
setDefaultEnv('GRIST_UI_FEATURES',
|
|
'helpCenter,billing,templates,multiSite,multiAccounts,sendToDrive,createSite,supportGrist');
|
|
setDefaultEnv('GRIST_WIDGET_LIST_URL', commonUrls.gristLabsWidgetRepository);
|
|
import {updateDb} from 'app/server/lib/dbUtils';
|
|
import {main as mergedServerMain, parseServerTypes} from 'app/server/mergedServerMain';
|
|
import * as fse from 'fs-extra';
|
|
import {runPrometheusExporter} from './prometheus-exporter';
|
|
|
|
const G = {
|
|
port: parseInt(process.env.PORT!, 10) || 8484,
|
|
};
|
|
|
|
// Set a default for an environment variable.
|
|
function setDefaultEnv(name: string, value: string) {
|
|
if (process.env[name] === undefined) {
|
|
process.env[name] = value;
|
|
}
|
|
}
|
|
|
|
async function setupDb() {
|
|
// Make a blank db if needed.
|
|
if (process.env.TEST_CLEAN_DATABASE) {
|
|
const {createInitialDb} = require('test/gen-server/seed');
|
|
await createInitialDb();
|
|
} else {
|
|
await updateDb();
|
|
}
|
|
const db = new HomeDBManager();
|
|
await db.connect();
|
|
await db.initializeSpecialIds({skipWorkspaces: true});
|
|
|
|
// If a team/organization is specified, make sure it exists.
|
|
const org = process.env.GRIST_SINGLE_ORG;
|
|
if (org && org !== 'docs') {
|
|
try {
|
|
db.unwrapQueryResult(await db.getOrg({
|
|
userId: db.getPreviewerUserId(),
|
|
includeSupport: false,
|
|
}, org));
|
|
} catch(e) {
|
|
if (!String(e).match(/organization not found/)) {
|
|
throw e;
|
|
}
|
|
const email = process.env.GRIST_DEFAULT_EMAIL;
|
|
if (!email) {
|
|
throw new Error('need GRIST_DEFAULT_EMAIL to create site');
|
|
}
|
|
const profile = {email, name: email};
|
|
const user = await db.getUserByLogin(email, {profile});
|
|
if (!user) {
|
|
// This should not happen.
|
|
throw new Error('failed to create GRIST_DEFAULT_EMAIL user');
|
|
}
|
|
db.unwrapQueryResult(await db.addOrg(user, {
|
|
name: org,
|
|
domain: org,
|
|
}, {
|
|
setUserAsOwner: false,
|
|
useNewPlan: true,
|
|
}));
|
|
}
|
|
}
|
|
}
|
|
|
|
// tslint:disable:no-console
|
|
export async function main() {
|
|
console.log('Welcome to Grist.');
|
|
if (!debugging) {
|
|
console.log(`In quiet mode, see http://localhost:${G.port} to use.`);
|
|
console.log('For full logs, re-run with DEBUG=1');
|
|
}
|
|
|
|
if (process.env.GRIST_PROMCLIENT_PORT) {
|
|
runPrometheusExporter(parseInt(process.env.GRIST_PROMCLIENT_PORT, 10));
|
|
}
|
|
|
|
// If SAML is not configured, there's no login system, so provide a default email address.
|
|
setDefaultEnv('GRIST_DEFAULT_EMAIL', 'you@example.com');
|
|
// Set directory for uploaded documents.
|
|
setDefaultEnv('GRIST_DATA_DIR', 'docs');
|
|
setDefaultEnv('GRIST_SERVERS', 'home,docs,static');
|
|
if (process.env.GRIST_SERVERS?.includes('home')) {
|
|
// By default, we will now start an untrusted port alongside a
|
|
// home server, for bundled custom widgets.
|
|
// Suppress with GRIST_UNTRUSTED_PORT=''
|
|
setDefaultEnv('GRIST_UNTRUSTED_PORT', '0');
|
|
}
|
|
const serverTypes = parseServerTypes(process.env.GRIST_SERVERS);
|
|
|
|
await fse.mkdirp(process.env.GRIST_DATA_DIR!);
|
|
|
|
if (serverTypes.includes("home")) {
|
|
console.log('Setting up database...');
|
|
await setupDb();
|
|
console.log('Database setup complete.');
|
|
}
|
|
|
|
// Launch single-port, self-contained version of Grist.
|
|
const server = await mergedServerMain(G.port, serverTypes);
|
|
if (process.env.GRIST_TESTING_SOCKET) {
|
|
await server.addTestingHooks();
|
|
}
|
|
if (process.env.GRIST_SERVE_PLUGINS_PORT) {
|
|
await server.startCopy('pluginServer', parseInt(process.env.GRIST_SERVE_PLUGINS_PORT, 10));
|
|
}
|
|
|
|
await fixSiteProducts({
|
|
deploymentType: server.getDeploymentType(),
|
|
db: server.getHomeDBManager()
|
|
});
|
|
|
|
return server;
|
|
}
|
|
|
|
if (require.main === module) {
|
|
main().catch((err) => {
|
|
console.error(err);
|
|
});
|
|
}
|