carta-controller 5.1.1 → 6.0.0-beta.1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "carta-controller",
3
- "version": "5.1.1",
3
+ "version": "6.0.0-beta.1.0.3",
4
4
  "description": "NodeJS-based controller for CARTA",
5
5
  "repository": "https://github.com/CARTAvis/carta-controller",
6
6
  "homepage": "https://www.cartavis.org",
@@ -12,20 +12,24 @@
12
12
  "scripts": {
13
13
  "start": "npx ts-node src/index.ts",
14
14
  "test": "npx ts-node src/index.ts --test",
15
- "reformat": "npx prettier --write ./src",
16
- "checkformat": "npx prettier --check ./src",
15
+ "reformat": "npx @biomejs/biome format --write",
16
+ "checkformat": "npx @biomejs/biome format",
17
+ "lint": "npx @biomejs/biome lint",
18
+ "fixlint": "npx @biomejs/biome lint --write",
19
+ "checkformat-and-lint": "npx @biomejs/biome check",
20
+ "reformat-and-fixlint": "npx @biomejs/biome check --write",
17
21
  "prepare": "npx tsc",
18
22
  "unit-test": "vitest run"
19
23
  },
20
24
  "author": "",
21
- "license": "ISC",
25
+ "license": "GPLV3",
22
26
  "dependencies": {
23
27
  "@pm2/io": "^6.1.0",
24
28
  "ajv": "^8.17.1",
25
29
  "ajv-formats": "^3.0.1",
26
30
  "axios": "^1.8.2",
27
31
  "body-parser": "^1.19.0",
28
- "carta-frontend": "^5.1.0",
32
+ "carta-frontend": "^6.0.0-beta.1.0.2",
29
33
  "compression": "^1.8.0",
30
34
  "cookie-parser": "^1.4.7",
31
35
  "cors": "^2.8.5",
@@ -45,16 +49,17 @@
45
49
  "moment-timezone": "^0.6.0",
46
50
  "mongodb": "^5.8.0",
47
51
  "ms": "^2.1.3",
48
- "node-linux-pam": "0.1.0",
52
+ "node-linux-pam": "github:cartavis/node-linux-pam#v0.2.2",
49
53
  "pug": "^3.0.0",
50
54
  "read": "^2.0.0",
51
55
  "tcp-port-used": "^1.0.2",
52
56
  "uuid": "^9.0.0",
53
- "websocket": "^1.0.34",
57
+ "websocket": "^1.0.35",
54
58
  "winston": "^3.17.0",
55
59
  "yargs": "^17.0.1"
56
60
  },
57
61
  "devDependencies": {
62
+ "@biomejs/biome": "2.1.4",
58
63
  "@types/compression": "^1.7.0",
59
64
  "@types/cookie-parser": "^1.4.8",
60
65
  "@types/cors": "^2.8.10",
@@ -68,8 +73,6 @@
68
73
  "@types/uuid": "^9.0.0",
69
74
  "@types/websocket": "^1.0.2",
70
75
  "@types/yargs": "^17.0.22",
71
- "patch-package": "^7.0.0",
72
- "prettier": "2.8.4",
73
76
  "ts-node": "^10.9.1",
74
77
  "typescript": "^5.5.4",
75
78
  "vitest": "^3.1.4"
@@ -12,7 +12,6 @@ const isPopup = urlParams.get("popup");
12
12
 
13
13
  let serverCheckHandle;
14
14
 
15
- let authenticationType = "";
16
15
  let authenticatedUser = "";
17
16
  let token = "";
18
17
  let tokenLifetime = -1;
@@ -22,8 +21,7 @@ let notyf;
22
21
 
23
22
  let apiBase;
24
23
  getApiBase = async () => {
25
- if (apiBase)
26
- return apiBase;
24
+ if (apiBase) return apiBase;
27
25
  else {
28
26
  try {
29
27
  const configData = await fetch(`${strippedPath}config`);
@@ -35,7 +33,7 @@ getApiBase = async () => {
35
33
  return "/api"; // use default
36
34
  }
37
35
  }
38
- }
36
+ };
39
37
 
40
38
  apiCall = async (callName, jsonBody, method, authRequired) => {
41
39
  const options = {
@@ -43,13 +41,13 @@ apiCall = async (callName, jsonBody, method, authRequired) => {
43
41
  };
44
42
  if (method !== "get" && jsonBody) {
45
43
  options.body = JSON.stringify(jsonBody);
46
- options.headers = {"Content-Type": "application/json"}
44
+ options.headers = {"Content-Type": "application/json"};
47
45
  } else {
48
46
  options.headers = {};
49
47
  }
50
48
 
51
49
  if (token) {
52
- options.headers["Authorization"] = `Bearer ${token}`;
50
+ options.headers.Authorization = `Bearer ${token}`;
53
51
  }
54
52
 
55
53
  const currentTime = Date.now() / 1000;
@@ -62,12 +60,12 @@ apiCall = async (callName, jsonBody, method, authRequired) => {
62
60
  }
63
61
  }
64
62
  return fetch(`${await getApiBase()}/${callName}`, options);
65
- }
63
+ };
66
64
 
