daveappserver 0.5.57 → 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 +124 -11
  2. package/package.json +3 -2
package/appserver.js CHANGED
@@ -1,4 +1,4 @@
1
- var myVersion = "0.5.57", 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,7 +68,8 @@ 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
 
@@ -924,6 +933,89 @@ function cleanFileStats (stats) { //4/19/21 by DW
924
933
  }
925
934
  });
926
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
+ }
927
1019
 
928
1020
  function startup (options, callback) {
929
1021
  function readConfig (f, theConfig, flReportError, callback) {
@@ -1098,14 +1190,26 @@ function startup (options, callback) {
1098
1190
  }
1099
1191
  }
1100
1192
  function callWithScreenname (callback) {
1101
- davetwitter.getScreenName (token, secret, function (screenname) {
1102
- if (screenname === undefined) {
1103
- returnError ({message: "Can't do the thing you want because the accessToken is not valid."});
1104
- }
1105
- else {
1106
- callback (screenname);
1107
- }
1108
- });
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
+ }
1109
1213
  }
1110
1214
 
1111
1215
  if (config.httpRequest !== undefined) {
@@ -1270,6 +1374,14 @@ function startup (options, callback) {
1270
1374
  userIsWhitelisted (screenname, httpReturn); //9/16/22 by DW
1271
1375
  });
1272
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);
1273
1385
 
1274
1386
  }
1275
1387
  break;
@@ -1340,6 +1452,7 @@ function startup (options, callback) {
1340
1452
  if (now.getMinutes () == 0) {
1341
1453
  console.log ("\n" + now.toLocaleTimeString () + ": " + config.productName + " v" + config.version + " running on port " + config.port + ".\n");
1342
1454
  }
1455
+ checkPendingConfirmations (); //12/7/22 by DW
1343
1456
  }
1344
1457
  function everySecond () {
1345
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.57",
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
  }