@saltcorn/server 0.8.6-beta.9 → 0.8.6

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/serve.js CHANGED
@@ -8,6 +8,7 @@ const runScheduler = require("@saltcorn/data/models/scheduler");
8
8
  const User = require("@saltcorn/data/models/user");
9
9
  const Plugin = require("@saltcorn/data/models/plugin");
10
10
  const db = require("@saltcorn/data/db");
11
+ const { getConfigFile, configFilePath } = require("@saltcorn/data/db/connect");
11
12
  const {
12
13
  getState,
13
14
  init_multi_tenant,
@@ -49,11 +50,33 @@ const {
49
50
  } = require("@saltcorn/admin-models/models/tenant");
50
51
  const { auto_backup_now } = require("@saltcorn/admin-models/models/backup");
51
52
  const Snapshot = require("@saltcorn/admin-models/models/snapshot");
53
+ const { writeFileSync } = require("fs");
52
54
 
53
55
  const take_snapshot = async () => {
54
56
  return await Snapshot.take_if_changed();
55
57
  };
56
58
 
59
+ /**
60
+ * Ensure the cfg file has a jwt_secret
61
+ */
62
+ const ensureJwtSecret = () => {
63
+ const cfg = getConfigFile();
64
+ if (cfg && !cfg.jwt_secret) {
65
+ try {
66
+ const newSecret = require("crypto").randomBytes(64).toString("hex");
67
+ cfg.jwt_secret = newSecret;
68
+ writeFileSync(configFilePath, JSON.stringify(cfg, null, 2));
69
+ db.connectObj.jwt_secret = newSecret;
70
+ } catch (error) {
71
+ console.log(
72
+ `Unable to set a jwt_secret: ${
73
+ error.message ? error.message : "Unknown error"
74
+ }`
75
+ );
76
+ }
77
+ }
78
+ };
79
+
57
80
  // helpful https://gist.github.com/jpoehls/2232358
58
81
  /**
59
82
  * @param {object} opts
@@ -195,6 +218,7 @@ module.exports =
195
218
  dev,
196
219
  ...appargs
197
220
  } = {}) => {
221
+ ensureJwtSecret();
198
222
  process.on("unhandledRejection", (reason, p) => {
199
223
  console.error(reason, "Unhandled Rejection at Promise");
200
224
  });
@@ -263,7 +287,7 @@ module.exports =
263
287
  httpsServer.setTimeout(timeout * 1000);
264
288
  process.on("message", workerDispatchMsg);
265
289
  glx.serveApp(app);
266
- process.send && process.send("Start");
290
+ getState().processSend("Start");
267
291
  })
268
292
  .master(() => {
269
293
  initMaster(appargs).then(initMasterListeners);
@@ -349,7 +373,7 @@ const nonGreenlockWorkerSetup = async (appargs, port) => {
349
373
  console.log(`Saltcorn listening on http://localhost:${port}/`);
350
374
  });
351
375
  }
352
- process.send && process.send("Start");
376
+ getState().processSend("Start");
353
377
  };
354
378
 
355
379
  /**
package/tests/api.test.js CHANGED
@@ -128,7 +128,7 @@ describe("API read", () => {
128
128
  .expect(succeedJsonWith((rows) => rows.length == 2));
129
129
  });
130
130
  it("should add version counts", async () => {
131
- const patients = await Table.findOne({ name: "patients" });
131
+ const patients = Table.findOne({ name: "patients" });
132
132
  await patients.update({ versioned: true });
133
133
 
134
134
  const loginCookie = await getStaffLoginCookie();
@@ -329,7 +329,7 @@ describe("user admin", () => {
329
329
  });
330
330
  describe("User fields", () => {
331
331
  it("should add fields", async () => {
332
- const table = await Table.findOne({ name: "users" });
332
+ const table = Table.findOne({ name: "users" });
333
333
  await Field.create({
334
334
  table,
335
335
  label: "Height",
@@ -395,7 +395,7 @@ describe("User fields", () => {
395
395
  .send("password=seCERGERG45et")
396
396
  .send("height=191")
397
397
  .expect(toRedirect("/"));
398
- const table = await Table.findOne({ name: "users" });
398
+ const table = Table.findOne({ name: "users" });
399
399
  const ut = await table.getRow({ email: "staff14@foo.com" });
400
400
  expect(ut.email).toBe("staff14@foo.com");
401
401
  expect(ut.height).toBe(191);
@@ -404,7 +404,7 @@ describe("User fields", () => {
404
404
 
405
405
  describe("signup with custom login form", () => {
406
406
  it("should create user fields and login form", async () => {
407
- const table = await Table.findOne({ name: "users" });
407
+ const table = Table.findOne({ name: "users" });
408
408
  const fc = await Field.create({
409
409
  table,
410
410
  label: "Username",
@@ -662,7 +662,7 @@ describe("signup with custom login form", () => {
662
662
  .send("height=15")
663
663
  .expect(toRedirect("/"));
664
664
 
665
- const table = await Table.findOne({ name: "users" });
665
+ const table = Table.findOne({ name: "users" });
666
666
  const user = await User.findOne({ email: "staff8@foo.com" });
667
667
  expect(!!user).toBe(true);
668
668
  expect(user.checkPassword("seCERRG45et")).toBe(true);
@@ -163,7 +163,7 @@ describe("homepage", () => {
163
163
  .expect(toInclude("No views"));
164
164
  });
165
165
  it("shows with-view quick start", async () => {
166
- const table = await Table.findOne({ name: "mytable" });
166
+ const table = Table.findOne({ name: "mytable" });
167
167
 
168
168
  const v = await View.create({
169
169
  table_id: table.id,
@@ -200,7 +200,7 @@ describe("bool toggle", () => {
200
200
 
201
201
  describe("history", () => {
202
202
  it("should enable history", async () => {
203
- const table = await Table.findOne({ name: "books" });
203
+ const table = Table.findOne({ name: "books" });
204
204
 
205
205
  const loginCookie = await getAdminLoginCookie();
206
206
 
@@ -211,7 +211,7 @@ describe("history", () => {
211
211
  .send("id=" + table.id)
212
212
  .send("versioned=on")
213
213
  .expect(toRedirect("/table/" + table.id));
214
- const table1 = await Table.findOne({ name: "books" });
214
+ const table1 = Table.findOne({ name: "books" });
215
215
  expect(table1.versioned).toBe(true);
216
216
  });
217
217
  it("create new row in versioned table", async () => {
@@ -231,7 +231,7 @@ describe("history", () => {
231
231
  it("edit row in versioned table", async () => {
232
232
  const loginCookie = await getAdminLoginCookie();
233
233
  const app = await getApp({ disableCsrf: true });
234
- const table = await Table.findOne({ name: "books" });
234
+ const table = Table.findOne({ name: "books" });
235
235
  const tolstoy = await table.getRow({ author: "Leo Tolstoy" });
236
236
  await request(app)
237
237
  .post("/api/books/" + tolstoy.id)
@@ -247,7 +247,7 @@ describe("history", () => {
247
247
  it("edit row in versioned table again", async () => {
248
248
  const loginCookie = await getAdminLoginCookie();
249
249
  const app = await getApp({ disableCsrf: true });
250
- const table = await Table.findOne({ name: "books" });
250
+ const table = Table.findOne({ name: "books" });
251
251
  const tolstoy = await table.getRow({ author: "Leo Tolstoy" });
252
252
  await request(app)
253
253
  .post("/api/books/" + tolstoy.id)
@@ -263,7 +263,7 @@ describe("history", () => {
263
263
 
264
264
  it("show versions", async () => {
265
265
  const loginCookie = await getAdminLoginCookie();
266
- const table = await Table.findOne({ name: "books" });
266
+ const table = Table.findOne({ name: "books" });
267
267
  const tolstoy = await table.getRow({ author: "Leo Tolstoy" });
268
268
  const app = await getApp({ disableCsrf: true });
269
269
  await request(app)
@@ -276,7 +276,7 @@ describe("history", () => {
276
276
  });
277
277
  it("restores old version", async () => {
278
278
  const loginCookie = await getAdminLoginCookie();
279
- const table = await Table.findOne({ name: "books" });
279
+ const table = Table.findOne({ name: "books" });
280
280
  const tolstoy = await table.getRow({ author: "Leo Tolstoy" });
281
281
  const app = await getApp({ disableCsrf: true });
282
282
  await request(app)
@@ -44,7 +44,7 @@ describe("Field Endpoints", () => {
44
44
 
45
45
  it("should post new int field", async () => {
46
46
  const loginCookie = await getAdminLoginCookie();
47
- const table = await Table.findOne({ name: "books" });
47
+ const table = Table.findOne({ name: "books" });
48
48
 
49
49
  const ctx = encodeURIComponent(JSON.stringify({ table_id: table.id }));
50
50
  const app = await getApp({ disableCsrf: true });
@@ -61,7 +61,7 @@ describe("Field Endpoints", () => {
61
61
 
62
62
  it("should post new int field with attributes", async () => {
63
63
  const loginCookie = await getAdminLoginCookie();
64
- const table = await Table.findOne({ name: "books" });
64
+ const table = Table.findOne({ name: "books" });
65
65
 
66
66
  const ctx = encodeURIComponent(
67
67
  JSON.stringify({
@@ -228,7 +228,7 @@ describe("Field Endpoints", () => {
228
228
 
229
229
  it("should post new calculated int field", async () => {
230
230
  const loginCookie = await getAdminLoginCookie();
231
- const table = await Table.findOne({ name: "books" });
231
+ const table = Table.findOne({ name: "books" });
232
232
 
233
233
  const ctx = encodeURIComponent(JSON.stringify({ table_id: table.id }));
234
234
  const app = await getApp({ disableCsrf: true });
@@ -258,14 +258,14 @@ describe("Field Endpoints", () => {
258
258
  .send("contextEnc=" + ctx1)
259
259
  .set("Cookie", loginCookie)
260
260
  .expect(toRedirect("/table/2"));
261
- const table1 = await Table.findOne({ name: "books" });
261
+ const table1 = Table.findOne({ name: "books" });
262
262
 
263
263
  const row = await table1.getRow({ id: 1 });
264
264
  expect(row.pagesplus10).toBe(977);
265
265
  });
266
266
  it("should post new calculated string field", async () => {
267
267
  const loginCookie = await getAdminLoginCookie();
268
- const table = await Table.findOne({ name: "books" });
268
+ const table = Table.findOne({ name: "books" });
269
269
 
270
270
  const ctx = encodeURIComponent(JSON.stringify({ table_id: table.id }));
271
271
  const app = await getApp({ disableCsrf: true });
@@ -283,7 +283,7 @@ describe("Field Endpoints", () => {
283
283
  });
284
284
  it("should post new calculated float field", async () => {
285
285
  const loginCookie = await getAdminLoginCookie();
286
- const table = await Table.findOne({ name: "books" });
286
+ const table = Table.findOne({ name: "books" });
287
287
 
288
288
  const ctx = encodeURIComponent(JSON.stringify({ table_id: table.id }));
289
289
  const app = await getApp({ disableCsrf: true });
@@ -301,7 +301,7 @@ describe("Field Endpoints", () => {
301
301
  });
302
302
  it("should post new calculated boolean field", async () => {
303
303
  const loginCookie = await getAdminLoginCookie();
304
- const table = await Table.findOne({ name: "books" });
304
+ const table = Table.findOne({ name: "books" });
305
305
 
306
306
  const ctx = encodeURIComponent(JSON.stringify({ table_id: table.id }));
307
307
  const app = await getApp({ disableCsrf: true });
@@ -319,7 +319,7 @@ describe("Field Endpoints", () => {
319
319
  });
320
320
  it("should test expression", async () => {
321
321
  const loginCookie = await getAdminLoginCookie();
322
- const table = await Table.findOne({ name: "books" });
322
+ const table = Table.findOne({ name: "books" });
323
323
 
324
324
  const ctx = encodeURIComponent(JSON.stringify({ table_id: table.id }));
325
325
  const app = await getApp({ disableCsrf: true });
@@ -335,7 +335,7 @@ describe("Field Endpoints", () => {
335
335
  });
336
336
  it("should test stored expression", async () => {
337
337
  const loginCookie = await getAdminLoginCookie();
338
- const table = await Table.findOne({ name: "books" });
338
+ const table = Table.findOne({ name: "books" });
339
339
 
340
340
  const ctx = encodeURIComponent(JSON.stringify({ table_id: table.id }));
341
341
  const app = await getApp({ disableCsrf: true });
@@ -351,7 +351,7 @@ describe("Field Endpoints", () => {
351
351
  });
352
352
  it("should show calculated", async () => {
353
353
  const loginCookie = await getAdminLoginCookie();
354
- const table = await Table.findOne({ name: "books" });
354
+ const table = Table.findOne({ name: "books" });
355
355
  await Field.create({
356
356
  table,
357
357
  label: "pagesp1",
@@ -218,7 +218,7 @@ describe("files edit", () => {
218
218
  .expect(toRedirect("/"));
219
219
  });
220
220
  it("has file", async () => {
221
- const table = await Table.findOne({ name: "thefiletable" });
221
+ const table = Table.findOne({ name: "thefiletable" });
222
222
  const row = await table.getRow({ first_name: "elvis" });
223
223
  const file = await File.findOne({ id: row.mugshot });
224
224
  expect(!!file).toBe(true);
@@ -256,7 +256,7 @@ describe("Kitten tracker", () => {
256
256
  .expect(toRedirect("/"));
257
257
  });
258
258
  it("should insert rows", async () => {
259
- const tbl = await Table.findOne({ name: "cats" });
259
+ const tbl = Table.findOne({ name: "cats" });
260
260
  expect(!!tbl).toBe(true);
261
261
  await tbl.insertRow({ name: "Charlie", stage: "Kitten", lat: 51, long: 0 });
262
262
  await tbl.insertRow({
@@ -86,7 +86,7 @@ describe("Table Endpoints", () => {
86
86
  it("should edit tables", async () => {
87
87
  const loginCookie = await getAdminLoginCookie();
88
88
 
89
- const tbl = await Table.findOne({ name: "mypostedtable" });
89
+ const tbl = Table.findOne({ name: "mypostedtable" });
90
90
 
91
91
  const app = await getApp({ disableCsrf: true });
92
92
  await request(app)
@@ -186,7 +186,7 @@ Gordon Kane, 218`;
186
186
  it("should delete tables", async () => {
187
187
  const loginCookie = await getAdminLoginCookie();
188
188
  const app = await getApp({ disableCsrf: true });
189
- const tbl = await Table.findOne({ name: "mypostedtable" });
189
+ const tbl = Table.findOne({ name: "mypostedtable" });
190
190
  const delres = await request(app)
191
191
  .post(`/table/delete/${tbl.id}`)
192
192
  .set("Cookie", loginCookie);
@@ -200,7 +200,7 @@ Gordon Kane, 218`;
200
200
  });
201
201
  it("should show constraints", async () => {
202
202
  const loginCookie = await getAdminLoginCookie();
203
- const tbl = await Table.findOne({ name: "books" });
203
+ const tbl = Table.findOne({ name: "books" });
204
204
  const id = tbl.id;
205
205
  const app = await getApp({ disableCsrf: true });
206
206
  await request(app)
@@ -241,7 +241,7 @@ Gordon Kane, 218`;
241
241
  it("should delete tables", async () => {
242
242
  const loginCookie = await getAdminLoginCookie();
243
243
  const app = await getApp({ disableCsrf: true });
244
- const tbl = await Table.findOne({ name: "books" });
244
+ const tbl = Table.findOne({ name: "books" });
245
245
  await request(app)
246
246
  .post(`/table/delete/${tbl.id}`)
247
247
  .set("Cookie", loginCookie)
@@ -92,7 +92,7 @@ describe("view with routes", () => {
92
92
  it("should enable", async () => {
93
93
  getState().registerPlugin("mock_plugin", plugin_with_routes());
94
94
  expect(getState().viewtemplates.ViewWithRoutes.name).toBe("ViewWithRoutes");
95
- const table = await Table.findOne({ name: "books" });
95
+ const table = Table.findOne({ name: "books" });
96
96
 
97
97
  const v = await View.create({
98
98
  table_id: table.id,
@@ -143,7 +143,7 @@ describe("render view on page", () => {
143
143
  describe("render view with slug", () => {
144
144
  it("should show with id slug in list", async () => {
145
145
  const view = await View.findOne({ name: "authorshow" });
146
- const table = await Table.findOne({ name: "books" });
146
+ const table = Table.findOne({ name: "books" });
147
147
  const slugOpts = await table.slug_options();
148
148
  const slugOpt = slugOpts.find((so) => so.label === "/:id");
149
149
  expect(!!slugOpt).toBe(true);
@@ -158,11 +158,11 @@ describe("render view with slug", () => {
158
158
  });
159
159
  it("should show with name slug in list", async () => {
160
160
  const view = await View.findOne({ name: "authorshow" });
161
- const table0 = await Table.findOne({ name: "books" });
161
+ const table0 = Table.findOne({ name: "books" });
162
162
  const fields = await table0.getFields();
163
163
  const field = fields.find((f) => f.name === "author");
164
164
  await field.update({ is_unique: true });
165
- const table = await Table.findOne({ name: "books" });
165
+ const table = Table.findOne({ name: "books" });
166
166
 
167
167
  const slugOpts = await table.slug_options();
168
168
  const slugOpt = slugOpts.find((so) => so.label === "/slugify-author");
@@ -102,7 +102,7 @@ describe("viewedit new List", () => {
102
102
  });
103
103
  it("save new view", async () => {
104
104
  const loginCookie = await getAdminLoginCookie();
105
- const table = await Table.findOne({ name: "books" });
105
+ const table = Table.findOne({ name: "books" });
106
106
 
107
107
  const ctx = encodeURIComponent(
108
108
  JSON.stringify({
@@ -125,7 +125,7 @@ describe("viewedit new List", () => {
125
125
  });
126
126
  it("save new views default state", async () => {
127
127
  const loginCookie = await getAdminLoginCookie();
128
- const table = await Table.findOne({ name: "books" });
128
+ const table = Table.findOne({ name: "books" });
129
129
 
130
130
  const ctx = encodeURIComponent(
131
131
  JSON.stringify({
@@ -153,7 +153,7 @@ describe("viewedit new List", () => {
153
153
  });
154
154
  it("save new views options", async () => {
155
155
  const loginCookie = await getAdminLoginCookie();
156
- const table = await Table.findOne({ name: "books" });
156
+ const table = Table.findOne({ name: "books" });
157
157
 
158
158
  const ctx = encodeURIComponent(
159
159
  JSON.stringify({
@@ -219,7 +219,7 @@ describe("viewedit new List with one field", () => {
219
219
  });
220
220
  it("save new view", async () => {
221
221
  const loginCookie = await getAdminLoginCookie();
222
- const table = await Table.findOne({ name: "books" });
222
+ const table = Table.findOne({ name: "books" });
223
223
 
224
224
  const ctx = encodeURIComponent(
225
225
  JSON.stringify({
@@ -240,7 +240,7 @@ describe("viewedit new List with one field", () => {
240
240
  });
241
241
  it("save new views default state", async () => {
242
242
  const loginCookie = await getAdminLoginCookie();
243
- const table = await Table.findOne({ name: "books" });
243
+ const table = Table.findOne({ name: "books" });
244
244
 
245
245
  const ctx = encodeURIComponent(
246
246
  JSON.stringify({
@@ -264,7 +264,7 @@ describe("viewedit new List with one field", () => {
264
264
  });
265
265
  it("save new views options", async () => {
266
266
  const loginCookie = await getAdminLoginCookie();
267
- const table = await Table.findOne({ name: "books" });
267
+ const table = Table.findOne({ name: "books" });
268
268
 
269
269
  const ctx = encodeURIComponent(
270
270
  JSON.stringify({
@@ -341,7 +341,7 @@ describe("viewedit new Show", () => {
341
341
  });
342
342
  it("save new view layout", async () => {
343
343
  const loginCookie = await getAdminLoginCookie();
344
- const table = await Table.findOne({ name: "books" });
344
+ const table = Table.findOne({ name: "books" });
345
345
 
346
346
  const ctx = encodeURIComponent(
347
347
  JSON.stringify({
@@ -362,7 +362,7 @@ describe("viewedit new Show", () => {
362
362
  });
363
363
  it("save new view page title", async () => {
364
364
  const loginCookie = await getAdminLoginCookie();
365
- const table = await Table.findOne({ name: "books" });
365
+ const table = Table.findOne({ name: "books" });
366
366
 
367
367
  const ctx = encodeURIComponent(
368
368
  JSON.stringify({