settings.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  1. /* eslint-disable
  2. camelcase,
  3. no-cond-assign,
  4. no-dupe-keys,
  5. no-unused-vars,
  6. */
  7. // TODO: This file was created by bulk-decaffeinate.
  8. // Fix any style issues and re-enable lint.
  9. /*
  10. * decaffeinate suggestions:
  11. * DS205: Consider reworking code to avoid use of IIFEs
  12. * DS207: Consider shorter variations of null checks
  13. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  14. */
  15. let allTexLiveDockerImageNames, allTexLiveDockerImages, redisConfig, siteUrl;
  16. let e;
  17. const Path = require('path');
  18. // These credentials are used for authenticating api requests
  19. // between services that may need to go over public channels
  20. const httpAuthUser = "sharelatex";
  21. const httpAuthPass = process.env.WEB_API_PASSWORD;
  22. const httpAuthUsers = {};
  23. httpAuthUsers[httpAuthUser] = httpAuthPass;
  24. const parse = function(option){
  25. if (option != null) {
  26. try {
  27. const opt = JSON.parse(option);
  28. return opt;
  29. } catch (err) {
  30. throw new Error(`problem parsing ${option}, invalid JSON`);
  31. }
  32. }
  33. };
  34. const parseIntOrFail = function(value){
  35. const parsedValue = parseInt(value, 10);
  36. if (isNaN(parsedValue)) {
  37. throw new Error(`'${value}' is an invalid integer`);
  38. }
  39. return parsedValue;
  40. };
  41. const DATA_DIR = '/var/lib/sharelatex/data';
  42. const TMP_DIR = '/var/lib/sharelatex/tmp';
  43. const settings = {
  44. clsi: {
  45. optimiseInDocker: process.env.OPTIMISE_PDF === 'true'
  46. },
  47. brandPrefix: "",
  48. allowAnonymousReadAndWriteSharing:
  49. process.env.SHARELATEX_ALLOW_ANONYMOUS_READ_AND_WRITE_SHARING === 'true',
  50. // Databases
  51. // ---------
  52. // ShareLaTeX's main persistent data store is MongoDB (http://www.mongodb.org/)
  53. // Documentation about the URL connection string format can be found at:
  54. //
  55. // http://docs.mongodb.org/manual/reference/connection-string/
  56. //
  57. // The following works out of the box with Mongo's default settings:
  58. mongo: {
  59. url : process.env.SHARELATEX_MONGO_URL || 'mongodb://dockerhost/sharelatex'
  60. },
  61. // Redis is used in ShareLaTeX for high volume queries, like real-time
  62. // editing, and session management.
  63. //
  64. // The following config will work with Redis's default settings:
  65. redis: {
  66. web: (redisConfig = {
  67. host: process.env.SHARELATEX_REDIS_HOST || "dockerhost",
  68. port: process.env.SHARELATEX_REDIS_PORT || "6379",
  69. password: process.env.SHARELATEX_REDIS_PASS || undefined,
  70. key_schema: {
  71. // document-updater
  72. blockingKey({doc_id}) { return `Blocking:${doc_id}`; },
  73. docLines({doc_id}) { return `doclines:${doc_id}`; },
  74. docOps({doc_id}) { return `DocOps:${doc_id}`; },
  75. docVersion({doc_id}) { return `DocVersion:${doc_id}`; },
  76. docHash({doc_id}) { return `DocHash:${doc_id}`; },
  77. projectKey({doc_id}) { return `ProjectId:${doc_id}`; },
  78. docsInProject({project_id}) { return `DocsIn:${project_id}`; },
  79. ranges({doc_id}) { return `Ranges:${doc_id}`; },
  80. // document-updater:realtime
  81. pendingUpdates({doc_id}) { return `PendingUpdates:${doc_id}`; },
  82. // document-updater:history
  83. uncompressedHistoryOps({doc_id}) { return `UncompressedHistoryOps:${doc_id}`; },
  84. docsWithHistoryOps({project_id}) { return `DocsWithHistoryOps:${project_id}`; },
  85. // document-updater:lock
  86. blockingKey({doc_id}) { return `Blocking:${doc_id}`; },
  87. // track-changes:lock
  88. historyLock({doc_id}) { return `HistoryLock:${doc_id}`; },
  89. historyIndexLock({project_id}) { return `HistoryIndexLock:${project_id}`; },
  90. // track-changes:history
  91. uncompressedHistoryOps({doc_id}) { return `UncompressedHistoryOps:${doc_id}`; },
  92. docsWithHistoryOps({project_id}) { return `DocsWithHistoryOps:${project_id}`; },
  93. // realtime
  94. clientsInProject({project_id}) { return `clients_in_project:${project_id}`; },
  95. connectedUser({project_id, client_id}){ return `connected_user:${project_id}:${client_id}`; }
  96. }
  97. }),
  98. fairy: redisConfig,
  99. // track-changes and document-updater
  100. realtime: redisConfig,
  101. documentupdater: redisConfig,
  102. lock: redisConfig,
  103. history: redisConfig,
  104. websessions: redisConfig,
  105. api: redisConfig,
  106. pubsub: redisConfig,
  107. project_history: redisConfig
  108. },
  109. // The compile server (the clsi) uses a SQL database to cache files and
  110. // meta-data. sqlite is the default, and the load is low enough that this will
  111. // be fine in production (we use sqlite at sharelatex.com).
  112. //
  113. // If you want to configure a different database, see the Sequelize documentation
  114. // for available options:
  115. //
  116. // https://github.com/sequelize/sequelize/wiki/API-Reference-Sequelize#example-usage
  117. //
  118. mysql: {
  119. clsi: {
  120. database: "clsi",
  121. username: "clsi",
  122. password: "",
  123. dialect: "sqlite",
  124. storage: Path.join(DATA_DIR, "db.sqlite")
  125. }
  126. },
  127. // File storage
  128. // ------------
  129. // ShareLaTeX can store binary files like images either locally or in Amazon
  130. // S3. The default is locally:
  131. filestore: {
  132. backend: "fs",
  133. stores: {
  134. user_files: Path.join(DATA_DIR, "user_files"),
  135. template_files: Path.join(DATA_DIR, "template_files")
  136. }
  137. },
  138. // To use Amazon S3 as a storage backend, comment out the above config, and
  139. // uncomment the following, filling in your key, secret, and bucket name:
  140. //
  141. // filestore:
  142. // backend: "s3"
  143. // stores:
  144. // user_files: "BUCKET_NAME"
  145. // s3:
  146. // key: "AWS_KEY"
  147. // secret: "AWS_SECRET"
  148. //
  149. trackchanges: {
  150. continueOnError: true
  151. },
  152. // Local disk caching
  153. // ------------------
  154. path: {
  155. // If we ever need to write something to disk (e.g. incoming requests
  156. // that need processing but may be too big for memory), then write
  157. // them to disk here:
  158. dumpFolder: Path.join(TMP_DIR, "dumpFolder"),
  159. // Where to write uploads before they are processed
  160. uploadFolder: Path.join(TMP_DIR, "uploads"),
  161. // Where to write the project to disk before running LaTeX on it
  162. compilesDir: Path.join(DATA_DIR, "compiles"),
  163. // Where to cache downloaded URLs for the CLSI
  164. clsiCacheDir: Path.join(DATA_DIR, "cache"),
  165. // Where to write the output files to disk after running LaTeX
  166. outputDir: Path.join(DATA_DIR, "output")
  167. },
  168. // Server Config
  169. // -------------
  170. // Where your instance of ShareLaTeX can be found publicly. This is used
  171. // when emails are sent out and in generated links:
  172. siteUrl: (siteUrl = process.env.SHARELATEX_SITE_URL || 'http://localhost'),
  173. // The name this is used to describe your ShareLaTeX Installation
  174. appName: process.env.SHARELATEX_APP_NAME || "ShareLaTeX (Community Edition)",
  175. restrictInvitesToExistingAccounts: process.env.SHARELATEX_RESTRICT_INVITES_TO_EXISTING_ACCOUNTS === 'true',
  176. nav: {
  177. title: process.env.SHARELATEX_NAV_TITLE || process.env.SHARELATEX_APP_NAME || "ShareLaTeX Community Edition"
  178. },
  179. // The email address which users will be directed to as the main point of
  180. // contact for this installation of ShareLaTeX.
  181. adminEmail: process.env.SHARELATEX_ADMIN_EMAIL || "placeholder@example.com",
  182. // If provided, a sessionSecret is used to sign cookies so that they cannot be
  183. // spoofed. This is recommended.
  184. security: {
  185. sessionSecret: process.env.SHARELATEX_SESSION_SECRET || process.env.CRYPTO_RANDOM
  186. },
  187. // These credentials are used for authenticating api requests
  188. // between services that may need to go over public channels
  189. httpAuthUsers,
  190. // Should javascript assets be served minified or not.
  191. useMinifiedJs: true,
  192. // Should static assets be sent with a header to tell the browser to cache
  193. // them. This should be false in development where changes are being made,
  194. // but should be set to true in production.
  195. cacheStaticAssets: true,
  196. // If you are running ShareLaTeX over https, set this to true to send the
  197. // cookie with a secure flag (recommended).
  198. secureCookie: (process.env.SHARELATEX_SECURE_COOKIE != null),
  199. // If you are running ShareLaTeX behind a proxy (like Apache, Nginx, etc)
  200. // then set this to true to allow it to correctly detect the forwarded IP
  201. // address and http/https protocol information.
  202. behindProxy: process.env.SHARELATEX_BEHIND_PROXY || false,
  203. i18n: {
  204. subdomainLang: {
  205. www: {lngCode:process.env.SHARELATEX_SITE_LANGUAGE || "en", url: siteUrl}
  206. },
  207. defaultLng: process.env.SHARELATEX_SITE_LANGUAGE || "en"
  208. },
  209. currentImageName: process.env.TEX_LIVE_DOCKER_IMAGE,
  210. apis: {
  211. web: {
  212. url: "http://localhost:3000",
  213. user: httpAuthUser,
  214. pass: httpAuthPass
  215. },
  216. project_history: {
  217. enabled: false
  218. }
  219. },
  220. references:{},
  221. notifications:undefined,
  222. defaultFeatures: {
  223. collaborators: -1,
  224. dropbox: true,
  225. versioning: true,
  226. compileTimeout: parseIntOrFail(process.env.COMPILE_TIMEOUT || 180),
  227. compileGroup: "standard",
  228. trackChanges: true,
  229. templates: true,
  230. references: true
  231. }
  232. };
  233. // # OPTIONAL CONFIGURABLE SETTINGS
  234. if (process.env.SHARELATEX_LEFT_FOOTER != null) {
  235. try {
  236. settings.nav.left_footer = JSON.parse(process.env.SHARELATEX_LEFT_FOOTER);
  237. } catch (error) {
  238. e = error;
  239. console.error("could not parse SHARELATEX_LEFT_FOOTER, not valid JSON");
  240. }
  241. }
  242. if (process.env.SHARELATEX_RIGHT_FOOTER != null) {
  243. settings.nav.right_footer = process.env.SHARELATEX_RIGHT_FOOTER;
  244. try {
  245. settings.nav.right_footer = JSON.parse(process.env.SHARELATEX_RIGHT_FOOTER);
  246. } catch (error1) {
  247. e = error1;
  248. console.error("could not parse SHARELATEX_RIGHT_FOOTER, not valid JSON");
  249. }
  250. }
  251. if (process.env.SHARELATEX_HEADER_IMAGE_URL != null) {
  252. settings.nav.custom_logo = process.env.SHARELATEX_HEADER_IMAGE_URL;
  253. }
  254. if (process.env.SHARELATEX_HEADER_NAV_LINKS != null) {
  255. console.error(`\
  256. # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  257. #
  258. # WARNING: SHARELATEX_HEADER_NAV_LINKS is no longer supported
  259. # See https://github.com/sharelatex/sharelatex/wiki/Configuring-Headers,-Footers-&-Logo
  260. #
  261. # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\
  262. `
  263. );
  264. }
  265. if (process.env.SHARELATEX_HEADER_EXTRAS != null) {
  266. try {
  267. settings.nav.header_extras = JSON.parse(process.env.SHARELATEX_HEADER_EXTRAS);
  268. } catch (error2) {
  269. e = error2;
  270. console.error("could not parse SHARELATEX_HEADER_EXTRAS, not valid JSON");
  271. }
  272. }
  273. // Sending Email
  274. // -------------
  275. //
  276. // You must configure a mail server to be able to send invite emails from
  277. // ShareLaTeX. The config settings are passed to nodemailer. See the nodemailer
  278. // documentation for available options:
  279. //
  280. // http://www.nodemailer.com/docs/transports
  281. if (process.env.SHARELATEX_EMAIL_FROM_ADDRESS != null) {
  282. settings.email = {
  283. fromAddress: process.env.SHARELATEX_EMAIL_FROM_ADDRESS,
  284. replyTo: process.env.SHARELATEX_EMAIL_REPLY_TO || "",
  285. driver: process.env.SHARELATEX_EMAIL_DRIVER,
  286. parameters: {
  287. // AWS Creds
  288. AWSAccessKeyID: process.env.SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID,
  289. AWSSecretKey: process.env.SHARELATEX_EMAIL_AWS_SES_SECRET_KEY,
  290. // SMTP Creds
  291. host: process.env.SHARELATEX_EMAIL_SMTP_HOST,
  292. port: process.env.SHARELATEX_EMAIL_SMTP_PORT,
  293. secure: parse(process.env.SHARELATEX_EMAIL_SMTP_SECURE),
  294. ignoreTLS: parse(process.env.SHARELATEX_EMAIL_SMTP_IGNORE_TLS),
  295. name: process.env.SHARELATEX_EMAIL_SMTP_NAME,
  296. logger: process.env.SHARELATEX_EMAIL_SMTP_LOGGER === 'true'
  297. },
  298. textEncoding: process.env.SHARELATEX_EMAIL_TEXT_ENCODING,
  299. template: {
  300. customFooter: process.env.SHARELATEX_CUSTOM_EMAIL_FOOTER
  301. }
  302. };
  303. if (process.env.SHARELATEX_EMAIL_AWS_SES_REGION != null) {
  304. settings.email.parameters.region = process.env.SHARELATEX_EMAIL_AWS_SES_REGION;
  305. }
  306. if ((process.env.SHARELATEX_EMAIL_SMTP_USER != null) || (process.env.SHARELATEX_EMAIL_SMTP_PASS != null)) {
  307. settings.email.parameters.auth = {
  308. user: process.env.SHARELATEX_EMAIL_SMTP_USER,
  309. pass: process.env.SHARELATEX_EMAIL_SMTP_PASS
  310. };
  311. }
  312. if (process.env.SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH != null) {
  313. settings.email.parameters.tls =
  314. {rejectUnauthorized: parse(process.env.SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH)};
  315. }
  316. }
  317. // i18n
  318. if (process.env.SHARELATEX_LANG_DOMAIN_MAPPING != null) {
  319. settings.i18n.subdomainLang = parse(process.env.SHARELATEX_LANG_DOMAIN_MAPPING);
  320. }
  321. // Password Settings
  322. // -----------
  323. // These restrict the passwords users can use when registering
  324. // opts are from http://antelle.github.io/passfield
  325. if (process.env.SHARELATEX_PASSWORD_VALIDATION_PATTERN || process.env.SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH || process.env.SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH) {
  326. settings.passwordStrengthOptions = {
  327. pattern: process.env.SHARELATEX_PASSWORD_VALIDATION_PATTERN || "aA$3",
  328. length: {min:process.env.SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH || 8, max: process.env.SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH || 150}
  329. };
  330. }
  331. // ######################
  332. // ShareLaTeX Server Pro
  333. // ######################
  334. if (parse(process.env.SHARELATEX_IS_SERVER_PRO) === true) {
  335. settings.bypassPercentageRollouts = true;
  336. settings.apis.references =
  337. {url: "http://localhost:3040"};
  338. }
  339. // LDAP - SERVER PRO ONLY
  340. // ----------
  341. if (process.env.SHARELATEX_LDAP_HOST) {
  342. console.error(`\
  343. # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  344. #
  345. # WARNING: The LDAP configuration format has changed in version 0.5.1
  346. # See https://github.com/sharelatex/sharelatex/wiki/Server-Pro:-LDAP-Config
  347. #
  348. # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\
  349. `
  350. );
  351. }
  352. if (process.env.SHARELATEX_LDAP_URL) {
  353. let _ldap_connect_timeout, _ldap_group_search_attribs, _ldap_search_attribs, _ldap_timeout;
  354. settings.externalAuth = true;
  355. settings.ldap = {
  356. emailAtt: process.env.SHARELATEX_LDAP_EMAIL_ATT,
  357. nameAtt: process.env.SHARELATEX_LDAP_NAME_ATT,
  358. lastNameAtt: process.env.SHARELATEX_LDAP_LAST_NAME_ATT,
  359. updateUserDetailsOnLogin: process.env.SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN === 'true',
  360. placeholder: process.env.SHARELATEX_LDAP_PLACEHOLDER,
  361. server: {
  362. url: process.env.SHARELATEX_LDAP_URL,
  363. bindDn: process.env.SHARELATEX_LDAP_BIND_DN,
  364. bindCredentials: process.env.SHARELATEX_LDAP_BIND_CREDENTIALS,
  365. bindProperty: process.env.SHARELATEX_LDAP_BIND_PROPERTY,
  366. searchBase: process.env.SHARELATEX_LDAP_SEARCH_BASE,
  367. searchScope: process.env.SHARELATEX_LDAP_SEARCH_SCOPE,
  368. searchFilter: process.env.SHARELATEX_LDAP_SEARCH_FILTER,
  369. searchAttributes: (
  370. (_ldap_search_attribs = process.env.SHARELATEX_LDAP_SEARCH_ATTRIBUTES) ?
  371. (() => { try {
  372. return JSON.parse(_ldap_search_attribs);
  373. } catch (error3) {
  374. e = error3;
  375. return console.error("could not parse SHARELATEX_LDAP_SEARCH_ATTRIBUTES");
  376. } })()
  377. :
  378. undefined
  379. ),
  380. groupDnProperty: process.env.SHARELATEX_LDAP_GROUP_DN_PROPERTY,
  381. groupSearchBase: process.env.SHARELATEX_LDAP_GROUP_SEARCH_BASE,
  382. groupSearchScope: process.env.SHARELATEX_LDAP_GROUP_SEARCH_SCOPE,
  383. groupSearchFilter: process.env.SHARELATEX_LDAP_GROUP_SEARCH_FILTER,
  384. groupSearchAttributes: (
  385. (_ldap_group_search_attribs = process.env.SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES) ?
  386. (() => { try {
  387. return JSON.parse(_ldap_group_search_attribs);
  388. } catch (error4) {
  389. e = error4;
  390. return console.error("could not parse SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES");
  391. } })()
  392. :
  393. undefined
  394. ),
  395. cache: process.env.SHARELATEX_LDAP_CACHE === 'true',
  396. timeout: (
  397. (_ldap_timeout = process.env.SHARELATEX_LDAP_TIMEOUT) ?
  398. (() => { try {
  399. return parseIntOrFail(_ldap_timeout);
  400. } catch (error5) {
  401. e = error5;
  402. return console.error("Cannot parse SHARELATEX_LDAP_TIMEOUT");
  403. } })()
  404. :
  405. undefined
  406. ),
  407. connectTimeout: (
  408. (_ldap_connect_timeout = process.env.SHARELATEX_LDAP_CONNECT_TIMEOUT) ?
  409. (() => { try {
  410. return parseIntOrFail(_ldap_connect_timeout);
  411. } catch (error6) {
  412. e = error6;
  413. return console.error("Cannot parse SHARELATEX_LDAP_CONNECT_TIMEOUT");
  414. } })()
  415. :
  416. undefined
  417. )
  418. }
  419. };
  420. if (process.env.SHARELATEX_LDAP_TLS_OPTS_CA_PATH) {
  421. let ca, ca_paths;
  422. try {
  423. ca = JSON.parse(process.env.SHARELATEX_LDAP_TLS_OPTS_CA_PATH);
  424. } catch (error7) {
  425. e = error7;
  426. console.error("could not parse SHARELATEX_LDAP_TLS_OPTS_CA_PATH, invalid JSON");
  427. }
  428. if (typeof(ca) === 'string') {
  429. ca_paths = [ca];
  430. } else if ((typeof(ca) === 'object') && ((ca != null ? ca.length : undefined) != null)) {
  431. ca_paths = ca;
  432. } else {
  433. console.error("problem parsing SHARELATEX_LDAP_TLS_OPTS_CA_PATH");
  434. }
  435. settings.ldap.server.tlsOptions = {
  436. rejectUnauthorized: process.env.SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH === "true",
  437. ca:ca_paths // e.g.'/etc/ldap/ca_certs.pem'
  438. };
  439. }
  440. }
  441. if (process.env.SHARELATEX_SAML_ENTRYPOINT) {
  442. // NOTE: see https://github.com/node-saml/passport-saml/blob/master/README.md for docs of `server` options
  443. let _saml_additionalAuthorizeParams, _saml_additionalLogoutParams, _saml_additionalParams, _saml_expiration, _saml_skew;
  444. settings.externalAuth = true;
  445. settings.saml = {
  446. updateUserDetailsOnLogin: process.env.SHARELATEX_SAML_UPDATE_USER_DETAILS_ON_LOGIN === 'true',
  447. identityServiceName: process.env.SHARELATEX_SAML_IDENTITY_SERVICE_NAME,
  448. emailField: process.env.SHARELATEX_SAML_EMAIL_FIELD || process.env.SHARELATEX_SAML_EMAIL_FIELD_NAME,
  449. firstNameField: process.env.SHARELATEX_SAML_FIRST_NAME_FIELD,
  450. lastNameField: process.env.SHARELATEX_SAML_LAST_NAME_FIELD,
  451. server: {
  452. // strings
  453. entryPoint: process.env.SHARELATEX_SAML_ENTRYPOINT,
  454. callbackUrl: process.env.SHARELATEX_SAML_CALLBACK_URL,
  455. issuer: process.env.SHARELATEX_SAML_ISSUER,
  456. decryptionPvk: process.env.SHARELATEX_SAML_DECRYPTION_PVK,
  457. decryptionCert: process.env.SHARELATEX_SAML_DECRYPTION_CERT,
  458. signatureAlgorithm: process.env.SHARELATEX_SAML_SIGNATURE_ALGORITHM,
  459. identifierFormat: process.env.SHARELATEX_SAML_IDENTIFIER_FORMAT,
  460. attributeConsumingServiceIndex: process.env.SHARELATEX_SAML_ATTRIBUTE_CONSUMING_SERVICE_INDEX,
  461. authnContext: process.env.SHARELATEX_SAML_AUTHN_CONTEXT,
  462. authnRequestBinding: process.env.SHARELATEX_SAML_AUTHN_REQUEST_BINDING,
  463. validateInResponseTo: process.env.SHARELATEX_SAML_VALIDATE_IN_RESPONSE_TO,
  464. cacheProvider: process.env.SHARELATEX_SAML_CACHE_PROVIDER,
  465. logoutUrl: process.env.SHARELATEX_SAML_LOGOUT_URL,
  466. logoutCallbackUrl: process.env.SHARELATEX_SAML_LOGOUT_CALLBACK_URL,
  467. disableRequestedAuthnContext: process.env.SHARELATEX_SAML_DISABLE_REQUESTED_AUTHN_CONTEXT === 'true',
  468. forceAuthn: process.env.SHARELATEX_SAML_FORCE_AUTHN === 'true',
  469. skipRequestCompression: process.env.SHARELATEX_SAML_SKIP_REQUEST_COMPRESSION === 'true',
  470. acceptedClockSkewMs: (
  471. (_saml_skew = process.env.SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS) ?
  472. (() => { try {
  473. return parseIntOrFail(_saml_skew);
  474. } catch (error8) {
  475. e = error8;
  476. return console.error("Cannot parse SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS");
  477. } })()
  478. :
  479. undefined
  480. ),
  481. requestIdExpirationPeriodMs: (
  482. (_saml_expiration = process.env.SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS) ?
  483. (() => { try {
  484. return parseIntOrFail(_saml_expiration);
  485. } catch (error9) {
  486. e = error9;
  487. return console.error("Cannot parse SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS");
  488. } })()
  489. :
  490. undefined
  491. ),
  492. additionalParams: (
  493. (_saml_additionalParams = process.env.SHARELATEX_SAML_ADDITIONAL_PARAMS) ?
  494. (() => { try {
  495. return JSON.parse(_saml_additionalParams);
  496. } catch (error10) {
  497. e = error10;
  498. return console.error("Cannot parse SHARELATEX_SAML_ADDITIONAL_PARAMS");
  499. } })()
  500. :
  501. undefined
  502. ),
  503. additionalAuthorizeParams: (
  504. (_saml_additionalAuthorizeParams = process.env.SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS) ?
  505. (() => { try {
  506. return JSON.parse(_saml_additionalAuthorizeParams );
  507. } catch (error11) {
  508. e = error11;
  509. return console.error("Cannot parse SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS");
  510. } })()
  511. :
  512. undefined
  513. ),
  514. additionalLogoutParams: (
  515. (_saml_additionalLogoutParams = process.env.SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS) ?
  516. (() => { try {
  517. return JSON.parse(_saml_additionalLogoutParams );
  518. } catch (error12) {
  519. e = error12;
  520. return console.error("Cannot parse SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS");
  521. } })()
  522. :
  523. undefined
  524. )
  525. }
  526. };
  527. // SHARELATEX_SAML_CERT cannot be empty
  528. // https://github.com/node-saml/passport-saml/commit/f6b1c885c0717f1083c664345556b535f217c102
  529. if (process.env.SHARELATEX_SAML_CERT) {
  530. settings.saml.server.cert = process.env.SHARELATEX_SAML_CERT;
  531. settings.saml.server.privateCert = process.env.SHARELATEX_SAML_PRIVATE_CERT;
  532. }
  533. }
  534. // Compiler
  535. // --------
  536. if (process.env.SANDBOXED_COMPILES === "true") {
  537. settings.clsi = {
  538. dockerRunner: true,
  539. docker: {
  540. image: process.env.TEX_LIVE_DOCKER_IMAGE,
  541. env: {
  542. HOME: "/tmp",
  543. PATH: process.env.COMPILER_PATH || "/usr/local/texlive/2015/bin/x86_64-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
  544. },
  545. user: "www-data"
  546. }
  547. };
  548. if ((settings.path == null)) {
  549. settings.path = {};
  550. }
  551. settings.path.synctexBaseDir = () => "/compile";
  552. if (process.env.SANDBOXED_COMPILES_SIBLING_CONTAINERS === 'true') {
  553. console.log("Using sibling containers for sandboxed compiles");
  554. if (process.env.SANDBOXED_COMPILES_HOST_DIR) {
  555. settings.path.sandboxedCompilesHostDir = process.env.SANDBOXED_COMPILES_HOST_DIR;
  556. } else {
  557. console.error('Sibling containers, but SANDBOXED_COMPILES_HOST_DIR not set');
  558. }
  559. }
  560. }
  561. // Templates
  562. // ---------
  563. if (process.env.SHARELATEX_TEMPLATES_USER_ID) {
  564. settings.templates = {
  565. mountPointUrl: "/templates",
  566. user_id: process.env.SHARELATEX_TEMPLATES_USER_ID
  567. };
  568. settings.templateLinks = parse(process.env.SHARELATEX_NEW_PROJECT_TEMPLATE_LINKS);
  569. }
  570. // /Learn
  571. // -------
  572. if (process.env.SHARELATEX_PROXY_LEARN != null) {
  573. settings.proxyLearn = parse(process.env.SHARELATEX_PROXY_LEARN);
  574. }
  575. // /References
  576. // -----------
  577. if (process.env.SHARELATEX_ELASTICSEARCH_URL != null) {
  578. settings.references.elasticsearch =
  579. {host: process.env.SHARELATEX_ELASTICSEARCH_URL};
  580. }
  581. // TeX Live Images
  582. // -----------
  583. if (process.env.ALL_TEX_LIVE_DOCKER_IMAGES != null) {
  584. allTexLiveDockerImages = process.env.ALL_TEX_LIVE_DOCKER_IMAGES.split(',');
  585. }
  586. if (process.env.ALL_TEX_LIVE_DOCKER_IMAGE_NAMES != null) {
  587. allTexLiveDockerImageNames = process.env.ALL_TEX_LIVE_DOCKER_IMAGE_NAMES.split(',');
  588. }
  589. if (allTexLiveDockerImages != null) {
  590. settings.allowedImageNames = [];
  591. for (let index = 0; index < allTexLiveDockerImages.length; index++) {
  592. const fullImageName = allTexLiveDockerImages[index];
  593. const imageName = Path.basename(fullImageName);
  594. const imageDesc = (allTexLiveDockerImageNames != null) ? allTexLiveDockerImageNames[index] : imageName;
  595. settings.allowedImageNames.push({ imageName, imageDesc });
  596. }
  597. }
  598. // With lots of incoming and outgoing HTTP connections to different services,
  599. // sometimes long running, it is a good idea to increase the default number
  600. // of sockets that Node will hold open.
  601. const http = require('http');
  602. http.globalAgent.maxSockets = 300;
  603. const https = require('https');
  604. https.globalAgent.maxSockets = 300;
  605. module.exports = settings;