aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Dockerfile4
-rw-r--r--docker-compose-test.yaml41
-rw-r--r--docker-compose.yaml39
-rw-r--r--model.js62
-rw-r--r--package-lock.json485
-rw-r--r--package.json1
-rw-r--r--put_in_db.js26
-rwxr-xr-xserver.js144
-rw-r--r--static/about.html12
-rw-r--r--views/archive.ejs4
-rw-r--r--views/index.ejs13
-rw-r--r--views/rss_feed.pug21
-rw-r--r--views/rss_feed_v2.pug22
13 files changed, 818 insertions, 56 deletions
diff --git a/Dockerfile b/Dockerfile
index 23e5984..551946e 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -3,7 +3,7 @@ RUN apk add openssl
WORKDIR /certs
RUN openssl req -nodes -new -x509 -subj="/C=US/ST=Denial/L=springfield/O=Dis/CN=localhost" -keyout server.key -out server.cert
-FROM node:lts-alpine3.13
+FROM node:lts-alpine3.15
COPY --from=certbuilder /certs/ /certs
COPY ./package.* /server/
RUN cd /server && npm install --production
@@ -11,6 +11,6 @@ COPY ./css /server/css/
COPY ./views /server/views/
COPY ./static /server/static/
COPY ./mds /server/mds/
-COPY ./server.js /server/
+COPY ./*.js /server/
ENTRYPOINT ["/server/server.js"]
EXPOSE 9000
diff --git a/docker-compose-test.yaml b/docker-compose-test.yaml
index 73981ef..fceb9b9 100644
--- a/docker-compose-test.yaml
+++ b/docker-compose-test.yaml
@@ -1,11 +1,12 @@
version: "3.7"
services:
- web:
- image: web
+ blog:
+ image: blog
build:
- context: ./
+ context: .
networks:
- - webnet
+ - blognet
+ - dbnet
ports:
- "19009:9000"
cap_drop:
@@ -13,5 +14,35 @@ services:
environment:
- SERVER_DEPLOYMENT_TYPE=test
- SERVER_LISTEN_PORT=9000
+ depends_on:
+ - mongo
+ secrets:
+ - mongo_user
+ - mongo_pass
+ mongo:
+ image: mongo:5.0
+ networks:
+ - dbnet
+ restart: on-failure
+ ports:
+ - "127.0.0.1:27117:27017"
+ - "127.0.0.1:27118:27018"
+ - "127.0.0.1:27119:27019"
+ volumes:
+ - blog-data:/data/db
+ environment:
+ - MONGO_INITDB_ROOT_USERNAME_FILE=/run/secrets/mongo_user
+ - MONGO_INITDB_ROOT_PASSWORD_FILE=/run/secrets/mongo_pass
+ secrets:
+ - mongo_user
+ - mongo_pass
networks:
- webnet:
+ blognet:
+ dbnet:
+volumes:
+ blog-data:
+secrets:
+ mongo_user:
+ file: ./mongo_secrets/mongo_user
+ mongo_pass:
+ file: ./mongo_secrets/mongo_pass
diff --git a/docker-compose.yaml b/docker-compose.yaml
index 5f3e217..79e5d0c 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -1,11 +1,12 @@
version: "3.7"
services:
- web:
- image: web
+ blog:
+ image: blog
build:
context: ./
networks:
- - webnet
+ - blognet
+ - dbnet
restart: unless-stopped
ports:
- "9000:9000"
@@ -16,5 +17,35 @@ services:
environment:
- SERVER_DEPLOYMENT_TYPE=deployment
- SERVER_LISTEN_PORT=9000
+ depends_on:
+ - mongo
+ secrets:
+ - mongo_user
+ - mongo_pass
+ mongo:
+ image: mongo:5.0
+ networks:
+ - dbnet
+ restart: on-failure
+ ports:
+ - "127.0.0.1:27117:27017"
+ - "127.0.0.1:27118:27018"
+ - "127.0.0.1:27119:27019"
+ volumes:
+ - blog-data:/data/db
+ environment:
+ - MONGO_INITDB_ROOT_USERNAME_FILE=/run/secrets/mongo_user
+ - MONGO_INITDB_ROOT_PASSWORD_FILE=/run/secrets/mongo_pass
+ secrets:
+ - mongo_user
+ - mongo_pass
networks:
- webnet:
+ blognet:
+ dbnet:
+volumes:
+ blog-data:
+secrets:
+ mongo_user:
+ file: ./mongo_secrets/mongo_user
+ mongo_pass:
+ file: ./mongo_secrets/mongo_pass
diff --git a/model.js b/model.js
new file mode 100644
index 0000000..dde3913
--- /dev/null
+++ b/model.js
@@ -0,0 +1,62 @@
+"use strict";
+
+const fs = require("fs");
+const path = require("path");
+const mongoose = require("mongoose");
+const Schema = mongoose.Schema;
+mongoose.Promise = global.Promise;
+const db = {};
+db.mongoose = mongoose;
+const db_pass = fs.readFileSync("/run/secrets/mongo_pass").toString();
+const db_user = fs.readFileSync("/run/secrets/mongo_user").toString();
+db.url = "mongodb://" + db_user + ":" + db_pass + "@mongo:27017";
+
+const BlogPostSchema = new Schema({
+ title: { type: String, required: true, trim: true },
+ slug: { type: String, required: true, lowercase: true, trim: true },
+ body: { type: String, required: true },
+ teaser: { type: String, required: true },
+ keywords: { type: Array, required: true },
+ lastUpdatedAt: { type: Number },
+});
+
+// a simple hook to update the timestamp(lastUpdatedAt) on update
+BlogPostSchema.pre("save", function (next) {
+ this.lastUpdatedAt = Date.now();
+ next();
+});
+
+function dbInit() {
+ db.mongoose
+ .connect(db.url, { useNewUrlParser: true, useUnifiedTopology: true })
+ .then(() => {
+ console.log("successfully connected to db");
+ })
+ .catch((err) => {
+ console.log("cannot connect to the database: ", err);
+ process.exit(1);
+ });
+}
+
+function populateDB(model) {
+ let filePaths = fs.readdirSync(path.join(__dirname, "mds"));
+ filePaths.forEach((fileName) => {
+ let fileContent = fs
+ .readFileSync(path.join(__dirname, "mds", fileName), "utf-8")
+ .toString();
+ let newBlogPost = new model({
+ title: fileName,
+ slug: fileName,
+ body: fileContent,
+ teaser: fileName,
+ keywords: ["kw1", "kw2"],
+ });
+ newBlogPost.save();
+ });
+}
+
+module.exports = {
+ blogPost: mongoose.model("BlogPost", BlogPostSchema),
+ dbInit: dbInit,
+ populateDB: populateDB,
+};
diff --git a/package-lock.json b/package-lock.json
index c111ea8..aa9d629 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,6 +20,7 @@
"markdown-it-highlightjs": "^3.4.0",
"markdown-it-multimd-table": "^4.0.2",
"markdown-it-texmath": "^0.7.0",
+ "mongoose": "^6.2.8",
"morgan": "^1.10.0",
"pug": "^3.0.2",
"spdy": "^4.0.2"
@@ -176,6 +177,25 @@
"node": ">= 6"
}
},
+ "node_modules/@types/node": {
+ "version": "17.0.23",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz",
+ "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw=="
+ },
+ "node_modules/@types/webidl-conversions": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz",
+ "integrity": "sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q=="
+ },
+ "node_modules/@types/whatwg-url": {
+ "version": "8.2.1",
+ "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.1.tgz",
+ "integrity": "sha512-2YubE1sjj5ifxievI5Ge1sckb9k/Er66HyR2c+3+I6VDUUg1TLPdYYTEbQ+DjRkS4nTxMJhgWfSfMRD2sl2EYQ==",
+ "dependencies": {
+ "@types/node": "*",
+ "@types/webidl-conversions": "*"
+ }
+ },
"node_modules/abab": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
@@ -376,6 +396,25 @@
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
"node_modules/basic-auth": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
@@ -421,6 +460,40 @@
"resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
"integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow=="
},
+ "node_modules/bson": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-4.6.2.tgz",
+ "integrity": "sha512-VeJKHShcu1b/ugl0QiujlVuBepab714X9nNyBdA1kfekuDGecxgpTA2Z6nYbagrWFeiIyzSWIOzju3lhj+RNyQ==",
+ "dependencies": {
+ "buffer": "^5.6.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
"node_modules/bytes": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
@@ -625,6 +698,14 @@
"node": ">=0.4.0"
}
},
+ "node_modules/denque": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz",
+ "integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
"node_modules/depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
@@ -1579,6 +1660,25 @@
"node": ">=0.10.0"
}
},
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
"node_modules/ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
@@ -1628,6 +1728,11 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
+ "node_modules/ip": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
+ "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
+ },
"node_modules/ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
@@ -1840,6 +1945,11 @@
"promise": "^7.0.1"
}
},
+ "node_modules/kareem": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.4.tgz",
+ "integrity": "sha512-Vcrt8lcpVl0s8ePx634BxwRqmFo+5DcOhlmNadehxreMTIQi/9hOL/B3hZQQbK5DgMS7Lem3xABXV7/S3jy+7g=="
+ },
"node_modules/katex": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/katex/-/katex-0.11.1.tgz",
@@ -1987,6 +2097,12 @@
"url": "https://github.com/sindresorhus/mem?sponsor=1"
}
},
+ "node_modules/memory-pager": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
+ "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
+ "optional": true
+ },
"node_modules/merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
@@ -2054,6 +2170,89 @@
"node": "*"
}
},
+ "node_modules/mongodb": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.3.1.tgz",
+ "integrity": "sha512-sNa8APSIk+r4x31ZwctKjuPSaeKuvUeNb/fu/3B6dRM02HpEgig7hTHM8A/PJQTlxuC/KFWlDlQjhsk/S43tBg==",
+ "dependencies": {
+ "bson": "^4.6.1",
+ "denque": "^2.0.1",
+ "mongodb-connection-string-url": "^2.4.1",
+ "socks": "^2.6.1"
+ },
+ "engines": {
+ "node": ">=12.9.0"
+ },
+ "optionalDependencies": {
+ "saslprep": "^1.0.3"
+ }
+ },
+ "node_modules/mongodb-connection-string-url": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.5.2.tgz",
+ "integrity": "sha512-tWDyIG8cQlI5k3skB6ywaEA5F9f5OntrKKsT/Lteub2zgwSUlhqEN2inGgBTm8bpYJf8QYBdA/5naz65XDpczA==",
+ "dependencies": {
+ "@types/whatwg-url": "^8.2.1",
+ "whatwg-url": "^11.0.0"
+ }
+ },
+ "node_modules/mongodb-connection-string-url/node_modules/tr46": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
+ "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
+ "dependencies": {
+ "punycode": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/mongodb-connection-string-url/node_modules/webidl-conversions": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
+ "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/mongodb-connection-string-url/node_modules/whatwg-url": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz",
+ "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==",
+ "dependencies": {
+ "tr46": "^3.0.0",
+ "webidl-conversions": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/mongoose": {
+ "version": "6.2.8",
+ "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-6.2.8.tgz",
+ "integrity": "sha512-Wq6HG0sOJEQHp5YqMlxrnf93vBFwdY2zlAwqI97EPPSt69kiVV21pTv4cDanrCNWi4upG8ajQ/p9jpDjcECjkQ==",
+ "dependencies": {
+ "bson": "^4.2.2",
+ "kareem": "2.3.4",
+ "mongodb": "4.3.1",
+ "mpath": "0.8.4",
+ "mquery": "4.0.2",
+ "ms": "2.1.3",
+ "sift": "16.0.0"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mongoose"
+ }
+ },
+ "node_modules/mongoose/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ },
"node_modules/morgan": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz",
@@ -2077,6 +2276,46 @@
"node": ">= 0.8"
}
},
+ "node_modules/mpath": {
+ "version": "0.8.4",
+ "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.8.4.tgz",
+ "integrity": "sha512-DTxNZomBcTWlrMW76jy1wvV37X/cNNxPW1y2Jzd4DZkAaC5ZGsm8bfGfNOthcDuRJujXLqiuS6o3Tpy0JEoh7g==",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/mquery": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/mquery/-/mquery-4.0.2.tgz",
+ "integrity": "sha512-oAVF0Nil1mT3rxty6Zln4YiD6x6QsUWYz927jZzjMxOK2aqmhEz5JQ7xmrKK7xRFA2dwV+YaOpKU/S+vfNqKxA==",
+ "dependencies": {
+ "debug": "4.x"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/mquery/node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/mquery/node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
"node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@@ -2515,6 +2754,18 @@
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
+ "node_modules/saslprep": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
+ "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
+ "optional": true,
+ "dependencies": {
+ "sparse-bitfield": "^3.0.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/saxes": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz",
@@ -2622,6 +2873,11 @@
"node": ">=8"
}
},
+ "node_modules/sift": {
+ "version": "16.0.0",
+ "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.0.tgz",
+ "integrity": "sha512-ILTjdP2Mv9V1kIxWMXeMTIRbOBrqKc4JAXmFMnFq3fKeyQ2Qwa3Dw1ubcye3vR+Y6ofA0b9gNDr/y2t6eUeIzQ=="
+ },
"node_modules/slice-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
@@ -2672,6 +2928,28 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
+ "node_modules/smart-buffer": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
+ "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
+ "engines": {
+ "node": ">= 6.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/socks": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz",
+ "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==",
+ "dependencies": {
+ "ip": "^1.1.5",
+ "smart-buffer": "^4.2.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0",
+ "npm": ">= 3.0.0"
+ }
+ },
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -2681,6 +2959,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/sparse-bitfield": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
+ "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
+ "optional": true,
+ "dependencies": {
+ "memory-pager": "^1.0.2"
+ }
+ },
"node_modules/spdy": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz",
@@ -3297,6 +3584,25 @@
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
"integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw=="
},
+ "@types/node": {
+ "version": "17.0.23",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz",
+ "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw=="
+ },
+ "@types/webidl-conversions": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz",
+ "integrity": "sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q=="
+ },
+ "@types/whatwg-url": {
+ "version": "8.2.1",
+ "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.1.tgz",
+ "integrity": "sha512-2YubE1sjj5ifxievI5Ge1sckb9k/Er66HyR2c+3+I6VDUUg1TLPdYYTEbQ+DjRkS4nTxMJhgWfSfMRD2sl2EYQ==",
+ "requires": {
+ "@types/node": "*",
+ "@types/webidl-conversions": "*"
+ }
+ },
"abab": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
@@ -3451,6 +3757,11 @@
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
+ "base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
+ },
"basic-auth": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
@@ -3490,6 +3801,23 @@
"resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
"integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow=="
},
+ "bson": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-4.6.2.tgz",
+ "integrity": "sha512-VeJKHShcu1b/ugl0QiujlVuBepab714X9nNyBdA1kfekuDGecxgpTA2Z6nYbagrWFeiIyzSWIOzju3lhj+RNyQ==",
+ "requires": {
+ "buffer": "^5.6.0"
+ }
+ },
+ "buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "requires": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
"bytes": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
@@ -3660,6 +3988,11 @@
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
+ "denque": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz",
+ "integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ=="
+ },
"depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
@@ -4375,6 +4708,11 @@
"safer-buffer": ">= 2.1.2 < 3"
}
},
+ "ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
+ },
"ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
@@ -4412,6 +4750,11 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
+ "ip": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
+ "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
+ },
"ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
@@ -4579,6 +4922,11 @@
"promise": "^7.0.1"
}
},
+ "kareem": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.4.tgz",
+ "integrity": "sha512-Vcrt8lcpVl0s8ePx634BxwRqmFo+5DcOhlmNadehxreMTIQi/9hOL/B3hZQQbK5DgMS7Lem3xABXV7/S3jy+7g=="
+ },
"katex": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/katex/-/katex-0.11.1.tgz",
@@ -4702,6 +5050,12 @@
"mimic-fn": "^3.0.0"
}
},
+ "memory-pager": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
+ "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
+ "optional": true
+ },
"merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
@@ -4748,6 +5102,72 @@
"brace-expansion": "^1.1.7"
}
},
+ "mongodb": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.3.1.tgz",
+ "integrity": "sha512-sNa8APSIk+r4x31ZwctKjuPSaeKuvUeNb/fu/3B6dRM02HpEgig7hTHM8A/PJQTlxuC/KFWlDlQjhsk/S43tBg==",
+ "requires": {
+ "bson": "^4.6.1",
+ "denque": "^2.0.1",
+ "mongodb-connection-string-url": "^2.4.1",
+ "saslprep": "^1.0.3",
+ "socks": "^2.6.1"
+ }
+ },
+ "mongodb-connection-string-url": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.5.2.tgz",
+ "integrity": "sha512-tWDyIG8cQlI5k3skB6ywaEA5F9f5OntrKKsT/Lteub2zgwSUlhqEN2inGgBTm8bpYJf8QYBdA/5naz65XDpczA==",
+ "requires": {
+ "@types/whatwg-url": "^8.2.1",
+ "whatwg-url": "^11.0.0"
+ },
+ "dependencies": {
+ "tr46": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
+ "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
+ "requires": {
+ "punycode": "^2.1.1"
+ }
+ },
+ "webidl-conversions": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
+ "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="
+ },
+ "whatwg-url": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz",
+ "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==",
+ "requires": {
+ "tr46": "^3.0.0",
+ "webidl-conversions": "^7.0.0"
+ }
+ }
+ }
+ },
+ "mongoose": {
+ "version": "6.2.8",
+ "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-6.2.8.tgz",
+ "integrity": "sha512-Wq6HG0sOJEQHp5YqMlxrnf93vBFwdY2zlAwqI97EPPSt69kiVV21pTv4cDanrCNWi4upG8ajQ/p9jpDjcECjkQ==",
+ "requires": {
+ "bson": "^4.2.2",
+ "kareem": "2.3.4",
+ "mongodb": "4.3.1",
+ "mpath": "0.8.4",
+ "mquery": "4.0.2",
+ "ms": "2.1.3",
+ "sift": "16.0.0"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ }
+ }
+ },
"morgan": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz",
@@ -4767,6 +5187,34 @@
}
}
},
+ "mpath": {
+ "version": "0.8.4",
+ "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.8.4.tgz",
+ "integrity": "sha512-DTxNZomBcTWlrMW76jy1wvV37X/cNNxPW1y2Jzd4DZkAaC5ZGsm8bfGfNOthcDuRJujXLqiuS6o3Tpy0JEoh7g=="
+ },
+ "mquery": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/mquery/-/mquery-4.0.2.tgz",
+ "integrity": "sha512-oAVF0Nil1mT3rxty6Zln4YiD6x6QsUWYz927jZzjMxOK2aqmhEz5JQ7xmrKK7xRFA2dwV+YaOpKU/S+vfNqKxA==",
+ "requires": {
+ "debug": "4.x"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
+ }
+ },
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@@ -5121,6 +5569,15 @@
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
+ "saslprep": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
+ "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
+ "optional": true,
+ "requires": {
+ "sparse-bitfield": "^3.0.3"
+ }
+ },
"saxes": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz",
@@ -5206,6 +5663,11 @@
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true
},
+ "sift": {
+ "version": "16.0.0",
+ "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.0.tgz",
+ "integrity": "sha512-ILTjdP2Mv9V1kIxWMXeMTIRbOBrqKc4JAXmFMnFq3fKeyQ2Qwa3Dw1ubcye3vR+Y6ofA0b9gNDr/y2t6eUeIzQ=="
+ },
"slice-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
@@ -5243,12 +5705,35 @@
}
}
},
+ "smart-buffer": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
+ "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="
+ },
+ "socks": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz",
+ "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==",
+ "requires": {
+ "ip": "^1.1.5",
+ "smart-buffer": "^4.2.0"
+ }
+ },
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"optional": true
},
+ "sparse-bitfield": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
+ "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
+ "optional": true,
+ "requires": {
+ "memory-pager": "^1.0.2"
+ }
+ },
"spdy": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz",
diff --git a/package.json b/package.json
index e7d7a5e..bef37be 100644
--- a/package.json
+++ b/package.json
@@ -28,6 +28,7 @@
"markdown-it-highlightjs": "^3.4.0",
"markdown-it-multimd-table": "^4.0.2",
"markdown-it-texmath": "^0.7.0",
+ "mongoose": "^6.2.8",
"morgan": "^1.10.0",
"pug": "^3.0.2",
"spdy": "^4.0.2"
diff --git a/put_in_db.js b/put_in_db.js
new file mode 100644
index 0000000..da5a050
--- /dev/null
+++ b/put_in_db.js
@@ -0,0 +1,26 @@
+"use strict";
+// mongosh --host 127.0.0.1 --port 27117 -u mongo -p mongo -f put_in_db.js
+
+const fs = require("fs");
+const path = require("path");
+// db = connect("http://mongo:mongo@127.0.0.1:27117");
+
+blog_entry_1 = {
+ title: "Turning C structs into Lua tables",
+ slug: "c_struct_lua_table",
+ body: fs.readFileSync(path.join(__dirname) + "/mds/cstruct2luatable.md"),
+ teaser: "Turning C structures into Lua tables",
+ keywords: "c,lua",
+ lastUpdatedAt: Date.now(),
+};
+
+blog_entry_2 = {
+ title: "Lazy Makefiles",
+ slug: "lazy_makefile",
+ body: fs.readFileSync(path.join(__dirname) + "/mds/lazymakefiles.md"),
+ teaser: "Lazy Makefiles",
+ keywords: "makefile,c,c++",
+ lastUpdatedAt: Date.now(),
+};
+
+db.blogposts.insertMany([blog_entry_1, blog_entry_2]);
diff --git a/server.js b/server.js
index ec4350e..eea4695 100755
--- a/server.js
+++ b/server.js
@@ -22,42 +22,80 @@ const mit = require("markdown-it")({ html: true })
const spdy = require("spdy");
const helmet = require("helmet");
const morgan = require("morgan");
-const pug = require("pug");
+const model = require("./model");
+
+model.dbInit();
const app = express();
+app.disable("x-powered-by");
app.use(express.static(path.join(__dirname, "css")));
app.use(express.static(path.join(__dirname, "static")));
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");
-app.engine("ejs", require("ejs").__express);
-app.use(helmet());
+app.set("view engine", "pug");
+
+app.use(helmet.crossOriginEmbedderPolicy());
+app.use(helmet.crossOriginOpenerPolicy());
+app.use(helmet.crossOriginResourcePolicy());
+app.use(helmet.dnsPrefetchControl());
+app.use(helmet.expectCt());
+app.use(helmet.frameguard());
+app.use(helmet.hidePoweredBy());
+app.use(helmet.hsts());
+app.use(helmet.ieNoOpen());
+app.use(helmet.noSniff());
+app.use(helmet.originAgentCluster());
+app.use(helmet.permittedCrossDomainPolicies());
+app.use(helmet.referrerPolicy());
+app.use(helmet.xssFilter());
+app.use((req, res, next) => {
+ res.setHeader(
+ "Permissions-Policy",
+ "geolocation=(self),midi=(self),sync-xhr=(self),microphone=(self),camera=(self),magnetometer=(self),gyroscope=(self),fullscreen=(self),payment=(self),usb=(self)"
+ );
+ next();
+});
+app.use(
+ helmet.contentSecurityPolicy({
+ useDefaults: false,
+ directives: {
+ baseUri: ["self"],
+ defaultSrc: ["self"],
+ scriptSrc: ["none"],
+ styleSrc: ["self", "https:", "unsafef-inline"],
+ },
+ })
+);
+
app.use(morgan("combined"));
-function renderAndSend(req, res) {
- try {
- let viewPath;
- if (req.path == "/") {
- viewPath = "mds/cstruct2luatable.md";
- } else {
- viewPath = req.path;
- }
- let readStream = fs.createReadStream(
- path.join(__dirname, viewPath),
- "utf-8"
- );
- //FIXME-this can obviously fail
- readStream.on("data", (chunk) => {
- res.render("index", {
+async function enumerateDir() {
+ return await fs.readdirSync(path.join(__dirname, "mds"));
+}
+
+function renderAndSend_v2(req, res, slug) {
+ model.blogPost
+ .findOne(
+ { slug: slug },
+ {
+ projection: {
+ _id: 0,
+ title: 0,
+ teaser: 0,
+ },
+ }
+ )
+ .exec(function (err, blogPost) {
+ if (err) return err;
+ return res.render("index.ejs", {
cache: true,
data: {
- blogHttp: mit.render(chunk),
- mds: fs.readdirSync(path.join(__dirname, "mds"), "utf-8"),
+ blogHttp: mit.render(blogPost.body),
+ lastUpdatedAt: blogPost.lastUpdatedAt,
+ keywords: blogPost.keywords,
},
});
});
- } catch (err) {
- console.log(err);
- }
}
app.get("/health", (req, res) => {
@@ -73,12 +111,17 @@ app.get("/about", (req, res) => {
app.get("/archive", (req, res) => {
res.type("text/html");
- res.render("archive", {
- cache: true,
- data: {
- mds: fs.readdirSync(path.join(__dirname, "mds"), "utf-8"),
- },
- });
+ model.blogPost
+ .find({}, { _id: 0, body: 0, teaser: 0, keywords: 0, lastUpdatedAt: 0 })
+ .exec(function (err, blogPosts) {
+ if (err) return err;
+ res.render("archive.ejs", {
+ cache: true,
+ data: {
+ blogPosts: blogPosts,
+ },
+ });
+ });
});
app.get("/robots.txt", (req, res) => {
@@ -90,25 +133,42 @@ app.get("/robots.txt", (req, res) => {
res.send(robots_txt);
});
-// app.get("/rss/feed", (req, res) => {
-// let html = pug.renderFile("./views/rss_feed.pug", merge(options, localls));
-// res.send(html);
-// });
-
-app.get("/$", (req, res) => {
- renderAndSend(req, res);
+app.get("/rss/feed", (req, res) => {
+ res.type("application/rss+xml");
+ model.blogPost
+ .find({})
+ .sort("-lastUpdatedAt")
+ .select("title slug lastUpdatedAt teaser")
+ .exec(function (err, posts) {
+ if (err) return err;
+ return res.render("rss_feed_v2.pug", { cache: true, posts: posts });
+ });
});
-app.get("/mds/:mdname$", (req, res) => {
- if (req.params["mdname"] == "") {
+app.get("/posts/:postName", (req, res) => {
+ if (req.params["postName"] == "") {
res.write("nothing requested!");
}
- renderAndSend(req, res);
+ renderAndSend_v2(req, res, req.params.postName);
});
-async function enumerateDir() {
- return await fs.readdirSync(path.join(__dirname, "mds"));
-}
+app.get("/$", (req, res) => {
+ model.blogPost
+ .find({}, { projection: { _id: 0, title: 0, teaser: 0 } })
+ .limit(1)
+ .sort({ $natural: -1 })
+ .exec(function (err, blogPost) {
+ if (err) return err;
+ return res.render("index.ejs", {
+ cache: true,
+ data: {
+ blogHttp: mit.render(blogPost[0].body),
+ lastUpdatedAt: blogPost[0].lastUpdatedAt,
+ keywords: blogPost[0].keywords,
+ },
+ });
+ });
+});
app.use(sitemap(enumerateDir, "https://blog.terminaldweller.com"));
diff --git a/static/about.html b/static/about.html
index ad9ed10..a56ad24 100644
--- a/static/about.html
+++ b/static/about.html
@@ -18,6 +18,18 @@
<p>
You can find my github
<a href="https://github.com/terminaldweller">here</a>
+ .
</p>
+ <p>
+ Also if the blog is broken please make a new issue
+ <a href="https://github.com/terminaldweller/web">here</a>
+ .
+ </p>
+ <br />
+ <br />
+ <hr />
+ <br />
+ <a href="/" class="left-footer">Home</a>
+ <br />
</body>
</html>
diff --git a/views/archive.ejs b/views/archive.ejs
index 36191de..72b963d 100644
--- a/views/archive.ejs
+++ b/views/archive.ejs
@@ -9,9 +9,9 @@
<body>
<script>0</script>
<div class="article">
- <% data.mds.forEach(function(md) { %>
+ <% data.blogPosts.forEach(function(blogPost) { %>
<ul>
- <li><a href=<%= "/mds/"+md %> target="_self" rel="noreferrer noopener" type="text/html"><%= md %></a></li>
+ <li><a href=<%= "/posts/"+blogPost.slug %> target="_self" rel="noreferrer noopener" type="text/html"><%= blogPost.title %></a></li>
</ul>
<% }) %>
</div>
diff --git a/views/index.ejs b/views/index.ejs
index 4679e4a..fdd49cc 100644
--- a/views/index.ejs
+++ b/views/index.ejs
@@ -5,16 +5,27 @@
<meta name="viewport" content="width=device-width">
<title>Blog</title>
<link rel="stylesheet" href="/master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+ <link rel="alternate" type="application/rss+xml" title="RSS" href="/rss/feed">
+ <!-- <link rel="alternate" type="application/atom+xml" title="RSS" href="/feed/rss"> -->
</head>
<body>
- <script>0</script>
+ <!-- <script>0</script> -->
<div class="article">
<%- data.blogHttp %>
<br/>
<hr/>
<br/>
+ <a class="left-footer">Keywords:</a>
+ <%- data.keywords %>
+ <%- data.lastUpdated %>
+ <br/>
+ <br/>
+ <hr/>
+ <br/>
<a href="/archive" class="left-footer">Archive</a>
<a href="/about" class="right-footer">About</a>
+ <a class="right-footer">&nbsp&nbsp&nbsp</a>
+ <a href="/rss/feed" class="right-footer">RSS</a>
</div>
</body>
</html>
diff --git a/views/rss_feed.pug b/views/rss_feed.pug
new file mode 100644
index 0000000..e75225d
--- /dev/null
+++ b/views/rss_feed.pug
@@ -0,0 +1,21 @@
+doctype xml
+rss(version='2.0', xmlns:atom='<a href="http://www.w3.org/2005/Atom" rel="nofollow">http://www.w3.org/2005/Atom</a>')
+ channel
+ title deviblog
+ link <a href="https://blog.terminaldweller.com" rel="nofollow">https://blog.terminaldweller.com</a>
+ atom:link(href='<a href="https://blog.terminaldweller.com/feed/rss" rel="nofollow">https://blog.terminaldweller.com/feed/rss</a>', rel='self', type='application/rss+xml')
+ description I talk about software here.
+ language en-US
+ if posts.length
+ lastBuildDate= new Date(posts[0].lastUpdatedAt).toUTCString()
+ each post in posts
+ item
+ title= post.title
+ link <a href="https://blog.terminaldweller.com/blog/#{post.slug}" rel="nofollow">https://terminaldweller.com/blog/#{post.slug}</a>
+ description
+ | <![CDATA[
+ | !{post.teaser}
+ p: a(href='<a href="https://blog.terminaldweller.com/blog/#{post.slug} rel="nofollow">https://blog.terminaldweller.com/blog/#{post.slug}</a>') 'Read more &raquo;'
+ | ]]>
+ pubDate= new Date(post.lastUpdatedAt).toUTCString()
+ guid(isPermaLink='false') <a href="https://blog.terminaldweller.com/blog/#{post.slug}" rel="nofollow">https://blog.terminaldweller.com/blog/#{post.slug}</a>
diff --git a/views/rss_feed_v2.pug b/views/rss_feed_v2.pug
new file mode 100644
index 0000000..d04297d
--- /dev/null
+++ b/views/rss_feed_v2.pug
@@ -0,0 +1,22 @@
+doctype xml
+rss(version='2.0', xmlns:atom='http://www.w3.org/2005/Atom')
+ channel
+ title deviblog
+ link https://blog.terminaldweller.com
+ atom:link(href='https://blog.terminaldweller.com/rss/feed', rel='self', type='application/rss+xml')
+ description I talk about software here.
+ managingEditor devi@terminaldweller.com (Farzad Sadeghi)
+ webMaster devi@terminaldweller.com (Farzad Sadeghi)
+ language en-US
+ if posts.length
+ lastBuildDate= new Date(posts[0].lastUpdatedAt).toUTCString()
+ each post in posts
+ item
+ title= post.title
+ link https://blog.terminaldweller.com/posts/#{post.slug}
+ description
+ | <![CDATA[
+ | #{post.teaser}
+ | ]]>
+ pubDate= new Date(post.lastUpdatedAt).toUTCString()
+ guid(isPermaLink='false') https://blog.terminaldweller.com/blog/#{post.slug}