From 020a53c4e04f1e7831b7f464bc0e5689f0cc79a9 Mon Sep 17 00:00:00 2001 From: tycrek Date: Thu, 15 Apr 2021 11:43:34 -0600 Subject: [PATCH 01/14] attempting opengraph stuff --- ass.js | 3 +- ogp.js | 81 +++++++++++++++++++++++++++++++++++++++++++++++ package-lock.json | 18 +++++++++-- package.json | 3 +- 4 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 ogp.js diff --git a/ass.js b/ass.js index 0a0567f..156e1b9 100755 --- a/ass.js +++ b/ass.js @@ -14,6 +14,7 @@ const fs = require('fs-extra'); const express = require('express'); const useragent = require('express-useragent'); const multer = require('multer'); +const OpenGraph = require('./ogp'); const { path, saveData, log, verify, generateToken, generateId } = require('./utils'); //#endregion @@ -108,7 +109,7 @@ function startup() { if (!resourceId || !data[resourceId]) return res.sendStatus(404); // If a Discord client wants to load an mp4, send the data needed for a proper inline embed - if (req.useragent.isBot && data[resourceId].mimetype == 'video/mp4') return res.type('html').send(genHtml(resourceId)); + if (req.useragent.isBot /* && data[resourceId].mimetype == 'video/mp4' */) return res.type('html').send(new OpenGraph(getTrueHttp(), getTrueDomain(), resourceId, data[resourceId]).build()); // Read the file and send it to the client fs.readFile(path(data[resourceId].path)) diff --git a/ogp.js b/ogp.js new file mode 100644 index 0000000..e61e11e --- /dev/null +++ b/ogp.js @@ -0,0 +1,81 @@ +/* + +Optional: +- og:title +- og:description +- og:site_name + +*/ +const Mustache = require('mustache'); + +// +class OpenGraph { + http; + domain; + resourceId; + + filename; + type; + size; + + title = ''; + author = ''; + showSize = false; + + constructor(http, domain, resourceId, { originalname, mimetype, size }) { + this.http = http; + this.domain = domain; + this.resourceId = resourceId; + + this.type = mimetype; + this.filename = originalname; + this.size = size; + } + + setTitle(title) { + this.title = title; + return this; + } + + setAuthor(author) { + this.author = author; + return this; + } + + setShowSize(showSize) { + this.showSize = showSize; + return this; + } + + build() { + let view = { + http: this.http, + domain: this.domain, + resourceId: this.resourceId, + + ogtype: this.type.includes('video') ? 'video.other' : 'image', + type: this.type.includes('video') ? 'video' : 'image', + ext: this.type.includes('video') ? '.mp4' : '', + }; + + view.title = (this.title.length != 0) ? `` : ''; + view.site = (this.author.length != 0) ? `` : ''; + + return Mustache.render(html, view); + } +} + +const html = ` + + + ass + + + {{title}} + {{site}} + + ass + +`; + +module.exports = OpenGraph; diff --git a/package-lock.json b/package-lock.json index 8d1f917..723d980 100755 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ass", - "version": "1.0.0", + "version": "0.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "ass", - "version": "1.0.0", + "version": "0.1.0", "license": "ISC", "dependencies": { "crypto-random-string": "3.3.1", @@ -14,6 +14,7 @@ "express-useragent": "^1.0.15", "fs-extra": "^9.1.0", "multer": "^1.4.2", + "mustache": "^4.2.0", "prompt": "^1.1.0", "uuid": "^8.3.2" } @@ -594,6 +595,14 @@ "node": ">= 0.10.0" } }, + "node_modules/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "bin": { + "mustache": "bin/mustache" + } + }, "node_modules/mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", @@ -1454,6 +1463,11 @@ "xtend": "^4.0.0" } }, + "mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==" + }, "mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", diff --git a/package.json b/package.json index 0fa2b4e..1dd0799 100755 --- a/package.json +++ b/package.json @@ -29,7 +29,8 @@ "express-useragent": "^1.0.15", "fs-extra": "^9.1.0", "multer": "^1.4.2", + "mustache": "^4.2.0", "prompt": "^1.1.0", "uuid": "^8.3.2" } -} \ No newline at end of file +} From acd92b78080770e6bc1f1a869cd25ead298b0fa2 Mon Sep 17 00:00:00 2001 From: tycrek Date: Thu, 15 Apr 2021 11:53:06 -0600 Subject: [PATCH 02/14] fixed escaping characters --- ogp.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ogp.js b/ogp.js index e61e11e..c549dc5 100644 --- a/ogp.js +++ b/ogp.js @@ -69,10 +69,10 @@ const html = ` ass - - - {{title}} - {{site}} + + + {{{title}}} + {{{site}}} ass From 7a24ed8f3ee3aa0e1b9a61adc70fc7b2693a5d4b Mon Sep 17 00:00:00 2001 From: tycrek Date: Thu, 15 Apr 2021 11:57:48 -0600 Subject: [PATCH 03/14] test image card fix & embed colour --- ogp.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ogp.js b/ogp.js index c549dc5..fabfe0f 100644 --- a/ogp.js +++ b/ogp.js @@ -73,6 +73,8 @@ const html = ` {{{title}}} {{{site}}} + + ass From f29a203b7501f4bc9d115f8e37a8b42443e1f54b Mon Sep 17 00:00:00 2001 From: tycrek Date: Thu, 15 Apr 2021 12:11:23 -0600 Subject: [PATCH 04/14] added embed colours --- ogp.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ogp.js b/ogp.js index fabfe0f..ecc8fba 100644 --- a/ogp.js +++ b/ogp.js @@ -20,6 +20,7 @@ class OpenGraph { title = ''; author = ''; + color = ''; showSize = false; constructor(http, domain, resourceId, { originalname, mimetype, size }) { @@ -42,6 +43,11 @@ class OpenGraph { return this; } + setColor(color) { + this.color = color; + return this; + } + setShowSize(showSize) { this.showSize = showSize; return this; @@ -60,6 +66,7 @@ class OpenGraph { view.title = (this.title.length != 0) ? `` : ''; view.site = (this.author.length != 0) ? `` : ''; + view.color = (this.color.length != 0) ? `` : ''; return Mustache.render(html, view); } @@ -73,7 +80,7 @@ const html = ` {{{title}}} {{{site}}} - + {{{color}}} ass From 8a37bb97f316b550ee597475551a58f888c85a32 Mon Sep 17 00:00:00 2001 From: tycrek Date: Thu, 15 Apr 2021 12:11:57 -0600 Subject: [PATCH 05/14] added automatic image card --- ogp.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ogp.js b/ogp.js index ecc8fba..951bd55 100644 --- a/ogp.js +++ b/ogp.js @@ -67,6 +67,7 @@ class OpenGraph { view.title = (this.title.length != 0) ? `` : ''; view.site = (this.author.length != 0) ? `` : ''; view.color = (this.color.length != 0) ? `` : ''; + view.card = !this.type.includes('video') ? `` : ''; return Mustache.render(html, view); } @@ -78,12 +79,14 @@ const html = ` ass - {{{title}}} - {{{site}}} + {{{title}}} + {{{site}}} {{{color}}} - + {{{card}}} - ass + + ass + `; From 4d56021b25a0c2576158b4e3f017afb877d2df8a Mon Sep 17 00:00:00 2001 From: tycrek Date: Thu, 15 Apr 2021 12:26:32 -0600 Subject: [PATCH 06/14] added homepage to body of open graph responses --- ogp.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/ogp.js b/ogp.js index 951bd55..794e3ea 100644 --- a/ogp.js +++ b/ogp.js @@ -1,12 +1,5 @@ -/* - -Optional: -- og:title -- og:description -- og:site_name - -*/ const Mustache = require('mustache'); +const github = require('./package.json').homepage; // class OpenGraph { @@ -55,6 +48,8 @@ class OpenGraph { build() { let view = { + github, + http: this.http, domain: this.domain, resourceId: this.resourceId, @@ -85,7 +80,7 @@ const html = ` {{{card}}} - ass + Open Graph response for ass. `; From 2341f807bda6fdbf14e6aee6af07a4346f50b6c1 Mon Sep 17 00:00:00 2001 From: tycrek Date: Thu, 15 Apr 2021 12:29:56 -0600 Subject: [PATCH 07/14] added todo --- ogp.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ogp.js b/ogp.js index 794e3ea..92738aa 100644 --- a/ogp.js +++ b/ogp.js @@ -64,6 +64,8 @@ class OpenGraph { view.color = (this.color.length != 0) ? `` : ''; view.card = !this.type.includes('video') ? `` : ''; + //todo: og:description + return Mustache.render(html, view); } } From 10e3ef7ac4107cd4ec59677647e074454269184f Mon Sep 17 00:00:00 2001 From: tycrek Date: Thu, 15 Apr 2021 12:30:13 -0600 Subject: [PATCH 08/14] removed need for checking if video --- ass.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ass.js b/ass.js index 156e1b9..5ab9155 100755 --- a/ass.js +++ b/ass.js @@ -108,8 +108,8 @@ function startup() { // If the ID is invalid, return 404 if (!resourceId || !data[resourceId]) return res.sendStatus(404); - // If a Discord client wants to load an mp4, send the data needed for a proper inline embed - if (req.useragent.isBot /* && data[resourceId].mimetype == 'video/mp4' */) return res.type('html').send(new OpenGraph(getTrueHttp(), getTrueDomain(), resourceId, data[resourceId]).build()); + // If the client is Discord, send an Open Graph embed + if (req.useragent.isBot) return res.type('html').send(new OpenGraph(getTrueHttp(), getTrueDomain(), resourceId, data[resourceId]).build()); // Read the file and send it to the client fs.readFile(path(data[resourceId].path)) From 49a3a11712c2d137b4b4af0d6b14fdf35390ee08 Mon Sep 17 00:00:00 2001 From: tycrek Date: Thu, 15 Apr 2021 13:19:44 -0600 Subject: [PATCH 09/14] removed old function --- ass.js | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/ass.js b/ass.js index 5ab9155..d1b30f5 100755 --- a/ass.js +++ b/ass.js @@ -148,16 +148,3 @@ function getTrueHttp() { function getTrueDomain(d = domain) { return d.concat((port == 80 || port == 443 || isProxied) ? '' : `:${port}`); } - -function genHtml(resourceId) { - return ` - - - ass - - - - ass - -`; -} From 850a920c384c85273de3c85625ee9dee6a9a415d Mon Sep 17 00:00:00 2001 From: tycrek Date: Thu, 15 Apr 2021 13:26:47 -0600 Subject: [PATCH 10/14] added description to opengraph --- ogp.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ogp.js b/ogp.js index 92738aa..88d565d 100644 --- a/ogp.js +++ b/ogp.js @@ -12,6 +12,7 @@ class OpenGraph { size; title = ''; + description = ''; author = ''; color = ''; showSize = false; @@ -31,6 +32,11 @@ class OpenGraph { return this; } + setDescription(description) { + this.description = description; + return this; + } + setAuthor(author) { this.author = author; return this; @@ -60,12 +66,11 @@ class OpenGraph { }; view.title = (this.title.length != 0) ? `` : ''; + view.description = (this.description.length != 0) ? `` : ''; view.site = (this.author.length != 0) ? `` : ''; view.color = (this.color.length != 0) ? `` : ''; view.card = !this.type.includes('video') ? `` : ''; - //todo: og:description - return Mustache.render(html, view); } } @@ -77,6 +82,7 @@ const html = ` {{{title}}} + {{{description}}} {{{site}}} {{{color}}} {{{card}}} From db1b88fb5ab61c8b33e792586a0761bd5df326c6 Mon Sep 17 00:00:00 2001 From: tycrek Date: Thu, 15 Apr 2021 13:33:35 -0600 Subject: [PATCH 11/14] minor cleanup --- ogp.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/ogp.js b/ogp.js index 88d565d..a0b0308 100644 --- a/ogp.js +++ b/ogp.js @@ -53,7 +53,7 @@ class OpenGraph { } build() { - let view = { + return Mustache.render(html, { github, http: this.http, @@ -63,15 +63,13 @@ class OpenGraph { ogtype: this.type.includes('video') ? 'video.other' : 'image', type: this.type.includes('video') ? 'video' : 'image', ext: this.type.includes('video') ? '.mp4' : '', - }; - view.title = (this.title.length != 0) ? `` : ''; - view.description = (this.description.length != 0) ? `` : ''; - view.site = (this.author.length != 0) ? `` : ''; - view.color = (this.color.length != 0) ? `` : ''; - view.card = !this.type.includes('video') ? `` : ''; - - return Mustache.render(html, view); + title: (this.title.length != 0) ? `` : '', + description: (this.description.length != 0) ? `` : '', + site: (this.author.length != 0) ? `` : '', + color: (this.color.length != 0) ? `` : '', + card: !this.type.includes('video') ? `` : '', + }); } } From a997a137d3b18b6b598f91989b0a99819404b7af Mon Sep 17 00:00:00 2001 From: tycrek Date: Thu, 15 Apr 2021 13:41:53 -0600 Subject: [PATCH 12/14] added luxon for saving upload timestamp --- ass.js | 4 ++++ package-lock.json | 14 ++++++++++++++ package.json | 1 + 3 files changed, 19 insertions(+) diff --git a/ass.js b/ass.js index d1b30f5..11e6752 100755 --- a/ass.js +++ b/ass.js @@ -14,6 +14,7 @@ const fs = require('fs-extra'); const express = require('express'); const useragent = require('express-useragent'); const multer = require('multer'); +const DateTime = require('luxon').DateTime; const OpenGraph = require('./ogp'); const { path, saveData, log, verify, generateToken, generateId } = require('./utils'); //#endregion @@ -83,6 +84,9 @@ function startup() { let trueDomain = getTrueDomain(req.headers["x-ass-domain"]); let generator = req.headers["x-ass-access"] || resourceIdType; + // Get the uploaded time in milliseconds + req.file.timestamp = DateTime.now().toMillis(); + // Save the file information let resourceId = generateId(generator, resourceIdSize, req.file.originalname); data[resourceId.split('.')[0]] = req.file; diff --git a/package-lock.json b/package-lock.json index 723d980..7639471 100755 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "express": "^4.17.1", "express-useragent": "^1.0.15", "fs-extra": "^9.1.0", + "luxon": "^1.26.0", "multer": "^1.4.2", "mustache": "^4.2.0", "prompt": "^1.1.0", @@ -494,6 +495,14 @@ "universalify": "^2.0.0" } }, + "node_modules/luxon": { + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.26.0.tgz", + "integrity": "sha512-+V5QIQ5f6CDXQpWNICELwjwuHdqeJM1UenlZWx5ujcRMc9venvluCjFb4t5NYLhb6IhkbMVOxzVuOqkgMxee2A==", + "engines": { + "node": "*" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -1389,6 +1398,11 @@ "universalify": "^2.0.0" } }, + "luxon": { + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.26.0.tgz", + "integrity": "sha512-+V5QIQ5f6CDXQpWNICELwjwuHdqeJM1UenlZWx5ujcRMc9venvluCjFb4t5NYLhb6IhkbMVOxzVuOqkgMxee2A==" + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", diff --git a/package.json b/package.json index 1dd0799..10f44c3 100755 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "express": "^4.17.1", "express-useragent": "^1.0.15", "fs-extra": "^9.1.0", + "luxon": "^1.26.0", "multer": "^1.4.2", "mustache": "^4.2.0", "prompt": "^1.1.0", From f936d14e1850f2807f46e1b7474d681909eaec1a Mon Sep 17 00:00:00 2001 From: tycrek Date: Thu, 15 Apr 2021 14:43:02 -0600 Subject: [PATCH 13/14] added custom embeds via http headers --- ass.js | 8 ++++++++ ogp.js | 47 ++++++++++++++++------------------------------- utils.js | 10 ++++++++-- 3 files changed, 32 insertions(+), 33 deletions(-) diff --git a/ass.js b/ass.js index 11e6752..0b10cba 100755 --- a/ass.js +++ b/ass.js @@ -87,6 +87,14 @@ function startup() { // Get the uploaded time in milliseconds req.file.timestamp = DateTime.now().toMillis(); + // Attach any embed overrides, if necessary + req.file.opengraph = { + title: req.headers['x-ass-og-title'], + description: req.headers['x-ass-og-description'], + author: req.headers['x-ass-og-author'], + color: req.headers['x-ass-og-color'] + }; + // Save the file information let resourceId = generateId(generator, resourceIdSize, req.file.originalname); data[resourceId.split('.')[0]] = req.file; diff --git a/ogp.js b/ogp.js index a0b0308..acd48b2 100644 --- a/ogp.js +++ b/ogp.js @@ -1,5 +1,6 @@ const Mustache = require('mustache'); const github = require('./package.json').homepage; +const { formatBytes } = require('./utils'); // class OpenGraph { @@ -10,14 +11,14 @@ class OpenGraph { filename; type; size; + timestamp; - title = ''; - description = ''; - author = ''; - color = ''; - showSize = false; + title; + description; + author; + color; - constructor(http, domain, resourceId, { originalname, mimetype, size }) { + constructor(http, domain, resourceId, { originalname, mimetype, size, timestamp, opengraph }) { this.http = http; this.domain = domain; this.resourceId = resourceId; @@ -25,31 +26,12 @@ class OpenGraph { this.type = mimetype; this.filename = originalname; this.size = size; - } - - setTitle(title) { - this.title = title; - return this; - } - - setDescription(description) { - this.description = description; - return this; - } - - setAuthor(author) { - this.author = author; - return this; - } - - setColor(color) { - this.color = color; - return this; - } + this.timestamp = timestamp; - setShowSize(showSize) { - this.showSize = showSize; - return this; + this.title = opengraph.title || ''; + this.description = opengraph.description || ''; + this.author = opengraph.author || ''; + this.color = opengraph.color || ''; } build() { @@ -69,7 +51,10 @@ class OpenGraph { site: (this.author.length != 0) ? `` : '', color: (this.color.length != 0) ? `` : '', card: !this.type.includes('video') ? `` : '', - }); + }) + .replace(new RegExp('&size', 'g'), formatBytes(this.size)) + .replace(new RegExp('&filename', 'g'), this.filename) + .replace(new RegExp('×tamp', 'g'), this.timestamp); } } diff --git a/utils.js b/utils.js index e4d81ce..d441e72 100755 --- a/utils.js +++ b/utils.js @@ -20,5 +20,11 @@ module.exports = { generateId: (mode, lenth, originalName) => (mode == idModes.zws) ? zwsGen(lenth) : (mode == idModes.r) ? randomGen(lenth) - : originalName -} \ No newline at end of file + : originalName, + formatBytes: (bytes, decimals = 2) => { + if (bytes === 0) return '0 Bytes'; + let sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + let i = Math.floor(Math.log(bytes) / Math.log(1024)); + return parseFloat((bytes / Math.pow(1024, i)).toFixed(decimals < 0 ? 0 : decimals)) + ' ' + sizes[i]; + } +} From cee810e63537c059ef0ffd4bc4e2a1d104354281 Mon Sep 17 00:00:00 2001 From: tycrek Date: Thu, 15 Apr 2021 14:56:08 -0600 Subject: [PATCH 14/14] added timestamp formatting --- ogp.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ogp.js b/ogp.js index acd48b2..29703f2 100644 --- a/ogp.js +++ b/ogp.js @@ -1,4 +1,5 @@ const Mustache = require('mustache'); +const DateTime = require('luxon').DateTime; const github = require('./package.json').homepage; const { formatBytes } = require('./utils'); @@ -54,7 +55,7 @@ class OpenGraph { }) .replace(new RegExp('&size', 'g'), formatBytes(this.size)) .replace(new RegExp('&filename', 'g'), this.filename) - .replace(new RegExp('×tamp', 'g'), this.timestamp); + .replace(new RegExp('×tamp', 'g'), DateTime.fromMillis(this.timestamp).toLocaleString(DateTime.DATETIME_MED)); } }