67
65
  function setToken(tokenString, expiresIn) {
68
66
  token = tokenString;
69
67
  tokenLifetime = expiresIn;
70
- if (isFinite(tokenLifetime) && tokenLifetime > 0) {
68
+ if (Number.isFinite(tokenLifetime) && tokenLifetime > 0) {
71
69
  console.log(`Token updated and valid for ${tokenLifetime.toFixed()} seconds`);
72
70
  const currentTimeSeconds = Date.now() / 1000;
73
71
  tokenExpiryTime = currentTimeSeconds + tokenLifetime;
@@ -98,7 +96,7 @@ showMessage = (message, error, elementId) => {
98
96
  statusElement.className = "success-message";
99
97
  }
100
98
  statusElement.innerHTML = message;
101
- }
99
+ };
102
100
 
103
101
  setButtonDisabled = (elementId, disabled) => {
104
102
  const button = document.getElementById(elementId);
@@ -107,10 +105,10 @@ setButtonDisabled = (elementId, disabled) => {
107
105
  if (disabled) {
108
106
  button.classList.add("button-disabled");
109
107
  } else {
110
- button.classList.remove("button-disabled")
108
+ button.classList.remove("button-disabled");
111
109
  }
112
110
  }
113
- }
111
+ };
114
112
 
115
113
  updateServerStatus = async () => {
116
114
  let hasServer = false;
@@ -130,15 +128,15 @@ updateServerStatus = async () => {
130
128
  }
131
129
  updateRedirectURL(hasServer);
132
130
  serverRunning = hasServer;
133
- }
131
+ };
134
132
 
135
- updateRedirectURL = (hasServer) => {
133
+ updateRedirectURL = hasServer => {
136
134
  if (hasServer) {
137
135
  showMessage("CARTA server running", false, "carta-status");
138
136
  } else {
139
137
  showMessage(`Logged in as ${authenticatedUser}`, false, "carta-status");
140
138
  }
141
- }
139
+ };
142
140
 
143
141
  handleLogin = async () => {
144
142
  setButtonDisabled("login", true);
@@ -156,20 +154,19 @@ handleLogin = async () => {
156
154
  } else {
157
155
  onLoginFailed(res.status);
158
156
  }
159
- } catch (e) {
157
+ } catch (_e) {
160
158
  onLoginFailed(500);
161
159
  }
162
160
  setButtonDisabled("login", false);
163
161
  };
164
162
 
165
- onLoginFailed = (status) => {
163
+ onLoginFailed = status => {
166
164
  clearToken();
167
165
  notyf.error(status === 403 ? "Invalid username/password combination" : "Could not authenticate correctly");
168
- }
166
+ };
169
167
 
170
168
  onLoginSucceeded = async (username, type) => {
171
169
  authenticatedUser = username;
172
- authenticationType = type;
173
170
  localStorage.setItem("authenticationType", type);
174
171
  notyf.success(`Logged in as ${authenticatedUser}`);
175
172
  if (autoRedirect) {
@@ -181,7 +178,7 @@ onLoginSucceeded = async (username, type) => {
181
178
  serverCheckHandle = setInterval(updateServerStatus, 5000);
182
179
  await updateServerStatus();
183
180
  }
184
- }
181
+ };
185
182
 
186
183
  handleServerStop = async () => {
187
184
  try {
@@ -202,7 +199,7 @@ handleServerStop = async () => {
202
199
  notyf.error("Failed to stop CARTA server");
203
200
  console.log(e);
204
201
  }
205
- }
202
+ };
206
203
 
207
204
  handleLogout = async () => {
208
205
  localStorage.removeItem("authenticationType");
@@ -210,11 +207,11 @@ handleLogout = async () => {
210
207
  await handleServerStop();
211
208
  }
212
209
  window.open(`${await getApiBase()}/auth/logout`, "_self");
213
- }
210
+ };
214
211
 
215
212
  handleOpenCarta = () => {
216
213
  window.open(redirectUrl, "_self");
217
- }
214
+ };
218
215
 
