settings.coffee 20.6 KB
Newer Older
James Allen's avatar
James Allen committed
1 2 3 4 5 6 7 8 9
Path = require('path')

# These credentials are used for authenticating api requests
# between services that may need to go over public channels
httpAuthUser = "sharelatex"
httpAuthPass = "CRYPTO_RANDOM" # Randomly generated for you
httpAuthUsers = {}
httpAuthUsers[httpAuthUser] = httpAuthPass

10 11 12 13 14 15 16 17 18 19
parse = (option)->
	if option?
		try
			opt = JSON.parse(option)
			return opt
		catch err
			console.error "problem parsing #{option}, invalid JSON"
			return undefined


James Allen's avatar
James Allen committed
20 21 22
DATA_DIR = '/var/lib/sharelatex/data'
TMP_DIR = '/var/lib/sharelatex/tmp'

23 24
settings =

James Allen's avatar
James Allen committed
25 26 27 28 29 30 31 32 33 34
	# Databases
	# ---------

	# ShareLaTeX's main persistant data store is MongoDB (http://www.mongodb.org/)
	# Documentation about the URL connection string format can be found at:
	#
	#    http://docs.mongodb.org/manual/reference/connection-string/
	# 
	# The following works out of the box with Mongo's default settings:
	mongo:
James Allen's avatar
James Allen committed
35
		url : process.env["SHARELATEX_MONGO_URL"] or 'mongodb://dockerhost/sharelatex'
James Allen's avatar
James Allen committed
36 37 38 39 40 41 42

	# Redis is used in ShareLaTeX for high volume queries, like real-time
	# editing, and session management.
	#
	# The following config will work with Redis's default settings:
	redis:
		web: redisConfig =
James Allen's avatar
James Allen committed
43
			host: process.env["SHARELATEX_REDIS_HOST"] or "dockerhost"
James Allen's avatar
James Allen committed
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
			port: process.env["SHARELATEX_REDIS_PORT"] or "6379"
			password: process.env["SHARELATEX_REDIS_PASS"] or ""
		fairy: redisConfig

	# The compile server (the clsi) uses a SQL database to cache files and
	# meta-data. sqllite is the default, and the load is low enough that this will
	# be fine in production (we use sqllite at sharelatex.com).
	#
	# If you want to configure a different database, see the Sequelize documentation
	# for available options:
	#
	#    https://github.com/sequelize/sequelize/wiki/API-Reference-Sequelize#example-usage
	#
	mysql:
		clsi:
			database: "clsi"
			username: "clsi"
			password: ""
			dialect: "sqlite"
			storage: Path.join(DATA_DIR, "db.sqlite")

	# File storage
	# ------------

	# ShareLaTeX can store binary files like images either locally or in Amazon
	# S3. The default is locally:
	filestore:
		backend: "fs"	
		stores:
			user_files: Path.join(DATA_DIR, "user_files")
74
			template_files: Path.join(DATA_DIR, "template_files")
James Allen's avatar
James Allen committed
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
			
	# To use Amazon S3 as a storage backend, comment out the above config, and
	# uncomment the following, filling in your key, secret, and bucket name:
	#
	# filestore:
	# 	backend: "s3"
	# 	stores:
	# 		user_files: "BUCKET_NAME"
	# 	s3:
	# 		key: "AWS_KEY"
	# 		secret: "AWS_SECRET"
	# 		

	# Local disk caching
	# ------------------
	path:
		# If we ever need to write something to disk (e.g. incoming requests
		# that need processing but may be too big for memory), then write
		# them to disk here:
		dumpFolder:   Path.join(TMP_DIR, "dumpFolder")
		# Where to write uploads before they are processed
		uploadFolder: Path.join(TMP_DIR, "uploads")
		# Where to write the project to disk before running LaTeX on it
		compilesDir:  Path.join(DATA_DIR, "compiles")
		# Where to cache downloaded URLs for the CLSI
		clsiCacheDir: Path.join(DATA_DIR, "cache")

	# Server Config
	# -------------

	# Where your instance of ShareLaTeX can be found publicly. This is used
	# when emails are sent out and in generated links:
