daveappserver 0.5.56 → 0.6.0

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.
Files changed (2) hide show
  1. package/appserver.js +148 -20
  2. package/package.json +3 -2
package/appserver.js CHANGED
@@ -1,4 +1,4 @@
1
- var myVersion = "0.5.56", myProductName = "daveAppServer";
1
+ var myVersion = "0.6.0", myProductName = "daveAppServer";
2
2
 
3
3
  exports.start = startup;
4
4
  exports.notifySocketSubscribers = notifySocketSubscribers;
@@ -22,6 +22,7 @@ const filesystem = require ("davefilesystem");
22
22
  const folderToJson = require ("foldertojson");
23
23
  const zip = require ("davezip");
24
24
  const qs = require ("querystring");
25
+ const mail = require ("davemail");
25
26
 
26
27
  const whenStart = new Date ();
27
28
 
@@ -51,7 +52,14 @@ var config = {
51
52
 
52
53
  userAgent: myProductName + " v" + myVersion, //11/8/21 by DW
53
54
 
54
- whitelist: undefined //7/21/22 by DW
55
+ whitelist: undefined, //7/21/22 by DW
56
+
57
+ confirmEmailSubject: "FeedLand confirmation", //12/7/22 by DW
58
+ fnameEmailTemplate: "emailtemplate.html",
59
+ operationToConfirm: "add your email address to your FeedLand user profile",
60
+ mailSender: "dave@scripting.com",
61
+ dataFolder: "data/",
62
+ confirmationExpiresAfter: 60 * 60 //emails expire after an hour
55
63
  };
56
64
  const fnameConfig = "config.json";
57
65
 
@@ -60,10 +68,34 @@ var stats = {
60
68
  whenLastStart: undefined,
61
69
  ctWrites: 0,
62
70
  ctHits: 0, ctHitsToday: 0, ctHitsThisRun:0,
63
- whenLastHit: new Date (0)
71
+ whenLastHit: new Date (0),
72
+ pendingConfirmations: new Array () //12/7/22 by DW
64
73
  };
65
74
  const fnameStats = "stats.json";
66
75
 
76
+
77
+
78
+ function userIsWhitelisted (screenname, callback) { //9/16/22 by DW
79
+ fs.readFile (fnameConfig, function (err, jsontext) {
80
+ var flWhitelisted = false;
81
+ if (!err) {
82
+ var jstruct;
83
+ try {
84
+ jstruct = JSON.parse (jsontext);
85
+ if (jstruct.whitelist === undefined) { //no whitelist
86
+ flWhitelisted = true;
87
+ }
88
+ else {
89
+ flWhitelisted = jstruct.whitelist.includes (screenname);
90
+ }
91
+ }
92
+ catch (err) {
93
+ }
94
+ }
95
+ console.log ("userIsWhitelisted: screenname == " + screenname + ", flWhitelisted == " + flWhitelisted);
96
+ callback (undefined, {flWhitelisted});
97
+ });
98
+ }
67
99
  function statsChanged () {
68
100
  flStatsChanged = true;
69
101
  }
@@ -901,6 +933,89 @@ function cleanFileStats (stats) { //4/19/21 by DW
901
933
  }
902
934
  });
903
935
  }
936
+ //email registration -- 12/7/22 by DW
937
+ function sendConfirmingEmail (email, screenname, callback) {
938
+ const magicString = utils.getRandomPassword (10);
939
+ const urlWebApp = "http://" + config.myDomain + "/";
940
+ console.log ("sendConfirmingEmail: email == " + email + ", urlWebApp == " + urlWebApp);
941
+ var obj = {
942
+ magicString: magicString,
943
+ email: email,
944
+ flDeleted: false,
945
+ screenname,
946
+ when: new Date ()
947
+ };
948
+ stats.pendingConfirmations.push (obj);
949
+ statsChanged ();
950
+ console.log ("sendConfirmingEmail: obj == " + utils.jsonStringify (obj));
951
+ var params = {
952
+ title: config.confirmEmailSubject,
953
+ operationToConfirm: config.operationToConfirm,
954
+ confirmationUrl: urlWebApp + "userconfirms?emailConfirmCode=" + encodeURIComponent (magicString)
955
+ };
956
+ fs.readFile (config.fnameEmailTemplate, function (err, emailTemplate) {
957
+ if (err) {
958
+ const message = "Error reading email template.";
959
+ console.log ("sendConfirmingEmail: err.message == " + err.message);
960
+ callback ({message});
961
+ }
962
+ else {
963
+ var mailtext = utils.multipleReplaceAll (emailTemplate.toString (), params, false, "[%", "%]");
964
+ mail.send (email, params.title, mailtext, config.mailSender, function (err, data) {
965
+ if (err) {
966
+ callback (err);
967
+ }
968
+ else {
969
+ callback (undefined, obj);
970
+ }
971
+ });
972
+ const f = config.dataFolder + "lastmail.html";
973
+ utils.sureFilePath (f, function () {
974
+ fs.writeFile (f, mailtext, function (err) {
975
+ });
976
+ });
977
+ }
978
+ });
979
+ }
980
+ function receiveConfirmation (emailConfirmCode, callback) {
981
+ const urlWebApp = "http://" + config.myDomain + "/";
982
+ var urlRedirect = undefined;
983
+ stats.pendingConfirmations.forEach (function (item) {
984
+ if (item.magicString == emailConfirmCode) {
985
+ console.log (utils.jsonStringify (item));
986
+
987
+
988
+ if (config.addEmailToUserInDatabase !== undefined) {
989
+ config.addEmailToUserInDatabase (item.screenname, item.email, item.magicString);
990
+ }
991
+
992
+ urlRedirect = urlWebApp + "?emailconfirmed=true&email=" + item.email + "&code=" + item.magicString;
993
+
994
+ item.flDeleted = true;
995
+ }
996
+ });
997
+ if (urlRedirect === undefined) {
998
+ urlRedirect = urlWebApp + "?failedLogin=true"; //add an error message here
999
+ }
1000
+ console.log ("receiveConfirmation: urlRedirect == " + urlRedirect);
1001
+ callback (urlRedirect);
1002
+ }
1003
+ function checkPendingConfirmations () {
1004
+ var flChanged = false;
1005
+ var newArray = new Array ();
1006
+ stats.pendingConfirmations.forEach (function (item) {
1007
+ if ((!item.flDeleted) && (utils.secondsSince (item.when) < config.confirmationExpiresAfter)) {
1008
+ newArray.push (item);
1009
+ }
1010
+ else {
1011
+ flChanged = true;
1012
+ }
1013
+ });
1014
+ if (flChanged) {
1015
+ stats.pendingConfirmations = newArray;
1016
+ statsChanged ();
1017
+ }
1018
+ }
904
1019
 
