-
Notifications
You must be signed in to change notification settings - Fork 28
/
changeBackend.js
159 lines (136 loc) · 5.04 KB
/
changeBackend.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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
74
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
const fs = require('fs');
const chalk = require('chalk');
const axios = require('axios');
// const https = require('https');
const { program } = require('commander');
const { createLogger, format, transports } = require('winston');
const logger = createLogger({
format: format.combine(
format.splat(),
format.simple()
),
transports: [new transports.Console()]
});
let backendList = {
production : "https://classtranscribe.illinois.edu",
dev : "https://ct-dev.ncsa.illinois.edu",
localhost : "https://localhost:8443/",
}
/**
* adds REACT_APP_TESTING_BASE_URL env var to the config file.
* If TestSignIn is true then the frontend will use
* REACT_APP_TESTING_BASE_URL for server calls
*
* @param {string} data config.js file data
* @param {string} url url of qchosen backend
*/
function appendServer(data, url) {
const testSignInConfig = data.split("\n").filter(line => line.includes("TEST_SIGN_IN"));
const isTesting = testSignInConfig.length === 1 && testSignInConfig[0].includes("true");
const serverEnv = `${data}\nwindow.env.REACT_APP_${ isTesting? "TESTING" : "API"}_BASE_URL="${url}"\n`
return serverEnv;
}
/**
* fetches config file
* @param {string} url url of chosen backend
*/
async function fetchConfig(url) {
// TODO ignore self cert for localhost
const isLocalhost = url.includes("://localhost");
if(isLocalhost) {
logger.log('info', chalk.greenBright(`Localhost API - self cert will be ignored. However you will still need to accept the self cert of the API endpoint in your browser for axios API calls to succeed.`));
logger.log('info', chalk.greenBright(`If you are using Chrome, you can do this by going to the API endpoint in your browser and clicking "Advanced" and then "Proceed to localhost (unsafe)"`) );
logger.log('info', chalk.greenBright(`Open ${ chalk.white(`${url}api/Universities`) }${chalk.green(" to accept the cert")}`));
// see requiredEnvs in env.js
return 'window.env={}\nwindow.env.TEST_SIGN_IN="true"\nwindow.env.AUTH0_DOMAIN="0"\nwindow.env.AUTH0_CLIENT_ID="0"\nwindow.env.CILOGON_CLIENT_ID="0"\n';
}
// const agent = new https.Agent({
// rejectUnauthorized: !isLocalhost,
// requestCert: !isLocalhost,
// agent: !isLocalhost,
// });
const client = axios.create(); // { httpsAgent: agent }
let d = await client.get(`${url}/config.js`,
)
.then(({data}) => data)
// eslint-disable-next-line no-unused-vars
.catch(err => {logger.error(err);})
return d;
}
/**
* saves data to "./public/config"
* @param {string} data url of chosen backend
*/
function saveToPublicDir(data, url) {
try {
fs.writeFileSync("./public/config.js", data)
logger.log('info', chalk.white(`Config file downloaded and written for new backend server <${chalk.bold(url)}>`))
}
catch(err) {
logger.log('error', chalk.red.bold(err))
}
}
/**
* gets config data from url and adds new env var
* before saving config file in /public dir
* @param {string} url url of chosen backend
*/
// async function setBackend(url) {
// let data = await fetchConfig(url)
// if (!data) {
// logger.log('error', chalk.red(`Could not connect to server ${url} `))
// return
// }
// data = appendServer(data, url);
// saveToPublicDir(data, url);
// }
/**
* gets config data from dev and sets backend to custom address
* before saving config file in /public dir
* @param {string} url url of chosen backend
*/
async function setBackend(url) {
if (!url.startsWith("http")) {
logger.log('error', chalk.red(`The full server address and protocol must be specified \ne.g., ${chalk.bold("https://localhost:8443/")}`))
return;
}
let data = await fetchConfig(url)
if (!data) {
logger.log('error', chalk.red(`Could not connect to server <${url}> to download config file`))
return
}
data = appendServer(data, url);
saveToPublicDir(data, url);
}
/**
* processs command line arguments to select
* dev or production server
*/
function processArgs() {
program.arguments("[url]")
.option('-p --production', `${backendList.production}` )
.option('-d --dev', backendList.dev)
.option('-l --localhost', `Local docker instance`);
program.parse(process.argv);
let backend = Object.keys(program.opts());
let url = backendList[backend[0]] ?? program.args[0];
if (! url) {
logger.log('error', chalk.red('Invalid args'))
program.help();
return
}
logger.log('info',chalk.gray(`Connecting to <${url}> ...`));
setBackend(url);
if(! url.includes("://localhost") && ! url.includes("://ct-dev")) {
logger.log('info', chalk.greenBright("Some production features are unavailable, including:"));
logger.log('info', chalk.greenBright("* CILogin (Illinois) authentication is unavailable. However auth0 (email) authentication is available"));
logger.log('info', chalk.greenBright("* Video playback is unavailable"));
}
}
/**
* runs processArgs only if the file is called as an export
*/
if (require.main === module) {
processArgs();
}
module.exports.setBackend = setBackend;