James Allen's avatar
James Allen committed
107
	siteUrl: siteUrl = process.env["SHARELATEX_SITE_URL"] or 'http://localhost'
108 109 110 111

	# The name this is used to describe your ShareLaTeX Installation
	appName: process.env["SHARELATEX_APP_NAME"] or "ShareLaTeX (Community Edition)"

112 113

	nav:
114
		title: process.env["SHARELATEX_NAV_TITLE"] or  process.env["SHARELATEX_APP_NAME"] or "ShareLaTeX Community Edition"
115 116


117 118 119
	# The email address which users will be directed to as the main point of
	# contact for this installation of ShareLaTeX.
	adminEmail: process.env["SHARELATEX_ADMIN_EMAIL"] or "placeholder@example.com"
James Allen's avatar
James Allen committed
120 121 122 123
	
	# If provided, a sessionSecret is used to sign cookies so that they cannot be
	# spoofed. This is recommended.
	security:
James Allen's avatar
James Allen committed
124
		sessionSecret: process.env["SHARELATEX_SESSION_SECRET"] or "CRYPTO_RANDOM" # This was randomly generated for you
James Allen's avatar
James Allen committed
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146

	# These credentials are used for authenticating api requests
	# between services that may need to go over public channels
	httpAuthUsers: httpAuthUsers
	
	# Should javascript assets be served minified or not. Note that you will
	# need to run `grunt compile:minify` within the web-sharelatex directory
	# to generate these.
	useMinifiedJs: true

	# Should static assets be sent with a header to tell the browser to cache
	# them. This should be false in development where changes are being made,
	# but should be set to true in production.
	cacheStaticAssets: true

	# If you are running ShareLaTeX over https, set this to true to send the
	# cookie with a secure flag (recommended).
	secureCookie: process.env["SHARELATEX_SECURE_COOKIE"]?
	
	# If you are running ShareLaTeX behind a proxy (like Apache, Nginx, etc)
	# then set this to true to allow it to correctly detect the forwarded IP
	# address and http/https protocol information.
147

148
	behindProxy: process.env["SHARELATEX_BEHIND_PROXY"] or false
James Allen's avatar
James Allen committed
149 150 151 152

	# Spell Check Languages
	# ---------------------
	#
153
	# You must have the corresponding aspell dictionary installed to
