daveappserver 0.5.57 → 0.6.1
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/appserver.js +128 -11
- package/package.json +3 -2
package/appserver.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var myVersion = "0.
|
|
1
|
+
var myVersion = "0.6.1", 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,93 @@ 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, flFoundConfirm = false;
|
|
983
|
+
stats.pendingConfirmations.forEach (function (item) {
|
|
984
|
+
if (item.magicString == emailConfirmCode) {
|
|
985
|
+
if (config.addEmailToUserInDatabase !== undefined) {
|
|
986
|
+
config.addEmailToUserInDatabase (item.screenname, item.email, item.magicString, function (err, emailSecret) {
|
|
987
|
+
if (err) {
|
|
988
|
+
urlRedirect = urlWebApp + "?failedLogin=true&message=" + encodeURIComponent (err.message);
|
|
989
|
+
}
|
|
990
|
+
else {
|
|
991
|
+
urlRedirect = urlWebApp + "?emailconfirmed=true&email=" + item.email + "&code=" + encodeURIComponent (emailSecret);
|
|
992
|
+
item.flDeleted = true;
|
|
993
|
+
}
|
|
994
|
+
callback (urlRedirect);
|
|
995
|
+
});
|
|
996
|
+
}
|
|
997
|
+
flFoundConfirm = true;
|
|
998
|
+
}
|
|
999
|
+
});
|
|
1000
|
+
if (!flFoundConfirm) {
|
|
1001
|
+
if (urlRedirect === undefined) {
|
|
1002
|
+
urlRedirect = urlWebApp + "?failedLogin=true&message=" + encodeURIComponent ("Can't find the pending confirmation.");
|
|
1003
|
+
}
|
|
1004
|
+
callback (urlRedirect);
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
function checkPendingConfirmations () {
|
|
1008
|
+
var flChanged = false;
|
|
1009
|
+
var newArray = new Array ();
|
|
1010
|
+
stats.pendingConfirmations.forEach (function (item) {
|
|
1011
|
+
if ((!item.flDeleted) && (utils.secondsSince (item.when) < config.confirmationExpiresAfter)) {
|
|
1012
|
+
newArray.push (item);
|
|
1013
|
+
}
|
|
1014
|
+
else {
|
|
1015
|
+
flChanged = true;
|
|
1016
|
+
}
|
|
1017
|
+
});
|
|
1018
|
+
if (flChanged) {
|
|
1019
|
+
stats.pendingConfirmations = newArray;
|
|
1020
|
+
statsChanged ();
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
927
1023
|
|
|
928
1024
|
function startup (options, callback) {
|
|
929
1025
|
function readConfig (f, theConfig, flReportError, callback) {
|
|
@@ -1098,14 +1194,26 @@ function startup (options, callback) {
|
|
|
1098
1194
|
}
|
|
1099
1195
|
}
|
|
1100
1196
|
function callWithScreenname (callback) {
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1197
|
+
if (config.getScreenname === undefined) {
|
|
1198
|
+
davetwitter.getScreenName (token, secret, function (screenname) {
|
|
1199
|
+
if (screenname === undefined) {
|
|
1200
|
+
returnError ({message: "Can't do the thing you want because the accessToken is not valid."});
|
|
1201
|
+
}
|
|
1202
|
+
else {
|
|
1203
|
+
callback (screenname);
|
|
1204
|
+
}
|
|
1205
|
+
});
|
|
1206
|
+
}
|
|
1207
|
+
else {
|
|
1208
|
+
config.getScreenname (params, function (err, screenname) { //12/23/22 by DW
|
|
1209
|
+
if (err) {
|
|
1210
|
+
returnError (err);
|
|
1211
|
+
}
|
|
1212
|
+
else {
|
|
1213
|
+
callback (screenname);
|
|
1214
|
+
}
|
|
1215
|
+
});
|
|
1216
|
+
}
|
|
1109
1217
|
}
|
|
1110
1218
|
|
|
1111
1219
|
if (config.httpRequest !== undefined) {
|
|
@@ -1270,6 +1378,14 @@ function startup (options, callback) {
|
|
|
1270
1378
|
userIsWhitelisted (screenname, httpReturn); //9/16/22 by DW
|
|
1271
1379
|
});
|
|
1272
1380
|
return (true);
|
|
1381
|
+
case "/sendconfirmingemail": //12/7/22 by DW
|
|
1382
|
+
callWithScreenname (function (screenname) {
|
|
1383
|
+
sendConfirmingEmail (params.email, screenname, httpReturn);
|
|
1384
|
+
});
|
|
1385
|
+
return (true);
|
|
1386
|
+
case "/userconfirms": //12/7/22 by DW
|
|
1387
|
+
receiveConfirmation (params.emailConfirmCode, httpReturnRedirect);
|
|
1388
|
+
return (true);
|
|
1273
1389
|
|
|
1274
1390
|
}
|
|
1275
1391
|
break;
|
|
@@ -1340,6 +1456,7 @@ function startup (options, callback) {
|
|
|
1340
1456
|
if (now.getMinutes () == 0) {
|
|
1341
1457
|
console.log ("\n" + now.toLocaleTimeString () + ": " + config.productName + " v" + config.version + " running on port " + config.port + ".\n");
|
|
1342
1458
|
}
|
|
1459
|
+
checkPendingConfirmations (); //12/7/22 by DW
|
|
1343
1460
|
}
|
|
1344
1461
|
function everySecond () {
|
|
1345
1462
|
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.
|
|
4
|
+
"version": "0.6.1",
|
|
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
|
}
|