@hivedev/hivesdk 1.0.33 → 1.0.34

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/hive-server.cjs CHANGED
@@ -35,7 +35,7 @@ var require_dist = __commonJS({
35
35
  "use strict";
36
36
  Object.defineProperty(exports2, "__esModule", { value: true });
37
37
  exports2.parse = parse2;
38
- exports2.serialize = serialize2;
38
+ exports2.serialize = serialize4;
39
39
  var cookieNameRegExp = /^[\u0021-\u003A\u003C\u003E-\u007E]+$/;
40
40
  var cookieValueRegExp = /^[\u0021-\u003A\u003C-\u007E]*$/;
41
41
  var domainValueRegExp = /^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i;
@@ -93,7 +93,7 @@ var require_dist = __commonJS({
93
93
  }
94
94
  return min;
95
95
  }
96
- function serialize2(name, val, options) {
96
+ function serialize4(name, val, options) {
97
97
  const enc = options?.encode || encodeURIComponent;
98
98
  if (!cookieNameRegExp.test(name)) {
99
99
  throw new TypeError(`argument name is invalid: ${name}`);
@@ -203,6 +203,8 @@ __export(server_exports, {
203
203
  isLoggedInWithPermission: () => isLoggedInWithPermission,
204
204
  loadConfiguration: () => loadConfiguration,
205
205
  promptPassword: () => promptPassword,
206
+ registerService: () => registerService,
207
+ saveConfiguration: () => saveConfiguration,
206
208
  sendMail: () => sendMail,
207
209
  setupPassword: () => setupPassword
208
210
  });
@@ -399,47 +401,64 @@ var DatabaseConnector_default = DatabaseConnector;
399
401
  var import_path2 = __toESM(require("path"), 1);
400
402
  var import_fs3 = __toESM(require("fs"), 1);
401
403
  async function loadConfiguration() {
402
- let firebaseAdminCredentials = "";
403
- let databaseCredentials = "";
404
- let permissions = "";
405
- let smtpCredentials = "";
404
+ let firebaseAdminCredentials = null;
405
+ let databaseCredentials = null;
406
+ let permissions = null;
407
+ let smtpCredentials = null;
406
408
  const firebaseAdminCredentialsPath = import_path2.default.join(getAppDataDirectory(), "firebase_admin_credentials.dat");
407
409
  const databaseCredentialsPath = import_path2.default.join(getAppDataDirectory(), "database_credentials.dat");
408
410
  const permissionsPath = import_path2.default.join(getAppDataDirectory(), "permissions.dat");
409
411
  const smtpCredentialsPath = import_path2.default.join(getAppDataDirectory(), "smtp_credentials.dat");
410
412
  if (import_fs3.default.existsSync(firebaseAdminCredentialsPath)) {
411
- firebaseAdminCredentials = await decryptFileWithPassword(import_path2.default.join(getAppDataDirectory(), "firebase_admin_credentials.dat"), process.env.SERVER_PASSWORD);
413
+ firebaseAdminCredentials = await decryptFileWithPassword(firebaseAdminCredentialsPath, process.env.SERVER_PASSWORD);
412
414
  }
413
415
  if (import_fs3.default.existsSync(databaseCredentialsPath)) {
414
- databaseCredentials = await decryptFileWithPassword(import_path2.default.join(getAppDataDirectory(), "database_credentials.dat"), process.env.SERVER_PASSWORD);
416
+ databaseCredentials = await decryptFileWithPassword(databaseCredentialsPath, process.env.SERVER_PASSWORD);
415
417
  }
416
418
  if (import_fs3.default.existsSync(permissionsPath)) {
417
- permissions = await decryptFileWithPassword(import_path2.default.join(getAppDataDirectory(), "permissions.dat"), process.env.SERVER_PASSWORD);
419
+ permissions = await decryptFileWithPassword(permissionsPath, process.env.SERVER_PASSWORD);
418
420
  }
419
421
  if (import_fs3.default.existsSync(smtpCredentialsPath)) {
420
- smtpCredentials = await decryptFileWithPassword(import_path2.default.join(getAppDataDirectory(), "smtp_credentials.dat"), process.env.SERVER_PASSWORD);
422
+ smtpCredentials = await decryptFileWithPassword(smtpCredentialsPath, process.env.SERVER_PASSWORD);
421
423
  }
422
- process.env.FIREBASE_ADMIN_CREDENTIALS = firebaseAdminCredentials;
423
- process.env.DATABASE_CREDENTIALS = databaseCredentials;
424
- process.env.PERMISSIONS = permissions;
425
- process.env.SMTP_CREDENTIALS = smtpCredentials;
426
- try {
427
- const smtpCredentialsObject = JSON.parse(smtpCredentials);
428
- process.env.SMTP_PASSWORD = smtpCredentialsObject.password || "";
429
- } catch (e) {
430
- console.error(e);
424
+ if (firebaseAdminCredentials) {
425
+ process.env.FIREBASE_ADMIN_CREDENTIALS = firebaseAdminCredentials;
431
426
  }
432
427
  if (databaseCredentials) {
433
- databaseCredentials = JSON.parse(databaseCredentials);
434
- const hivePortalDatabaseCredentials = databaseCredentials[HiveServerGlobals_default.getServiceName()];
435
- DatabaseConnector_default.setCredentials(
436
- {
437
- host: hivePortalDatabaseCredentials.host || "127.0.0.1",
438
- username: hivePortalDatabaseCredentials.username || "",
439
- password: hivePortalDatabaseCredentials.password || "",
440
- name: hivePortalDatabaseCredentials.name || "hive"
428
+ process.env.DATABASE_CREDENTIALS = databaseCredentials;
429
+ }
430
+ if (permissions) {
431
+ process.env.PERMISSIONS = permissions;
432
+ }
433
+ if (smtpCredentials) {
434
+ process.env.SMTP_CREDENTIALS = smtpCredentials;
435
+ try {
436
+ const smtpCredentialsObject = JSON.parse(smtpCredentials);
437
+ process.env.SMTP_PASSWORD = smtpCredentialsObject.password || "";
438
+ } catch (error) {
439
+ console.error("loadConfiguration: Failed to parse SMTP credentials.", error);
440
+ }
441
+ }
442
+ if (databaseCredentials) {
443
+ try {
444
+ const parsedDatabaseCredentials = JSON.parse(databaseCredentials);
445
+ const serviceName = HiveServerGlobals_default.getServiceName();
446
+ const serviceCredentials = parsedDatabaseCredentials[serviceName];
447
+ if (!serviceCredentials) {
448
+ console.error(`loadConfiguration: No database credentials found for service "${serviceName}".`);
449
+ return;
441
450
  }
442
- );
451
+ DatabaseConnector_default.setCredentials(
452
+ {
453
+ host: serviceCredentials.host || "127.0.0.1",
454
+ username: serviceCredentials.username || "",
455
+ password: serviceCredentials.password || "",
456
+ name: serviceCredentials.name || "hive"
457
+ }
458
+ );
459
+ } catch (error) {
460
+ console.error("loadConfiguration: Failed to parse database credentials.", error);
461
+ }
443
462
  }
444
463
  }
445
464
 
@@ -465,10 +484,47 @@ async function encryptAndStoreFile(data, fullPath, password) {
465
484
  await import_fs4.promises.writeFile(fullPath, payload);
466
485
  }
467
486
 
487
+ // Server/Utility/SaveConfiguration.js
488
+ var import_path4 = __toESM(require("path"), 1);
489
+ async function saveConfiguration(configurationObject) {
490
+ if (!configurationObject) {
491
+ console.error("saveConfiguration: No configuration object provided.");
492
+ return;
493
+ }
494
+ if (configurationObject.firebaseAdminCredentials) {
495
+ await encryptAndStoreFile(
496
+ JSON.stringify(configurationObject.firebaseAdminCredentials),
497
+ import_path4.default.join(getAppDataDirectory(), "firebase_admin_credentials.dat"),
498
+ process.env.SERVER_PASSWORD
499
+ );
500
+ }
501
+ if (configurationObject.databaseCredentials) {
502
+ await encryptAndStoreFile(
503
+ JSON.stringify(configurationObject.databaseCredentials),
504
+ import_path4.default.join(getAppDataDirectory(), "database_credentials.dat"),
505
+ process.env.SERVER_PASSWORD
506
+ );
507
+ }
508
+ if (configurationObject.permissions) {
509
+ await encryptAndStoreFile(
510
+ JSON.stringify(configurationObject.permissions),
511
+ import_path4.default.join(getAppDataDirectory(), "permissions.dat"),
512
+ process.env.SERVER_PASSWORD
513
+ );
514
+ }
515
+ if (configurationObject.smtpCredentials) {
516
+ await encryptAndStoreFile(
517
+ JSON.stringify(configurationObject.smtpCredentials),
518
+ import_path4.default.join(getAppDataDirectory(), "smtp_credentials.dat"),
519
+ process.env.SERVER_PASSWORD
520
+ );
521
+ }
522
+ }
523
+
468
524
  // Server/Utility/ExtractConfigurationForService.js
469
525
  function extractConfigurationForService() {
470
526
  const firebaseAdminCredentials = process.env.FIREBASE_ADMIN_CREDENTIALS ? JSON.parse(process.env.FIREBASE_ADMIN_CREDENTIALS) : null;
471
- const databaseCredentials = process.env.DATABASE_CREDENTIALS ? JSON.parse(process.env.databaseCredentials) : null;
527
+ const databaseCredentials = process.env.DATABASE_CREDENTIALS ? JSON.parse(process.env.DATABASE_CREDENTIALS) : null;
472
528
  const permissions = process.env.PERMISSIONS ? JSON.parse(process.env.PERMISSIONS) : null;
473
529
  const smtpCredentials = process.env.SMTP_CREDENTIALS ? JSON.parse(process.env.SMTP_CREDENTIALS) : null;
474
530
  const databaseCredentialsForService = databaseCredentials[HiveServerGlobals_default.getServiceName()] ? databaseCredentials[HiveServerGlobals_default.getServiceName()] : null;
@@ -512,7 +568,7 @@ async function promptPassword(promptText = "Enter password: ") {
512
568
 
513
569
  // Server/Utility/SetupPassword.js
514
570
  var import_fs5 = __toESM(require("fs"), 1);
515
- var import_path4 = __toESM(require("path"), 1);
571
+ var import_path5 = __toESM(require("path"), 1);
516
572
 
517
573
  // Common/Utility/GetSha512Hash.js
518
574
  var import_crypto3 = require("crypto");
@@ -523,7 +579,7 @@ function getSha512Hash(text) {
523
579
  // Server/Utility/SetupPassword.js
524
580
  async function setupPassword() {
525
581
  const appDataDirectory = getAppDataDirectory();
526
- const passwordFilePath = import_path4.default.join(appDataDirectory, "password.dat");
582
+ const passwordFilePath = import_path5.default.join(appDataDirectory, "password.dat");
527
583
  let correctPassword = null;
528
584
  if (!import_fs5.default.existsSync(passwordFilePath)) {
529
585
  while (true) {
@@ -651,9 +707,9 @@ function getClientConnectionTypeFromHostname(hostname) {
651
707
  }
652
708
 
653
709
  // Common/Utility/GetHiveUrl.js
654
- async function getHiveUrl(path6) {
655
- while (path6.startsWith("/")) {
656
- path6 = path6.substring(1);
710
+ async function getHiveUrl(path7) {
711
+ while (path7.startsWith("/")) {
712
+ path7 = path7.substring(1);
657
713
  }
658
714
  const connectionType = typeof window !== "undefined" ? getClientConnectionTypeFromHostname(window.location.hostname) : clientConnectionTypeFlags.LAN;
659
715
  const isLan = connectionType & clientConnectionTypeFlags.LAN ? true : false;
@@ -662,9 +718,9 @@ async function getHiveUrl(path6) {
662
718
  const response = await fetch(url, { method: "GET" });
663
719
  if (response.ok) {
664
720
  const hiveAddress = await response.json();
665
- return hiveAddress + "/" + path6;
721
+ return hiveAddress + "/" + path7;
666
722
  }
667
- return "http://127.0.0.1:49152/" + path6;
723
+ return "http://127.0.0.1:49152/" + path7;
668
724
  }
669
725
 
670
726
  // Server/Utility/ParseRequestBody.js
@@ -672,6 +728,7 @@ async function parseRequestBody(request) {
672
728
  if (typeof request.body == "object") {
673
729
  return request.body;
674
730
  }
731
+ let body = "";
675
732
  for await (const chunk of request) {
676
733
  body += chunk;
677
734
  }
@@ -686,6 +743,7 @@ async function parseRequestBody(request) {
686
743
  }
687
744
 
688
745
  // Server/RequestHandlers/HandleLogin.js
746
+ var import_cookie = __toESM(require_dist(), 1);
689
747
  async function handleLogin(request, response) {
690
748
  await parseRequestBody(request);
691
749
  const userId = request.body.userId;
@@ -707,15 +765,17 @@ async function handleLogin(request, response) {
707
765
  } else if (loginResponse.status == 200) {
708
766
  const sessionTokenObject = await loginResponse.json();
709
767
  const sessionToken = sessionTokenObject.sessionToken;
710
- response.cookie(
768
+ const cookieHeader = (0, import_cookie.serialize)(
711
769
  "sessionToken",
712
770
  sessionToken,
713
771
  {
714
772
  httpOnly: true,
715
773
  sameSite: "lax",
716
- maxAge: 7 * 24 * 60 * 60 * 1e3
774
+ maxAge: 7 * 24 * 60 * 60,
775
+ path: "/"
717
776
  }
718
777
  );
778
+ response.setHeader("Set-Cookie", cookieHeader);
719
779
  if (!request.cookies["usesCookies"]) {
720
780
  response.setHeader("x-session-token", sessionToken);
721
781
  }
@@ -725,9 +785,12 @@ async function handleLogin(request, response) {
725
785
  }
726
786
 
727
787
  // Server/HandleHiveRequests.js
728
- var import_path5 = __toESM(require("path"), 1);
788
+ var import_path6 = __toESM(require("path"), 1);
729
789
  var import_fs6 = __toESM(require("fs"), 1);
730
790
 
791
+ // Server/Authentication/IsLoggedIn.js
792
+ var import_cookie2 = __toESM(require_dist(), 1);
793
+
731
794
  // Server/Utility/ParseRequestCookies.js
732
795
  async function parseRequestCookies(request) {
733
796
  if (typeof request.cookies === "object") {
@@ -752,7 +815,6 @@ async function parseRequestCookies(request) {
752
815
  }
753
816
 
754
817
  // Server/Authentication/IsLoggedIn.js
755
- var import_cookie = __toESM(require_dist(), 1);
756
818
  async function isLoggedIn(request, response, bSendResponse = false) {
757
819
  await parseRequestCookies(request);
758
820
  const cookies = request.cookies;
@@ -785,7 +847,7 @@ async function isLoggedIn(request, response, bSendResponse = false) {
785
847
  const sessionJson = isLoggedInResponseJson.session;
786
848
  if (isLoggedInResponseJson.refresh) {
787
849
  const newSessionToken = sessionJson.sessionToken;
788
- const cookieHeader = (0, import_cookie.serialize)(
850
+ const cookieHeader = (0, import_cookie2.serialize)(
789
851
  "sessionToken",
790
852
  newSessionToken,
791
853
  {
@@ -841,6 +903,7 @@ async function handleLogout(request, response) {
841
903
  }
842
904
 
843
905
  // Server/Authentication/IsLoggedInWithPermission.js
906
+ var import_cookie3 = __toESM(require_dist(), 1);
844
907
  async function isLoggedInWithPermission(request, response, bSendResponse = false) {
845
908
  await parseRequestCookies(request);
846
909
  await parseRequestBody(request);
@@ -884,15 +947,17 @@ async function isLoggedInWithPermission(request, response, bSendResponse = false
884
947
  const sessionJson = isLoggedInResponseJson.session;
885
948
  if (isLoggedInResponseJson.refresh) {
886
949
  const newSessionToken = sessionJson.sessionToken;
887
- response.cookie(
950
+ const cookieHeader = (0, import_cookie3.serialize)(
888
951
  "sessionToken",
889
952
  newSessionToken,
890
953
  {
891
954
  httpOnly: true,
892
955
  sameSite: "strict",
893
- maxAge: 7 * 24 * 60 * 60 * 1e3
956
+ maxAge: 7 * 24 * 60 * 60,
957
+ path: "/"
894
958
  }
895
959
  );
960
+ response.setHeader("Set-Cookie", cookieHeader);
896
961
  }
897
962
  }
898
963
  if (bSendResponse) {
@@ -937,6 +1002,37 @@ async function saveUserFilter(request, response) {
937
1002
  response.end("Unauthorized");
938
1003
  }
939
1004
 
1005
+ // Server/RequestHandlers/PushNotificationToken.js
1006
+ async function pushNotificationToken(request, response) {
1007
+ await parseRequestBody(request);
1008
+ const notificationToken = request.body.notificationToken;
1009
+ const sessionToken = request.cookies.sessionToken || request.headers["x-session-token"];
1010
+ const deviceId = request.headers["x-device-id"];
1011
+ const url = await getHiveUrl("/PushNotificationToken");
1012
+ const pushResponse = await fetch(
1013
+ url,
1014
+ {
1015
+ method: "POST",
1016
+ headers: {
1017
+ "Content-Type": "application/json",
1018
+ "x-device-id": deviceId,
1019
+ "x-session-token": sessionToken
1020
+ },
1021
+ body: JSON.stringify({
1022
+ notificationToken,
1023
+ serviceName: process.env.SERVICE_NAME
1024
+ })
1025
+ }
1026
+ );
1027
+ if (pushResponse.ok) {
1028
+ response.statusCode = 200;
1029
+ response.end();
1030
+ } else {
1031
+ response.statusCode = 500;
1032
+ response.end();
1033
+ }
1034
+ }
1035
+
940
1036
  // Server/HandleHiveRequests.js
941
1037
  async function handleHiveRequests(request, response, next) {
942
1038
  const { url, method } = request;
@@ -959,8 +1055,11 @@ async function handleHiveRequests(request, response, next) {
959
1055
  } else if (url === "/SaveUserFilter" && method === "POST") {
960
1056
  await saveUserFilter(request, response);
961
1057
  return;
1058
+ } else if (url === "/PushNotificationToken" && method === "POST") {
1059
+ pushNotificationToken(request, response);
1060
+ return;
962
1061
  } else if (url === "/hive-client.js") {
963
- const filePath = import_path5.default.join(process.cwd(), "node_modules/@hivedev/hivesdk/hive-client.js");
1062
+ const filePath = import_path6.default.join(process.cwd(), "node_modules/@hivedev/hivesdk/hive-client.js");
964
1063
  const stream = import_fs6.default.createReadStream(filePath);
965
1064
  stream.on("open", () => {
966
1065
  response.writeHead(200, { "Content-Type": "application/javascript" });
@@ -1041,6 +1140,55 @@ async function findService(serviceName) {
1041
1140
  }, RESPONSE_TIMEOUT);
1042
1141
  });
1043
1142
  }
1143
+
1144
+ // Server/Utility/RegisterService.js
1145
+ async function registerService() {
1146
+ const serviceName = HiveServerGlobals_default.getServiceName();
1147
+ HiveServerGlobals_default.setServiceUrls(
1148
+ serviceName,
1149
+ {
1150
+ local: `http://${getHostIp()}:${HiveServerGlobals_default.getServicePort()}`,
1151
+ remote: HiveServerGlobals_default.getRemoteUrl() || ""
1152
+ }
1153
+ );
1154
+ const hiveUrl = await getHiveUrl("/RegisterService");
1155
+ console.log("Registering service...");
1156
+ const registrationResponse = await fetch(
1157
+ hiveUrl,
1158
+ {
1159
+ method: "POST",
1160
+ headers: { "Content-Type": "application/json" },
1161
+ body: JSON.stringify({ serviceName, urls: HiveServerGlobals_default.getServiceUrls(serviceName) })
1162
+ }
1163
+ );
1164
+ if (registrationResponse.status != 200) {
1165
+ console.log("Failed to register service.");
1166
+ return;
1167
+ }
1168
+ const configurationUrl = await getHiveUrl("/Configuration");
1169
+ const configurationInterval = setInterval(async () => {
1170
+ const configurationResponse = await fetch(
1171
+ configurationUrl,
1172
+ {
1173
+ method: "POST",
1174
+ headers: { "Content-Type": "application/json" },
1175
+ body: JSON.stringify({ serviceName })
1176
+ }
1177
+ );
1178
+ if (configurationResponse.ok) {
1179
+ clearInterval(configurationInterval);
1180
+ const encryptedConfiguration = await configurationResponse.text();
1181
+ console.log("Configuration received.");
1182
+ const decryptedConfiguration = await decryptDataWithPassword(Buffer.from(encryptedConfiguration, "base64"), process.env.SERVER_PASSWORD);
1183
+ const configurationObject = JSON.parse(decryptedConfiguration);
1184
+ console.log("Saving configuration...");
1185
+ await saveConfiguration(configurationObject);
1186
+ console.log("Service registered.");
1187
+ } else {
1188
+ console.log("Service registration hasn't been approved yet. Please contact administrators!");
1189
+ }
1190
+ }, 2e3);
1191
+ }
1044
1192
  // Annotate the CommonJS export names for ESM import in node:
1045
1193
  0 && (module.exports = {
1046
1194
  decryptFileWithPassword,
@@ -1055,6 +1203,8 @@ async function findService(serviceName) {
1055
1203
  isLoggedInWithPermission,
1056
1204
  loadConfiguration,
1057
1205
  promptPassword,
1206
+ registerService,
1207
+ saveConfiguration,
1058
1208
  sendMail,
1059
1209
  setupPassword
1060
1210
  });
package/hive-server.js CHANGED
@@ -30,7 +30,7 @@ var require_dist = __commonJS({
30
30
  "use strict";
31
31
  Object.defineProperty(exports, "__esModule", { value: true });
32
32
  exports.parse = parse2;
33
- exports.serialize = serialize2;
33
+ exports.serialize = serialize4;
34
34
  var cookieNameRegExp = /^[\u0021-\u003A\u003C\u003E-\u007E]+$/;
35
35
  var cookieValueRegExp = /^[\u0021-\u003A\u003C-\u007E]*$/;
36
36
  var domainValueRegExp = /^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i;
@@ -88,7 +88,7 @@ var require_dist = __commonJS({
88
88
  }
89
89
  return min;
90
90
  }
91
- function serialize2(name, val, options) {
91
+ function serialize4(name, val, options) {
92
92
  const enc = options?.encode || encodeURIComponent;
93
93
  if (!cookieNameRegExp.test(name)) {
94
94
  throw new TypeError(`argument name is invalid: ${name}`);
@@ -374,47 +374,64 @@ var DatabaseConnector_default = DatabaseConnector;
374
374
  import path2 from "path";
375
375
  import fs3 from "fs";
376
376
  async function loadConfiguration() {
377
- let firebaseAdminCredentials = "";
378
- let databaseCredentials = "";
379
- let permissions = "";
380
- let smtpCredentials = "";
377
+ let firebaseAdminCredentials = null;
378
+ let databaseCredentials = null;
379
+ let permissions = null;
380
+ let smtpCredentials = null;
381
381
  const firebaseAdminCredentialsPath = path2.join(getAppDataDirectory(), "firebase_admin_credentials.dat");
382
382
  const databaseCredentialsPath = path2.join(getAppDataDirectory(), "database_credentials.dat");
383
383
  const permissionsPath = path2.join(getAppDataDirectory(), "permissions.dat");
384
384
  const smtpCredentialsPath = path2.join(getAppDataDirectory(), "smtp_credentials.dat");
385
385
  if (fs3.existsSync(firebaseAdminCredentialsPath)) {
386
- firebaseAdminCredentials = await decryptFileWithPassword(path2.join(getAppDataDirectory(), "firebase_admin_credentials.dat"), process.env.SERVER_PASSWORD);
386
+ firebaseAdminCredentials = await decryptFileWithPassword(firebaseAdminCredentialsPath, process.env.SERVER_PASSWORD);
387
387
  }
388
388
  if (fs3.existsSync(databaseCredentialsPath)) {
389
- databaseCredentials = await decryptFileWithPassword(path2.join(getAppDataDirectory(), "database_credentials.dat"), process.env.SERVER_PASSWORD);
389
+ databaseCredentials = await decryptFileWithPassword(databaseCredentialsPath, process.env.SERVER_PASSWORD);
390
390
  }
391
391
  if (fs3.existsSync(permissionsPath)) {
392
- permissions = await decryptFileWithPassword(path2.join(getAppDataDirectory(), "permissions.dat"), process.env.SERVER_PASSWORD);
392
+ permissions = await decryptFileWithPassword(permissionsPath, process.env.SERVER_PASSWORD);
393
393
  }
394
394
  if (fs3.existsSync(smtpCredentialsPath)) {
395
- smtpCredentials = await decryptFileWithPassword(path2.join(getAppDataDirectory(), "smtp_credentials.dat"), process.env.SERVER_PASSWORD);
395
+ smtpCredentials = await decryptFileWithPassword(smtpCredentialsPath, process.env.SERVER_PASSWORD);
396
396
  }
397
- process.env.FIREBASE_ADMIN_CREDENTIALS = firebaseAdminCredentials;
398
- process.env.DATABASE_CREDENTIALS = databaseCredentials;
399
- process.env.PERMISSIONS = permissions;
400
- process.env.SMTP_CREDENTIALS = smtpCredentials;
401
- try {
402
- const smtpCredentialsObject = JSON.parse(smtpCredentials);
403
- process.env.SMTP_PASSWORD = smtpCredentialsObject.password || "";
404
- } catch (e) {
405
- console.error(e);
397
+ if (firebaseAdminCredentials) {
398
+ process.env.FIREBASE_ADMIN_CREDENTIALS = firebaseAdminCredentials;
406
399
  }
407
400
  if (databaseCredentials) {
408
- databaseCredentials = JSON.parse(databaseCredentials);
409
- const hivePortalDatabaseCredentials = databaseCredentials[HiveServerGlobals_default.getServiceName()];
410
- DatabaseConnector_default.setCredentials(
411
- {
412
- host: hivePortalDatabaseCredentials.host || "127.0.0.1",
413
- username: hivePortalDatabaseCredentials.username || "",
414
- password: hivePortalDatabaseCredentials.password || "",
415
- name: hivePortalDatabaseCredentials.name || "hive"
401
+ process.env.DATABASE_CREDENTIALS = databaseCredentials;
402
+ }
403
+ if (permissions) {
404
+ process.env.PERMISSIONS = permissions;
405
+ }
406
+ if (smtpCredentials) {
407
+ process.env.SMTP_CREDENTIALS = smtpCredentials;
408
+ try {
409
+ const smtpCredentialsObject = JSON.parse(smtpCredentials);
410
+ process.env.SMTP_PASSWORD = smtpCredentialsObject.password || "";
411
+ } catch (error) {
412
+ console.error("loadConfiguration: Failed to parse SMTP credentials.", error);
413
+ }
414
+ }
415
+ if (databaseCredentials) {
416
+ try {
417
+ const parsedDatabaseCredentials = JSON.parse(databaseCredentials);
418
+ const serviceName = HiveServerGlobals_default.getServiceName();
419
+ const serviceCredentials = parsedDatabaseCredentials[serviceName];
420
+ if (!serviceCredentials) {
421
+ console.error(`loadConfiguration: No database credentials found for service "${serviceName}".`);
422
+ return;
416
423
  }
417
- );
424
+ DatabaseConnector_default.setCredentials(
425
+ {
426
+ host: serviceCredentials.host || "127.0.0.1",
427
+ username: serviceCredentials.username || "",
428
+ password: serviceCredentials.password || "",
429
+ name: serviceCredentials.name || "hive"
430
+ }
431
+ );
432
+ } catch (error) {
433
+ console.error("loadConfiguration: Failed to parse database credentials.", error);
434
+ }
418
435
  }
419
436
  }
420
437
 
@@ -440,10 +457,47 @@ async function encryptAndStoreFile(data, fullPath, password) {
440
457
  await fs4.writeFile(fullPath, payload);
441
458
  }
442
459
 
460
+ // Server/Utility/SaveConfiguration.js
461
+ import path4 from "path";
462
+ async function saveConfiguration(configurationObject) {
463
+ if (!configurationObject) {
464
+ console.error("saveConfiguration: No configuration object provided.");
465
+ return;
466
+ }
467
+ if (configurationObject.firebaseAdminCredentials) {
468
+ await encryptAndStoreFile(
469
+ JSON.stringify(configurationObject.firebaseAdminCredentials),
470
+ path4.join(getAppDataDirectory(), "firebase_admin_credentials.dat"),
471
+ process.env.SERVER_PASSWORD
472
+ );
473
+ }
474
+ if (configurationObject.databaseCredentials) {
475
+ await encryptAndStoreFile(
476
+ JSON.stringify(configurationObject.databaseCredentials),
477
+ path4.join(getAppDataDirectory(), "database_credentials.dat"),
478
+ process.env.SERVER_PASSWORD
479
+ );
480
+ }
481
+ if (configurationObject.permissions) {
482
+ await encryptAndStoreFile(
483
+ JSON.stringify(configurationObject.permissions),
484
+ path4.join(getAppDataDirectory(), "permissions.dat"),
485
+ process.env.SERVER_PASSWORD
486
+ );
487
+ }
488
+ if (configurationObject.smtpCredentials) {
489
+ await encryptAndStoreFile(
490
+ JSON.stringify(configurationObject.smtpCredentials),
491
+ path4.join(getAppDataDirectory(), "smtp_credentials.dat"),
492
+ process.env.SERVER_PASSWORD
493
+ );
494
+ }
495
+ }
496
+
443
497
  // Server/Utility/ExtractConfigurationForService.js
444
498
  function extractConfigurationForService() {
445
499
  const firebaseAdminCredentials = process.env.FIREBASE_ADMIN_CREDENTIALS ? JSON.parse(process.env.FIREBASE_ADMIN_CREDENTIALS) : null;
446
- const databaseCredentials = process.env.DATABASE_CREDENTIALS ? JSON.parse(process.env.databaseCredentials) : null;
500
+ const databaseCredentials = process.env.DATABASE_CREDENTIALS ? JSON.parse(process.env.DATABASE_CREDENTIALS) : null;
447
501
  const permissions = process.env.PERMISSIONS ? JSON.parse(process.env.PERMISSIONS) : null;
448
502
  const smtpCredentials = process.env.SMTP_CREDENTIALS ? JSON.parse(process.env.SMTP_CREDENTIALS) : null;
449
503
  const databaseCredentialsForService = databaseCredentials[HiveServerGlobals_default.getServiceName()] ? databaseCredentials[HiveServerGlobals_default.getServiceName()] : null;
@@ -487,7 +541,7 @@ async function promptPassword(promptText = "Enter password: ") {
487
541
 
488
542
  // Server/Utility/SetupPassword.js
489
543
  import fs5 from "fs";
490
- import path4 from "path";
544
+ import path5 from "path";
491
545
 
492
546
  // Common/Utility/GetSha512Hash.js
493
547
  import { createHash } from "crypto";
@@ -498,7 +552,7 @@ function getSha512Hash(text) {
498
552
  // Server/Utility/SetupPassword.js
499
553
  async function setupPassword() {
500
554
  const appDataDirectory = getAppDataDirectory();
501
- const passwordFilePath = path4.join(appDataDirectory, "password.dat");
555
+ const passwordFilePath = path5.join(appDataDirectory, "password.dat");
502
556
  let correctPassword = null;
503
557
  if (!fs5.existsSync(passwordFilePath)) {
504
558
  while (true) {
@@ -626,9 +680,9 @@ function getClientConnectionTypeFromHostname(hostname) {
626
680
  }
627
681
 
628
682
  // Common/Utility/GetHiveUrl.js
629
- async function getHiveUrl(path6) {
630
- while (path6.startsWith("/")) {
631
- path6 = path6.substring(1);
683
+ async function getHiveUrl(path7) {
684
+ while (path7.startsWith("/")) {
685
+ path7 = path7.substring(1);
632
686
  }
633
687
  const connectionType = typeof window !== "undefined" ? getClientConnectionTypeFromHostname(window.location.hostname) : clientConnectionTypeFlags.LAN;
634
688
  const isLan = connectionType & clientConnectionTypeFlags.LAN ? true : false;
@@ -637,9 +691,9 @@ async function getHiveUrl(path6) {
637
691
  const response = await fetch(url, { method: "GET" });
638
692
  if (response.ok) {
639
693
  const hiveAddress = await response.json();
640
- return hiveAddress + "/" + path6;
694
+ return hiveAddress + "/" + path7;
641
695
  }
642
- return "http://127.0.0.1:49152/" + path6;
696
+ return "http://127.0.0.1:49152/" + path7;
643
697
  }
644
698
 
645
699
  // Server/Utility/ParseRequestBody.js
@@ -647,6 +701,7 @@ async function parseRequestBody(request) {
647
701
  if (typeof request.body == "object") {
648
702
  return request.body;
649
703
  }
704
+ let body = "";
650
705
  for await (const chunk of request) {
651
706
  body += chunk;
652
707
  }
@@ -661,6 +716,7 @@ async function parseRequestBody(request) {
661
716
  }
662
717
 
663
718
  // Server/RequestHandlers/HandleLogin.js
719
+ var import_cookie = __toESM(require_dist(), 1);
664
720
  async function handleLogin(request, response) {
665
721
  await parseRequestBody(request);
666
722
  const userId = request.body.userId;
@@ -682,15 +738,17 @@ async function handleLogin(request, response) {
682
738
  } else if (loginResponse.status == 200) {
683
739
  const sessionTokenObject = await loginResponse.json();
684
740
  const sessionToken = sessionTokenObject.sessionToken;
685
- response.cookie(
741
+ const cookieHeader = (0, import_cookie.serialize)(
686
742
  "sessionToken",
687
743
  sessionToken,
688
744
  {
689
745
  httpOnly: true,
690
746
  sameSite: "lax",
691
- maxAge: 7 * 24 * 60 * 60 * 1e3
747
+ maxAge: 7 * 24 * 60 * 60,
748
+ path: "/"
692
749
  }
693
750
  );
751
+ response.setHeader("Set-Cookie", cookieHeader);
694
752
  if (!request.cookies["usesCookies"]) {
695
753
  response.setHeader("x-session-token", sessionToken);
696
754
  }
@@ -700,9 +758,12 @@ async function handleLogin(request, response) {
700
758
  }
701
759
 
702
760
  // Server/HandleHiveRequests.js
703
- import path5, { parse } from "path";
761
+ import path6, { parse } from "path";
704
762
  import fs6 from "fs";
705
763
 
764
+ // Server/Authentication/IsLoggedIn.js
765
+ var import_cookie2 = __toESM(require_dist(), 1);
766
+
706
767
  // Server/Utility/ParseRequestCookies.js
707
768
  async function parseRequestCookies(request) {
708
769
  if (typeof request.cookies === "object") {
@@ -727,7 +788,6 @@ async function parseRequestCookies(request) {
727
788
  }
728
789
 
729
790
  // Server/Authentication/IsLoggedIn.js
730
- var import_cookie = __toESM(require_dist(), 1);
731
791
  async function isLoggedIn(request, response, bSendResponse = false) {
732
792
  await parseRequestCookies(request);
733
793
  const cookies = request.cookies;
@@ -760,7 +820,7 @@ async function isLoggedIn(request, response, bSendResponse = false) {
760
820
  const sessionJson = isLoggedInResponseJson.session;
761
821
  if (isLoggedInResponseJson.refresh) {
762
822
  const newSessionToken = sessionJson.sessionToken;
763
- const cookieHeader = (0, import_cookie.serialize)(
823
+ const cookieHeader = (0, import_cookie2.serialize)(
764
824
  "sessionToken",
765
825
  newSessionToken,
766
826
  {
@@ -816,6 +876,7 @@ async function handleLogout(request, response) {
816
876
  }
817
877
 
818
878
  // Server/Authentication/IsLoggedInWithPermission.js
879
+ var import_cookie3 = __toESM(require_dist(), 1);
819
880
  async function isLoggedInWithPermission(request, response, bSendResponse = false) {
820
881
  await parseRequestCookies(request);
821
882
  await parseRequestBody(request);
@@ -859,15 +920,17 @@ async function isLoggedInWithPermission(request, response, bSendResponse = false
859
920
  const sessionJson = isLoggedInResponseJson.session;
860
921
  if (isLoggedInResponseJson.refresh) {
861
922
  const newSessionToken = sessionJson.sessionToken;
862
- response.cookie(
923
+ const cookieHeader = (0, import_cookie3.serialize)(
863
924
  "sessionToken",
864
925
  newSessionToken,
865
926
  {
866
927
  httpOnly: true,
867
928
  sameSite: "strict",
868
- maxAge: 7 * 24 * 60 * 60 * 1e3
929
+ maxAge: 7 * 24 * 60 * 60,
930
+ path: "/"
869
931
  }
870
932
  );
933
+ response.setHeader("Set-Cookie", cookieHeader);
871
934
  }
872
935
  }
873
936
  if (bSendResponse) {
@@ -912,6 +975,37 @@ async function saveUserFilter(request, response) {
912
975
  response.end("Unauthorized");
913
976
  }
914
977
 
978
+ // Server/RequestHandlers/PushNotificationToken.js
979
+ async function pushNotificationToken(request, response) {
980
+ await parseRequestBody(request);
981
+ const notificationToken = request.body.notificationToken;
982
+ const sessionToken = request.cookies.sessionToken || request.headers["x-session-token"];
983
+ const deviceId = request.headers["x-device-id"];
984
+ const url = await getHiveUrl("/PushNotificationToken");
985
+ const pushResponse = await fetch(
986
+ url,
987
+ {
988
+ method: "POST",
989
+ headers: {
990
+ "Content-Type": "application/json",
991
+ "x-device-id": deviceId,
992
+ "x-session-token": sessionToken
993
+ },
994
+ body: JSON.stringify({
995
+ notificationToken,
996
+ serviceName: process.env.SERVICE_NAME
997
+ })
998
+ }
999
+ );
1000
+ if (pushResponse.ok) {
1001
+ response.statusCode = 200;
1002
+ response.end();
1003
+ } else {
1004
+ response.statusCode = 500;
1005
+ response.end();
1006
+ }
1007
+ }
1008
+
915
1009
  // Server/HandleHiveRequests.js
916
1010
  async function handleHiveRequests(request, response, next) {
917
1011
  const { url, method } = request;
@@ -934,8 +1028,11 @@ async function handleHiveRequests(request, response, next) {
934
1028
  } else if (url === "/SaveUserFilter" && method === "POST") {
935
1029
  await saveUserFilter(request, response);
936
1030
  return;
1031
+ } else if (url === "/PushNotificationToken" && method === "POST") {
1032
+ pushNotificationToken(request, response);
1033
+ return;
937
1034
  } else if (url === "/hive-client.js") {
938
- const filePath = path5.join(process.cwd(), "node_modules/@hivedev/hivesdk/hive-client.js");
1035
+ const filePath = path6.join(process.cwd(), "node_modules/@hivedev/hivesdk/hive-client.js");
939
1036
  const stream = fs6.createReadStream(filePath);
940
1037
  stream.on("open", () => {
941
1038
  response.writeHead(200, { "Content-Type": "application/javascript" });
@@ -1016,6 +1113,55 @@ async function findService(serviceName) {
1016
1113
  }, RESPONSE_TIMEOUT);
1017
1114
  });
1018
1115
  }
1116
+
1117
+ // Server/Utility/RegisterService.js
1118
+ async function registerService() {
1119
+ const serviceName = HiveServerGlobals_default.getServiceName();
1120
+ HiveServerGlobals_default.setServiceUrls(
1121
+ serviceName,
1122
+ {
1123
+ local: `http://${getHostIp()}:${HiveServerGlobals_default.getServicePort()}`,
1124
+ remote: HiveServerGlobals_default.getRemoteUrl() || ""
1125
+ }
1126
+ );
1127
+ const hiveUrl = await getHiveUrl("/RegisterService");
1128
+ console.log("Registering service...");
1129
+ const registrationResponse = await fetch(
1130
+ hiveUrl,
1131
+ {
1132
+ method: "POST",
1133
+ headers: { "Content-Type": "application/json" },
1134
+ body: JSON.stringify({ serviceName, urls: HiveServerGlobals_default.getServiceUrls(serviceName) })
1135
+ }
1136
+ );
1137
+ if (registrationResponse.status != 200) {
1138
+ console.log("Failed to register service.");
1139
+ return;
1140
+ }
1141
+ const configurationUrl = await getHiveUrl("/Configuration");
1142
+ const configurationInterval = setInterval(async () => {
1143
+ const configurationResponse = await fetch(
1144
+ configurationUrl,
1145
+ {
1146
+ method: "POST",
1147
+ headers: { "Content-Type": "application/json" },
1148
+ body: JSON.stringify({ serviceName })
1149
+ }
1150
+ );
1151
+ if (configurationResponse.ok) {
1152
+ clearInterval(configurationInterval);
1153
+ const encryptedConfiguration = await configurationResponse.text();
1154
+ console.log("Configuration received.");
1155
+ const decryptedConfiguration = await decryptDataWithPassword(Buffer.from(encryptedConfiguration, "base64"), process.env.SERVER_PASSWORD);
1156
+ const configurationObject = JSON.parse(decryptedConfiguration);
1157
+ console.log("Saving configuration...");
1158
+ await saveConfiguration(configurationObject);
1159
+ console.log("Service registered.");
1160
+ } else {
1161
+ console.log("Service registration hasn't been approved yet. Please contact administrators!");
1162
+ }
1163
+ }, 2e3);
1164
+ }
1019
1165
  export {
1020
1166
  decryptFileWithPassword,
1021
1167
  encryptAndStoreFile,
@@ -1029,6 +1175,8 @@ export {
1029
1175
  isLoggedInWithPermission,
1030
1176
  loadConfiguration,
1031
1177
  promptPassword,
1178
+ registerService,
1179
+ saveConfiguration,
1032
1180
  sendMail,
1033
1181
  setupPassword
1034
1182
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hivedev/hivesdk",
3
3
  "type": "module",
4
- "version": "1.0.33",
4
+ "version": "1.0.34",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
7
7
  "scripts": {