James Allen's avatar
James Allen committed
154 155 156 157
	# be able to use a language. Run `grunt check:aspell` to check which
	# dictionaries you have installed. These should be set for the `code` for
	# each language.
	languages: [{
158
		"code":"en", "name":"English (American)"
James Allen's avatar
James Allen committed
159
		},{
160
		"code":"en_GB", "name":"English (British)"
James Allen's avatar
James Allen committed
161
		},{
162
		"code":"af", "name":"Africaans"
James Allen's avatar
James Allen committed
163
		},{
164
		"code":"am", "name":"Amharic"
James Allen's avatar
James Allen committed
165
		},{
166
		"code":"ar", "name":"Arabic"
James Allen's avatar
James Allen committed
167
		},{
168
		"code":"hy", "name":"Armenian"
James Allen's avatar
James Allen committed
169
		},{
170
		"code":"gl", "name":"Galician"
James Allen's avatar
James Allen committed
171
		},{
172
		"code":"eu", "name":"Basque"
James Allen's avatar
James Allen committed
173
		},{
174
		"code":"bn", "name":"Bengali"
James Allen's avatar
James Allen committed
175
		},{
176
		"code":"br", "name":"Breton"
James Allen's avatar
James Allen committed
177
		},{
178
		"code":"bg", "name":"Bulgarian"
James Allen's avatar
James Allen committed
179
		},{
180
		"code":"ca", "name":"Catalan"
James Allen's avatar
James Allen committed
181
		},{
182
		"code":"hr", "name":"Croatian"
James Allen's avatar
James Allen committed
183
		},{
184
		"code":"cs", "name":"Czech"
James Allen's avatar
James Allen committed
185
		},{
186
		"code":"da", "name":"Danish"
James Allen's avatar
James Allen committed
187
		},{
188
		"code":"nl", "name":"Dutch"
James Allen's avatar
James Allen committed
189
		},{
190
		"code":"eo", "name":"Esperanto"
James Allen's avatar
James Allen committed
191
		},{
192
		"code":"et", "name":"Estonian"
James Allen's avatar
James Allen committed
193
		},{
194
		"code":"fo", "name":"Faroese"
James Allen's avatar
James Allen committed
195
		},{
196
		"code":"fr", "name":"French"
James Allen's avatar
James Allen committed
197
		},{
198
		"code":"de", "name":"German"
James Allen's avatar
James Allen committed
199
		},{
200
		"code":"el", "name":"Greek"
James Allen's avatar
James Allen committed
201
		},{
202
		"code":"gu", "name":"Gujarati"
James Allen's avatar
James Allen committed
203
		},{
204
		"code":"he", "name":"Hebrew"
James Allen's avatar
James Allen committed
205
		},{
206
		"code":"hi", "name":"Hindi"
James Allen's avatar
James Allen committed
207
		},{
208
		"code":"hu", "name":"Hungarian"
James Allen's avatar
James Allen committed
209
		},{
210
		"code":"is", "name":"Icelandic"
James Allen's avatar
James Allen committed
211
		},{
212
		"code":"id", "name":"Indonesian"
James Allen's avatar
James Allen committed
213
		},{
214
		"code":"ga", "name":"Irish"
James Allen's avatar
James Allen committed
215
		},{
216
		"code":"it", "name":"Italian"
James Allen's avatar
James Allen committed
217
		},{
218
		"code":"kn", "name":"Kannada"
James Allen's avatar
James Allen committed
219
		},{
220
		"code":"kk", "name":"Kazakh"
James Allen's avatar
James Allen committed
221
		},{
222
		"code":"ku", "name":"Kurdish"
James Allen's avatar
James Allen committed
223
		},{
224
		"code":"lv", "name":"Latvian"
James Allen's avatar
James Allen committed
225
		},{
226
		"code":"lt", "name":"Lithuanian"
James Allen's avatar
James Allen committed
227
		},{
228
		"code":"ml", "name":"Malayalam"
James Allen's avatar
James Allen committed
229
		},{
230
		"code":"mr", "name":"Marathi"
James Allen's avatar
James Allen committed
231
		},{
232
		"code":"nr", "name":"Ndebele"
James Allen's avatar
James Allen committed
233
		},{
234
		"code":"ns", "name":"Northern Sotho"
James Allen's avatar
James Allen committed
235
		},{
236
		"code":"no", "name":"Norwegian"
James Allen's avatar
James Allen committed
237
		},{
238
		"code":"or", "name":"Oriya"
James Allen's avatar
James Allen committed
239
		},{
240
		"code":"fa", "name":"Persian"
James Allen's avatar
James Allen committed
241
		},{
242
		"code":"pl", "name":"Polish"
James Allen's avatar
James Allen committed
243
		},{
244
		"code":"pt_BR", "name":"Portuguese (Brazilian)"
James Allen's avatar
James Allen committed
245
		},{
246
		"code":"pt_PT", "name":"Portuguese (European)"
James Allen's avatar
James Allen committed
247
		},{
248
		"code":"pa", "name":"Punjabi"
James Allen's avatar
James Allen committed
249
		},{
250
		"code":"ro", "name":"Romanian"
James Allen's avatar
James Allen committed
251
		},{
252
		"code":"ru", "name":"Russian"
James Allen's avatar
James Allen committed
253
		},{
254
		"code":"sk", "name":"Slovak"
James Allen's avatar
James Allen committed
255
		},{
256
		"code":"sl", "name":"Slovenian"
James Allen's avatar
James Allen committed
257
		},{
258
		"code":"st", "name":"Southern Sotho"
James Allen's avatar
James Allen committed
259
		},{
260
		"code":"es", "name":"Spanish"
James Allen's avatar
James Allen committed
261
		},{
262
		"code":"ss", "name":"Swazi"
James Allen's avatar
James Allen committed
263
		},{
264
		"code":"sv", "name":"Swedish"
James Allen's avatar
James Allen committed
265
		},{
266
		"code":"tl", "name":"Tagalog"
James Allen's avatar
James Allen committed
267
		},{
268
		"code":"ta", "name":"Tamil"
James Allen's avatar
James Allen committed
269
		},{
270
		"code":"te", "name":"Telugu"
James Allen's avatar
James Allen committed
271
		},{
272
		"code":"ts", "name":"Tsonga"
James Allen's avatar
James Allen committed
273
		},{
274
		"code":"tn", "name":"Tswana"
James Allen's avatar
James Allen committed
275
		},{
276
		"code":"uk", "name":"Ukrainian"
James Allen's avatar
James Allen committed
277
		},{
278
		"code":"hsb", "name":"Upper Sorbian"
James Allen's avatar
James Allen committed
279
		},{
280
		"code":"uz", "name":"Uzbek"
James Allen's avatar
James Allen committed
281
		},{
282
		"code":"cy", "name":"Welsh"
James Allen's avatar
James Allen committed
283
		},{
284
		"code":"xh", "name":"Xhosa"
James Allen's avatar
James Allen committed
285
		},{
286
		"code":"zu", "name":"Zulu"
James Allen's avatar
James Allen committed
287 288
		}
	]
