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.
- package/appserver.js +148 -20
- package/package.json +3 -2
package/appserver.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var myVersion = "0.
|
|
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
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
}
|