UNPKG

6.84 kBJavaScriptView Raw
1const fs = require('fs');
2const merge = require('lodash.merge');
3const stripIndent = require('common-tags/lib/stripIndent');
4const utils = require('../server/helpers/utils');
5const logger = require('../server/logger');
6const crypto = require('crypto');
7// @ts-ignore
8const { version } = require('../../package.json');
9/**
10 * Reads all companion configuration set via environment variables
11 * and via the config file path
12 *
13 * @returns {object}
14 */
15exports.getCompanionOptions = (options = {}) => {
16 return merge({}, getConfigFromEnv(), getConfigFromFile(), options);
17};
18/**
19 * Loads the config from environment variables
20 *
21 * @returns {object}
22 */
23const getConfigFromEnv = () => {
24 const uploadUrls = process.env.COMPANION_UPLOAD_URLS;
25 const domains = process.env.COMPANION_DOMAINS || process.env.COMPANION_DOMAIN || null;
26 const validHosts = domains ? domains.split(',') : [];
27 return {
28 providerOptions: {
29 drive: {
30 key: process.env.COMPANION_GOOGLE_KEY,
31 secret: getSecret('COMPANION_GOOGLE_SECRET')
32 },
33 dropbox: {
34 key: process.env.COMPANION_DROPBOX_KEY,
35 secret: getSecret('COMPANION_DROPBOX_SECRET')
36 },
37 box: {
38 key: process.env.COMPANION_BOX_KEY,
39 secret: getSecret('COMPANION_BOX_SECRET')
40 },
41 instagram: {
42 key: process.env.COMPANION_INSTAGRAM_KEY,
43 secret: getSecret('COMPANION_INSTAGRAM_SECRET')
44 },
45 facebook: {
46 key: process.env.COMPANION_FACEBOOK_KEY,
47 secret: getSecret('COMPANION_FACEBOOK_SECRET')
48 },
49 onedrive: {
50 key: process.env.COMPANION_ONEDRIVE_KEY,
51 secret: getSecret('COMPANION_ONEDRIVE_SECRET')
52 },
53 zoom: {
54 key: process.env.COMPANION_ZOOM_KEY,
55 secret: getSecret('COMPANION_ZOOM_SECRET'),
56 verificationToken: getSecret('COMPANION_ZOOM_VERIFICATION_TOKEN')
57 },
58 searchProviders: {
59 unsplash: {
60 key: process.env.COMPANION_UNSPLASH_KEY
61 }
62 },
63 s3: {
64 key: process.env.COMPANION_AWS_KEY,
65 secret: getSecret('COMPANION_AWS_SECRET'),
66 bucket: process.env.COMPANION_AWS_BUCKET,
67 endpoint: process.env.COMPANION_AWS_ENDPOINT,
68 region: process.env.COMPANION_AWS_REGION,
69 useAccelerateEndpoint: process.env.COMPANION_AWS_USE_ACCELERATE_ENDPOINT === 'true',
70 expires: parseInt(process.env.COMPANION_AWS_EXPIRES || '300', 10),
71 acl: process.env.COMPANION_AWS_ACL || 'public-read'
72 }
73 },
74 server: {
75 host: process.env.COMPANION_DOMAIN,
76 protocol: process.env.COMPANION_PROTOCOL,
77 path: process.env.COMPANION_PATH,
78 implicitPath: process.env.COMPANION_IMPLICIT_PATH,
79 oauthDomain: process.env.COMPANION_OAUTH_DOMAIN,
80 validHosts: validHosts
81 },
82 filePath: process.env.COMPANION_DATADIR,
83 redisUrl: process.env.COMPANION_REDIS_URL,
84 // adding redisOptions to keep all companion options easily visible
85 // redisOptions refers to https://www.npmjs.com/package/redis#options-object-properties
86 redisOptions: {},
87 sendSelfEndpoint: process.env.COMPANION_SELF_ENDPOINT,
88 uploadUrls: uploadUrls ? uploadUrls.split(',') : null,
89 secret: getSecret('COMPANION_SECRET') || generateSecret(),
90 debug: process.env.NODE_ENV && process.env.NODE_ENV !== 'production',
91 // TODO: this is a temporary hack to support distributed systems.
92 // it is not documented, because it should be changed soon.
93 cookieDomain: process.env.COMPANION_COOKIE_DOMAIN,
94 multipleInstances: true
95 };
96};
97/**
98 * Tries to read the secret from a file if the according environment variable is set.
99 * Otherwise it falls back to the standard secret environment variable.
100 *
101 * @param {string} baseEnvVar
102 *
103 * @returns {string}
104 */
105const getSecret = (baseEnvVar) => {
106 const secretFile = process.env[`${baseEnvVar}_FILE`];
107 return secretFile
108 ? fs.readFileSync(secretFile).toString()
109 : process.env[baseEnvVar];
110};
111/**
112 * Auto-generates server secret
113 *
114 * @returns {string}
115 */
116const generateSecret = () => {
117 logger.warn('auto-generating server secret because none was specified', 'startup.secret');
118 return crypto.randomBytes(64).toString('hex');
119};
120/**
121 * Loads the config from a file and returns it as an object
122 *
123 * @returns {object}
124 */
125const getConfigFromFile = () => {
126 const path = getConfigPath();
127 if (!path)
128 return {};
129 const rawdata = fs.readFileSync(getConfigPath());
130 // @ts-ignore
131 return JSON.parse(rawdata);
132};
133/**
134 * Returns the config path specified via cli arguments
135 *
136 * @returns {string}
137 */
138const getConfigPath = () => {
139 let configPath;
140 for (let i = process.argv.length - 1; i >= 0; i--) {
141 const isConfigFlag = process.argv[i] === '-c' || process.argv[i] === '--config';
142 const flagHasValue = i + 1 <= process.argv.length;
143 if (isConfigFlag && flagHasValue) {
144 configPath = process.argv[i + 1];
145 break;
146 }
147 }
148 return configPath;
149};
150/**
151 *
152 * @param {string} url
153 */
154exports.hasProtocol = (url) => {
155 return url.startsWith('http://') || url.startsWith('https://');
156};
157exports.buildHelpfulStartupMessage = (companionOptions) => {
158 const buildURL = utils.getURLBuilder(companionOptions);
159 const callbackURLs = [];
160 Object.keys(companionOptions.providerOptions).forEach((providerName) => {
161 // s3 does not need redirect_uris
162 if (providerName === 's3') {
163 return;
164 }
165 callbackURLs.push(buildURL(`/connect/${providerName}/callback`, true));
166 });
167 return stripIndent `
168 Welcome to Companion v${version}
169 ===================================
170
171 Congratulations on setting up Companion! Thanks for joining our cause, you have taken
172 the first step towards the future of file uploading! We
173 hope you are as excited about this as we are!
174
175 While you did an awesome job on getting Companion running, this is just the welcome
176 message, so let's talk about the places that really matter:
177
178 - Be sure to add ${callbackURLs.join(', ')} as your Oauth redirect uris on their corresponding developer interfaces.
179 - The URL ${buildURL('/metrics', true)} is available for statistics to keep Companion running smoothly
180 - https://github.com/transloadit/uppy/issues - report your bugs here
181
182 So quit lollygagging, start uploading and experience the future!
183 `;
184};