LOADING
AdsUrl bypass ambil final url dengan cepat, dan sangat lama jika solve manual ke web, dan menggunakan bypass cloudflare fgsi atau bisa manual menggunakan token SESSION di ambil manual
#!/usr/bin/env node
/**
* Move2Link resolver
*
* Mode token:
* node move2link.js --token "eyJ..."
* node move2link.js --token-file token.txt
*
* Mode auto (Fgsi WAF Session):
* node move2link.js --url "https://move2link.co/4b08f3c"
*
*/
import { readFileSync } from 'node:fs';
import { stdin as input } from 'node:process';
const API_BASE = 'https://api.move2link.com/api/v1';
const JWT_RE = /^eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/;
const FGSI_KEY = 'AMBIL-KEY-DI-https://fgsi.dpdns.org';
const FGSI_WAF_URL = 'https://fgsi.dpdns.org/api/tools/cfclearance/waf-session';
function parseArgs() {
const args = process.argv.slice(2);
const get = (flag) => {
const i = args.indexOf(flag);
return i !== -1 && args[i + 1] ? args[i + 1] : null;
};
return {
url: get('--url') || args.find((a) => a.startsWith('http')) || null,
token: get('--token'),
cookie: get('--cookie'),
tokenFile: get('--token-file'),
stdin: args.includes('--stdin'),
};
}
function asJwt(raw) {
if (!raw) return null;
let t = String(raw).trim();
t = t.replace(/^SESSION=/i, '');
t = t.replace(/^["']|["']$/g, '');
return JWT_RE.test(t) ? t : null;
}
function extractTokenFromCookie(cookie) {
if (!cookie) return null;
const m = String(cookie).match(/(?:^|;\s*)SESSION=([^;]+)/i);
if (m) return asJwt(decodeURIComponent(m[1].trim()));
return asJwt(cookie);
}
function jwtProgress(token) {
try {
const part = token.split('.')[1];
if (!part) return null;
const pad = '='.repeat((4 - (part.length % 4)) % 4);
const b64 = part.replace(/-/g, '+').replace(/_/g, '/') + pad;
const json = Buffer.from(b64, 'base64').toString('utf8');
const p = JSON.parse(json);
const step = Number(p.step);
const maxStep = Number(p.max_step);
if (!Number.isFinite(step) || !Number.isFinite(maxStep) || maxStep < 1) return null;
return { step, maxStep };
} catch {
return null;
}
}
async function apiCall(path, method, token) {
const endpoint = API_BASE + path;
const res = await fetch(endpoint, {
method,
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
Origin: 'https://move2link.co',
Referer: 'https://move2link.co/',
},
body: JSON.stringify({ token, csrf_token: 'x', imps: [] }),
});
const text = await res.text();
let parsed = {};
try {
parsed = JSON.parse(text);
} catch {}
if (!res.ok) {
throw new Error(path + ' HTTP ' + res.status + ': ' + text.slice(0, 400));
}
return parsed.data ?? parsed ?? {};
}
async function unlock(token) {
let cur = token;
const steps = [];
for (;;) {
const progress = jwtProgress(cur);
if (!progress) throw new Error('JWT invalid / tidak ada step & max_step');
steps.push({ step: progress.step, maxStep: progress.maxStep });
if (progress.step >= progress.maxStep - 1) break;
const data = await apiCall('/views/track', 'PUT', cur);
const next = (data.token || '').trim();
if (!next || !JWT_RE.test(next)) {
throw new Error('Track gagal. Response: ' + JSON.stringify(data).slice(0, 300));
}
cur = next;
}
const data = await apiCall('/views/finalize', 'POST', cur);
const finalUrl = String(data.redirect_url || data.url || '').trim();
if (!/^https?:\/\//i.test(finalUrl)) {
throw new Error('Finalize gagal. Response: ' + JSON.stringify(data).slice(0, 400));
}
return { finalUrl, steps };
}
/** Auto: Fgsi WAF Session → ambil SESSION JWT → unlock */
async function resolveFromUrl(url) {
const res = await fetch(`${FGSI_WAF_URL}?apikey=${FGSI_KEY}&url=${encodeURIComponent(url)}`);
const json = await res.json();
if (!json.status || !json.data?.cookies) {
throw new Error('Fgsi WAF Session gagal: ' + JSON.stringify(json).slice(0, 300));
}
const sessionCookie = json.data.cookies.find((c) => c.name === 'SESSION');
if (!sessionCookie) {
throw new Error('SESSION cookie tidak ada di response Fgsi');
}
const token = asJwt(sessionCookie.value);
if (!token) throw new Error('SESSION value bukan JWT valid');
return token;
}
async function readStdin() {
const chunks = [];
for await (const chunk of input) chunks.push(chunk);
return Buffer.concat(chunks).toString('utf8').trim();
}
async function resolveToken(opts) {
if (opts.token) {
const t = asJwt(opts.token);
if (t) return { token: t, source: 'token' };
}
if (opts.cookie) {
const t = extractTokenFromCookie(opts.cookie);
if (t) return { token: t, source: 'cookie' };
}
if (opts.tokenFile) {
const raw = readFileSync(opts.tokenFile, 'utf8');
const t = asJwt(raw) || extractTokenFromCookie(raw);
if (t) return { token: t, source: 'token-file' };
}
if (opts.stdin) {
const raw = await readStdin();
const t = asJwt(raw) || extractTokenFromCookie(raw);
if (t) return { token: t, source: 'stdin' };
}
if (opts.url) {
const t = await resolveFromUrl(opts.url);
return { token: t, source: 'fgsi+url' };
}
return null;
}
async function main() {
const opts = parseArgs();
const t0 = Date.now();
const out = {
ok: false,
finalUrl: null,
durationMs: 0,
durationSec: 0,
steps: [],
source: null,
input: opts.url || null,
timestamp: new Date().toISOString(),
};
try {
const resolved = await resolveToken(opts);
if (!resolved) {
throw new Error(
'Butuh --token / --token-file / --cookie / --stdin / --url. ' +
'Untuk auto full: node move2link.js --url https://move2link.co/xxxx'
);
}
out.source = resolved.source;
const { finalUrl, steps } = await unlock(resolved.token);
out.ok = true;
out.finalUrl = finalUrl;
out.steps = steps;
} catch (err) {
out.error = err.message || String(err);
}
const ms = Date.now() - t0;
out.durationMs = ms;
out.durationSec = Math.round((ms / 1000) * 100) / 100;
if (!out.input) delete out.input;
if (!out.error) delete out.error;
if (!out.ok) {
delete out.finalUrl;
delete out.steps;
}
console.log(JSON.stringify(out, null, 2));
process.exit(out.ok ? 0 : 1);
}
main();CLI tool untuk resolve shortlink/AdLink move2link.co secara otomatis dan cepat — bypass Cloudflare WAF via Fgsi API dan kembalikan URL asli dalam format JSON.
SESSION JWT tanpa browser>= 18 (native fetch built-in)Tidak perlu npm install — tidak ada dependency eksternal.
Edit baris berikut di move2link.js sesuai API key kamu:
jsconst FGSI_KEY = 'fgsiapi-xxxxxxx';
Resolve URL secara penuh — Cloudflare bypass + unlock dilakukan otomatis.
bashnode move2link.js --url "https://move2link.co/4b08f3c"
Jika kamu sudah punya SESSION JWT (dari browser inspect, dsb):
bashnode move2link.js --token "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
bashnode move2link.js --cookie "SESSION=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
bash# isi file: token JWT atau cookie string node move2link.js --token-file token.txt
bashecho "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." | node move2link.js --stdin # atau pipe dari command lain cat token.txt | node move2link.js --stdin
| Flag | Deskripsi |
|---|---|
--url <url> | URL move2link — auto bypass CF + unlock |
--token <jwt> | SESSION JWT langsung |
--cookie <str> | Cookie string (SESSION=eyJ...) |
--token-file <path> | Path ke file berisi token/cookie |
--stdin | Baca token/cookie dari stdin |
Prioritas:
--token→--cookie→--token-file→--stdin→--url
Semua mode mengembalikan JSON ke stdout.
Sukses:
json{ "ok": true, "finalUrl": "https://safefileku.com/download/tgGjhshRTBv8bN2H", "durationMs": 6831, "durationSec": 6.83, "steps": [ { "step": 0, "maxStep": 3 }, { "step": 1, "maxStep": 3 }, { "step": 2, "maxStep": 3 } ], "source": "fgsi+url", "input": "https://move2link.co/4b08f3c", "timestamp": "2026-08-24T15:43:16.887Z" }
Gagal:
json{ "ok": false, "durationMs": 1021, "durationSec": 1.02, "source": null, "error": "SESSION cookie tidak ada di response Fgsi", "timestamp": "2026-08-24T15:38:58.000Z" }
| Field | Tipe | Deskripsi |
|---|---|---|
ok | boolean | true jika berhasil |
finalUrl | string | URL asli hasil resolve |
durationMs | number | Total waktu eksekusi (ms) |
durationSec | number | Total waktu eksekusi (detik) |
steps | array | Progress step unlock |
source | string | Sumber token (fgsi+url, token, cookie, dll) |
input | string | URL input (hanya di auto mode) |
error | string | Pesan error (hanya jika gagal) |
timestamp | string | Waktu eksekusi (ISO 8601) |
--url input │ ▼ Fgsi WAF Session API (bypass Cloudflare, ambil SESSION cookie) │ ▼ Decode JWT → cek step & max_step │ ▼ Loop: PUT /views/track (per step) │ ▼ POST /views/finalize │ ▼ finalUrl ✓
| Code | Keterangan |
|---|---|
0 | Berhasil, finalUrl tersedia |
1 | Gagal, lihat field error di output JSON |
MIT