Merge pull request #96 from tycrek/minor-things

pull/97/head
Josh Moore 3 years ago committed by GitHub
commit 202e990888
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

379
package-lock.json generated

@ -15,23 +15,23 @@
"@tycrek/log": "^0.5.9",
"@tycrek/papito": "^0.3.4",
"any-shell-escape": "^0.1.1",
"aws-sdk": "^2.930.0",
"aws-sdk": "^2.1008.0",
"check-node-version": "^4.1.0",
"crypto-random-string": "3.3.1",
"discord-webhook-node": "^1.1.8",
"escape-html": "^1.0.3",
"express": "^4.17.1",
"express-busboy": "^8.0.0",
"express-rate-limit": "^5.2.6",
"ffmpeg-static": "^4.3.0",
"fs-extra": "^9.1.0",
"express-rate-limit": "^5.5.0",
"ffmpeg-static": "^4.4.0",
"fs-extra": "^10.0.0",
"helmet": "^4.6.0",
"jimp": "^0.16.1",
"luxon": "^1.26.0",
"marked": "^2.0.7",
"node-fetch": "^2.6.2",
"node-vibrant": "*",
"prompt": "^1.1.0",
"luxon": "^2.0.2",
"marked": "^3.0.7",
"node-fetch": "^2.6.5",
"node-vibrant": "^3.1.6",
"prompt": "^1.2.0",
"pug": "^3.0.2",
"sanitize-filename": "^1.6.3",
"stream-to-array": "^2.3.0",
@ -688,6 +688,14 @@
"url": "https://patreon.com/tycrek"
}
},
"node_modules/@tycrek/log/node_modules/luxon": {
"version": "1.28.0",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz",
"integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ==",
"engines": {
"node": "*"
}
},
"node_modules/@tycrek/papito": {
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/@tycrek/papito/-/papito-0.3.4.tgz",
@ -704,19 +712,6 @@
"url": "https://patreon.com/tycrek"
}
},
"node_modules/@tycrek/papito/node_modules/fs-extra": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
"integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/@types/body-parser": {
"version": "1.19.1",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.1.tgz",
@ -809,6 +804,11 @@
"@types/node": "*"
}
},
"node_modules/@types/lodash": {
"version": "4.14.175",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.175.tgz",
"integrity": "sha512-XmdEOrKQ8a1Y/yxQFOMbC47G/V2VDO1GvMRnl4O75M4GW/abC5tnfzadQYkqEveqRM1dEJGFFegfPNA2vvx2iw=="
},
"node_modules/@types/luxon": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-2.0.5.tgz",
@ -889,103 +889,6 @@
"@types/node": "*"
}
},
"node_modules/@vibrant/color": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/@vibrant/color/-/color-3.2.1-alpha.1.tgz",
"integrity": "sha512-cvm+jAPwao2NerTr3d1JttYyLhp3eD/AQBeevxF7KT6HctToWZCwr2AeTr003/wKgbjzdOV1qySnbyOeu+R+Jw=="
},
"node_modules/@vibrant/core": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/@vibrant/core/-/core-3.2.1-alpha.1.tgz",
"integrity": "sha512-X9Oa9WfPEQnZ6L+5dLRlh+IlsxJkYTw9b/g3stFKoNXbVRKCeXHmH48l7jIBBOg3VcXOGUdsYBqsTwPNkIveaA==",
"dependencies": {
"@vibrant/color": "^3.2.1-alpha.1",
"@vibrant/generator": "^3.2.1-alpha.1",
"@vibrant/image": "^3.2.1-alpha.1",
"@vibrant/quantizer": "^3.2.1-alpha.1",
"@vibrant/types": "^3.2.1-alpha.1",
"@vibrant/worker": "^3.2.1-alpha.1"
}
},
"node_modules/@vibrant/generator": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/@vibrant/generator/-/generator-3.2.1-alpha.1.tgz",
"integrity": "sha512-luS5YvMhwMqG01YTj1dJ+cmkuIw1VCByOR6zIaCOwQqI/mcOs88JBWcA1r2TywJTOPlVpjfnDvAlyaKBKh4dMA==",
"dependencies": {
"@vibrant/color": "^3.2.1-alpha.1",
"@vibrant/types": "^3.2.1-alpha.1"
}
},
"node_modules/@vibrant/generator-default": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/@vibrant/generator-default/-/generator-default-3.2.1-alpha.1.tgz",
"integrity": "sha512-BWnQhDaz92UhyHnpdAzKXHQecY+jvyMXtzjKYbveFxThm6+HVoLjwONlbck7oyOpFzV2OM7V11XuR85BxaHvjw==",
"dependencies": {
"@vibrant/color": "^3.2.1-alpha.1",
"@vibrant/generator": "^3.2.1-alpha.1"
}
},
"node_modules/@vibrant/image": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/@vibrant/image/-/image-3.2.1-alpha.1.tgz",
"integrity": "sha512-4aF5k79QfyhZOqRovJpbnIjWfe3uuWhY8voqVdd4/qgu4o70/AwVlM+pYmCaJVzI45VWNWWHYA5QlYuKsXnBqQ==",
"dependencies": {
"@vibrant/color": "^3.2.1-alpha.1",
"@vibrant/types": "^3.2.1-alpha.1"
}
},
"node_modules/@vibrant/image-browser": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/@vibrant/image-browser/-/image-browser-3.2.1-alpha.1.tgz",
"integrity": "sha512-6xWvQfB20sE6YtCWylgEAHuee3iD8h3aFIDbCS2yj7jIelKcYTrrp5jg2d2BhOOB6pC5JzF+QfpCrm0DmAIlgQ==",
"dependencies": {
"@vibrant/image": "^3.2.1-alpha.1"
}
},
"node_modules/@vibrant/image-node": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/@vibrant/image-node/-/image-node-3.2.1-alpha.1.tgz",
"integrity": "sha512-/Io/Rpo4EkO6AhaXdcxUXkbOFhSFtjm0LSAM4c0AyGA5EbC8PyZqjk8b11bQAEMCaYaweFQfTdGD7oVbXe21CQ==",
"dependencies": {
"@jimp/custom": "^0.16.1",
"@jimp/plugin-resize": "^0.16.1",
"@jimp/types": "^0.16.1",
"@vibrant/image": "^3.2.1-alpha.1"
}
},
"node_modules/@vibrant/quantizer": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/@vibrant/quantizer/-/quantizer-3.2.1-alpha.1.tgz",
"integrity": "sha512-iHnPx/+n4iLtYLm1GClSfyg2fFbMatFG0ipCyp9M6tXNIPAg+pSvUJSGBnVnH7Nl/bR8Gkkj1h0pJ4RsKcdIrQ==",
"dependencies": {
"@vibrant/color": "^3.2.1-alpha.1",
"@vibrant/image": "^3.2.1-alpha.1",
"@vibrant/types": "^3.2.1-alpha.1"
}
},
"node_modules/@vibrant/quantizer-mmcq": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/@vibrant/quantizer-mmcq/-/quantizer-mmcq-3.2.1-alpha.1.tgz",
"integrity": "sha512-Wuk9PTZtxr8qsWTcgP6lcrrmrq36syVwxf+BUxdgQYntBcQ053SaN34lVGOJ0WPdK5vABoxbYljhceCgiILtZw==",
"dependencies": {
"@vibrant/color": "^3.2.1-alpha.1",
"@vibrant/image": "^3.2.1-alpha.1",
"@vibrant/quantizer": "^3.2.1-alpha.1"
}
},
"node_modules/@vibrant/types": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/@vibrant/types/-/types-3.2.1-alpha.1.tgz",
"integrity": "sha512-ts9u7nsrENoYI5s0MmPOeY5kCLFKvQndKVDOPFCbTA0z493uhDp8mpiQhjFYTf3kPbS04z9zbHLE2luFC7x4KQ=="
},
"node_modules/@vibrant/worker": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/@vibrant/worker/-/worker-3.2.1-alpha.1.tgz",
"integrity": "sha512-mtSlBdHkFNr4FOnMtqtHJxy9z5AsUcZzGlpiHzvWOoaoN9lNTDPwxOBd0q4VTYWuGPrIm6Fuq5m7aRbLv7KqiQ==",
"dependencies": {
"@vibrant/types": "^3.2.1-alpha.1"
}
},
"node_modules/accepts": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
@ -1161,18 +1064,10 @@
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"node_modules/at-least-node": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
"integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
"engines": {
"node": ">= 4.0.0"
}
},
"node_modules/aws-sdk": {
"version": "2.1007.0",
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1007.0.tgz",
"integrity": "sha512-I/o2R7RTh6NGRilsBrJHg7r9WprU9EavozZ43qMQcppaLAeZrECBbGfpfRyhfrj7885+KS+WOu1SGn6bsSd2VQ==",
"version": "2.1008.0",
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1008.0.tgz",
"integrity": "sha512-wBEon+ARCuMcwEPpOFZqRT3elBLfLtPqv8jMql3Hsr7Ua5toPlgKMmjf368iTzBNaY7TOZsjLAT9nAhvtSZ++g==",
"hasInstallScript": true,
"dependencies": {
"buffer": "4.9.2",
@ -2210,17 +2105,16 @@
}
},
"node_modules/fs-extra": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
"integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
"integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
"dependencies": {
"at-least-node": "^1.0.0",
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
},
"engines": {
"node": ">=10"
"node": ">=12"
}
},
"node_modules/fs.realpath": {
@ -2734,6 +2628,11 @@
"node": ">=4"
}
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"node_modules/loud-rejection": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
@ -2747,9 +2646,9 @@
}
},
"node_modules/luxon": {
"version": "1.28.0",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz",
"integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-2.0.2.tgz",
"integrity": "sha512-ZRioYLCgRHrtTORaZX1mx+jtxKtKuI5ZDvHNAmqpUzGqSrR+tL4FVLn/CUGMA3h0+AKD1MAxGI5GnCqR5txNqg==",
"engines": {
"node": "*"
}
@ -2779,14 +2678,14 @@
"integrity": "sha1-douOecAJvytk/ugG4ip7HEGQyZA="
},
"node_modules/marked": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz",
"integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==",
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/marked/-/marked-3.0.7.tgz",
"integrity": "sha512-ctKqbnLuNbsHbI26cfMyOlKgXGfl1orOv1AvWWDX7AkgfMOwCWvmuYc+mVLeWhQ9W6hdWVBynOs96VkcscKo0Q==",
"bin": {
"marked": "bin/marked"
},
"engines": {
"node": ">= 10"
"node": ">= 12"
}
},
"node_modules/media-typer": {
@ -2962,16 +2861,16 @@
}
},
"node_modules/node-vibrant": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/node-vibrant/-/node-vibrant-3.2.1-alpha.1.tgz",
"integrity": "sha512-EQergCp7fvbvUCE0VMCBnvaAV0lGWSP8SXLmuWQIBzQK5M5pIwcd9fIOXuzFkJx/8hUiiiLvAzzGDS/bIy2ikA==",
"dependencies": {
"@types/node": "^10.12.18",
"@vibrant/core": "^3.2.1-alpha.1",
"@vibrant/generator-default": "^3.2.1-alpha.1",
"@vibrant/image-browser": "^3.2.1-alpha.1",
"@vibrant/image-node": "^3.2.1-alpha.1",
"@vibrant/quantizer-mmcq": "^3.2.1-alpha.1",
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/node-vibrant/-/node-vibrant-3.1.6.tgz",
"integrity": "sha512-Wlc/hQmBMOu6xon12ZJHS2N3M+I6J8DhrD3Yo6m5175v8sFkVIN+UjhKVRcO+fqvre89ASTpmiFEP3nPO13SwA==",
"dependencies": {
"@jimp/custom": "^0.16.1",
"@jimp/plugin-resize": "^0.16.1",
"@jimp/types": "^0.16.1",
"@types/lodash": "^4.14.53",
"@types/node": "^10.11.7",
"lodash": "^4.17.20",
"url": "^0.11.0"
}
},
@ -5060,6 +4959,13 @@
"deepmerge": "^4.2.2",
"luxon": "^1.27.0",
"use-climate-change-reminder": "^0.0.7"
},
"dependencies": {
"luxon": {
"version": "1.28.0",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz",
"integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ=="
}
}
},
"@tycrek/papito": {
@ -5068,18 +4974,6 @@
"integrity": "sha512-P5sQAJQOeirCzpphU6tXqjiCUmJf+A8T/1iJkpWu/uLq30lHyKjIoOeCXnW92b3hdDDxO1ruanxX2muJZTPQdA==",
"requires": {
"fs-extra": "^10.0.0"
},
"dependencies": {
"fs-extra": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
"integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
"requires": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
}
}
}
},
"@types/body-parser": {
@ -5174,6 +5068,11 @@
"@types/node": "*"
}
},
"@types/lodash": {
"version": "4.14.175",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.175.tgz",
"integrity": "sha512-XmdEOrKQ8a1Y/yxQFOMbC47G/V2VDO1GvMRnl4O75M4GW/abC5tnfzadQYkqEveqRM1dEJGFFegfPNA2vvx2iw=="
},
"@types/luxon": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-2.0.5.tgz",
@ -5254,103 +5153,6 @@
"@types/node": "*"
}
},
"@vibrant/color": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/@vibrant/color/-/color-3.2.1-alpha.1.tgz",
"integrity": "sha512-cvm+jAPwao2NerTr3d1JttYyLhp3eD/AQBeevxF7KT6HctToWZCwr2AeTr003/wKgbjzdOV1qySnbyOeu+R+Jw=="
},
"@vibrant/core": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/@vibrant/core/-/core-3.2.1-alpha.1.tgz",
"integrity": "sha512-X9Oa9WfPEQnZ6L+5dLRlh+IlsxJkYTw9b/g3stFKoNXbVRKCeXHmH48l7jIBBOg3VcXOGUdsYBqsTwPNkIveaA==",
"requires": {
"@vibrant/color": "^3.2.1-alpha.1",
"@vibrant/generator": "^3.2.1-alpha.1",
"@vibrant/image": "^3.2.1-alpha.1",
"@vibrant/quantizer": "^3.2.1-alpha.1",
"@vibrant/types": "^3.2.1-alpha.1",
"@vibrant/worker": "^3.2.1-alpha.1"
}
},
"@vibrant/generator": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/@vibrant/generator/-/generator-3.2.1-alpha.1.tgz",
"integrity": "sha512-luS5YvMhwMqG01YTj1dJ+cmkuIw1VCByOR6zIaCOwQqI/mcOs88JBWcA1r2TywJTOPlVpjfnDvAlyaKBKh4dMA==",
"requires": {
"@vibrant/color": "^3.2.1-alpha.1",
"@vibrant/types": "^3.2.1-alpha.1"
}
},
"@vibrant/generator-default": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/@vibrant/generator-default/-/generator-default-3.2.1-alpha.1.tgz",
"integrity": "sha512-BWnQhDaz92UhyHnpdAzKXHQecY+jvyMXtzjKYbveFxThm6+HVoLjwONlbck7oyOpFzV2OM7V11XuR85BxaHvjw==",
"requires": {
"@vibrant/color": "^3.2.1-alpha.1",
"@vibrant/generator": "^3.2.1-alpha.1"
}
},
"@vibrant/image": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/@vibrant/image/-/image-3.2.1-alpha.1.tgz",
"integrity": "sha512-4aF5k79QfyhZOqRovJpbnIjWfe3uuWhY8voqVdd4/qgu4o70/AwVlM+pYmCaJVzI45VWNWWHYA5QlYuKsXnBqQ==",
"requires": {
"@vibrant/color": "^3.2.1-alpha.1",
"@vibrant/types": "^3.2.1-alpha.1"
}
},
"@vibrant/image-browser": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/@vibrant/image-browser/-/image-browser-3.2.1-alpha.1.tgz",
"integrity": "sha512-6xWvQfB20sE6YtCWylgEAHuee3iD8h3aFIDbCS2yj7jIelKcYTrrp5jg2d2BhOOB6pC5JzF+QfpCrm0DmAIlgQ==",
"requires": {
"@vibrant/image": "^3.2.1-alpha.1"
}
},
"@vibrant/image-node": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/@vibrant/image-node/-/image-node-3.2.1-alpha.1.tgz",
"integrity": "sha512-/Io/Rpo4EkO6AhaXdcxUXkbOFhSFtjm0LSAM4c0AyGA5EbC8PyZqjk8b11bQAEMCaYaweFQfTdGD7oVbXe21CQ==",
"requires": {
"@jimp/custom": "^0.16.1",
"@jimp/plugin-resize": "^0.16.1",
"@jimp/types": "^0.16.1",
"@vibrant/image": "^3.2.1-alpha.1"
}
},
"@vibrant/quantizer": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/@vibrant/quantizer/-/quantizer-3.2.1-alpha.1.tgz",
"integrity": "sha512-iHnPx/+n4iLtYLm1GClSfyg2fFbMatFG0ipCyp9M6tXNIPAg+pSvUJSGBnVnH7Nl/bR8Gkkj1h0pJ4RsKcdIrQ==",
"requires": {
"@vibrant/color": "^3.2.1-alpha.1",
"@vibrant/image": "^3.2.1-alpha.1",
"@vibrant/types": "^3.2.1-alpha.1"
}
},
"@vibrant/quantizer-mmcq": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/@vibrant/quantizer-mmcq/-/quantizer-mmcq-3.2.1-alpha.1.tgz",
"integrity": "sha512-Wuk9PTZtxr8qsWTcgP6lcrrmrq36syVwxf+BUxdgQYntBcQ053SaN34lVGOJ0WPdK5vABoxbYljhceCgiILtZw==",
"requires": {
"@vibrant/color": "^3.2.1-alpha.1",
"@vibrant/image": "^3.2.1-alpha.1",
"@vibrant/quantizer": "^3.2.1-alpha.1"
}
},
"@vibrant/types": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/@vibrant/types/-/types-3.2.1-alpha.1.tgz",
"integrity": "sha512-ts9u7nsrENoYI5s0MmPOeY5kCLFKvQndKVDOPFCbTA0z493uhDp8mpiQhjFYTf3kPbS04z9zbHLE2luFC7x4KQ=="
},
"@vibrant/worker": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/@vibrant/worker/-/worker-3.2.1-alpha.1.tgz",
"integrity": "sha512-mtSlBdHkFNr4FOnMtqtHJxy9z5AsUcZzGlpiHzvWOoaoN9lNTDPwxOBd0q4VTYWuGPrIm6Fuq5m7aRbLv7KqiQ==",
"requires": {
"@vibrant/types": "^3.2.1-alpha.1"
}
},
"accepts": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
@ -5483,15 +5285,10 @@
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"at-least-node": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
"integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg=="
},
"aws-sdk": {
"version": "2.1007.0",
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1007.0.tgz",
"integrity": "sha512-I/o2R7RTh6NGRilsBrJHg7r9WprU9EavozZ43qMQcppaLAeZrECBbGfpfRyhfrj7885+KS+WOu1SGn6bsSd2VQ==",
"version": "2.1008.0",
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1008.0.tgz",
"integrity": "sha512-wBEon+ARCuMcwEPpOFZqRT3elBLfLtPqv8jMql3Hsr7Ua5toPlgKMmjf368iTzBNaY7TOZsjLAT9nAhvtSZ++g==",
"requires": {
"buffer": "4.9.2",
"events": "1.1.1",
@ -6313,11 +6110,10 @@
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
},
"fs-extra": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
"integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
"integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
"requires": {
"at-least-node": "^1.0.0",
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
@ -6723,6 +6519,11 @@
"path-exists": "^3.0.0"
}
},
"lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"loud-rejection": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
@ -6733,9 +6534,9 @@
}
},
"luxon": {
"version": "1.28.0",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz",
"integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ=="
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-2.0.2.tgz",
"integrity": "sha512-ZRioYLCgRHrtTORaZX1mx+jtxKtKuI5ZDvHNAmqpUzGqSrR+tL4FVLn/CUGMA3h0+AKD1MAxGI5GnCqR5txNqg=="
},
"map-age-cleaner": {
"version": "0.1.3",
@ -6756,9 +6557,9 @@
"integrity": "sha1-douOecAJvytk/ugG4ip7HEGQyZA="
},
"marked": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz",
"integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA=="
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/marked/-/marked-3.0.7.tgz",
"integrity": "sha512-ctKqbnLuNbsHbI26cfMyOlKgXGfl1orOv1AvWWDX7AkgfMOwCWvmuYc+mVLeWhQ9W6hdWVBynOs96VkcscKo0Q=="
},
"media-typer": {
"version": "0.3.0",
@ -6891,16 +6692,16 @@
}
},
"node-vibrant": {
"version": "3.2.1-alpha.1",
"resolved": "https://registry.npmjs.org/node-vibrant/-/node-vibrant-3.2.1-alpha.1.tgz",
"integrity": "sha512-EQergCp7fvbvUCE0VMCBnvaAV0lGWSP8SXLmuWQIBzQK5M5pIwcd9fIOXuzFkJx/8hUiiiLvAzzGDS/bIy2ikA==",
"requires": {
"@types/node": "^10.12.18",
"@vibrant/core": "^3.2.1-alpha.1",
"@vibrant/generator-default": "^3.2.1-alpha.1",
"@vibrant/image-browser": "^3.2.1-alpha.1",
"@vibrant/image-node": "^3.2.1-alpha.1",
"@vibrant/quantizer-mmcq": "^3.2.1-alpha.1",
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/node-vibrant/-/node-vibrant-3.1.6.tgz",
"integrity": "sha512-Wlc/hQmBMOu6xon12ZJHS2N3M+I6J8DhrD3Yo6m5175v8sFkVIN+UjhKVRcO+fqvre89ASTpmiFEP3nPO13SwA==",
"requires": {
"@jimp/custom": "^0.16.1",
"@jimp/plugin-resize": "^0.16.1",
"@jimp/types": "^0.16.1",
"@types/lodash": "^4.14.53",
"@types/node": "^10.11.7",
"lodash": "^4.17.20",
"url": "^0.11.0"
},
"dependencies": {

@ -43,23 +43,23 @@
"@tycrek/log": "^0.5.9",
"@tycrek/papito": "^0.3.4",
"any-shell-escape": "^0.1.1",
"aws-sdk": "^2.930.0",
"aws-sdk": "^2.1008.0",
"check-node-version": "^4.1.0",
"crypto-random-string": "3.3.1",
"discord-webhook-node": "^1.1.8",
"escape-html": "^1.0.3",
"express": "^4.17.1",
"express-busboy": "^8.0.0",
"express-rate-limit": "^5.2.6",
"ffmpeg-static": "^4.3.0",
"fs-extra": "^9.1.0",
"express-rate-limit": "^5.5.0",
"ffmpeg-static": "^4.4.0",
"fs-extra": "^10.0.0",
"helmet": "^4.6.0",
"jimp": "^0.16.1",
"luxon": "^1.26.0",
"marked": "^2.0.7",
"node-fetch": "^2.6.2",
"node-vibrant": "*",
"prompt": "^1.1.0",
"luxon": "^2.0.2",
"marked": "^3.0.7",
"node-fetch": "^2.6.5",
"node-vibrant": "^3.1.6",
"prompt": "^1.2.0",
"pug": "^3.0.2",
"sanitize-filename": "^1.6.3",
"stream-to-array": "^2.3.0",

@ -80,7 +80,7 @@ app.get('/', (req, res, next) => ASS_INDEX_ENABLED // skipcq: JS-0229
.catch(next));
// Set up custom frontend
const ASS_FRONTEND = fs.existsSync(path(`./${frontendName}/package.json`)) ? (require('submodule'), require(`../${frontendName}`)) : { enabled: false }; // todo: update with src/
const ASS_FRONTEND = fs.existsSync(path(`./${frontendName}/package.json`)) ? (require('submodule'), require(`../${frontendName}`)) : { enabled: false };
ASS_FRONTEND.enabled && app.use(ASS_FRONTEND.endpoint, ASS_FRONTEND.router); // skipcq: JS-0093
// Upload router (has to come after custom frontends as express-busboy interferes with all POST calls)

@ -6,7 +6,15 @@ export interface User {
}
export interface FileData {
// Data from Multer file object
// Data from request file object
uuid?: string
field?: string
file?: string
filename?: string
truncated?: boolean
done?: boolean
// Old Multer data being carried over to non-Multer files
path: string
size: number
mimetype: string
@ -52,6 +60,7 @@ export interface AssRequest extends Request {
ass?: { resourceId: string }
token?: string
file?: FileData
files?: { [key: string]: any }
}
export interface AssResponse extends Response {

@ -9,7 +9,7 @@ import { log } from './utils';
* @param {*} file The file to hash
* @returns The SHA1 hash
*/
export default (file: FileData) =>
export default (file: FileData): Promise<string> =>
new Promise((resolve, reject) =>
toArray((fs.createReadStream(file.path)))
.then((parts: any[]) => Buffer.concat(parts.map((part: any) => (Buffer.isBuffer(part) ? part : Buffer.from(part)))))

@ -1,151 +0,0 @@
// https://docs.digitalocean.com/products/spaces/resources/s3-sdk-examples/
// https://www.digitalocean.com/community/tutorials/how-to-upload-a-file-to-object-storage-with-node-js
const fs = require('fs-extra');
const aws = require('aws-sdk');
const Thumbnail = require('./thumbnails').default;
const Vibrant = require('./vibrant').default;
const Hash = require('./hash').default;
const { generateId, log } = require('./utils');
const { s3enabled, s3endpoint, s3bucket, s3usePathStyle, s3accessKey, s3secretKey, diskFilePath, saveAsOriginal, saveWithDate, mediaStrict, maxUploadSize } = require('../config.json');
const { CODE_UNSUPPORTED_MEDIA_TYPE } = require('../MagicNumbers.json');
const ID_GEN_LENGTH = 32;
const ALLOWED_MIMETYPES = /(image)|(video)|(audio)\//;
const s3 = new aws.S3({
s3ForcePathStyle: s3usePathStyle,
endpoint: new aws.Endpoint(s3endpoint),
credentials: new aws.Credentials({ accessKeyId: s3accessKey, secretAccessKey: s3secretKey })
});
function getDatedDirname() {
if (!saveWithDate) return diskFilePath;
// Get current month and year
const [month, , year] = new Date().toLocaleDateString('en-US').split('/');
// Add 0 before single digit months (6 turns into 06)
return `${diskFilePath}${diskFilePath.endsWith('/') ? '' : '/'}${year}-${`0${month}`.slice(-2)}`; // skipcq: JS-0074
}
function getLocalFilename(req) {
return `${getDatedDirname()}/${saveAsOriginal ? req.file.originalname : req.file.sha1}`;
}
function processUploaded(req, res, next) { // skipcq: JS-0045
// Fix file object
req.file = req.files.file;
// Other fixes
req.file.ext = '.'.concat(req.file.filename.split('.').pop());
req.file.originalname = req.file.filename;
req.file.path = req.file.file;
req.file.randomId = generateId('random', ID_GEN_LENGTH, null, null);
req.file.deleteId = generateId('random', ID_GEN_LENGTH, null, null);
// Set up types
req.file.is = {
image: false,
video: false,
audio: false,
other: false
};
// Specify correct type
const isType = req.file.mimetype.includes('image') ? 'image' : req.file.mimetype.includes('video') ? 'video' : req.file.mimetype.includes('audio') ? 'audio' : 'other';
req.file.is[isType] = true;
// Block the resource if the mimetype is not an image or video
if (mediaStrict && !ALLOWED_MIMETYPES.test(req.file.mimetype))
return log
.warn('Upload blocked', req.file.originalname, req.file.mimetype)
.warn('Strict media mode', 'only images, videos, & audio are file permitted')
.callback(() =>
fs.remove(req.file.path)
.then(() => log
.debug('Temp file', 'deleted')
.callback(() => res.sendStatus(CODE_UNSUPPORTED_MEDIA_TYPE)))
.catch((err) => log
.error('Temp file could not be deleted', err)
.callback(next, err)));
// Remove unwanted fields
delete req.file.uuid;
delete req.file.field;
delete req.file.file;
delete req.file.filename;
delete req.file.truncated;
delete req.file.done;
// Operations
Promise.all([Thumbnail(req.file), Vibrant(req.file), Hash(req.file), fs.stat(req.file.path)])
// skipcq: JS-0086
.then(([thumbnail, vibrant, sha1, stat]) => (
req.file.thumbnail = thumbnail, // skipcq: JS-0090
req.file.vibrant = vibrant, // skipcq: JS-0090
req.file.sha1 = sha1, // skipcq: JS-0090
req.file.size = stat.size // skipcq: JS-0090
))
// Check if file size is too big
.then(() => { if (req.file.size / Math.pow(1024, 2) > maxUploadSize) throw new Error('LIMIT_FILE_SIZE'); })
// Save file
.then(() => log.debug('Saving file', req.file.originalname, s3enabled ? 'in S3' : 'on disk'))
.then(() =>
// skipcq: JS-0229
new Promise((resolve, reject) => s3enabled
// Upload to Amazon S3
? s3.putObject({
Bucket: s3bucket,
Key: req.file.randomId.concat(req.file.ext),
ACL: 'public-read',
ContentType: req.file.mimetype,
Body: fs.createReadStream(req.file.path)
}).promise().then(resolve).catch(reject)
// Save to local storage
: fs.ensureDir(getDatedDirname())
.then(() => fs.copy(req.file.path, getLocalFilename(req), { preserveTimestamps: true }))
.then(resolve)
.catch(reject)
))
.then(() => log.debug('File saved', req.file.originalname, s3enabled ? 'in S3' : 'on disk'))
.catch(next)
// Delete the file
.then(() => fs.remove(req.file.path))
.then(() => log.debug('Temp file', 'deleted'))
// Fix the file path
.then(() => !s3enabled && (req.file.path = getLocalFilename(req))) // skipcq: JS-0090
.then(() => next())
.catch(next);
}
function deleteS3(file) {
return new Promise((resolve, reject) => s3
.deleteObject({ Bucket: s3bucket, Key: file.randomId.concat(file.ext) })
.promise()
.then(resolve)
.catch(reject));
}
function listAllKeys(resolve, reject, token) {
let allKeys = [];
s3.listObjectsV2({ Bucket: s3bucket, ContinuationToken: token }).promise()
.then((data) => (allKeys = allKeys.concat(data.Contents), data.IsTruncated ? listAllKeys(resolve, reject, data.NextContinuationToken) : resolve(allKeys.length))) // skipcq: JS-0086, JS-0090
.catch(reject);
}
function bucketSize() {
return new Promise((resolve, reject) => (s3enabled ? listAllKeys(resolve, reject) : resolve(0)));
}
module.exports = {
processUploaded,
deleteS3,
bucketSize
};

@ -0,0 +1,147 @@
// https://docs.digitalocean.com/products/spaces/resources/s3-sdk-examples/
// https://www.digitalocean.com/community/tutorials/how-to-upload-a-file-to-object-storage-with-node-js
import { AssRequest, AssResponse, FileData } from './definitions';
import fs, { Stats } from 'fs-extra';
import aws from 'aws-sdk';
import Thumbnail from './thumbnails';
import Vibrant from './vibrant';
import Hash from './hash';
import { generateId, log } from './utils';
const { s3enabled, s3endpoint, s3bucket, s3usePathStyle, s3accessKey, s3secretKey, diskFilePath, saveAsOriginal, saveWithDate, mediaStrict, maxUploadSize } = require('../config.json');
const { CODE_UNSUPPORTED_MEDIA_TYPE } = require('../MagicNumbers.json');
const ID_GEN_LENGTH = 32;
const ALLOWED_MIMETYPES = /(image)|(video)|(audio)\//;
const s3 = new aws.S3({
s3ForcePathStyle: s3usePathStyle,
endpoint: new aws.Endpoint(s3endpoint),
credentials: new aws.Credentials({ accessKeyId: s3accessKey, secretAccessKey: s3secretKey })
});
function getDatedDirname() {
if (!saveWithDate) return diskFilePath;
// Get current month and year
const [month, , year] = new Date().toLocaleDateString('en-US').split('/');
// Add 0 before single digit months (6 turns into 06)
return `${diskFilePath}${diskFilePath.endsWith('/') ? '' : '/'}${year}-${`0${month}`.slice(-2)}`; // skipcq: JS-0074
}
function getLocalFilename(req: AssRequest) {
return `${getDatedDirname()}/${saveAsOriginal ? req.file!.originalname : req.file!.sha1}`;
}
export function processUploaded(req: AssRequest, res: AssResponse, next: Function) { // skipcq: JS-0045
// Fix file object
req.file = req.files!.file;
// Other fixes
req.file!.ext = '.'.concat((req.file!.filename ?? '').split('.').pop() ?? '');
req.file!.originalname = req.file!.filename ?? '';
req.file!.path = req.file!.file ?? '';
req.file!.randomId = generateId('random', ID_GEN_LENGTH, 0, '');
req.file!.deleteId = generateId('random', ID_GEN_LENGTH, 0, '');
// Set up types
req.file!.is = {
image: false,
video: false,
audio: false,
other: false
};
// Specify correct type
const isType = req.file!.mimetype.includes('image') ? 'image' : req.file!.mimetype.includes('video') ? 'video' : req.file!.mimetype.includes('audio') ? 'audio' : 'other';
req.file!.is[isType] = true;
// Block the resource if the mimetype is not an image or video
if (mediaStrict && !ALLOWED_MIMETYPES.test(req.file!.mimetype))
return log
.warn('Upload blocked', req.file!.originalname, req.file!.mimetype)
.warn('Strict media mode', 'only images, videos, & audio are file permitted')
.callback(() =>
fs.remove(req.file!.path)
.then(() => log
.debug('Temp file', 'deleted')
.callback(() => res.sendStatus(CODE_UNSUPPORTED_MEDIA_TYPE)))
.catch((err) => log
.error('Temp file could not be deleted', err)
.callback(next, err)));
// Remove unwanted fields
delete req.file!.uuid;
delete req.file!.field;
delete req.file!.file;
delete req.file!.filename;
delete req.file!.truncated;
delete req.file!.done;
// Operations
// @ts-ignore
Promise.all([Thumbnail(req.file), Vibrant(req.file), Hash(req.file), fs.stat(req.file!.path)])
// skipcq: JS-0086
.then(([thumbnail, vibrant, sha1, stat]: [string, string, string, Stats]) => (
req.file!.thumbnail = thumbnail, // skipcq: JS-0090
req.file!.vibrant = vibrant, // skipcq: JS-0090
req.file!.sha1 = sha1, // skipcq: JS-0090
req.file!.size = stat.size // skipcq: JS-0090
))
// Check if file size is too big
.then(() => { if (req.file!.size / Math.pow(1024, 2) > maxUploadSize) throw new Error('LIMIT_FILE_SIZE'); })
// Save file
.then(() => log.debug('Saving file', req.file!.originalname, s3enabled ? 'in S3' : 'on disk'))
.then(() =>
// skipcq: JS-0229
new Promise((resolve, reject) => s3enabled
// Upload to Amazon S3
? s3.putObject({
Bucket: s3bucket,
Key: req.file!.randomId.concat(req.file!.ext),
ACL: 'public-read',
ContentType: req.file!.mimetype,
Body: fs.createReadStream(req.file!.path)
}).promise().then(resolve).catch(reject)
// Save to local storage
: fs.ensureDir(getDatedDirname())
.then(() => fs.copy(req.file!.path, getLocalFilename(req), { preserveTimestamps: true }))
.then(resolve)
.catch(reject)
))
.then(() => log.debug('File saved', req.file!.originalname, s3enabled ? 'in S3' : 'on disk'))
.catch((err) => next(err))
// Delete the file
.then(() => fs.remove(req.file!.path))
.then(() => log.debug('Temp file', 'deleted'))
// Fix the file path
.then(() => !s3enabled && (req.file!.path = getLocalFilename(req))) // skipcq: JS-0090
.then(() => next())
.catch((err) => next(err));
}
export function deleteS3(file: FileData) {
return new Promise((resolve, reject) => s3
.deleteObject({ Bucket: s3bucket, Key: file.randomId.concat(file.ext) })
.promise()
.then(resolve)
.catch(reject));
}
function listAllKeys(resolve: Function, reject: Function, token?: string) {
let allKeys: string[] = [];
s3.listObjectsV2({ Bucket: s3bucket, ContinuationToken: token }).promise()
.then((data: { [key: string]: any }) => (allKeys = allKeys.concat(data.Contents), data.IsTruncated ? listAllKeys(resolve, reject, data.NextContinuationToken) : resolve(allKeys.length))) // skipcq: JS-0086, JS-0090
.catch((err) => reject(err));
}
export function bucketSize() {
return new Promise((resolve, reject) => (s3enabled ? listAllKeys(resolve, reject) : resolve(0)));
}

@ -82,7 +82,7 @@ function getImageThumbnail(file: FileData) {
* @param {*} file The file to generate a thumbnail for
* @returns The thumbnail filename (NOT the path)
*/
export default (file: FileData) =>
export default (file: FileData): Promise<string> =>
new Promise((resolve, reject) =>
(file.is.video ? getVideoThumbnail : file.is.image ? getImageThumbnail : () => Promise.resolve())(file)
.then(() => resolve((file.is.video || file.is.image) ? getNewName(file.randomId) : file.is.audio ? 'views/ass-audio-icon.png' : 'views/ass-file-icon.png'))

@ -78,7 +78,7 @@ export function generateId(mode: string, length: number, gfyLength: number, orig
}
// Set up pathing
export const path = (...paths: string[]) => Path.join(process.cwd(), ...paths); // '..' was added to make it easier to run files after moving the project to src/
export const path = (...paths: string[]) => Path.join(process.cwd(), ...paths);
const idModes = {
zws: 'zws', // Zero-width spaces (see: https://zws.im/)
@ -121,7 +121,7 @@ module.exports = {
arrayEquals,
downloadTempS3: (file: FileData) => new Promise((resolve: Function, reject) =>
fetch(getS3url(file.randomId, file.ext))
.then((f2) => f2.body.pipe(fs.createWriteStream(Path.join(__dirname, diskFilePath, sanitize(file.originalname))).on('close', () => resolve())))
.then((f2) => f2.body!.pipe(fs.createWriteStream(Path.join(__dirname, diskFilePath, sanitize(file.originalname))).on('close', () => resolve())))
.catch(reject)),
}

@ -26,4 +26,4 @@ function getVibrant(file: FileData, resolve: Function, reject: Function) {
* @param {*} file The file to get a colour from
* @returns The Vibrant colour as a Hex value (or random Hex value for videos)
*/
export default (file: FileData) => new Promise((resolve, reject) => !file.is.image ? resolve(randomHexColour()) : getVibrant(file, resolve, reject)); // skipcq: JS-0229
export default (file: FileData): Promise<string> => new Promise((resolve, reject) => !file.is.image ? resolve(randomHexColour()) : getVibrant(file, resolve, reject)); // skipcq: JS-0229

Loading…
Cancel
Save