Ctrl K
ComunidadGuías…

src/dashboard/account-text-parser.js

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
// Smart account-text parser — ported from xinghuo-windsurf accountTextParser.js
// (users own project). Pure string parsing, no network. Recognizes mixed formats:
// devin-session-token$ / show-auth-token URL / Firebase-refresh-JWT / email----password /
// labeled pairs (邮箱:xxx + Token:auth1_xxx). CommonJS→ESM: exports at bottom.
'use strict';

function isValidEmail(arg1) {
  if (!arg1 || typeof arg1 !== "string") {
    return false;
  }
  const trimResult = arg1.trim();
  if (trimResult.length < 5 || trimResult.length > 254) {
    return false;
  }
  if (/[\s|;,,;\t]/.test(trimResult)) {
    return false;
  }
  return /^[A-Za-z0-9._+\-]+@[A-Za-z0-9](?:[A-Za-z0-9\-]*[A-Za-z0-9])?(?:\.[A-Za-z0-9](?:[A-Za-z0-9\-]*[A-Za-z0-9])?)*\.[A-Za-z]{2,}$/.test(trimResult);
}
function stripWxHints(arg1) {
  if (!arg1) {
    return arg1;
  }
  let v2;
  let v3 = arg1;
  do {
    v2 = v3;
    v3 = v3.replace(/[((]\s*(?:无任何空格|去掉点|去点|去掉空格|无空格)\s*[))]/g, "").replace(/\s+账号管理器\s*[::==]\s*\S+/, "").trim();
  } while (v3 !== v2 && v3.length > 0);
  return v3;
}
function isNoiseLine(arg1) {
  if (!arg1) {
    return true;
  }
  if (/^(?:您的|您好|自动发货|订单编号|订单号|交易号|发货时间|订单时间|发货成功|交易成功|尊敬的)/.test(arg1)) {
    return true;
  }
  if (/^\s*\d{4}[\-\/年]\d{1,2}[\-\/月]\d{1,2}[\s\d::年月日时分秒]*$/.test(arg1)) {
    return true;
  }
  if (/^(?:账号管理器|管理面板|管理后台|官网|官方网站|官方地址|商城|售后|客服|发货)\s*[::==]/.test(arg1)) {
    return true;
  }
  return false;
}
const RE_TOKEN_PREFIX = /^(devin-session-token\$|auth1_|sk-)/i;
const RE_JWT = /^eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+$/;
// Any absolute URL scheme, not just http(s): the desktop app's sign-in
// callback is `windsurf://codeium.windsurf?access_token=…` (F4).
const ABSOLUTE_URL_RE = /^[a-z][a-z0-9+.\-]*:\/\//i;
function looksLikeToken(arg1) {
  if (!arg1) {
    return false;
  }
  if (arg1.includes("@")) {
    return false;
  }
  if (/[\s|]|----/.test(arg1)) {
    return false;
  }
  if (RE_TOKEN_PREFIX.test(arg1)) {
    return true;
  }
  if (RE_JWT.test(arg1)) {
    return true;
  }
  if (arg1.length >= 60 && /^[A-Za-z0-9_\-\.\$\/+=]+$/.test(arg1)) {
    return true;
  }
  return false;
}
function tryPair(arg1, arg2) {
  const trimResult = (arg1 || "").trim();
  const trimResult2 = (arg2 || "").trim();
  if (!trimResult || !trimResult2) {
    return null;
  }
  const isvalidemailResult = isValidEmail(trimResult);
  const isvalidemailResult2 = isValidEmail(trimResult2);
  if (isvalidemailResult && !isvalidemailResult2) {
    return {
      email: trimResult,
      password: trimResult2
    };
  }
  if (isvalidemailResult2 && !isvalidemailResult) {
    return {
      email: trimResult2,
      password: trimResult
    };
  }
  if (isvalidemailResult && isvalidemailResult2) {
    return {
      email: trimResult,
      password: trimResult2
    };
  }
  return null;
}
function parseSingleLine(arg1) {
  if (/----+/.test(arg1)) {
    const searchResult = arg1.search(/----+/);
    const matchResult2 = arg1.substring(searchResult).match(/^----+/);
    if (matchResult2) {
      const trypairResult = tryPair(arg1.substring(0, searchResult), arg1.substring(searchResult + matchResult2[0].length));
      if (trypairResult) {
        return trypairResult;
      }
    }
  }
  if (arg1.includes("\t")) {
    const indexofResult = arg1.indexOf("\t");
    const trypairResult = tryPair(arg1.substring(0, indexofResult), arg1.substring(indexofResult + 1));
    if (trypairResult) {
      return trypairResult;
    }
  }
  if (!ABSOLUTE_URL_RE.test(arg1)) {
    const searchResult = arg1.search(/[::==]/);
    if (searchResult !== -1) {
      const trypairResult = tryPair(arg1.substring(0, searchResult), arg1.substring(searchResult + 1));
      if (trypairResult) {
        return trypairResult;
      }
    }
  }
  if (arg1.includes("|")) {
    const indexofResult = arg1.indexOf("|");
    const trypairResult = tryPair(arg1.substring(0, indexofResult), arg1.substring(indexofResult + 1));
    if (trypairResult) {
      return trypairResult;
    }
  }
  for (const v1 of [",", ";", ",", ";"]) {
    if (arg1.includes(v1)) {
      const splitResult = arg1.split(v1);
      if (splitResult.length === 2) {
        const trypairResult = tryPair(splitResult[0], splitResult[1]);
        if (trypairResult) {
          return trypairResult;
        }
      }
    }
  }
  const matchResult = arg1.match(/^(\S+)\s+(\S.*?)\s*$/);
  if (matchResult) {
    const trypairResult = tryPair(matchResult[1], matchResult[2]);
    if (trypairResult) {
      return trypairResult;
    }
  }
  return null;
}
const RE_LABEL_EMAIL = /^\s*(?:邮箱|邮件|账号|账户|帐号|帐户|用户名|用户名称|用户|登录名|登陆名|登录账号|登陆账号|登录账户|卡号|号码|账户名|e[\-\s]?mail|email|account|user(?:name)?|login|mail|id|number|num)\s*\d*\s*[::==]\s*/i;
const RE_LABEL_PASS = /^\s*(?:密码|登录密码|登陆密码|口令|秘钥|密钥|卡密|令牌|password|pass(?:word|wd)?|pwd|secret|key|token|access(?:[\-_]?token)?)\s*\d*\s*[::==]\s*/i;
function parseAccountText(content) {
  const arr = [];
  const arr2 = [];
  const arr3 = [];
  const arr4 = [];
  if (!content || typeof content !== "string") {
    return {
      accounts: arr,
      tokens: arr2,
      tokenPairs: arr3,
      githubAccounts: arr4
    };
  }
  const trimResult = content.trim();
  if (trimResult.startsWith("[") && trimResult.endsWith("]")) {
    try {
      const parseResult = JSON.parse(trimResult);
      if (Array.isArray(parseResult) && parseResult.length > 0) {
        let v12 = true;
        const arr6 = [];
        const arr7 = [];
        const arr8 = [];
        const arr9 = [];
        for (const v13 of parseResult) {
          if (!v13 || typeof v13 !== "object") {
            v12 = false;
            break;
          }
          const v14 = v13.username || v13.user || v13.login;
          const v22 = v13.password || v13.pass || v13.pwd;
          const v32 = v13.totp_secret || v13.totp || v13.totpSecret;
          if (v14 && v22 && v32) {
            arr9.push({
              username: String(v14).trim(),
              password: String(v22).trim(),
              totpSecret: String(v32).trim()
            });
            continue;
          }
          const v4 = v13.email || v13.username || v13.account || v13.user || v13.mail || v13.login;
          const v5 = v13.password || v13.pass || v13.pwd || v13.passwd || v13.secret;
          const v6 = v13.token || v13.sessionToken || v13.session_token || v13.authToken || v13.access_token;
          if (v4 && v5 && isValidEmail(String(v4).trim())) {
            arr6.push({
              email: String(v4).trim(),
              password: String(v5).trim()
            });
          } else if (v6 && v4 && isValidEmail(String(v4).trim())) {
            arr8.push({
              email: String(v4).trim(),
              token: String(v6).trim()
            });
          } else if (v6) {
            arr7.push(String(v6).trim());
          } else {
            v12 = false;
            break;
          }
        }
        if (v12 && (arr6.length > 0 || arr7.length > 0 || arr8.length > 0 || arr9.length > 0)) {
          return {
            accounts: arr6,
            tokens: arr7,
            tokenPairs: arr8,
            githubAccounts: arr9
          };
        }
      }
    } catch (err) {}
  }
  const arr5 = [];
  for (const v12 of content.split(/\r?\n/)) {
    let trimResult2 = v12.trim();
    if (!trimResult2 || trimResult2.startsWith("#") || trimResult2.startsWith("//")) {
      continue;
    }
    trimResult2 = stripWxHints(trimResult2);
    if (!trimResult2) {
      continue;
    }
    if (isNoiseLine(trimResult2)) {
      continue;
    }
    if (/----/.test(trimResult2)) {
      const mapResult = trimResult2.split(/----+/).map(arg1 => arg1.trim());
      if (mapResult.length === 3 && mapResult[0] && mapResult[1] && mapResult[2]) {
        arr4.push({
          username: mapResult[0],
          password: mapResult[1],
          totpSecret: mapResult[2]
        });
        continue;
      }
    }
    if (ABSOLUTE_URL_RE.test(trimResult2)) {
      try {
        const inner = unwrapPastedSecret(trimResult2);
        arr5.push({
          type: "token",
          raw: inner
        });
      } catch {
        // Keep the URL so import-text reports failed (ERR_NO_TOKEN_IN_INPUT)
        // instead of added=0 skipped=0 failed=0.
        arr5.push({
          type: "token",
          raw: trimResult2
        });
      }
      continue;
    }
    if (looksLikeToken(trimResult2)) {
      arr5.push({
        type: "token",
        raw: trimResult2
      });
      continue;
    }
    if (trimResult2.startsWith("{") && trimResult2.endsWith("}")) {
      try {
        const parseResult = JSON.parse(trimResult2);
        const v13 = parseResult.email || parseResult.username || parseResult.account || parseResult.user || parseResult.mail || parseResult.login;
        const v22 = parseResult.password || parseResult.pass || parseResult.pwd || parseResult.passwd || parseResult.secret;
        if (v13 && v22 && isValidEmail(String(v13).trim())) {
          arr5.push({
            type: "pair",
            email: String(v13).trim(),
            password: String(v22).trim()
          });
          continue;
        }
        const v32 = parseResult.token || parseResult.sessionToken || parseResult.session_token || parseResult.authToken || parseResult.access_token;
        if (v32) {
          arr5.push({
            type: "token",
            raw: String(v32).trim()
          });
          continue;
        }
      } catch (err) {}
    }
    const matchResult = trimResult2.match(RE_LABEL_PASS);
    if (matchResult) {
      const trimResult3 = trimResult2.substring(matchResult[0].length).trim();
      if (trimResult3) {
        if (ABSOLUTE_URL_RE.test(trimResult3)) {
          try {
            arr5.push({
              type: "token",
              raw: unwrapPastedSecret(trimResult3)
            });
          } catch {
            arr5.push({
              type: "token",
              raw: trimResult3
            });
          }
        } else if (looksLikeToken(trimResult3)) {
          arr5.push({
            type: "token",
            raw: trimResult3
          });
        } else {
          arr5.push({
            type: "pass",
            password: trimResult3
          });
        }
        continue;
      }
      continue;
    }
    const matchResult2 = trimResult2.match(RE_LABEL_EMAIL);
    if (matchResult2) {
      const trimResult3 = trimResult2.substring(matchResult2[0].length).trim();
      if (isValidEmail(trimResult3)) {
        arr5.push({
          type: "email",
          email: trimResult3
        });
        continue;
      }
      trimResult2 = trimResult3 || trimResult2;
    }
    const parsesinglelineResult = parseSingleLine(trimResult2);
    if (parsesinglelineResult) {
      arr5.push({
        type: "pair",
        email: parsesinglelineResult.email,
        password: parsesinglelineResult.password
      });
      continue;
    }
    if (isValidEmail(trimResult2)) {
      arr5.push({
        type: "email",
        email: trimResult2
      });
      continue;
    }
    if (trimResult2.length >= 40 && /^[A-Za-z0-9_\-\.\$\/+=]+$/.test(trimResult2) && !trimResult2.includes("@")) {
      arr5.push({
        type: "token",
        raw: trimResult2
      });
      continue;
    }
  }
  let v1 = null;
  let v2 = null;
  let v3 = null;
  for (const v12 of arr5) {
    if (v12.type === "pair") {
      if (v12.email && v12.password && isValidEmail(v12.email)) {
        arr.push({
          email: v12.email,
          password: v12.password
        });
      }
      v1 = null;
      v2 = null;
    } else if (v12.type === "email") {
      if (v3) {
        arr3.push({
          email: v12.email,
          token: v3
        });
        v3 = null;
        v1 = null;
      } else if (v2) {
        arr.push({
          email: v12.email,
          password: v2
        });
        v2 = null;
        v1 = null;
      } else {
        v1 = v12.email;
      }
    } else if (v12.type === "pass") {
      if (v1) {
        arr.push({
          email: v1,
          password: v12.password
        });
        v1 = null;
      } else {
        v2 = v12.password;
      }
    } else if (v12.type === "token") {
      if (v12.raw) {
        if (v1) {
          arr3.push({
            email: v1,
            token: v12.raw
          });
          v1 = null;
        } else {
          if (v3) {
            arr2.push(v3);
          }
          v3 = v12.raw;
        }
      }
    }
  }
  if (v3) {
    arr2.push(v3);
  }
  return {
    accounts: arr,
    tokens: arr2,
    tokenPairs: arr3,
    githubAccounts: arr4
  };
}
// Pull a token out of a show-auth-token / OAuth redirect URL. Bare strings
// pass through. A URL with no token query/hash throws ERR_NO_TOKEN_IN_INPUT
// so POST /accounts does not send the whole URL to RegisterUser (#257).
//
// Any absolute scheme counts, not just http(s): the desktop app's callback is
// `windsurf://codeium.windsurf?access_token=…` and it used to be handed to
// RegisterUser verbatim as an 88-char "token" (F4).
function unwrapPastedSecret(input) {
  const raw = String(input || '').trim();
  if (!raw) return '';
  if (!ABSOLUTE_URL_RE.test(raw)) return raw;
  try {
    const u = new URL(raw);
    const pick = (params) => (params.get('access_token') || params.get('token') || params.get('auth_token') || '').trim();
    const fromQuery = pick(u.searchParams);
    if (fromQuery) return fromQuery;
    const frag = u.hash.startsWith('#') ? u.hash.slice(1) : u.hash;
    if (frag) {
      const fromHash = pick(new URLSearchParams(frag));
      if (fromHash) return fromHash;
    }
  } catch (e) {
    if (e && e.code === 'ERR_NO_TOKEN_IN_INPUT') throw e;
  }
  const err = new Error('ERR_NO_TOKEN_IN_INPUT');
  err.code = 'ERR_NO_TOKEN_IN_INPUT';
  throw err;
}

