From dd6a72eace5093197a1249d250993d399539d1fb Mon Sep 17 00:00:00 2001 From: Pablo Ferreiro Date: Tue, 28 Jun 2022 20:35:11 +0200 Subject: [PATCH] Using Alpine variant for Docker --- .dockerignore | 1 + .gitignore | 1 - Dockerfile | 9 +++++--- README.md | 9 +++++--- api/index.js | 50 +++++++++++++++++++++++------------------ package.json | 4 ++-- src/Signer.js | 61 +++++++++++++++++++++++++-------------------------- src/Utils.js | 4 ++-- yarn.lock | 30 ++++++++++++------------- 9 files changed, 91 insertions(+), 78 deletions(-) diff --git a/.dockerignore b/.dockerignore index 81e83fe..a9960f5 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,3 @@ node_modules .vercel +.vscode diff --git a/.gitignore b/.gitignore index 0904902..0e9e6cc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ /.venv /.vscode -/.idea /node_modules .vercel diff --git a/Dockerfile b/Dockerfile index 5e74a2b..371a568 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,12 @@ -FROM node:17 - +FROM node:18-alpine WORKDIR /usr/src/app -COPY package.json ./ +# Setup Alpine for building "canvas" package +RUN apk add --no-cache python3 make g++ pkgconfig cairo-dev pango-dev + +COPY package.json yarn.lock ./ RUN yarn install COPY . . + EXPOSE 8080 CMD [ "node", "api/index.js" ] diff --git a/README.md b/README.md index 306f5aa..5f182b1 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ This is a port of [tiktok-signature](https://github.com/carcabot/tiktok-signatur This project allows signing TikTok urls without having to run a headless browser, which lowers ram usage a lot. +[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://www.heroku.com/deploy/?template=https://github.com/pablouser1/SignTok) ## Installation ### Docker ``` @@ -24,12 +25,14 @@ Now you can run the server with: node api/index.js ``` ## Usage -For webserver: +### Webserver You can send a POST request to http://localhost:8080/signature with a raw/plain body containing the url (Content-Type: text/plain) -For cli usage: +If you plan to use the already deployed Vercel version, you should use https://signtok.vercel.app/api/signature + +### Cli ``` -node index.js 'YOUR_URL_HERE' +node local.js 'YOUR_URL_HERE' ``` diff --git a/api/index.js b/api/index.js index cf64246..92dc098 100644 --- a/api/index.js +++ b/api/index.js @@ -1,17 +1,16 @@ -const Signer = require("../src/Signer") -const http = require("http") +const Signer = require("../src/Signer"); +const http = require("http"); -const PORT = process.env.PORT || 8080 +const PORT = process.env.PORT || 8080; -const signer = new Signer() +const signer = new Signer(); const server = http.createServer(async (req, res) => { + res.writeHead(200, { + "Content-Type": "application/json", + "Cache-Control": "s-max-age=1, stale-while-revalidate" // caching stuff for vercel + }); if (req.method === "POST") { - res.writeHead(200, { - "Content-Type": "application/json", - "Cache-Control": "s-max-age=1, stale-while-revalidate" // caching stuff for vercel - }); - // Get url from POST body const buffers = []; for await (const chunk of req) { @@ -19,19 +18,28 @@ const server = http.createServer(async (req, res) => { } const url = Buffer.concat(buffers).toString(); - const data = signer.sign(url) - console.log("Sent data from request with url: " + url) - res.write(JSON.stringify({ - status: "ok", - data: { - ...data, - navigator: signer.navigator() - } - })); + const data = signer.sign(url); + console.log("Sent data from request with url: " + url); + res.write( + JSON.stringify({ + status: "ok", + data: { + ...data, + navigator: signer.navigator() + } + }) + ); + } else { + res.write( + JSON.stringify({ + status: "error", + data: "You have to send a POST request with a valid TikTok URL on the body!" + }) + ) } - res.end() -}) + res.end(); +}); server.listen(PORT, () => { console.log(`App listening on port: ${PORT}`); -}) +}); diff --git a/package.json b/package.json index c1fc7d4..9cac2fb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "signtok", - "version": "1.1.2", + "version": "1.1.3", "description": "Sign your TikTok requests easily", "repository": "https://github.com/pablouser1/SignTok", "author": "Pablo Ferreiro", @@ -11,7 +11,7 @@ "vercel-build": "yum -y install libuuid-devel libmount-devel && cp /lib64/{libuuid,libmount,libblkid}.so.1 node_modules/canvas/build/Release/" }, "dependencies": { - "canvas": "^2.9.1", + "canvas": "^2.9.3", "jsdom": "^19.0.0" } } diff --git a/src/Signer.js b/src/Signer.js index 1fb113f..c3934d7 100644 --- a/src/Signer.js +++ b/src/Signer.js @@ -1,37 +1,36 @@ -const fs = require("fs") -const Utils = require("./Utils") -const { JSDOM, ResourceLoader } = require("jsdom") -const { createCipheriv } = require("crypto") +const fs = require("fs"); +const Utils = require("./Utils"); +const { JSDOM, ResourceLoader } = require("jsdom"); +const { createCipheriv } = require("crypto"); class Signer { static DEFAULT_USERAGENT = - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36" - static PASSWORD = 'webapp1.0+202106' + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36"; + static PASSWORD = "webapp1.0+202106"; /** * @type Window */ - window = null + window = null; constructor(userAgent = Signer.DEFAULT_USERAGENT) { - const signature_js = fs.readFileSync(__dirname + "/../js/signature.js", "utf-8") - const resourceLoader = new ResourceLoader({ - userAgent - }) + const signature_js = fs.readFileSync(__dirname + "/../js/signature.js", "utf-8"); + const resourceLoader = new ResourceLoader({ userAgent }); - const { window } = new JSDOM(``, { + const { window } = new JSDOM("", { url: "https://www.tiktok.com", referrer: "https://www.tiktok.com", contentType: "text/html", - includeNodeLocations: true, + includeNodeLocations: false, runScripts: "outside-only", + pretendToBeVisual: true, resources: resourceLoader - }) - this.window = window - this.window.eval(signature_js.toString()) + }); + this.window = window; + this.window.eval(signature_js.toString()); this.window.byted_acrawler.init({ - "aid":24, - "dfp":true - }) + aid: 24, + dfp: true + }); } navigator() { @@ -42,34 +41,34 @@ class Signer { browser_platform: this.window.navigator.platform, browser_name: this.window.navigator.appCodeName, browser_version: this.window.navigator.appVersion - } + }; } signature(url) { - return this.window.byted_acrawler.sign({ url }) + return this.window.byted_acrawler.sign({ url }); } xttparams(params) { - params += "&is_encryption=1" + params += "&is_encryption=1"; // Encrypt query string using aes-128-cbc const cipher = createCipheriv("aes-128-cbc", Signer.PASSWORD, Signer.PASSWORD); - return Buffer.concat([cipher.update(params), cipher.final()]).toString('base64'); + return Buffer.concat([cipher.update(params), cipher.final()]).toString("base64"); } sign(url) { - const verifyFp = Utils.verify_fp() - url += "&verifyFp=" + verifyFp - const signature = this.signature(url) - const signed_url = url + "&_signature=" + signature - const params = new URL(url).searchParams.toString() - const xttparams = this.xttparams(params) + const verifyFp = Utils.verify_fp(); + url += "&verifyFp=" + verifyFp; + const signature = this.signature(url); + const signed_url = url + "&_signature=" + signature; + const params = new URL(url).searchParams.toString(); + const xttparams = this.xttparams(params); return { signature: signature, verify_fp: verifyFp, signed_url: signed_url, "x-tt-params": xttparams - } + }; } } -module.exports = Signer +module.exports = Signer; diff --git a/src/Utils.js b/src/Utils.js index a77a9d9..8c9db69 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -1,8 +1,8 @@ class Utils { static verify_fp() { // TODO, add proper verify fp method - return "verify_68b8ccfa65726db8b3db0cc07821d696" + return "verify_68b8ccfa65726db8b3db0cc07821d696"; } } -module.exports = Utils +module.exports = Utils; diff --git a/yarn.lock b/yarn.lock index fa2a538..04bc244 100644 --- a/yarn.lock +++ b/yarn.lock @@ -103,10 +103,10 @@ browser-process-hrtime@^1.0.0: resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== -canvas@^2.9.1: - version "2.9.1" - resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.9.1.tgz#58ec841cba36cef0675bc7a74ebd1561f0b476b0" - integrity sha512-vSQti1uG/2gjv3x6QLOZw7TctfufaerTWbVe+NSduHxxLGB+qf3kFgQ6n66DSnuoINtVUjrLLIK2R+lxrBG07A== +canvas@^2.9.3: + version "2.9.3" + resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.9.3.tgz#8723c4f970442d4cdcedba5221579f9660a58bdb" + integrity sha512-WOUM7ghii5TV2rbhaZkh1youv/vW1/Canev6Yx6BG2W+1S07w8jKZqKkPnbiPpQEDsnJdN8ouDd7OvQEGXDcUw== dependencies: "@mapbox/node-pre-gyp" "^1.0.0" nan "^2.15.0" @@ -435,9 +435,9 @@ minimatch@^3.1.1: brace-expansion "^1.1.7" minipass@^3.0.0: - version "3.1.6" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.6.tgz#3b8150aa688a711a1521af5e8779c1d3bb4f45ee" - integrity sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ== + version "3.3.3" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.3.tgz#fd1f0e6c06449c10dadda72618b59c00f3d6378d" + integrity sha512-N0BOsdFAlNRfmwMhjAsLVWOk7Ljmeb39iqFlsV1At+jqRhSUP9yeof8FyJu4imaJiSUp8vQebWD/guZwGQC8iA== dependencies: yallist "^4.0.0" @@ -489,9 +489,9 @@ npmlog@^5.0.1: set-blocking "^2.0.0" nwsapi@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" - integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== + version "2.2.1" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.1.tgz#10a9f268fbf4c461249ebcfe38e359aa36e2577c" + integrity sha512-JYOWTeFoS0Z93587vRJgASD5Ut11fYl5NyihP3KrYBvMe1FRRs6RN7m20SA/16GM4P6hTnZjT+UmDOt38UeXNg== object-assign@^4.1.1: version "4.1.1" @@ -680,7 +680,7 @@ tr46@~0.0.3: type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== dependencies: prelude-ls "~1.1.2" @@ -692,7 +692,7 @@ universalify@^0.1.2: util-deprecate@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== w3c-hr-time@^1.0.2: version "1.0.2" @@ -711,7 +711,7 @@ w3c-xmlserializer@^3.0.0: webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== webidl-conversions@^7.0.0: version "7.0.0" @@ -749,7 +749,7 @@ whatwg-url@^11.0.0: whatwg-url@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== dependencies: tr46 "~0.0.3" webidl-conversions "^3.0.0" @@ -769,7 +769,7 @@ word-wrap@~1.2.3: wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== ws@^8.2.3: version "8.8.0"