289

James Allen's avatar
James Allen committed
290 291 292 293 294
	apis:
		web:
			url: "http://localhost:3000"
			user: httpAuthUser
			pass: httpAuthPass
295
	references:{}
Henry Oswald's avatar
Henry Oswald committed
296 297
	notifications:undefined

Henry Oswald's avatar
Henry Oswald committed
298 299 300 301 302 303 304 305
	defaultFeatures:
		collaborators: -1
		dropbox: true
		versioning: true
		compileTimeout: 180
		compileGroup: "standard"
		references: true
		templates: true
306 307 308

#### OPTIONAL CONFIGERABLE SETTINGS

309
if process.env["SHARELATEX_LEFT_FOOTER"]?
310 311 312 313
	try
		settings.nav.left_footer = JSON.parse(process.env["SHARELATEX_LEFT_FOOTER"])
	catch e
		console.error("could not parse SHARELATEX_LEFT_FOOTER, not valid JSON")
314 315

if process.env["SHARELATEX_RIGHT_FOOTER"]?
316 317 318 319 320
	settings.nav.right_footer = process.env["SHARELATEX_RIGHT_FOOTER"]
	try
		settings.nav.right_footer = JSON.parse(process.env["SHARELATEX_RIGHT_FOOTER"])
	catch e
		console.error("could not parse SHARELATEX_RIGHT_FOOTER, not valid JSON")
Henry Oswald's avatar
Henry Oswald committed
321 322 323 324

if process.env["SHARELATEX_HEADER_IMAGE_URL"]?
	settings.nav.custom_logo = process.env["SHARELATEX_HEADER_IMAGE_URL"]
	
325
if process.env["SHARELATEX_HEADER"]?
326 327 328 329
	settings.nav.header = process.env["SHARELATEX_HEADER_NAV_LINKS"]

# if process.env["SHARELATEX_PROXY_LEARN"]?
# 	settings.nav.header.push({text: "help", class: "subdued", dropdown: [{text: "documentation", url: "/learn"}] })
330 331


332 333 334 335 336 337 338 339 340 341
# Sending Email
# -------------
#
# You must configure a mail server to be able to send invite emails from
# ShareLaTeX. The config settings are passed to nodemailer. See the nodemailer
# documentation for available options:
#
#     http://www.nodemailer.com/docs/transports


342
if process.env["SHARELATEX_EMAIL_FROM_ADDRESS"]?
James Allen's avatar
James Allen committed
343
	
344
	settings.email =
345 346 347 348 349 350 351 352 353 354
		fromAddress: process.env["SHARELATEX_EMAIL_FROM_ADDRESS"]
		replyTo: process.env["SHARELATEX_EMAIL_REPLY_TO"] or ""
		parameters:
			#AWS Creds
			AWSAccessKeyID: process.env["SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID"]
			AWSSecretKey: process.env["SHARELATEX_EMAIL_AWS_SES_SECRET_KEY"]

			#SMTP Creds
			host: process.env["SHARELATEX_EMAIL_SMTP_HOST"]
			port: process.env["SHARELATEX_EMAIL_SMTP_PORT"],