function classifyToken(arg1) {
  const trimResult = (arg1 || "").trim();
  if (!trimResult) {
    return "unknown";
  }
  if (trimResult.startsWith("devin-session-token$")) {
    return "session";
  }
  if (trimResult.startsWith("auth1_") && trimResult.length >= 20) {
    return "auth1";
  }
  if (trimResult.length > 100 && !trimResult.includes(" ") && !trimResult.includes("@") && !trimResult.startsWith("devin-") && !trimResult.startsWith("auth1_")) {
    return "refresh";
  }
  if (/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(trimResult) && trimResult.length > 100) {
    return "refresh";
  }
  return "unknown";
}

export { parseAccountText, isValidEmail, looksLikeToken, classifyToken, unwrapPastedSecret };

// Whitelabel: decode a devin-session-token$<JWT> payload to harvest email/exp
// without any network call (ported from devinSessionImporter.js). auth1_ tokens
// are not JWTs → returns nulls.
export function parseDevinJwtPayload(t) {
  const o = { email: null, sub: null, exp: null };
  if (!t || typeof t !== 'string') return o;
  let v = t;
  if (t.startsWith('devin-session-token$')) v = t.slice('devin-session-token$'.length);
  else if (t.startsWith('auth1_')) return o;
  const s = v.split('.'); if (s.length < 2) return o;
  try {
    let b = s[1].replace(/-/g, '+').replace(/_/g, '/'); while (b.length % 4) b += '=';
    const p = JSON.parse(Buffer.from(b, 'base64').toString('utf8'));
    return { email: typeof p.email === 'string' ? p.email : null,
             sub: typeof p.sub === 'string' ? p.sub : null,
             exp: typeof p.exp === 'number' ? p.exp : null };
  } catch { return o; }
}