219
216
  handleLog = async () => {
220
217
  // Disable log buttons for 5 seconds
@@ -230,7 +227,7 @@ handleLog = async () => {
230
227
  const res = await apiCall("server/log", undefined, "get", true);
231
228
  const body = await res.json();
232
229
  if (body.success && body.log) {
233
- document.getElementById("log-modal").style.display = "block"
230
+ document.getElementById("log-modal").style.display = "block";
234
231
  document.getElementById("main-div").classList.add("blurred");
235
232
  const outputElement = document.getElementById("log-output");
236
233
  if (outputElement) {
@@ -244,25 +241,25 @@ handleLog = async () => {
244
241
  } catch (e) {
245
242
  console.log(e);
246
243
  }
247
- }
244
+ };
248
245
 
249
246
  handleHideLog = () => {
250
- document.getElementById("log-modal").style.display = "none"
247
+ document.getElementById("log-modal").style.display = "none";
251
248
  document.getElementById("main-div").classList.remove("blurred");
252
- }
249
+ };
253
250
 
254
251
  handleLocalLogout = async () => {
255
252
  await apiCall("auth/logout", undefined, "post", false);
256
- }
253
+ };
257
254
 
258
- handleKeyup = (e) => {
255
+ handleKeyup = e => {
259
256
  if (e.keyCode === 13) {
260
257
  const loginButton = document.getElementById("login");
261
258
  if (loginButton && !loginButton.disabled) {
262
259
  handleLogin();
263
260
  }
264
261
  }
265
- }
262
+ };
266
263
 
267
264
  refreshLocalToken = async () => {
268
265
  try {
@@ -277,46 +274,47 @@ refreshLocalToken = async () => {
277
274
  notyf.error("Error refreshing authentication");
278
275
  console.log(err);
279
276
  }
280
- }
277
+ };
281
278
 
282
- showCartaForm = (show) => {
279
+ showCartaForm = show => {
283
280
  const cartaForm = document.getElementsByClassName("carta-form")[0];
284
281
  if (show) {
285
282
  cartaForm.style.display = "block";
286
283
  } else {
287
284
  cartaForm.style.display = "none";
288
-
289
285
  }
290
- }
286
+ };
291
287
 
292
- showLoginForm = (show) => {
288
+ showLoginForm = show => {
293
289
  const loginForm = document.getElementsByClassName("login-form")[0];
294
290
  if (show) {
295
291
  loginForm.style.display = "block";
296
292
  } else {
297
293
  loginForm.style.display = "none";
298
-
299
294
  }
300
- }
295
+ };
301
296
 
302
297
  window.onload = async () => {
303
298
  notyf = new Notyf({
304
299
  ripple: true,
305
300
  position: {x: "center"},
306
- types: [{
307
- type: "warning",
308
- background: "orange"
309
- }, {
310
- type: "info",
311
- background: "#4c84af",
312
- }]
301
+ types: [
302
+ {
303
+ type: "warning",
304
+ background: "orange"
305
+ },
306
+ {
307
+ type: "info",
308
+ background: "#4c84af"
309
+ }
310
+ ]
313
311
  });
314
312
 
315
313
  // Check for completed login
316
314
  const usp = new URLSearchParams(window.location.search);
317
315
  if (usp.has("oidcuser")) {
318
316
  await refreshLocalToken();
319
- onLoginSucceeded(usp.get("oidcuser"), "oidc")
317
+ onLoginSucceeded(usp.get("oidcuser"), "oidc");
320
318
  } else if (usp.has("googleuser")) {
321
319
  await refreshLocalToken();
322
320
  if (localStorage.getItem("redirectParams")) {
@@ -324,7 +322,7 @@ window.onload = async () => {
324
322
  localStorage.removeItem("redirectParams");
325
323
  autoRedirect = true;
326
324
  }
327
- onLoginSucceeded(usp.get("googleuser"), "google")
325
+ onLoginSucceeded(usp.get("googleuser"), "google");
328
326
  } else if (usp.has("err")) {
329
327
  console.log(usp.get("err"));
330
328
  notyf.open({type: "error", message: usp.get("err")});
@@ -375,7 +373,9 @@ window.onload = async () => {
375
373
 
376
374
  const oidcLoginButton = document.getElementById("oidcLogin");
377
375
  if (oidcLoginButton) {
378
- oidcLoginButton.onclick = async () => { window.location.href = `${await getApiBase()}/auth/login${window.location.search}` };
376
+ oidcLoginButton.onclick = async () => {
377
+ window.location.href = `${await getApiBase()}/auth/login${window.location.search}`;
378
+ };
379
379
  }
380
380
 
381
381
  document.getElementById("stop").onclick = handleServerStop;
@@ -384,5 +384,4 @@ window.onload = async () => {
384
384
  document.getElementById("refresh-logs").onclick = handleLog;
385
385
  document.getElementById("hide-logs").onclick = handleHideLog;
386
386
  document.getElementById("logout").onclick = handleLogout;
387
-
388
- }
387
+ };