355 356 357
			secure: parse(process.env["SHARELATEX_EMAIL_SMTP_SECURE"])
			ignoreTLS: parse(process.env["SHARELATEX_EMAIL_SMTP_IGNORE_TLS"])

358
		textEncoding:  process.env["SHARELATEX_EMAIL_TEXT_ENCODING"]
359 360 361
		templates:
			customFooter: process.env["SHARELATEX_CUSTOM_EMAIL_FOOTER"]

362 363 364 365 366 367 368
	if process.env["SHARELATEX_EMAIL_SMTP_USER"]? or process.env["SHARELATEX_EMAIL_SMTP_PASS"]?
		settings.email.parameters.auth =
			user: process.env["SHARELATEX_EMAIL_SMTP_USER"]
			pass: process.env["SHARELATEX_EMAIL_SMTP_PASS"]

	if process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"]?
		settings.email.parameters.tls =
369
			rejectUnauthorized: parse(process.env["SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH"])
370
		
371 372 373 374 375 376 377

# Password Settings
# -----------
# These restrict the passwords users can use when registering
# opts are from http://antelle.github.io/passfield
if process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] or process.env["SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH"] or process.env["SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH"]

378
	settings.passwordStrengthOptions =
379 380 381 382
		pattern: process.env["SHARELATEX_PASSWORD_VALIDATION_PATTERN"] or "aA$3"
		length: {min:process.env["SHARELATEX_PASSWORD_VALIDATION_MIN_LENGTH"] or 8, max: process.env["SHARELATEX_PASSWORD_VALIDATION_MAX_LENGTH"] or 50}


383 384 385 386 387 388


#######################
# ShareLaTeX Server Pro
#######################

389 390 391
if parse(process.env["SHARELATEX_IS_SERVER_PRO"]) == true
	settings.apis.references =
		 url: "http://localhost:3040"
392 393


394 395 396 397
# LDAP - SERVER PRO ONLY
# ----------
# Settings below use a working LDAP test server kindly provided by forumsys.com
# When testing with forumsys.com use username = einstein and password = password
James Allen's avatar
James Allen committed
398 399
	

Shane Kilkelly's avatar
Shane Kilkelly committed
400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441
# if process.env["SHARELATEX_LDAP_HOST"]
# 	settings.externalAuth = true
# 	settings.ldap =
# 		host: process.env["SHARELATEX_LDAP_HOST"]
# 		dn: process.env["SHARELATEX_LDAP_DN"]
# 		baseSearch: process.env["SHARELATEX_LDAP_BASE_SEARCH"]
# 		filter:  process.env["SHARELATEX_LDAP_FILTER"]
# 		failMessage: process.env["SHARELATEX_LDAP_FAIL_MESSAGE"] or 'LDAP User Fail'
# 		fieldName: process.env["SHARELATEX_LDAP_FIELD_NAME"] or 'LDAP User'
# 		placeholder: process.env["SHARELATEX_LDAP_PLACEHOLDER"] or 'LDAP User ID'
# 		emailAtt: process.env["SHARELATEX_LDAP_EMAIL_ATT"] or 'mail'
# 		anonymous: parse(process.env["SHARELATEX_LDAP_ANONYMOUS"])
# 		adminDN: process.env["SHARELATEX_LDAP_ADMIN_DN"]
# 		adminPW: process.env["SHARELATEX_LDAP_ADMIN_PW"]
# 		starttls:  parse(process.env["SHARELATEX_LDAP_TLS"])
# 		nameAtt: process.env["SHARELATEX_LDAP_NAME_ATT"]
# 		lastNameAtt: process.env["SHARELATEX_LDAP_LAST_NAME_ATT"]
# 		updateUserDetailsOnLogin: process.env["SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN"] == 'true'

# 	if process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"]
# 		try
# 			ca = JSON.parse(process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"])
# 		catch e
# 			console.error "could not parse SHARELATEX_LDAP_TLS_OPTS_CA_PATH, invalid JSON"