905
1020
  function startup (options, callback) {
906
1021
  function readConfig (f, theConfig, flReportError, callback) {
@@ -1075,14 +1190,26 @@ function startup (options, callback) {
1075
1190
  }
1076
1191
  }
1077
1192
  function callWithScreenname (callback) {
1078
- davetwitter.getScreenName (token, secret, function (screenname) {
1079
- if (screenname === undefined) {
1080
- returnError ({message: "Can't do the thing you want because the accessToken is not valid."});
1081
- }
1082
- else {
1083
- callback (screenname);
1084
- }
1085
- });
1193
+ if (config.getScreenname === undefined) {
1194
+ davetwitter.getScreenName (token, secret, function (screenname) {
1195
+ if (screenname === undefined) {
1196
+ returnError ({message: "Can't do the thing you want because the accessToken is not valid."});
1197
+ }
1198
+ else {
1199
+ callback (screenname);
1200
+ }
1201
+ });
1202
+ }
1203
+ else {
1204
+ config.getScreenname (params, function (err, screenname) { //12/23/22 by DW
1205
+ if (err) {
1206
+ returnError (err);
1207
+ }
1208
+ else {
1209
+ callback (screenname);
1210
+ }
1211
+ });
1212
+ }
1086
1213
  }
1087
1214
 
1088
1215
  if (config.httpRequest !== undefined) {
@@ -1244,17 +1371,17 @@ function startup (options, callback) {
1244
1371
  return (true);
1245
1372
  case "/useriswhitelisted": //7/21/22 by DW
1246
1373
  callWithScreenname (function (screenname) {
1247
- var flWhitelisted = false;
1248
- if (config.whitelist === undefined) {
1249
- flWhitelisted = true;
1250
- }
1251
- else {
1252
- flWhitelisted = config.whitelist.includes (screenname);
1253
- }
1254
- console.log ("/useriswhitelisted: screenname == " + screenname + ", flWhitelisted == " + flWhitelisted);
1255
- returnData ({flWhitelisted});
1374
+ userIsWhitelisted (screenname, httpReturn); //9/16/22 by DW
1256
1375
  });
1257
1376
  return (true);
1377
+ case "/sendconfirmingemail": //12/7/22 by DW
1378
+ callWithScreenname (function (screenname) {
1379
+ sendConfirmingEmail (params.email, screenname, httpReturn);
1380
+ });
1381
+ return (true);
1382
+ case "/userconfirms": //12/7/22 by DW
1383
+ receiveConfirmation (params.emailConfirmCode, httpReturnRedirect);
1384
+ return (true);
1258
1385
 
1259
1386
  }
1260
1387
  break;
@@ -1325,6 +1452,7 @@ function startup (options, callback) {
1325
1452
  if (now.getMinutes () == 0) {
1326
1453
  console.log ("\n" + now.toLocaleTimeString () + ": " + config.productName + " v" + config.version + " running on port " + config.port + ".\n");
1327
1454
  }
1455
+ checkPendingConfirmations (); //12/7/22 by DW
1328
1456
  }
1329
1457
  function everySecond () {
1330
1458
  if (flStatsChanged) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "daveappserver",
3
3
  "description": "Factored code that was appearing in all my servers.",
4
- "version": "0.5.56",
4
+ "version": "0.6.0",
5
5
  "main": "appserver.js",
6
6
  "repository": {
7
7
  "type" : "git",
@@ -20,6 +20,7 @@
20
20
  "foldertojson": "*",
21
21
  "davetwitter": "*",
22
22
  "davezip": "*",
23
- "davehttp": "*"
23
+ "davehttp": "*",
24
+ "davemail": "*"
24
25
  }
25
26
  }