File size: 2,446 Bytes
3fe39f8
 
1f7f268
39f75ab
1f7f268
3fe39f8
0027263
3fe39f8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import got from "got";
import vm from "vm";
import { DEFAULT_HEADERS } from "../constant.js";
import { generateHash } from "./util.js";
import { SavefromArgsSchema, SavefromSchema } from "../types/savefrom-v1.js";

export async function savefrom(url) {
    SavefromArgsSchema.parse(arguments);

    const form = {
        sf_url: url,
        sf_submit: "",
        new: "2",
        lang: "en",
        app: "",
        country: "en",
        os: "Windows",
        browser: "Chrome",
        channel: "main",
        "sf-nomad": "1",
        url,
        ts: Date.now(),
        _ts: 1720433117117,
        _tsc: 0,
        _s: generateHash(url),
        _x: 1,
    };

    const data = await got
        .post("https://worker.savefrom.net/savefrom.php", {
            headers: {
                ...DEFAULT_HEADERS,
                "content-type": "application/x-www-form-urlencoded",
                origin: "https://en.savefrom.net",
                referer: "https://en.savefrom.net/",
            },
            form,
        })
        .text();

    const context = {
        results: null,
        parent: { document: { location: {} } },
        frameElement: {},
        atob: (base64) => Buffer.from(base64, "base64").toString(),
        _decodeURIComponent: (uri) => {
            const decoded = decodeURIComponent(uri);
            if (/showResult/.test(decoded)) {
                context.results = decoded;
                return "true";
            }
            return decoded;
        },
    };

    vm.createContext(context);
    new vm.Script(`decodeURIComponent=_decodeURIComponent;${data}`).runInContext(context);

    const executed =
        context.results?.split("window.parent.sf.videoResult.show(")?.[1] ||
        context.results?.split("window.parent.sf.videoResult.showRows(")?.[1];

    if (!executed) {
        throw new Error("Cannot find result from evaluation!");
    }

    let json = null;
    try {
        if (context.results?.includes("showRows")) {
            const splits = executed.split('],"');
            const lastIndex = splits.findIndex((v) => v.includes("window.parent.sf.enableElement"));
            json = JSON.parse(splits.slice(0, lastIndex).join('],"') + "]");
        } else {
            json = [JSON.parse(executed.split(");")[0])];
        }
    } catch (e) {
        throw new Error("Cannot parse JSON results data from evaluation!");
    }

    return SavefromSchema.parse(json);
}