# 		if typeof(ca)  == 'string'
# 			ca_paths = [ca]
# 		else if typeof(ca) == 'object' && ca?.length?
# 			ca_paths = ca
# 		else
# 			console.error "problem parsing SHARELATEX_LDAP_TLS_OPTS_CA_PATH"

# 		settings.ldap.tlsOptions =
# 			rejectUnauthorized: process.env["SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH"] == "true"
# 			ca:ca_paths  # e.g.'/etc/ldap/ca_certs.pem'




# LDAP - SERVER PRO ONLY
# ----------

442
if process.env["SHARELATEX_LDAP_HOST"]
Shane Kilkelly's avatar
Shane Kilkelly committed
443 444 445 446 447 448 449 450 451 452
	console.error """
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
#  WARNING: The LDAP configuration format has changed in version 0.5.1
#  See https://github.com/sharelatex/sharelatex/wiki/Server-Pro:-LDAP-Config
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
"""

if process.env["SHARELATEX_LDAP_URL"]
453
	settings.externalAuth = true
454
	settings.ldap =
Shane Kilkelly's avatar
Shane Kilkelly committed
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506
		server:
			url: process.env["SHARELATEX_LDAP_URL"]
			bindDn: process.env["SHARELATEX_LDAP_BIND_DN"]
			bindCredentials: process.env["SHARELATEX_LDAP_BIND_CREDENTIALS"]
			bindProperty: process.env["SHARELATEX_LDAP_BIND_PROPERTY"]
			searchBase: process.env["SHARELATEX_LDAP_SEARCHBASE"]
			searchScope: process.env["SHARELATEX_LDAP_SEARCH_SCOPE"]
			searchFilter: process.env["SHARELATEX_LDAP_SEARCH_FILTER"]
			searchAttributes: (
				if _ldap_search_attribs = process.env["SHARELATEX_LDAP_SEARCH_ATTRIBUTES"]
					try
						JSON.parse(_ldap_search_attribs)
					catch
						console.error "could not parse SHARELATEX_LDAP_SEARCH_ATTRIBUTES"
				else
					undefined
			)
			groupDnProperty: process.env["SHARELATEX_LDAP_GROUP_DN_PROPERTY"]
			groupSearchBase: process.env["SHARELATEX_LDAP_GROUP_SEARCH_BASE"]
			groupSearchScope: process.env["SHARELATEX_LDAP_GROUP_SEARCH_SCOPE"]
			groupSearchFilter: process.env["SHARELATEX_LDAP_GROUP_SEARCH_FILTER"] #
			groupSearchAttributes: (
				if _ldap_group_search_attribs = process.env["SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES"]
					try
						JSON.parse(_ldap_group_search_attribs)
					catch
						console.error "could not parse SHARELATEX_LDAP_GROUP_SEARCH_ATTRIBUTES"
				else
					undefined
			)
			cache: process.env["SHARELATEX_LDAP_CACHE"] == 'true'
			timeout: (
				if _ldap_timeout = process.env["SHARELATEX_LDAP_TIMEOUT"]
					try
						parseInt(_ldap_timeout)
					catch e
						console.error "Cannot parse SHARELATEX_LDAP_TIMEOUT"
				else
					undefined
			)
			connectTimeout: (
				if _ldap_connect_timeout = process.env["SHARELATEX_LDAP_CONNECT_TIMEOUT"]
					try
						parseInt(_ldap_connect_timeout)
					catch e
						console.error "Cannot parse SHARELATEX_CONNECTLDAP_TIMEOUT"
				else
					undefined
			)
		emailAtt: process.env["SHARELATEX_LDAP_"]
		nameAtt: process.env["SHARELATEX_LDAP_"]
		lastNameAtt: process.env["SHARELATEX_LDAP_"]
507
		updateUserDetailsOnLogin: process.env["SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN"] == 'true'
Shane Kilkelly's avatar
Shane Kilkelly committed
508
		placeholder: process.env["SHARELATEX_LDAP_"]
Henry Oswald's avatar
Henry Oswald committed
509 510

	if process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"]
