Using Alpine variant for Docker

This commit is contained in:
Pablo Ferreiro
2022-06-28 20:35:11 +02:00
parent eaa76f0dd9
commit dd6a72eace
9 changed files with 91 additions and 78 deletions

View File

@@ -1,2 +1,3 @@
node_modules node_modules
.vercel .vercel
.vscode

1
.gitignore vendored
View File

@@ -1,5 +1,4 @@
/.venv /.venv
/.vscode /.vscode
/.idea
/node_modules /node_modules
.vercel .vercel

View File

@@ -1,9 +1,12 @@
FROM node:17 FROM node:18-alpine
WORKDIR /usr/src/app 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 RUN yarn install
COPY . . COPY . .
EXPOSE 8080 EXPOSE 8080
CMD [ "node", "api/index.js" ] CMD [ "node", "api/index.js" ]

View File

@@ -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. 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 ## Installation
### Docker ### Docker
``` ```
@@ -24,12 +25,14 @@ Now you can run the server with:
node api/index.js node api/index.js
``` ```
## Usage ## Usage
For webserver: ### Webserver
You can send a POST request to http://localhost:8080/signature with a raw/plain body containing the url You can send a POST request to http://localhost:8080/signature with a raw/plain body containing the url
(Content-Type: text/plain) (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'
``` ```

View File

@@ -1,17 +1,16 @@
const Signer = require("../src/Signer") const Signer = require("../src/Signer");
const http = require("http") 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) => { 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") { 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 // Get url from POST body
const buffers = []; const buffers = [];
for await (const chunk of req) { for await (const chunk of req) {
@@ -19,19 +18,28 @@ const server = http.createServer(async (req, res) => {
} }
const url = Buffer.concat(buffers).toString(); const url = Buffer.concat(buffers).toString();
const data = signer.sign(url) const data = signer.sign(url);
console.log("Sent data from request with url: " + url) console.log("Sent data from request with url: " + url);
res.write(JSON.stringify({ res.write(
status: "ok", JSON.stringify({
data: { status: "ok",
...data, data: {
navigator: signer.navigator() ...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, () => { server.listen(PORT, () => {
console.log(`App listening on port: ${PORT}`); console.log(`App listening on port: ${PORT}`);
}) });

View File

@@ -1,6 +1,6 @@
{ {
"name": "signtok", "name": "signtok",
"version": "1.1.2", "version": "1.1.3",
"description": "Sign your TikTok requests easily", "description": "Sign your TikTok requests easily",
"repository": "https://github.com/pablouser1/SignTok", "repository": "https://github.com/pablouser1/SignTok",
"author": "Pablo Ferreiro", "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/" "vercel-build": "yum -y install libuuid-devel libmount-devel && cp /lib64/{libuuid,libmount,libblkid}.so.1 node_modules/canvas/build/Release/"
}, },
"dependencies": { "dependencies": {
"canvas": "^2.9.1", "canvas": "^2.9.3",
"jsdom": "^19.0.0" "jsdom": "^19.0.0"
} }
} }

View File

@@ -1,37 +1,36 @@
const fs = require("fs") const fs = require("fs");
const Utils = require("./Utils") const Utils = require("./Utils");
const { JSDOM, ResourceLoader } = require("jsdom") const { JSDOM, ResourceLoader } = require("jsdom");
const { createCipheriv } = require("crypto") const { createCipheriv } = require("crypto");
class Signer { class Signer {
static DEFAULT_USERAGENT = 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" "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' static PASSWORD = "webapp1.0+202106";
/** /**
* @type Window * @type Window
*/ */
window = null window = null;
constructor(userAgent = Signer.DEFAULT_USERAGENT) { constructor(userAgent = Signer.DEFAULT_USERAGENT) {
const signature_js = fs.readFileSync(__dirname + "/../js/signature.js", "utf-8") const signature_js = fs.readFileSync(__dirname + "/../js/signature.js", "utf-8");
const resourceLoader = new ResourceLoader({ const resourceLoader = new ResourceLoader({ userAgent });
userAgent
})
const { window } = new JSDOM(``, { const { window } = new JSDOM("", {
url: "https://www.tiktok.com", url: "https://www.tiktok.com",
referrer: "https://www.tiktok.com", referrer: "https://www.tiktok.com",
contentType: "text/html", contentType: "text/html",
includeNodeLocations: true, includeNodeLocations: false,
runScripts: "outside-only", runScripts: "outside-only",
pretendToBeVisual: true,
resources: resourceLoader resources: resourceLoader
}) });
this.window = window this.window = window;
this.window.eval(signature_js.toString()) this.window.eval(signature_js.toString());
this.window.byted_acrawler.init({ this.window.byted_acrawler.init({
"aid":24, aid: 24,
"dfp":true dfp: true
}) });
} }
navigator() { navigator() {
@@ -42,34 +41,34 @@ class Signer {
browser_platform: this.window.navigator.platform, browser_platform: this.window.navigator.platform,
browser_name: this.window.navigator.appCodeName, browser_name: this.window.navigator.appCodeName,
browser_version: this.window.navigator.appVersion browser_version: this.window.navigator.appVersion
} };
} }
signature(url) { signature(url) {
return this.window.byted_acrawler.sign({ url }) return this.window.byted_acrawler.sign({ url });
} }
xttparams(params) { xttparams(params) {
params += "&is_encryption=1" params += "&is_encryption=1";
// Encrypt query string using aes-128-cbc // Encrypt query string using aes-128-cbc
const cipher = createCipheriv("aes-128-cbc", Signer.PASSWORD, Signer.PASSWORD); 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) { sign(url) {
const verifyFp = Utils.verify_fp() const verifyFp = Utils.verify_fp();
url += "&verifyFp=" + verifyFp url += "&verifyFp=" + verifyFp;
const signature = this.signature(url) const signature = this.signature(url);
const signed_url = url + "&_signature=" + signature const signed_url = url + "&_signature=" + signature;
const params = new URL(url).searchParams.toString() const params = new URL(url).searchParams.toString();
const xttparams = this.xttparams(params) const xttparams = this.xttparams(params);
return { return {
signature: signature, signature: signature,
verify_fp: verifyFp, verify_fp: verifyFp,
signed_url: signed_url, signed_url: signed_url,
"x-tt-params": xttparams "x-tt-params": xttparams
} };
} }
} }
module.exports = Signer module.exports = Signer;

View File

@@ -1,8 +1,8 @@
class Utils { class Utils {
static verify_fp() { static verify_fp() {
// TODO, add proper verify fp method // TODO, add proper verify fp method
return "verify_68b8ccfa65726db8b3db0cc07821d696" return "verify_68b8ccfa65726db8b3db0cc07821d696";
} }
} }
module.exports = Utils module.exports = Utils;

View File

@@ -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" resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626"
integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==
canvas@^2.9.1: canvas@^2.9.3:
version "2.9.1" version "2.9.3"
resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.9.1.tgz#58ec841cba36cef0675bc7a74ebd1561f0b476b0" resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.9.3.tgz#8723c4f970442d4cdcedba5221579f9660a58bdb"
integrity sha512-vSQti1uG/2gjv3x6QLOZw7TctfufaerTWbVe+NSduHxxLGB+qf3kFgQ6n66DSnuoINtVUjrLLIK2R+lxrBG07A== integrity sha512-WOUM7ghii5TV2rbhaZkh1youv/vW1/Canev6Yx6BG2W+1S07w8jKZqKkPnbiPpQEDsnJdN8ouDd7OvQEGXDcUw==
dependencies: dependencies:
"@mapbox/node-pre-gyp" "^1.0.0" "@mapbox/node-pre-gyp" "^1.0.0"
nan "^2.15.0" nan "^2.15.0"
@@ -435,9 +435,9 @@ minimatch@^3.1.1:
brace-expansion "^1.1.7" brace-expansion "^1.1.7"
minipass@^3.0.0: minipass@^3.0.0:
version "3.1.6" version "3.3.3"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.6.tgz#3b8150aa688a711a1521af5e8779c1d3bb4f45ee" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.3.tgz#fd1f0e6c06449c10dadda72618b59c00f3d6378d"
integrity sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ== integrity sha512-N0BOsdFAlNRfmwMhjAsLVWOk7Ljmeb39iqFlsV1At+jqRhSUP9yeof8FyJu4imaJiSUp8vQebWD/guZwGQC8iA==
dependencies: dependencies:
yallist "^4.0.0" yallist "^4.0.0"
@@ -489,9 +489,9 @@ npmlog@^5.0.1:
set-blocking "^2.0.0" set-blocking "^2.0.0"
nwsapi@^2.2.0: nwsapi@^2.2.0:
version "2.2.0" version "2.2.1"
resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.1.tgz#10a9f268fbf4c461249ebcfe38e359aa36e2577c"
integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== integrity sha512-JYOWTeFoS0Z93587vRJgASD5Ut11fYl5NyihP3KrYBvMe1FRRs6RN7m20SA/16GM4P6hTnZjT+UmDOt38UeXNg==
object-assign@^4.1.1: object-assign@^4.1.1:
version "4.1.1" version "4.1.1"
@@ -680,7 +680,7 @@ tr46@~0.0.3:
type-check@~0.3.2: type-check@~0.3.2:
version "0.3.2" version "0.3.2"
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==
dependencies: dependencies:
prelude-ls "~1.1.2" prelude-ls "~1.1.2"
@@ -692,7 +692,7 @@ universalify@^0.1.2:
util-deprecate@^1.0.1: util-deprecate@^1.0.1:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 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: w3c-hr-time@^1.0.2:
version "1.0.2" version "1.0.2"
@@ -711,7 +711,7 @@ w3c-xmlserializer@^3.0.0:
webidl-conversions@^3.0.0: webidl-conversions@^3.0.0:
version "3.0.1" version "3.0.1"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" 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: webidl-conversions@^7.0.0:
version "7.0.0" version "7.0.0"
@@ -749,7 +749,7 @@ whatwg-url@^11.0.0:
whatwg-url@^5.0.0: whatwg-url@^5.0.0:
version "5.0.0" version "5.0.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==
dependencies: dependencies:
tr46 "~0.0.3" tr46 "~0.0.3"
webidl-conversions "^3.0.0" webidl-conversions "^3.0.0"
@@ -769,7 +769,7 @@ word-wrap@~1.2.3:
wrappy@1: wrappy@1:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 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: ws@^8.2.3:
version "8.8.0" version "8.8.0"