Henry Oswald's avatar
Henry Oswald committed
511 512 513 514
		try
			ca = JSON.parse(process.env["SHARELATEX_LDAP_TLS_OPTS_CA_PATH"])
		catch e
			console.error "could not parse SHARELATEX_LDAP_TLS_OPTS_CA_PATH, invalid JSON"
Henry Oswald's avatar
Henry Oswald committed
515

Henry Oswald's avatar
Henry Oswald committed
516 517
		if typeof(ca)  == 'string'
			ca_paths = [ca]
Shane Kilkelly's avatar
Shane Kilkelly committed
518
		else if typeof(ca) == 'object' && ca?.length?
Henry Oswald's avatar
Henry Oswald committed
519 520 521 522
			ca_paths = ca
		else
			console.error "problem parsing SHARELATEX_LDAP_TLS_OPTS_CA_PATH"

Shane Kilkelly's avatar
Shane Kilkelly committed
523
		settings.ldap.server.tlsOptions =
524
			rejectUnauthorized: process.env["SHARELATEX_LDAP_TLS_OPTS_REJECT_UNAUTH"] == "true"
Henry Oswald's avatar
Henry Oswald committed
525
			ca:ca_paths  # e.g.'/etc/ldap/ca_certs.pem'
526

Shane Kilkelly's avatar
Shane Kilkelly committed
527 528 529 530




Shane Kilkelly's avatar
Shane Kilkelly committed
531 532 533 534
if process.env["SHARELATEX_SAML_ENTRYPOINT"]
	# NOTE: see https://github.com/bergie/passport-saml/blob/master/README.md for docs of `server` options
	settings.externalAuth = true
	settings.saml =
535
		updateUserDetailsOnLogin: process.env["SHARELATEX_SAML_UPDATE_USER_DETAILS_ON_LOGIN"] == 'true'
Shane Kilkelly's avatar
Shane Kilkelly committed
536
		identityServiceName: process.env["SHARELATEX_SAML_IDENTITY_SERVICE_NAME"]
537 538 539
		emailField: process.env["SHARELATEX_SAML_EMAIL_FIELD"] || process.env["SHARELATEX_SAML_EMAIL_FIELD_NAME"]
		firstNameField: process.env["SHARELATEX_SAML_FIRST_NAME_FIELD"]
		lastNameField:  process.env["SHARELATEX_SAML_LAST_NAME_FIELD"]
Shane Kilkelly's avatar
Shane Kilkelly committed
540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577
		server:
			# strings
			entryPoint: process.env["SHARELATEX_SAML_ENTRYPOINT"]
			callbackUrl: process.env["SHARELATEX_SAML_CALLBACK_URL"]
			issuer: process.env["SHARELATEX_SAML_ISSUER"]
			cert: process.env["SHARELATEX_SAML_CERT"]
			privateCert: process.env["SHARELATEX_SAML_PRIVATE_CERT"]
			decryptionPvk: process.env["SHARELATEX_SAML_DECRYPTION_PVK"]
			signatureAlgorithm: process.env["SHARELATEX_SAML_SIGNATURE_ALGORITHM"]
			identifierFormat: process.env["SHARELATEX_SAML_IDENTIFIER_FORMAT"]
			attributeConsumingServiceIndex: process.env["SHARELATEX_SAML_ATTRIBUTE_CONSUMING_SERVICE_INDEX"]
			authnContext: process.env["SHARELATEX_SAML_AUTHN_CONTEXT"]
			authnRequestBinding: process.env["SHARELATEX_SAML_AUTHN_REQUEST_BINDING"]
			validateInResponseTo: process.env["SHARELATEX_SAML_VALIDATE_IN_RESPONSE_TO"]
			cacheProvider: process.env["SHARELATEX_SAML_CACHE_PROVIDER"]
			logoutUrl: process.env["SHARELATEX_SAML_LOGOUT_URL"]
			logoutCallbackUrl: process.env["SHARELATEX_SAML_LOGOUT_CALLBACK_URL"]
			disableRequestedAuthnContext: process.env["SHARELATEX_SAML_DISABLE_REQUESTED_AUTHN_CONTEXT"] == 'true'
			forceAuthn: process.env["SHARELATEX_SAML_FORCE_AUTHN"] == 'true'
			skipRequestCompression: process.env["SHARELATEX_SAML_SKIP_REQUEST_COMPRESSION"] == 'true'
			acceptedClockSkewMs: (
				if _saml_skew = process.env["SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS"]
					try
						parseInt(_saml_skew)
					catch e
						console.error "Cannot parse SHARELATEX_SAML_ACCEPTED_CLOCK_SKEW_MS"
				else
					undefined
			)
			requestIdExpirationPeriodMs: (
				if _saml_exiration = process.env["SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS"]
					try
						parseInt(_saml_expiration)
					catch e
						console.error "Cannot parse SHARELATEX_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS"
				else
					undefined
			)
Shane Kilkelly's avatar
Shane Kilkelly committed
578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604
			additionalParams: (
				if _saml_additionalParams = process.env["SHARELATEX_SAML_ADDITIONAL_PARAMS"]
					try
						JSON.parse(_saml_additionalParams)
					catch e
						console.error "Cannot parse SHARELATEX_SAML_ADDITIONAL_PARAMS"
				else
					undefined
			)
			additionalAuthorizeParams: (
				if _saml_additionalAuthorizeParams = process.env["SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS"]
					try
						JSON.parse(_saml_additionalAuthorizeParams )
					catch e
						console.error "Cannot parse SHARELATEX_SAML_ADDITIONAL_AUTHORIZE_PARAMS"
				else
					undefined
			)
			additionalLogoutParams: (
				if _saml_additionalLogoutParams = process.env["SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS"]
					try
						JSON.parse(_saml_additionalLogoutParams )
					catch e
						console.error "Cannot parse SHARELATEX_SAML_ADDITIONAL_LOGOUT_PARAMS"
				else
					undefined
			)
Shane Kilkelly's avatar
Shane Kilkelly committed
605

606
if settings.externalAuth and settings?.nav?.header?
607 608 609 610 611
	results = []
	for button in settings.nav.header
		if button.url != "/register"
			results.push(button)
	settings.nav.header = results
612

613

614 615
# Compiler
# --------
616
if process.env["SANDBOXED_COMPILES"] == "true"
617
	settings.clsi =
618 619
		commandRunner: "docker-runner-sharelatex"
		docker:
620
			image: process.env["TEX_LIVE_DOCKER_IMAGE"]
621
			env:
622
				HOME: "/tmp"
623
				PATH: process.env["COMPILER_PATH"] or "/usr/local/texlive/2015/bin/x86_64-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Henry Oswald's avatar
Henry Oswald committed
624
			user: "www-data"
625

626 627 628 629
	if !settings.path?
		settings.path = {}
	settings.path.synctexBaseDir = () -> "/compile"

630 631 632 633

# Templates
# ---------
if process.env["SHARELATEX_TEMPLATES_USER_ID"]
634
	settings.templates =
635 636
		mountPointUrl: "/templates"
		user_id: process.env["SHARELATEX_TEMPLATES_USER_ID"]
637 638
		
	settings.templateLinks = parse(process.env["SHARELATEX_NEW_PROJECT_TEMPLATE_LINKS"])
639

640

641 642 643 644
# /Learn
# -------
if process.env["SHARELATEX_PROXY_LEARN"]?
	settings.proxyLearn = parse(process.env["SHARELATEX_PROXY_LEARN"])
645 646


647 648 649 650 651 652
# /References
# -----------
if process.env["SHARELATEX_ELASTICSEARCH_URL"]?
	settings.references.elasticsearch =
			host: process.env["SHARELATEX_ELASTICSEARCH_URL"]
	
James Allen's avatar
James Allen committed
653 654 655 656 657 658 659 660

# With lots of incoming and outgoing HTTP connections to different services,
# sometimes long running, it is a good idea to increase the default number
# of sockets that Node will hold open.
http = require('http')
http.globalAgent.maxSockets = 300
https = require('https')
https.globalAgent.maxSockets = 300
661

662
module.exports = settings
663