karin-plugin-kkk 2.45.1-beta.1 → 2.45.1-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/config/default_config/config.json +5 -2
- package/config/default_config/cookies.yaml +4 -0
- package/config/default_config/kuaishou.yaml +3 -0
- package/config/default_config/xiaohongshu.yaml +3 -0
- package/lib/apps/admin.js +2 -2
- package/lib/build-metadata.json +5 -5
- package/lib/core_chunk/amagiClient.js +1 -1
- package/lib/core_chunk/db.js +1 -1
- package/lib/core_chunk/default.js +30694 -18354
- package/lib/core_chunk/main.js +1028 -26
- package/lib/core_chunk/vendor.js +522 -283
- package/lib/root.js +1 -1
- package/lib/style.css +83 -0
- package/lib/template-registry.js +1 -1
- package/lib/web/assets/{CronEditor-By-hG-v8.js → CronEditor-SToxfZLf.js} +1 -1
- package/lib/web/assets/{DesktopLayout-_4M-Hi0T.js → DesktopLayout-wpebBuCj.js} +1 -1
- package/lib/web/assets/{MobileLayout-Dkxb7rZd.js → MobileLayout-DhcWgEcj.js} +1 -1
- package/lib/web/assets/{ThemeSwitch-C1cJylms.js → ThemeSwitch-Cm4QAM5e.js} +1 -1
- package/lib/web/assets/{index-CXrY4Bct.js → index-DBbIxsmd.js} +2 -2
- package/lib/web/assets/{separator-QN4bEOP0.js → separator-BQ8-sWCU.js} +1 -1
- package/lib/web/index.html +1 -1
- package/lib/web.config.js +1 -1
- package/package.json +2 -2
package/lib/core_chunk/main.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
globalThis.__KTR_BUNDLED__ = true;
|
|
2
2
|
import { o as __toESM } from "./rolldown-runtime.js";
|
|
3
3
|
import { a as createBilibiliRoutes, c as createXiaohongshuRoutes, i as bilibiliApiUrls, l as wbi_sign, n as DynamicType, o as createDouyinRoutes, r as MajorType, s as createKuaishouRoutes, t as Client } from "./default.js";
|
|
4
|
-
import { $ as RiPieChart2Fill, $n as
|
|
4
|
+
import { $ as RiPieChart2Fill, $n as Globe, $t as Video, A as MdFitScreen, An as Quote, Ar as Calendar, At as n, B as AiFillHeart, Bn as Monitor, Br as require_jsx_runtime, Bt as p, C as webassembly_default, Cn as ScanLine, Cr as CircleDashed, Ct as o$3, D as tailwind_css_default, Dn as Repeat, Dr as Check, Dt as s, E as tsdown_default, En as RotateCcw, Er as CircleAlert, Et as o$1, F as FaCommentDots, Fn as Pencil, Fr as BookOpenText, Ft as m$1, G as RiArrowRightFill, Gn as LoaderCircle, Gr as require_server_node, Gt as parse, H as AiFillStar, Hn as Menu, Hr as clsx, Ht as s$1, I as FaMusic, In as Palette, Ir as BellRing, It as m$2, J as RiHeart3Fill, Jn as LayoutTemplate, Jr as defineTemplate, Jt as format, K as RiGroupLine, Kn as ListChecks, Kr as require_react, Kt as fromUnixTime, L as FaTiktok, Ln as Network$1, Lr as ArrowRight, Lt as c$1, M as MdLightbulbOutline, Mn as Puzzle, Mr as Box, Mt as e, N as MdLocationOn, Nn as Plus, Nr as Bot, Nt as c$2, O as sqlite_default, On as RefreshCw, Or as ChartColumn, Ot as m, P as MdSchedule, Pn as Play, Pr as Bookmark, Pt as a$1, Q as RiMessage3Fill, Qn as Hash, Qt as WandSparkles, R as FaUserGroup, Rn as Music, Rr as Chip, Rt as o$2, S as rehypeHighlight, Sn as Search, Sr as CircleEllipsis, St as SiAnthropic, T as typescript_default, Tn as Route, Tr as CircleCheckBig, Tt as o, U as AiOutlineVideoCamera, Un as Maximize, Ur as createTemplateRenderer, Ut as m$3, V as AiFillPushpin, Vn as MessageCircle, Vr as twMerge, Vt as n$1, W as Markdown, Wn as MapPin, Wr as resolveTemplateStyle, Wt as zhCN, X as RiHeartLine, Xn as Image$1, Xt as Zap, Y as RiHeart3Line, Yn as Info, Yt as differenceInSeconds, Z as RiLiveLine, Zn as Heart, Zt as X, _ as use, _n as Shield, _r as Clock, _t as SiHonor, a as drawDither, an as Upload, ar as FileText, at as RiTrophyFill, b as install$2, bn as Share2, br as CircleQuestionMark, bt as SiBilibili, c as install$11, cn as Timer, cr as Eye, ct as RiVideoLine, d as install$8, dn as Star, dr as Download, dt as SiVivo, en as Users, er as GitBranch, et as RiShareForwardFill, f as install$7, fn as Square, fr as Crown, ft as SiSamsung, g as install$5, gn as ShoppingBag, gr as Code, gt as SiHuawei, h as install$6, hn as Smartphone, hr as Copy, ht as SiKuaishou, in as UserPlus, ir as FingerprintPattern, it as RiTiktokFill, j as MdInfoOutline, jn as QrCode, jr as Braces, jt as p$1, k as react_default, kn as Radio, kr as Camera, kt as a, l as install$10, ln as Terminal, lr as EyeOff, lt as SiXiaomi, m as install$4, mn as Sparkles, mr as CornerDownLeft, mt as SiOneplus, nn as User, nr as Gauge, nt as RiStarLine, o as require_jpeg_js, on as TriangleAlert, or as FilePlay, ot as RiUserFollowLine, p as install$3, pn as SquarePen, pr as Cpu, pt as SiOppo, q as RiHashtag, qn as Link, qr as HtmlWrapper, qt as formatDistanceToNow, rn as UserRound, rr as Gamepad2, rt as RiThumbUpFill, s as require_heic_decode, sn as Trash, sr as FileExclamationPoint, st as RiVerifiedBadgeFill, tn as UsersRound, tr as Gift, tt as RiStarFill, u as install$9, un as Sun, ur as ExternalLink, ut as SiXiaohongshu, v as init, vn as ShieldCheck, vr as Clock3, vt as SiGooglephotos, w as vite_default, wn as Save, wr as CircleCheck, wt as r, x as install$1, xn as Settings2, xr as CircleFadingArrowUp, xt as SiApple, y as install, yn as ShieldAlert, yr as Clapperboard, yt as SiGithub, z as BiImage, zn as Moon, zr as Button, zt as c } from "./vendor.js";
|
|
5
5
|
import { createRequire } from "node:module";
|
|
6
6
|
import fs from "node:fs";
|
|
7
7
|
import path, { resolve } from "node:path";
|
|
@@ -15341,7 +15341,7 @@ var BilibiliQrcodeImg = import_react.memo((props) => {
|
|
|
15341
15341
|
BilibiliQrcodeImg.displayName = "BilibiliQrcodeImg";
|
|
15342
15342
|
//#endregion
|
|
15343
15343
|
//#region ktr/template/bilibili/qrcodeImg/index.tsx
|
|
15344
|
-
var qrcodeImg_default$
|
|
15344
|
+
var qrcodeImg_default$3 = defineTemplate({
|
|
15345
15345
|
name: "登录二维码",
|
|
15346
15346
|
description: "B站登录二维码展示模板",
|
|
15347
15347
|
component: BilibiliQrcodeImg,
|
|
@@ -18974,7 +18974,7 @@ var DouyinQrcodeImg = import_react.memo((props) => {
|
|
|
18974
18974
|
DouyinQrcodeImg.displayName = "DouyinQrcodeImg";
|
|
18975
18975
|
//#endregion
|
|
18976
18976
|
//#region ktr/template/douyin/qrcodeImg/index.tsx
|
|
18977
|
-
var qrcodeImg_default = defineTemplate({
|
|
18977
|
+
var qrcodeImg_default$2 = defineTemplate({
|
|
18978
18978
|
name: "登录二维码",
|
|
18979
18979
|
description: "抖音登录二维码展示模板",
|
|
18980
18980
|
component: DouyinQrcodeImg
|
|
@@ -20586,6 +20586,169 @@ var comment_default$1 = defineTemplate({
|
|
|
20586
20586
|
validate: (data) => typeof data === "object" && data !== null && typeof data.share_url === "string"
|
|
20587
20587
|
});
|
|
20588
20588
|
//#endregion
|
|
20589
|
+
//#region ktr/template/kuaishou/qrcodeImg/components/qrcodeImg.tsx
|
|
20590
|
+
/**
|
|
20591
|
+
* 快手二维码登录组件
|
|
20592
|
+
* @param props 组件属性
|
|
20593
|
+
* @returns JSX元素
|
|
20594
|
+
*/
|
|
20595
|
+
var KuaishouQrcodeImg = import_react.memo((props) => {
|
|
20596
|
+
const dark = isDark(props.ctx);
|
|
20597
|
+
const theme = {
|
|
20598
|
+
bg: dark ? "#000000" : "#FFFFFF",
|
|
20599
|
+
text: dark ? "#FFFFFF" : "#000000",
|
|
20600
|
+
subText: dark ? "#888888" : "#666666",
|
|
20601
|
+
accent: "#FF5000"
|
|
20602
|
+
};
|
|
20603
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DefaultLayout, {
|
|
20604
|
+
...props,
|
|
20605
|
+
className: "relative overflow-hidden",
|
|
20606
|
+
style: {
|
|
20607
|
+
background: theme.bg,
|
|
20608
|
+
color: theme.text
|
|
20609
|
+
},
|
|
20610
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20611
|
+
className: "absolute inset-0 overflow-hidden pointer-events-none",
|
|
20612
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
20613
|
+
className: "absolute top-[-40%] left-[-50%] w-400 h-600 rounded-full blur-[200px] opacity-25",
|
|
20614
|
+
style: { background: theme.accent }
|
|
20615
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
20616
|
+
className: "absolute bottom-[-40%] right-[-50%] w-400 h-600 rounded-full blur-[200px] opacity-20",
|
|
20617
|
+
style: { background: "#FFB800" }
|
|
20618
|
+
})]
|
|
20619
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20620
|
+
className: "relative z-10 flex flex-col items-center justify-center h-full py-40 px-24 space-y-32",
|
|
20621
|
+
children: [
|
|
20622
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20623
|
+
className: "text-center space-y-12",
|
|
20624
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", {
|
|
20625
|
+
className: "text-8xl font-bold tracking-tight",
|
|
20626
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
20627
|
+
className: "bg-clip-text text-transparent",
|
|
20628
|
+
style: { backgroundImage: `linear-gradient(to right, ${theme.text}, ${theme.subText})` },
|
|
20629
|
+
children: "快手扫码登录"
|
|
20630
|
+
})
|
|
20631
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20632
|
+
className: "flex items-start justify-center gap-10 opacity-90",
|
|
20633
|
+
style: { color: theme.text },
|
|
20634
|
+
children: [
|
|
20635
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20636
|
+
className: "flex flex-col items-center gap-4",
|
|
20637
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
20638
|
+
className: "p-5 rounded-3xl bg-surface/50 backdrop-blur-md",
|
|
20639
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SiKuaishou, { size: 64 })
|
|
20640
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
20641
|
+
className: "text-[28px] font-medium tracking-wide",
|
|
20642
|
+
children: "打开快手"
|
|
20643
|
+
})]
|
|
20644
|
+
}),
|
|
20645
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RiArrowRightFill, {
|
|
20646
|
+
size: 40,
|
|
20647
|
+
className: "mt-8 opacity-40"
|
|
20648
|
+
}),
|
|
20649
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20650
|
+
className: "flex flex-col items-center gap-4",
|
|
20651
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
20652
|
+
className: "p-5 rounded-3xl bg-surface/50 backdrop-blur-md",
|
|
20653
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu, { size: 64 })
|
|
20654
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
20655
|
+
className: "text-[28px] font-medium tracking-wide",
|
|
20656
|
+
children: "左上角菜单"
|
|
20657
|
+
})]
|
|
20658
|
+
}),
|
|
20659
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RiArrowRightFill, {
|
|
20660
|
+
size: 40,
|
|
20661
|
+
className: "mt-8 opacity-40"
|
|
20662
|
+
}),
|
|
20663
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20664
|
+
className: "flex flex-col items-center gap-4",
|
|
20665
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
20666
|
+
className: "p-5 rounded-3xl bg-surface/50 backdrop-blur-md",
|
|
20667
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScanLine, { size: 64 })
|
|
20668
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
20669
|
+
className: "text-[28px] font-medium tracking-wide",
|
|
20670
|
+
children: "扫一扫"
|
|
20671
|
+
})]
|
|
20672
|
+
})
|
|
20673
|
+
]
|
|
20674
|
+
})]
|
|
20675
|
+
}),
|
|
20676
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20677
|
+
className: "relative group",
|
|
20678
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
20679
|
+
className: "relative p-4",
|
|
20680
|
+
style: {
|
|
20681
|
+
width: "800px",
|
|
20682
|
+
height: "800px"
|
|
20683
|
+
},
|
|
20684
|
+
children: props.data.share_url ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(QRCodeWithAvatar, {
|
|
20685
|
+
value: props.data.share_url,
|
|
20686
|
+
avatarUrl: props.data.avatarUrl,
|
|
20687
|
+
useDarkTheme: dark,
|
|
20688
|
+
alt: "QR Code",
|
|
20689
|
+
className: "w-full h-full object-contain"
|
|
20690
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20691
|
+
className: "w-full h-full flex flex-col items-center justify-center gap-8",
|
|
20692
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
20693
|
+
className: "w-24 h-24 border-4 border-gray-200 rounded-full animate-spin",
|
|
20694
|
+
style: { borderTopColor: theme.accent }
|
|
20695
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
20696
|
+
className: "text-3xl text-muted",
|
|
20697
|
+
children: "未提供二维码图片"
|
|
20698
|
+
})]
|
|
20699
|
+
})
|
|
20700
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
20701
|
+
className: "absolute -bottom-24 left-0 right-0 text-center",
|
|
20702
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
|
|
20703
|
+
className: "text-[28px] font-medium tracking-wide flex items-center justify-center gap-3",
|
|
20704
|
+
style: { color: theme.subText },
|
|
20705
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
20706
|
+
className: "h-6 w-1.5 rounded-full",
|
|
20707
|
+
style: { backgroundColor: theme.accent }
|
|
20708
|
+
}), "此二维码 1 分钟内有效,请及时扫码登录。"]
|
|
20709
|
+
})
|
|
20710
|
+
})]
|
|
20711
|
+
}),
|
|
20712
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
20713
|
+
className: "w-full max-w-4xl pt-20",
|
|
20714
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
20715
|
+
className: "flex flex-col items-center space-y-6 text-center",
|
|
20716
|
+
children: [
|
|
20717
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
20718
|
+
className: "flex items-center justify-center w-16 h-16 mb-2",
|
|
20719
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShieldCheck, {
|
|
20720
|
+
size: 64,
|
|
20721
|
+
style: { color: theme.text },
|
|
20722
|
+
strokeWidth: 1.5
|
|
20723
|
+
})
|
|
20724
|
+
}),
|
|
20725
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
|
|
20726
|
+
className: "text-[40px] font-bold",
|
|
20727
|
+
style: { color: theme.text },
|
|
20728
|
+
children: "安全承诺"
|
|
20729
|
+
}),
|
|
20730
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
20731
|
+
className: "text-[24px] leading-relaxed opacity-60 max-w-3xl",
|
|
20732
|
+
style: { color: theme.text },
|
|
20733
|
+
children: "扫码只会把快手网页端的登录凭证(ck)保存在本机配置里,用于请求快手官方接口;不会上传到任何第三方。请在可信环境下使用。"
|
|
20734
|
+
})
|
|
20735
|
+
]
|
|
20736
|
+
})
|
|
20737
|
+
})
|
|
20738
|
+
]
|
|
20739
|
+
})]
|
|
20740
|
+
});
|
|
20741
|
+
});
|
|
20742
|
+
KuaishouQrcodeImg.displayName = "KuaishouQrcodeImg";
|
|
20743
|
+
//#endregion
|
|
20744
|
+
//#region ktr/template/kuaishou/qrcodeImg/index.tsx
|
|
20745
|
+
var qrcodeImg_default$1 = defineTemplate({
|
|
20746
|
+
name: "登录二维码",
|
|
20747
|
+
description: "快手登录二维码展示模板",
|
|
20748
|
+
component: KuaishouQrcodeImg,
|
|
20749
|
+
validate: (data) => typeof data === "object" && data !== null && typeof data.share_url === "string"
|
|
20750
|
+
});
|
|
20751
|
+
//#endregion
|
|
20589
20752
|
//#region ktr/template/other/changelog/components/changelog.tsx
|
|
20590
20753
|
var InlineCalloutCode = ({ children, className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
20591
20754
|
className: `inline-flex items-center rounded-[0.55em] px-[0.48em] py-[0.18em] font-semibold ${className ?? ""}`.trim(),
|
|
@@ -24964,6 +25127,222 @@ var updateHelp_default = defineTemplate({
|
|
|
24964
25127
|
component: UpdateHelp
|
|
24965
25128
|
});
|
|
24966
25129
|
//#endregion
|
|
25130
|
+
//#region ktr/template/other/verifyQr/components/verifyQr.tsx
|
|
25131
|
+
/**
|
|
25132
|
+
* 风控验证二维码(弥散信息海报系统)。
|
|
25133
|
+
*
|
|
25134
|
+
* 视觉中心只有一个 —— 二维码本身;其余元素按「做什么 → 怎么扫 → 扫完怎么办」
|
|
25135
|
+
* 三段排布,避免把说明文字铺成正文墙。二维码来自**平台官方页面地址**:
|
|
25136
|
+
* 扫码后在手机上完成验证即可,本页不做任何自动过码。
|
|
25137
|
+
* @param props 组件属性
|
|
25138
|
+
* @returns JSX元素
|
|
25139
|
+
*/
|
|
25140
|
+
var VerifyQr = import_react.memo((props) => {
|
|
25141
|
+
const dark = isDark(props.ctx);
|
|
25142
|
+
const platform = props.data.platform ?? "";
|
|
25143
|
+
const theme = {
|
|
25144
|
+
bg: dark ? "#000000" : "#FFFFFF",
|
|
25145
|
+
text: dark ? "#FFFFFF" : "#000000",
|
|
25146
|
+
subText: dark ? "#8A8A8E" : "#6B6B70",
|
|
25147
|
+
accent: "#FF7A45",
|
|
25148
|
+
glow: "#FFB020"
|
|
25149
|
+
};
|
|
25150
|
+
const steps = [
|
|
25151
|
+
{
|
|
25152
|
+
icon: ScanLine,
|
|
25153
|
+
title: "手机扫码",
|
|
25154
|
+
desc: "相机或平台 App 均可"
|
|
25155
|
+
},
|
|
25156
|
+
{
|
|
25157
|
+
icon: Globe,
|
|
25158
|
+
title: "完成验证",
|
|
25159
|
+
desc: "在官方页面里手动通过验证"
|
|
25160
|
+
},
|
|
25161
|
+
{
|
|
25162
|
+
icon: CircleCheckBig,
|
|
25163
|
+
title: "自动继续",
|
|
25164
|
+
desc: "无需回复,我会自动接着解析"
|
|
25165
|
+
}
|
|
25166
|
+
];
|
|
25167
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DefaultLayout, {
|
|
25168
|
+
...props,
|
|
25169
|
+
className: "relative overflow-hidden",
|
|
25170
|
+
style: {
|
|
25171
|
+
background: theme.bg,
|
|
25172
|
+
color: theme.text
|
|
25173
|
+
},
|
|
25174
|
+
children: [
|
|
25175
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
25176
|
+
className: "absolute inset-0 overflow-hidden pointer-events-none",
|
|
25177
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
25178
|
+
className: "absolute top-[-45%] left-[-45%] w-500 h-700 rounded-full blur-[220px] opacity-25",
|
|
25179
|
+
style: { background: theme.accent }
|
|
25180
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
25181
|
+
className: "absolute bottom-[-45%] right-[-45%] w-500 h-700 rounded-full blur-[220px] opacity-20",
|
|
25182
|
+
style: { background: theme.glow }
|
|
25183
|
+
})]
|
|
25184
|
+
}),
|
|
25185
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
25186
|
+
className: "absolute inset-0 pointer-events-none",
|
|
25187
|
+
style: { opacity: dark ? .16 : .2 },
|
|
25188
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", {
|
|
25189
|
+
className: "w-full h-full",
|
|
25190
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
25191
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("filter", {
|
|
25192
|
+
id: "verifyNoise",
|
|
25193
|
+
x: "0%",
|
|
25194
|
+
y: "0%",
|
|
25195
|
+
width: "100%",
|
|
25196
|
+
height: "100%",
|
|
25197
|
+
children: [
|
|
25198
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("feTurbulence", {
|
|
25199
|
+
type: "fractalNoise",
|
|
25200
|
+
baseFrequency: "0.8",
|
|
25201
|
+
numOctaves: "2",
|
|
25202
|
+
stitchTiles: "stitch",
|
|
25203
|
+
result: "noise"
|
|
25204
|
+
}),
|
|
25205
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("feColorMatrix", {
|
|
25206
|
+
type: "saturate",
|
|
25207
|
+
values: "0",
|
|
25208
|
+
result: "gray"
|
|
25209
|
+
}),
|
|
25210
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("feComponentTransfer", { children: [
|
|
25211
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("feFuncR", {
|
|
25212
|
+
type: "discrete",
|
|
25213
|
+
tableValues: "0 1"
|
|
25214
|
+
}),
|
|
25215
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("feFuncG", {
|
|
25216
|
+
type: "discrete",
|
|
25217
|
+
tableValues: "0 1"
|
|
25218
|
+
}),
|
|
25219
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("feFuncB", {
|
|
25220
|
+
type: "discrete",
|
|
25221
|
+
tableValues: "0 1"
|
|
25222
|
+
})
|
|
25223
|
+
] })
|
|
25224
|
+
]
|
|
25225
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", {
|
|
25226
|
+
width: "100%",
|
|
25227
|
+
height: "100%",
|
|
25228
|
+
filter: "url(#verifyNoise)"
|
|
25229
|
+
})]
|
|
25230
|
+
})
|
|
25231
|
+
}),
|
|
25232
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
25233
|
+
className: "relative z-10 flex flex-col items-center h-full py-36 px-24 space-y-24",
|
|
25234
|
+
children: [
|
|
25235
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
25236
|
+
className: "w-full max-w-5xl flex flex-col items-center gap-8",
|
|
25237
|
+
children: [
|
|
25238
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
25239
|
+
className: "flex items-center gap-4 px-6 py-2 rounded-full border border-white/15 bg-surface/40 backdrop-blur-md",
|
|
25240
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShieldAlert, {
|
|
25241
|
+
size: 26,
|
|
25242
|
+
style: { color: theme.accent }
|
|
25243
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
25244
|
+
className: "text-[24px] font-medium tracking-[0.2em]",
|
|
25245
|
+
style: { color: theme.subText },
|
|
25246
|
+
children: platform ? `${platform} · HUMAN CHECK` : "HUMAN CHECK"
|
|
25247
|
+
})]
|
|
25248
|
+
}),
|
|
25249
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", {
|
|
25250
|
+
className: "text-8xl font-bold tracking-tight text-center",
|
|
25251
|
+
children: "需要人机验证"
|
|
25252
|
+
}),
|
|
25253
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
25254
|
+
className: "text-[26px] opacity-70 text-center max-w-3xl leading-relaxed",
|
|
25255
|
+
children: "平台对刚才的请求发起了风控。验证在手机上的官方页面完成,本机器人不做任何自动过码。"
|
|
25256
|
+
})
|
|
25257
|
+
]
|
|
25258
|
+
}),
|
|
25259
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
25260
|
+
className: "w-full max-w-6xl flex items-center justify-center gap-16 flex-1",
|
|
25261
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
25262
|
+
className: "flex flex-col gap-10 min-w-0 flex-1 max-w-2xl",
|
|
25263
|
+
children: steps.map((step, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
25264
|
+
className: "flex items-start gap-8",
|
|
25265
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
25266
|
+
className: "flex flex-col items-center gap-3 shrink-0",
|
|
25267
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
25268
|
+
className: "p-5 rounded-3xl bg-surface/50 backdrop-blur-md border border-white/10",
|
|
25269
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(step.icon, {
|
|
25270
|
+
size: 48,
|
|
25271
|
+
style: { color: theme.text },
|
|
25272
|
+
strokeWidth: 1.5
|
|
25273
|
+
})
|
|
25274
|
+
}), index < steps.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
25275
|
+
className: "w-px h-10",
|
|
25276
|
+
style: { background: `${theme.subText}55` }
|
|
25277
|
+
})]
|
|
25278
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
25279
|
+
className: "flex flex-col gap-2 pt-2",
|
|
25280
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
25281
|
+
className: "text-[30px] font-semibold tracking-wide",
|
|
25282
|
+
children: step.title
|
|
25283
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
25284
|
+
className: "text-[22px] leading-relaxed opacity-60",
|
|
25285
|
+
children: step.desc
|
|
25286
|
+
})]
|
|
25287
|
+
})]
|
|
25288
|
+
}, step.title))
|
|
25289
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
25290
|
+
className: "relative shrink-0",
|
|
25291
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
25292
|
+
className: "relative p-6",
|
|
25293
|
+
style: {
|
|
25294
|
+
width: "760px",
|
|
25295
|
+
height: "760px"
|
|
25296
|
+
},
|
|
25297
|
+
children: props.data.share_url ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(QRCodeWithAvatar, {
|
|
25298
|
+
value: props.data.share_url,
|
|
25299
|
+
avatarUrl: props.data.avatarUrl,
|
|
25300
|
+
useDarkTheme: dark,
|
|
25301
|
+
alt: "验证二维码",
|
|
25302
|
+
className: "w-full h-full object-contain"
|
|
25303
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
25304
|
+
className: "w-full h-full flex items-center justify-center",
|
|
25305
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
25306
|
+
className: "text-3xl text-muted",
|
|
25307
|
+
children: platform ? "平台未给出验证页地址" : "未提供验证地址"
|
|
25308
|
+
})
|
|
25309
|
+
})
|
|
25310
|
+
}), props.data.expiresHint && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
|
|
25311
|
+
className: "absolute -bottom-16 left-0 right-0 text-center text-[26px] font-medium tracking-wide flex items-center justify-center gap-3",
|
|
25312
|
+
style: { color: theme.subText },
|
|
25313
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
25314
|
+
className: "h-6 w-1.5 rounded-full",
|
|
25315
|
+
style: { backgroundColor: theme.accent }
|
|
25316
|
+
}), props.data.expiresHint]
|
|
25317
|
+
})]
|
|
25318
|
+
})]
|
|
25319
|
+
}),
|
|
25320
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
25321
|
+
className: "w-full max-w-5xl flex items-center gap-6 px-10 py-8 rounded-4xl bg-surface/55 backdrop-blur-md border border-white/20",
|
|
25322
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShieldAlert, {
|
|
25323
|
+
size: 40,
|
|
25324
|
+
style: { color: theme.accent },
|
|
25325
|
+
strokeWidth: 1.5
|
|
25326
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
25327
|
+
className: "text-[22px] leading-relaxed opacity-70",
|
|
25328
|
+
children: "验证与本次会话绑定:请用同一账号在手机上完成,完成后不要再换 CK;二维码有时效,过期请重新触发一次解析。"
|
|
25329
|
+
})]
|
|
25330
|
+
})
|
|
25331
|
+
]
|
|
25332
|
+
})
|
|
25333
|
+
]
|
|
25334
|
+
});
|
|
25335
|
+
});
|
|
25336
|
+
VerifyQr.displayName = "VerifyQr";
|
|
25337
|
+
//#endregion
|
|
25338
|
+
//#region ktr/template/other/verifyQr/index.tsx
|
|
25339
|
+
var verifyQr_default = defineTemplate({
|
|
25340
|
+
name: "风控验证二维码",
|
|
25341
|
+
description: "把平台的风控验证页地址渲染成二维码,交给真人扫码过码",
|
|
25342
|
+
component: VerifyQr,
|
|
25343
|
+
validate: (data) => typeof data === "object" && data !== null && typeof data.share_url === "string"
|
|
25344
|
+
});
|
|
25345
|
+
//#endregion
|
|
24967
25346
|
//#region ktr/template/other/version_warning/components/VersionWarning.tsx
|
|
24968
25347
|
var VersionWarning = (props) => {
|
|
24969
25348
|
const dark = isDark(props.ctx);
|
|
@@ -28829,6 +29208,168 @@ var XiaohongshuNoteInfo = import_react.memo((props) => {
|
|
|
28829
29208
|
});
|
|
28830
29209
|
XiaohongshuNoteInfo.displayName = "XiaohongshuNoteInfo";
|
|
28831
29210
|
//#endregion
|
|
29211
|
+
//#region ktr/template/xiaohongshu/noteInfo/index.tsx
|
|
29212
|
+
var noteInfo_default = defineTemplate({
|
|
29213
|
+
name: "笔记信息",
|
|
29214
|
+
description: "小红书笔记信息展示模板",
|
|
29215
|
+
component: XiaohongshuNoteInfo
|
|
29216
|
+
});
|
|
29217
|
+
//#endregion
|
|
29218
|
+
//#region ktr/template/xiaohongshu/qrcodeImg/components/qrcodeImg.tsx
|
|
29219
|
+
/**
|
|
29220
|
+
* 小红书二维码登录组件
|
|
29221
|
+
* @param props 组件属性
|
|
29222
|
+
* @returns JSX元素
|
|
29223
|
+
*/
|
|
29224
|
+
var XiaohongshuQrcodeImg = import_react.memo((props) => {
|
|
29225
|
+
const dark = isDark(props.ctx);
|
|
29226
|
+
const theme = {
|
|
29227
|
+
bg: dark ? "#000000" : "#FFFFFF",
|
|
29228
|
+
text: dark ? "#FFFFFF" : "#000000",
|
|
29229
|
+
subText: dark ? "#888888" : "#666666",
|
|
29230
|
+
accent: "#FF2442"
|
|
29231
|
+
};
|
|
29232
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DefaultLayout, {
|
|
29233
|
+
...props,
|
|
29234
|
+
className: "relative overflow-hidden",
|
|
29235
|
+
style: {
|
|
29236
|
+
background: theme.bg,
|
|
29237
|
+
color: theme.text
|
|
29238
|
+
},
|
|
29239
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
29240
|
+
className: "absolute inset-0 overflow-hidden pointer-events-none",
|
|
29241
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
29242
|
+
className: "absolute top-[-40%] right-[-50%] w-400 h-600 rounded-full blur-[200px] opacity-25",
|
|
29243
|
+
style: { background: theme.accent }
|
|
29244
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
29245
|
+
className: "absolute bottom-[-40%] left-[-50%] w-400 h-600 rounded-full blur-[200px] opacity-20",
|
|
29246
|
+
style: { background: "#FF8A9B" }
|
|
29247
|
+
})]
|
|
29248
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
29249
|
+
className: "relative z-10 flex flex-col items-center justify-center h-full py-40 px-24 space-y-32",
|
|
29250
|
+
children: [
|
|
29251
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
29252
|
+
className: "text-center space-y-12",
|
|
29253
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", {
|
|
29254
|
+
className: "text-8xl font-bold tracking-tight",
|
|
29255
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
29256
|
+
className: "bg-clip-text text-transparent",
|
|
29257
|
+
style: { backgroundImage: `linear-gradient(to right, ${theme.text}, ${theme.subText})` },
|
|
29258
|
+
children: "小红书扫码登录"
|
|
29259
|
+
})
|
|
29260
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
29261
|
+
className: "flex items-start justify-center gap-10 opacity-90",
|
|
29262
|
+
style: { color: theme.text },
|
|
29263
|
+
children: [
|
|
29264
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
29265
|
+
className: "flex flex-col items-center gap-4",
|
|
29266
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
29267
|
+
className: "p-5 rounded-3xl bg-surface/50 backdrop-blur-md",
|
|
29268
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SiXiaohongshu, { size: 64 })
|
|
29269
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
29270
|
+
className: "text-[28px] font-medium tracking-wide",
|
|
29271
|
+
children: "打开小红书"
|
|
29272
|
+
})]
|
|
29273
|
+
}),
|
|
29274
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RiArrowRightFill, {
|
|
29275
|
+
size: 40,
|
|
29276
|
+
className: "mt-8 opacity-40"
|
|
29277
|
+
}),
|
|
29278
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
29279
|
+
className: "flex flex-col items-center gap-4",
|
|
29280
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
29281
|
+
className: "p-5 rounded-3xl bg-surface/50 backdrop-blur-md",
|
|
29282
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(UserRound, { size: 64 })
|
|
29283
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
29284
|
+
className: "text-[28px] font-medium tracking-wide",
|
|
29285
|
+
children: "右下角「我」"
|
|
29286
|
+
})]
|
|
29287
|
+
}),
|
|
29288
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RiArrowRightFill, {
|
|
29289
|
+
size: 40,
|
|
29290
|
+
className: "mt-8 opacity-40"
|
|
29291
|
+
}),
|
|
29292
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
29293
|
+
className: "flex flex-col items-center gap-4",
|
|
29294
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
29295
|
+
className: "p-5 rounded-3xl bg-surface/50 backdrop-blur-md",
|
|
29296
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScanLine, { size: 64 })
|
|
29297
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
29298
|
+
className: "text-[28px] font-medium tracking-wide",
|
|
29299
|
+
children: "顶部扫一扫"
|
|
29300
|
+
})]
|
|
29301
|
+
})
|
|
29302
|
+
]
|
|
29303
|
+
})]
|
|
29304
|
+
}),
|
|
29305
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
29306
|
+
className: "relative group",
|
|
29307
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
29308
|
+
className: "relative p-4",
|
|
29309
|
+
style: {
|
|
29310
|
+
width: "800px",
|
|
29311
|
+
height: "800px"
|
|
29312
|
+
},
|
|
29313
|
+
children: props.data.share_url ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(QRCodeWithAvatar, {
|
|
29314
|
+
value: props.data.share_url,
|
|
29315
|
+
avatarUrl: props.data.avatarUrl,
|
|
29316
|
+
useDarkTheme: dark,
|
|
29317
|
+
alt: "QR Code",
|
|
29318
|
+
className: "w-full h-full object-contain"
|
|
29319
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
29320
|
+
className: "w-full h-full flex flex-col items-center justify-center gap-8",
|
|
29321
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
29322
|
+
className: "w-24 h-24 border-4 border-gray-200 rounded-full animate-spin",
|
|
29323
|
+
style: { borderTopColor: theme.accent }
|
|
29324
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
29325
|
+
className: "text-3xl text-muted",
|
|
29326
|
+
children: "未提供二维码图片"
|
|
29327
|
+
})]
|
|
29328
|
+
})
|
|
29329
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
29330
|
+
className: "absolute -bottom-24 left-0 right-0 text-center",
|
|
29331
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
|
|
29332
|
+
className: "text-[28px] font-medium tracking-wide flex items-center justify-center gap-3",
|
|
29333
|
+
style: { color: theme.subText },
|
|
29334
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
29335
|
+
className: "h-6 w-1.5 rounded-full",
|
|
29336
|
+
style: { backgroundColor: theme.accent }
|
|
29337
|
+
}), "此二维码 3 分钟内有效,请及时扫码登录。"]
|
|
29338
|
+
})
|
|
29339
|
+
})]
|
|
29340
|
+
}),
|
|
29341
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
29342
|
+
className: "w-full max-w-4xl pt-20",
|
|
29343
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
29344
|
+
className: "flex flex-col items-center space-y-6 text-center",
|
|
29345
|
+
children: [
|
|
29346
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
29347
|
+
className: "flex items-center justify-center w-16 h-16 mb-2",
|
|
29348
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShieldCheck, {
|
|
29349
|
+
size: 64,
|
|
29350
|
+
style: { color: theme.text },
|
|
29351
|
+
strokeWidth: 1.5
|
|
29352
|
+
})
|
|
29353
|
+
}),
|
|
29354
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
|
|
29355
|
+
className: "text-[40px] font-bold",
|
|
29356
|
+
style: { color: theme.text },
|
|
29357
|
+
children: "安全承诺"
|
|
29358
|
+
}),
|
|
29359
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
29360
|
+
className: "text-[24px] leading-relaxed opacity-60 max-w-3xl",
|
|
29361
|
+
style: { color: theme.text },
|
|
29362
|
+
children: "扫码只会把小红书网页端的登录凭证(ck)保存在本机配置里,用于请求小红书官方接口;不会上传到任何第三方。请在可信环境下使用。"
|
|
29363
|
+
})
|
|
29364
|
+
]
|
|
29365
|
+
})
|
|
29366
|
+
})
|
|
29367
|
+
]
|
|
29368
|
+
})]
|
|
29369
|
+
});
|
|
29370
|
+
});
|
|
29371
|
+
XiaohongshuQrcodeImg.displayName = "XiaohongshuQrcodeImg";
|
|
29372
|
+
//#endregion
|
|
28832
29373
|
//#region .ktr/template-registry.ts
|
|
28833
29374
|
var templates = {
|
|
28834
29375
|
"bilibili/bangumi": bangumi_default,
|
|
@@ -28839,7 +29380,7 @@ var templates = {
|
|
|
28839
29380
|
"bilibili/dynamic/DYNAMIC_TYPE_FORWARD": DYNAMIC_TYPE_FORWARD_default,
|
|
28840
29381
|
"bilibili/dynamic/DYNAMIC_TYPE_LIVE_RCMD": DYNAMIC_TYPE_LIVE_RCMD_default,
|
|
28841
29382
|
"bilibili/dynamic/DYNAMIC_TYPE_WORD": DYNAMIC_TYPE_WORD_default,
|
|
28842
|
-
"bilibili/qrcodeImg": qrcodeImg_default$
|
|
29383
|
+
"bilibili/qrcodeImg": qrcodeImg_default$3,
|
|
28843
29384
|
"bilibili/userlist": userlist_default$1,
|
|
28844
29385
|
"bilibili/videoInfo": videoInfo_default,
|
|
28845
29386
|
"douyin/article-work": article_work_default,
|
|
@@ -28849,12 +29390,13 @@ var templates = {
|
|
|
28849
29390
|
"douyin/image-work": image_work_default,
|
|
28850
29391
|
"douyin/live": live_default,
|
|
28851
29392
|
"douyin/musicinfo": musicinfo_default,
|
|
28852
|
-
"douyin/qrcodeImg": qrcodeImg_default,
|
|
29393
|
+
"douyin/qrcodeImg": qrcodeImg_default$2,
|
|
28853
29394
|
"douyin/recommend-list": recommend_list_default,
|
|
28854
29395
|
"douyin/user_profile": user_profile_default,
|
|
28855
29396
|
"douyin/userlist": userlist_default,
|
|
28856
29397
|
"douyin/video-work": video_work_default,
|
|
28857
29398
|
"kuaishou/comment": comment_default$1,
|
|
29399
|
+
"kuaishou/qrcodeImg": qrcodeImg_default$1,
|
|
28858
29400
|
"other/changelog": changelog_default,
|
|
28859
29401
|
"other/handlerError": handlerError_default,
|
|
28860
29402
|
"other/help": help_default,
|
|
@@ -28862,14 +29404,17 @@ var templates = {
|
|
|
28862
29404
|
"other/qrlogin": qrlogin_default,
|
|
28863
29405
|
"other/runtime": runtime_default,
|
|
28864
29406
|
"other/updateHelp": updateHelp_default,
|
|
29407
|
+
"other/verifyQr": verifyQr_default,
|
|
28865
29408
|
"other/version_warning": version_warning_default,
|
|
28866
29409
|
"statistics/global": global_default,
|
|
28867
29410
|
"statistics/group": group_default,
|
|
28868
29411
|
"xiaohongshu/comment": comment_default,
|
|
28869
|
-
"xiaohongshu/noteInfo":
|
|
28870
|
-
|
|
28871
|
-
|
|
28872
|
-
|
|
29412
|
+
"xiaohongshu/noteInfo": noteInfo_default,
|
|
29413
|
+
"xiaohongshu/qrcodeImg": defineTemplate({
|
|
29414
|
+
name: "登录二维码",
|
|
29415
|
+
description: "小红书登录二维码展示模板",
|
|
29416
|
+
component: XiaohongshuQrcodeImg,
|
|
29417
|
+
validate: (data) => typeof data === "object" && data !== null && typeof data.share_url === "string"
|
|
28873
29418
|
})
|
|
28874
29419
|
};
|
|
28875
29420
|
//#endregion
|
|
@@ -31682,7 +32227,7 @@ var mapping_table = (type) => {
|
|
|
31682
32227
|
],
|
|
31683
32228
|
19: ["DYNAMIC_TYPE_MEDIALIST"]
|
|
31684
32229
|
};
|
|
31685
|
-
for (const key in Array) if (Array[key].includes(type)) return
|
|
32230
|
+
for (const key in Array) if (Array[key].includes(type)) return Number(key);
|
|
31686
32231
|
return 1;
|
|
31687
32232
|
};
|
|
31688
32233
|
/**
|
|
@@ -32250,7 +32795,7 @@ var getBilibiliID = async (url) => {
|
|
|
32250
32795
|
* @param e - 消息事件
|
|
32251
32796
|
* @returns 带 send / recall / recallAll 的登记器
|
|
32252
32797
|
*/
|
|
32253
|
-
var createMessageTracker$
|
|
32798
|
+
var createMessageTracker$3 = (e) => {
|
|
32254
32799
|
const messageIds = [];
|
|
32255
32800
|
const recall = async (id) => {
|
|
32256
32801
|
try {
|
|
@@ -32286,7 +32831,7 @@ var createMessageTracker$1 = (e) => {
|
|
|
32286
32831
|
* @param tracker - 消息登记器
|
|
32287
32832
|
* @returns 二维码消息的 id,扫码后要单独撤回它
|
|
32288
32833
|
*/
|
|
32289
|
-
var sendQrcode$
|
|
32834
|
+
var sendQrcode$3 = async (e, qrcode, tracker) => {
|
|
32290
32835
|
const qrimg = await Render(e, "bilibili/qrcodeImg", {
|
|
32291
32836
|
share_url: qrcode.content,
|
|
32292
32837
|
avatarUrl: await resolveTriggerAvatarUrl(e)
|
|
@@ -32297,12 +32842,25 @@ var sendQrcode$1 = async (e, qrcode, tracker) => {
|
|
|
32297
32842
|
return tracker.send(qrimg);
|
|
32298
32843
|
};
|
|
32299
32844
|
/** 把会话的失败原因翻成给用户看的话 */
|
|
32300
|
-
var noticeOf$
|
|
32845
|
+
var noticeOf$3 = (error) => {
|
|
32301
32846
|
if (error.kind === "risk") return `登录请求被B站风控拦截:${error.message}`;
|
|
32302
32847
|
if (error.code === "COOKIE_EXPIRED") return "二维码已失效";
|
|
32303
32848
|
return `登录未完成:${error.message}`;
|
|
32304
32849
|
};
|
|
32305
32850
|
/**
|
|
32851
|
+
* 从 B站扫码登录的响应体里取 refresh_token。
|
|
32852
|
+
*
|
|
32853
|
+
* 官方把续期令牌存在浏览器 `localStorage.ac_time_value`;扫码轮询接口返回的
|
|
32854
|
+
* `data.refresh_token` 就是同一份东西(见 amagi 的 `platforms/bilibili/cookieRefresh.ts`
|
|
32855
|
+
* 与 `endpoints/qrcodeStatus.ts` 的类型)。取不到就续不了期,只能重新扫码。
|
|
32856
|
+
* @param raw - 会话给出的 `credential.raw`(qrcode/status 的响应体)
|
|
32857
|
+
* @returns refresh_token;没有时 undefined
|
|
32858
|
+
*/
|
|
32859
|
+
var readRefreshToken = (raw) => {
|
|
32860
|
+
const token = raw?.data?.refresh_token;
|
|
32861
|
+
return typeof token === "string" && token.trim() !== "" ? token : void 0;
|
|
32862
|
+
};
|
|
32863
|
+
/**
|
|
32306
32864
|
* B站扫码登录。
|
|
32307
32865
|
*
|
|
32308
32866
|
* 轮询、退避、超时都在 amagi 的 v7 登录会话里(`client.bilibili.login.qrcode()`),
|
|
@@ -32316,13 +32874,13 @@ var noticeOf$1 = (error) => {
|
|
|
32316
32874
|
* @param e - 消息事件
|
|
32317
32875
|
*/
|
|
32318
32876
|
var bilibiliLogin = async (e) => {
|
|
32319
|
-
const tracker = createMessageTracker$
|
|
32877
|
+
const tracker = createMessageTracker$3(e);
|
|
32320
32878
|
let qrcodeMessageId;
|
|
32321
32879
|
let scanned = false;
|
|
32322
32880
|
try {
|
|
32323
32881
|
const outcome = await getAmagiClient().bilibili.login.qrcode().watch({
|
|
32324
32882
|
onQrcode: async (qrcode) => {
|
|
32325
|
-
qrcodeMessageId = await sendQrcode$
|
|
32883
|
+
qrcodeMessageId = await sendQrcode$3(e, qrcode, tracker);
|
|
32326
32884
|
},
|
|
32327
32885
|
onScanned: async () => {
|
|
32328
32886
|
if (scanned) return;
|
|
@@ -32332,6 +32890,9 @@ var bilibiliLogin = async (e) => {
|
|
|
32332
32890
|
},
|
|
32333
32891
|
onSuccess: async (credential) => {
|
|
32334
32892
|
await Config.Modify("amagi", "cookies.bilibili", credential.cookie);
|
|
32893
|
+
const refreshToken = readRefreshToken(credential.raw);
|
|
32894
|
+
if (refreshToken) await Config.Modify("amagi", "cookies.bilibiliRefreshToken", refreshToken);
|
|
32895
|
+
else logger$1.warn("[B站登录] 本次登录未返回 refresh_token,后续无法续期,只能重新扫码");
|
|
32335
32896
|
const reloaded = reloadAmagiConfig();
|
|
32336
32897
|
logger$1.mark(`[B站登录] 登录凭证已保存,Amagi Client ${reloaded ? "已重载" : "配置未变化"}`);
|
|
32337
32898
|
}
|
|
@@ -32339,7 +32900,7 @@ var bilibiliLogin = async (e) => {
|
|
|
32339
32900
|
if (outcome.ok) await e.reply("登录成功!用户登录凭证已保存至配置", { reply: true });
|
|
32340
32901
|
else {
|
|
32341
32902
|
logger$1.warn(`[B站登录] 会话结束于失败态: kind=${outcome.error.kind} code=${outcome.error.code}`);
|
|
32342
|
-
await e.reply(noticeOf$
|
|
32903
|
+
await e.reply(noticeOf$3(outcome.error), { reply: true });
|
|
32343
32904
|
}
|
|
32344
32905
|
} catch (error) {
|
|
32345
32906
|
logger$1.error("[B站登录] 登录流程出错:", error);
|
|
@@ -32348,6 +32909,43 @@ var bilibiliLogin = async (e) => {
|
|
|
32348
32909
|
await tracker.recallAll();
|
|
32349
32910
|
}
|
|
32350
32911
|
};
|
|
32912
|
+
/**
|
|
32913
|
+
* B站登录态续期(官方四步协议)。
|
|
32914
|
+
*
|
|
32915
|
+
* 与「重新扫码」是两回事:走的是平台正规续期通道,用旧 cookie + 旧 refresh_token 换一份
|
|
32916
|
+
* 新 cookie 与**新的** refresh_token。两者必须整组替换 —— 旧 token 在第四步已被服务端
|
|
32917
|
+
* 作废(amagi 侧的说明见其 `platforms/bilibili/cookieRefresh.ts`)。失败时不动配置,
|
|
32918
|
+
* 用户可重新扫码。
|
|
32919
|
+
* @param e - 消息事件
|
|
32920
|
+
* @returns 固定 true,交回命令框架
|
|
32921
|
+
*/
|
|
32922
|
+
var bilibiliRefreshLogin = async (e) => {
|
|
32923
|
+
const cookie = Config.amagi.cookies.bilibili;
|
|
32924
|
+
const refreshToken = Config.amagi.cookies.bilibiliRefreshToken;
|
|
32925
|
+
if (!cookie) {
|
|
32926
|
+
await e.reply("还没有配置 B站 cookie,请先执行 B站扫码登录", { reply: true });
|
|
32927
|
+
return true;
|
|
32928
|
+
}
|
|
32929
|
+
if (!refreshToken) {
|
|
32930
|
+
await e.reply("没有可用的续期令牌(refresh_token):请重新执行一次 B站扫码登录,新的登录会把令牌一并保存", { reply: true });
|
|
32931
|
+
return true;
|
|
32932
|
+
}
|
|
32933
|
+
const result = await getAmagiClient().bilibili.refreshCredential({
|
|
32934
|
+
cookie,
|
|
32935
|
+
refreshToken
|
|
32936
|
+
});
|
|
32937
|
+
if (!result.ok) {
|
|
32938
|
+
logger$1.warn(`[B站续期] 失败:kind=${result.error.kind} code=${result.error.code} ${result.error.message}`);
|
|
32939
|
+
await e.reply(`B站登录态续期失败:${result.error.message}`, { reply: true });
|
|
32940
|
+
return true;
|
|
32941
|
+
}
|
|
32942
|
+
await Config.Modify("amagi", "cookies.bilibili", result.credential.cookie);
|
|
32943
|
+
await Config.Modify("amagi", "cookies.bilibiliRefreshToken", result.credential.refreshToken);
|
|
32944
|
+
const reloaded = reloadAmagiConfig();
|
|
32945
|
+
logger$1.mark(`[B站续期] 新 cookie 与 refresh_token 已保存,Amagi Client ${reloaded ? "已重载" : "配置未变化"}`);
|
|
32946
|
+
await e.reply("B站登录态已续期,新的 cookie 与续期令牌已保存", { reply: true });
|
|
32947
|
+
return true;
|
|
32948
|
+
};
|
|
32351
32949
|
//#endregion
|
|
32352
32950
|
//#region src/platform/bilibili/live-status.ts
|
|
32353
32951
|
var invalidLiveTimes = /* @__PURE__ */ new Set([
|
|
@@ -36248,10 +36846,11 @@ var DouYin = class DouYin extends Base {
|
|
|
36248
36846
|
return true;
|
|
36249
36847
|
}
|
|
36250
36848
|
const room_data = JSON.parse(roomDataRaw);
|
|
36251
|
-
const
|
|
36849
|
+
const liveParams = {
|
|
36252
36850
|
room_id: UserInfoData.data.user.room_id_str,
|
|
36253
36851
|
web_rid: room_data.owner.web_rid
|
|
36254
|
-
}
|
|
36852
|
+
};
|
|
36853
|
+
const live_data = await this.amagi.douyin.fetcher.fetchLiveRoomInfo(liveParams);
|
|
36255
36854
|
const liveItem = live_data.data.data.data[0];
|
|
36256
36855
|
const user = UserInfoData.data.user;
|
|
36257
36856
|
const streamExtra = liveItem.stream_url?.extra;
|
|
@@ -36507,10 +37106,11 @@ async function processLiveStream(sec_uid, userinfo, item, targets, amagi) {
|
|
|
36507
37106
|
return null;
|
|
36508
37107
|
}
|
|
36509
37108
|
const room_data = JSON.parse(UserInfoData.data.user.room_data);
|
|
36510
|
-
const
|
|
37109
|
+
const liveParams = {
|
|
36511
37110
|
room_id: UserInfoData.data.user.room_id_str,
|
|
36512
37111
|
web_rid: room_data.owner.web_rid
|
|
36513
|
-
}
|
|
37112
|
+
};
|
|
37113
|
+
const liveInfo = await amagi.douyin.fetcher.fetchLiveRoomInfo(liveParams);
|
|
36514
37114
|
if (!liveStatus.living) {
|
|
36515
37115
|
logger$1.info(`用户 ${item.remark ?? sec_uid} 开播了`);
|
|
36516
37116
|
return {
|
|
@@ -37593,6 +38193,191 @@ var fetchKuaishouData = async (type, opt) => {
|
|
|
37593
38193
|
}
|
|
37594
38194
|
};
|
|
37595
38195
|
//#endregion
|
|
38196
|
+
//#region src/platform/kuaishou/login.ts
|
|
38197
|
+
/**
|
|
38198
|
+
* 等扫码的时限:撤回窗口是 120s,这里留 10s 余量给网络与程序时延 ——
|
|
38199
|
+
* 顶格写 120s 的话,超时那一刻二维码已经撤不掉了。
|
|
38200
|
+
*/
|
|
38201
|
+
var SCAN_TIMEOUT$2 = 11e4;
|
|
38202
|
+
/** 等用户回「已完成验证」的时限(秒) */
|
|
38203
|
+
var VERIFY_INPUT_TIMEOUT$1 = 120;
|
|
38204
|
+
/** 登录凭证里需要确认下发的关键字段 */
|
|
38205
|
+
var REQUIRED_COOKIES$2 = ["passToken", "userId"];
|
|
38206
|
+
/**
|
|
38207
|
+
* 主动中断登录会话。
|
|
38208
|
+
*
|
|
38209
|
+
* v7 的 `watch` 只在调用方回调自己抛出时才 reject,所以从 `onChallenge` 里退出流程
|
|
38210
|
+
* 只能靠抛 —— 回调的返回类型是 `{ ticket }`,没有「放弃」这个取值。用一个专门的异常
|
|
38211
|
+
* 带上要发给用户的话,外层认出它就正常收尾。
|
|
38212
|
+
*/
|
|
38213
|
+
var LoginAborted$2 = class extends Error {
|
|
38214
|
+
notice;
|
|
38215
|
+
constructor(notice) {
|
|
38216
|
+
super(notice);
|
|
38217
|
+
this.notice = notice;
|
|
38218
|
+
this.name = "LoginAborted";
|
|
38219
|
+
}
|
|
38220
|
+
};
|
|
38221
|
+
/**
|
|
38222
|
+
* 登录过程中发出的消息统一登记,结束时一起撤回,避免二维码留在群里
|
|
38223
|
+
* @param e - 消息事件
|
|
38224
|
+
* @returns 带 send / recallAll 的登记器
|
|
38225
|
+
*/
|
|
38226
|
+
var createMessageTracker$2 = (e) => {
|
|
38227
|
+
const messageIds = [];
|
|
38228
|
+
return {
|
|
38229
|
+
/**
|
|
38230
|
+
* 发送并登记一条消息
|
|
38231
|
+
* @param message - 消息内容
|
|
38232
|
+
* @returns 发送结果
|
|
38233
|
+
*/
|
|
38234
|
+
async send(message) {
|
|
38235
|
+
const sent = await e.reply(message, { reply: true });
|
|
38236
|
+
if (sent.messageId) messageIds.push(sent.messageId);
|
|
38237
|
+
return sent;
|
|
38238
|
+
},
|
|
38239
|
+
/** 撤回目前登记的全部消息 */
|
|
38240
|
+
async recallAll() {
|
|
38241
|
+
const pending = messageIds.splice(0, messageIds.length);
|
|
38242
|
+
await Promise.all(pending.map(async (id) => {
|
|
38243
|
+
try {
|
|
38244
|
+
await e.bot.recallMsg(e.contact, id);
|
|
38245
|
+
} catch (error) {
|
|
38246
|
+
logger$1.debug("[快手登录] 撤回消息失败:", error);
|
|
38247
|
+
}
|
|
38248
|
+
}));
|
|
38249
|
+
}
|
|
38250
|
+
};
|
|
38251
|
+
};
|
|
38252
|
+
/**
|
|
38253
|
+
* 渲染并发送登录二维码,同时落一份到临时目录方便排查
|
|
38254
|
+
* @param e - 消息事件
|
|
38255
|
+
* @param qrcode - 会话给出的二维码
|
|
38256
|
+
* @param tracker - 消息登记器
|
|
38257
|
+
*/
|
|
38258
|
+
var sendQrcode$2 = async (e, qrcode, tracker) => {
|
|
38259
|
+
const rendered = await Render(e, "kuaishou/qrcodeImg", {
|
|
38260
|
+
share_url: qrcode.content,
|
|
38261
|
+
avatarUrl: await resolveTriggerAvatarUrl(e)
|
|
38262
|
+
});
|
|
38263
|
+
const base64Data = rendered[0]?.file;
|
|
38264
|
+
if (!base64Data) throw new Error("生成二维码图片失败");
|
|
38265
|
+
fs.writeFileSync(`${Common.tempDri.default}KuaishouLoginQrcode.png`, Buffer.from(base64Data.replace(/^base64:\/\//, ""), "base64"));
|
|
38266
|
+
await tracker.send(rendered);
|
|
38267
|
+
};
|
|
38268
|
+
/**
|
|
38269
|
+
* 把验证页交给真人,等他确认过完。
|
|
38270
|
+
*
|
|
38271
|
+
* amagi 的快手登录策略**只把验证页原样吐出来**(身份校验页 / 滑块),票据由服务端按
|
|
38272
|
+
* 会话解除 —— 没有可回填进下一次请求的字段。所以这里等的是「用户说过了」,随后让引擎
|
|
38273
|
+
* 自己接着轮询。
|
|
38274
|
+
*
|
|
38275
|
+
* **未真机验证**:amagi 侧标注二次验证之后的响应结构只有契约、没有真机扫码记录
|
|
38276
|
+
* (见其 `platforms/kuaishou/qrcodeLogin.ts` 模块头)。真机扫一次即可校正这一段。
|
|
38277
|
+
* @param e - 消息事件
|
|
38278
|
+
* @param url - 验证页地址(`challenge.imageUrl`)
|
|
38279
|
+
* @param tracker - 消息登记器
|
|
38280
|
+
* @throws {LoginAborted} 用户超时未确认
|
|
38281
|
+
*/
|
|
38282
|
+
var waitForVerify$1 = async (e, url, tracker) => {
|
|
38283
|
+
await tracker.send(`此次登录需要人机验证\n请在浏览器里打开下面的地址完成验证:\n${url}\n完成后回复「已完成」` + (url === "" ? "\n(平台这次没有给出验证页地址,可改用手机快手重新扫码)" : ""));
|
|
38284
|
+
if (!await karin$1.ctx(e, {
|
|
38285
|
+
time: VERIFY_INPUT_TIMEOUT$1,
|
|
38286
|
+
reply: false,
|
|
38287
|
+
throwOnTimeout: false
|
|
38288
|
+
})) throw new LoginAborted$2("等待验证超时,登录已取消");
|
|
38289
|
+
};
|
|
38290
|
+
/**
|
|
38291
|
+
* 保存登录凭证并重载 Amagi 客户端
|
|
38292
|
+
* @param cookie - 完整登录 cookie
|
|
38293
|
+
*/
|
|
38294
|
+
var persistCookie$2 = async (cookie) => {
|
|
38295
|
+
const present = new Set(cookie.split(";").map((pair) => pair.split("=")[0].trim()));
|
|
38296
|
+
const missing = REQUIRED_COOKIES$2.filter((name) => !present.has(name));
|
|
38297
|
+
if (missing.length > 0) logger$1.warn(`[快手登录] 以下字段未在本次登录中下发:${missing.join(", ")}`);
|
|
38298
|
+
await Config.Modify("amagi", "cookies.kuaishou", cookie);
|
|
38299
|
+
const reloaded = reloadAmagiConfig();
|
|
38300
|
+
logger$1.mark(`[快手登录] 登录凭证已保存,Amagi Client ${reloaded ? "已重载" : "配置未变化"}`);
|
|
38301
|
+
};
|
|
38302
|
+
/** 把会话的失败原因翻成给用户看的话 */
|
|
38303
|
+
var noticeOf$2 = (error) => {
|
|
38304
|
+
if (error.kind === "risk") return `登录请求被快手风控拦截:${error.message}\n请稍后再试`;
|
|
38305
|
+
if (error.code === "COOKIE_EXPIRED") return "二维码已失效,请重新发起登录";
|
|
38306
|
+
return `登录未完成:${error.message}`;
|
|
38307
|
+
};
|
|
38308
|
+
/**
|
|
38309
|
+
* 快手扫码登录。
|
|
38310
|
+
*
|
|
38311
|
+
* 协议与轮询编排都在 amagi 的 v7 登录会话里(`client.kuaishou.login.qrcode()`):
|
|
38312
|
+
* 本地生成 did、取码、两段 long-poll(先等扫码、再等手机确认)、退避、二次验证
|
|
38313
|
+
* 全部由引擎负责。这里只做三件与用户交互的事 —— 渲染二维码、把验证页转给人、
|
|
38314
|
+
* 把凭证落库。
|
|
38315
|
+
* @param e - 消息事件
|
|
38316
|
+
* @returns 固定 true,交回命令框架
|
|
38317
|
+
*/
|
|
38318
|
+
var kuaishouLogin = async (e) => {
|
|
38319
|
+
const tracker = createMessageTracker$2(e);
|
|
38320
|
+
const controller = new AbortController();
|
|
38321
|
+
/** 自己中断时要发的话;有值说明不是引擎给出的失败 */
|
|
38322
|
+
let abortNotice;
|
|
38323
|
+
let scanned = false;
|
|
38324
|
+
let scanTimer;
|
|
38325
|
+
try {
|
|
38326
|
+
const outcome = await getAmagiClient().kuaishou.login.qrcode().watch({
|
|
38327
|
+
signal: controller.signal,
|
|
38328
|
+
timeoutMs: 29e4,
|
|
38329
|
+
onQrcode: async (qrcode) => {
|
|
38330
|
+
logger$1.mark(`[快手登录] 二维码已获取,有效期 ${qrcode.expiresInSec} 秒`);
|
|
38331
|
+
await sendQrcode$2(e, qrcode, tracker);
|
|
38332
|
+
scanTimer = setTimeout(() => {
|
|
38333
|
+
if (scanned) return;
|
|
38334
|
+
abortNotice = "登录超时!二维码已失效!";
|
|
38335
|
+
controller.abort();
|
|
38336
|
+
}, SCAN_TIMEOUT$2);
|
|
38337
|
+
},
|
|
38338
|
+
onScanned: async () => {
|
|
38339
|
+
if (scanned) return;
|
|
38340
|
+
scanned = true;
|
|
38341
|
+
clearTimeout(scanTimer);
|
|
38342
|
+
await tracker.recallAll();
|
|
38343
|
+
await tracker.send("二维码已扫描,请在手机上确认登录");
|
|
38344
|
+
},
|
|
38345
|
+
onChallenge: (async (challenge) => {
|
|
38346
|
+
scanned = true;
|
|
38347
|
+
clearTimeout(scanTimer);
|
|
38348
|
+
if (challenge.kind !== "captcha") throw new LoginAborted$2("这次登录要求短信验证,当前只支持人机验证,请改用手机快手重新扫码");
|
|
38349
|
+
await waitForVerify$1(e, challenge.imageUrl, tracker);
|
|
38350
|
+
return { ticket: "" };
|
|
38351
|
+
}),
|
|
38352
|
+
onSuccess: async (credential) => {
|
|
38353
|
+
await persistCookie$2(credential.cookie);
|
|
38354
|
+
}
|
|
38355
|
+
});
|
|
38356
|
+
await tracker.recallAll();
|
|
38357
|
+
if (outcome.ok) {
|
|
38358
|
+
await e.reply("登录成功!用户登录凭证已保存至配置", { reply: true });
|
|
38359
|
+
return true;
|
|
38360
|
+
}
|
|
38361
|
+
if (abortNotice) {
|
|
38362
|
+
await e.reply(abortNotice, { reply: true });
|
|
38363
|
+
return true;
|
|
38364
|
+
}
|
|
38365
|
+
logger$1.warn(`[快手登录] 会话结束于失败态: kind=${outcome.error.kind} code=${outcome.error.code}`);
|
|
38366
|
+
await e.reply(noticeOf$2(outcome.error), { reply: true });
|
|
38367
|
+
} catch (error) {
|
|
38368
|
+
await tracker.recallAll();
|
|
38369
|
+
if (error instanceof LoginAborted$2) {
|
|
38370
|
+
await e.reply(error.notice, { reply: true });
|
|
38371
|
+
return true;
|
|
38372
|
+
}
|
|
38373
|
+
logger$1.error("[快手登录] 登录流程出错:", error);
|
|
38374
|
+
await e.reply("登录过程出错,请查看控制台日志", { reply: true });
|
|
38375
|
+
} finally {
|
|
38376
|
+
clearTimeout(scanTimer);
|
|
38377
|
+
}
|
|
38378
|
+
return true;
|
|
38379
|
+
};
|
|
38380
|
+
//#endregion
|
|
37596
38381
|
//#region src/platform/kuaishou/getID.ts
|
|
37597
38382
|
/**
|
|
37598
38383
|
*
|
|
@@ -37813,6 +38598,195 @@ var getXiaohongshuID = async (url, log = true) => {
|
|
|
37813
38598
|
return result;
|
|
37814
38599
|
};
|
|
37815
38600
|
//#endregion
|
|
38601
|
+
//#region src/platform/xiaohongshu/login.ts
|
|
38602
|
+
/**
|
|
38603
|
+
* 等扫码的时限:撤回窗口是 120s,这里留 10s 余量给网络与程序时延 ——
|
|
38604
|
+
* 顶格写 120s 的话,超时那一刻二维码已经撤不掉了。
|
|
38605
|
+
*/
|
|
38606
|
+
var SCAN_TIMEOUT$1 = 11e4;
|
|
38607
|
+
/** 等用户回「已完成验证」的时限(秒) */
|
|
38608
|
+
var VERIFY_INPUT_TIMEOUT = 120;
|
|
38609
|
+
/** 登录凭证里需要确认下发的关键字段 */
|
|
38610
|
+
var REQUIRED_COOKIES$1 = ["web_session"];
|
|
38611
|
+
/**
|
|
38612
|
+
* 主动中断登录会话。
|
|
38613
|
+
*
|
|
38614
|
+
* v7 的 `watch` 只在调用方回调自己抛出时才 reject,所以从 `onChallenge` 里退出流程
|
|
38615
|
+
* 只能靠抛 —— 回调的返回类型是 `{ ticket }`,没有「放弃」这个取值。用一个专门的异常
|
|
38616
|
+
* 带上要发给用户的话,外层认出它就正常收尾。
|
|
38617
|
+
*/
|
|
38618
|
+
var LoginAborted$1 = class extends Error {
|
|
38619
|
+
notice;
|
|
38620
|
+
constructor(notice) {
|
|
38621
|
+
super(notice);
|
|
38622
|
+
this.notice = notice;
|
|
38623
|
+
this.name = "LoginAborted";
|
|
38624
|
+
}
|
|
38625
|
+
};
|
|
38626
|
+
/**
|
|
38627
|
+
* 登录过程中发出的消息统一登记,结束时一起撤回,避免二维码留在群里
|
|
38628
|
+
* @param e - 消息事件
|
|
38629
|
+
* @returns 带 send / recallAll 的登记器
|
|
38630
|
+
*/
|
|
38631
|
+
var createMessageTracker$1 = (e) => {
|
|
38632
|
+
const messageIds = [];
|
|
38633
|
+
return {
|
|
38634
|
+
/**
|
|
38635
|
+
* 发送并登记一条消息
|
|
38636
|
+
* @param message - 消息内容
|
|
38637
|
+
* @returns 发送结果
|
|
38638
|
+
*/
|
|
38639
|
+
async send(message) {
|
|
38640
|
+
const sent = await e.reply(message, { reply: true });
|
|
38641
|
+
if (sent.messageId) messageIds.push(sent.messageId);
|
|
38642
|
+
return sent;
|
|
38643
|
+
},
|
|
38644
|
+
/** 撤回目前登记的全部消息 */
|
|
38645
|
+
async recallAll() {
|
|
38646
|
+
const pending = messageIds.splice(0, messageIds.length);
|
|
38647
|
+
await Promise.all(pending.map(async (id) => {
|
|
38648
|
+
try {
|
|
38649
|
+
await e.bot.recallMsg(e.contact, id);
|
|
38650
|
+
} catch (error) {
|
|
38651
|
+
logger$1.debug("[小红书登录] 撤回消息失败:", error);
|
|
38652
|
+
}
|
|
38653
|
+
}));
|
|
38654
|
+
}
|
|
38655
|
+
};
|
|
38656
|
+
};
|
|
38657
|
+
/**
|
|
38658
|
+
* 渲染并发送登录二维码,同时落一份到临时目录方便排查
|
|
38659
|
+
* @param e - 消息事件
|
|
38660
|
+
* @param qrcode - 会话给出的二维码
|
|
38661
|
+
* @param tracker - 消息登记器
|
|
38662
|
+
*/
|
|
38663
|
+
var sendQrcode$1 = async (e, qrcode, tracker) => {
|
|
38664
|
+
const rendered = await Render(e, "xiaohongshu/qrcodeImg", {
|
|
38665
|
+
share_url: qrcode.content,
|
|
38666
|
+
avatarUrl: await resolveTriggerAvatarUrl(e)
|
|
38667
|
+
});
|
|
38668
|
+
const base64Data = rendered[0]?.file;
|
|
38669
|
+
if (!base64Data) throw new Error("生成二维码图片失败");
|
|
38670
|
+
fs.writeFileSync(`${Common.tempDri.default}XiaohongshuLoginQrcode.png`, Buffer.from(base64Data.replace(/^base64:\/\//, ""), "base64"));
|
|
38671
|
+
await tracker.send(rendered);
|
|
38672
|
+
};
|
|
38673
|
+
/**
|
|
38674
|
+
* 把风控验证页交给真人,等他确认过完。
|
|
38675
|
+
*
|
|
38676
|
+
* 小红书的 redcaptcha 没有可回填进 `status` 调用的票据 —— 验证通过是**服务端按
|
|
38677
|
+
* `verifyUuid` 解除**的,解除后用同一套 cookie 重放 `status` 才会放行(amagi 策略的
|
|
38678
|
+
* `answer()` 只合并调用方带回的新 cookie,随后那次 poll 重放)。所以这里等的是
|
|
38679
|
+
* 「用户说过了」,接着让引擎自己继续轮询。
|
|
38680
|
+
*
|
|
38681
|
+
* **未真机验证**:amagi 侧标注扫码闭环无法在自动化环境端到端实测,需要真人用小红书
|
|
38682
|
+
* App 扫一次(见其 `platforms/xiaohongshu/qrcodeLogin.ts` 模块头)。
|
|
38683
|
+
* @param e - 消息事件
|
|
38684
|
+
* @param url - 验证页地址(`challenge.imageUrl`)
|
|
38685
|
+
* @param tracker - 消息登记器
|
|
38686
|
+
* @throws {LoginAborted} 用户超时未确认
|
|
38687
|
+
*/
|
|
38688
|
+
var waitForVerify = async (e, url, tracker) => {
|
|
38689
|
+
await tracker.send(`此次登录触发了风控验证\n请在浏览器里打开下面的地址完成验证:\n${url}\n完成后回复「已完成」` + (url === "" ? "\n(平台这次没有给出验证页地址,可稍后重试)" : ""));
|
|
38690
|
+
if (!await karin$1.ctx(e, {
|
|
38691
|
+
time: VERIFY_INPUT_TIMEOUT,
|
|
38692
|
+
reply: false,
|
|
38693
|
+
throwOnTimeout: false
|
|
38694
|
+
})) throw new LoginAborted$1("等待验证超时,登录已取消");
|
|
38695
|
+
};
|
|
38696
|
+
/**
|
|
38697
|
+
* 保存登录凭证并重载 Amagi 客户端
|
|
38698
|
+
*
|
|
38699
|
+
* 只落 cookie:amagi 的 x-s 签名会在服务端要求时用会话密钥(webSsk)补 x6/x7,而扫码
|
|
38700
|
+
* 产物里没有这一项 —— 真机上如果登录态请求被 406 拒绝,再考虑把 webSsk 一并持久化。
|
|
38701
|
+
* @param cookie - 完整登录 cookie
|
|
38702
|
+
*/
|
|
38703
|
+
var persistCookie$1 = async (cookie) => {
|
|
38704
|
+
const present = new Set(cookie.split(";").map((pair) => pair.split("=")[0].trim()));
|
|
38705
|
+
const missing = REQUIRED_COOKIES$1.filter((name) => !present.has(name));
|
|
38706
|
+
if (missing.length > 0) logger$1.warn(`[小红书登录] 以下字段未在本次登录中下发:${missing.join(", ")}`);
|
|
38707
|
+
await Config.Modify("amagi", "cookies.xiaohongshu", cookie);
|
|
38708
|
+
const reloaded = reloadAmagiConfig();
|
|
38709
|
+
logger$1.mark(`[小红书登录] 登录凭证已保存,Amagi Client ${reloaded ? "已重载" : "配置未变化"}`);
|
|
38710
|
+
};
|
|
38711
|
+
/** 把会话的失败原因翻成给用户看的话 */
|
|
38712
|
+
var noticeOf$1 = (error) => {
|
|
38713
|
+
if (error.kind === "risk") return `登录请求被小红书风控拦截:${error.message}\n请稍后再试`;
|
|
38714
|
+
if (error.code === "COOKIE_EXPIRED") return "二维码已失效,请重新发起登录";
|
|
38715
|
+
return `登录未完成:${error.message}`;
|
|
38716
|
+
};
|
|
38717
|
+
/**
|
|
38718
|
+
* 小红书扫码登录。
|
|
38719
|
+
*
|
|
38720
|
+
* 协议与轮询编排都在 amagi 的 v7 登录会话里(`client.xiaohongshu.login.qrcode()`):
|
|
38721
|
+
* 游客冷启动(a1 / webId / SSK)→ 取码 → 轮询 codeStatus → 换正式 web_session,
|
|
38722
|
+
* 以及风控二次验证的挑战中转都由引擎负责。这里只做三件与用户交互的事 ——
|
|
38723
|
+
* 渲染二维码、把验证页转给人、把凭证落库。
|
|
38724
|
+
* @param e - 消息事件
|
|
38725
|
+
* @returns 固定 true,交回命令框架
|
|
38726
|
+
*/
|
|
38727
|
+
var xiaohongshuLogin = async (e) => {
|
|
38728
|
+
const tracker = createMessageTracker$1(e);
|
|
38729
|
+
const controller = new AbortController();
|
|
38730
|
+
/** 自己中断时要发的话;有值说明不是引擎给出的失败 */
|
|
38731
|
+
let abortNotice;
|
|
38732
|
+
let scanned = false;
|
|
38733
|
+
let scanTimer;
|
|
38734
|
+
try {
|
|
38735
|
+
const outcome = await getAmagiClient().xiaohongshu.login.qrcode().watch({
|
|
38736
|
+
signal: controller.signal,
|
|
38737
|
+
timeoutMs: 29e4,
|
|
38738
|
+
onQrcode: async (qrcode) => {
|
|
38739
|
+
logger$1.mark(`[小红书登录] 二维码已获取,有效期 ${qrcode.expiresInSec} 秒`);
|
|
38740
|
+
await sendQrcode$1(e, qrcode, tracker);
|
|
38741
|
+
scanTimer = setTimeout(() => {
|
|
38742
|
+
if (scanned) return;
|
|
38743
|
+
abortNotice = "登录超时!二维码已失效!";
|
|
38744
|
+
controller.abort();
|
|
38745
|
+
}, SCAN_TIMEOUT$1);
|
|
38746
|
+
},
|
|
38747
|
+
onScanned: async () => {
|
|
38748
|
+
if (scanned) return;
|
|
38749
|
+
scanned = true;
|
|
38750
|
+
clearTimeout(scanTimer);
|
|
38751
|
+
await tracker.recallAll();
|
|
38752
|
+
await tracker.send("二维码已扫描,请在手机上确认登录");
|
|
38753
|
+
},
|
|
38754
|
+
onChallenge: (async (challenge) => {
|
|
38755
|
+
scanned = true;
|
|
38756
|
+
clearTimeout(scanTimer);
|
|
38757
|
+
if (challenge.kind !== "captcha") throw new LoginAborted$1("这次登录要求短信验证,当前只支持风控验证,请稍后重试");
|
|
38758
|
+
await waitForVerify(e, challenge.imageUrl, tracker);
|
|
38759
|
+
return { ticket: "" };
|
|
38760
|
+
}),
|
|
38761
|
+
onSuccess: async (credential) => {
|
|
38762
|
+
await persistCookie$1(credential.cookie);
|
|
38763
|
+
}
|
|
38764
|
+
});
|
|
38765
|
+
await tracker.recallAll();
|
|
38766
|
+
if (outcome.ok) {
|
|
38767
|
+
await e.reply("登录成功!用户登录凭证已保存至配置", { reply: true });
|
|
38768
|
+
return true;
|
|
38769
|
+
}
|
|
38770
|
+
if (abortNotice) {
|
|
38771
|
+
await e.reply(abortNotice, { reply: true });
|
|
38772
|
+
return true;
|
|
38773
|
+
}
|
|
38774
|
+
logger$1.warn(`[小红书登录] 会话结束于失败态: kind=${outcome.error.kind} code=${outcome.error.code}`);
|
|
38775
|
+
await e.reply(noticeOf$1(outcome.error), { reply: true });
|
|
38776
|
+
} catch (error) {
|
|
38777
|
+
await tracker.recallAll();
|
|
38778
|
+
if (error instanceof LoginAborted$1) {
|
|
38779
|
+
await e.reply(error.notice, { reply: true });
|
|
38780
|
+
return true;
|
|
38781
|
+
}
|
|
38782
|
+
logger$1.error("[小红书登录] 登录流程出错:", error);
|
|
38783
|
+
await e.reply("登录过程出错,请查看控制台日志", { reply: true });
|
|
38784
|
+
} finally {
|
|
38785
|
+
clearTimeout(scanTimer);
|
|
38786
|
+
}
|
|
38787
|
+
return true;
|
|
38788
|
+
};
|
|
38789
|
+
//#endregion
|
|
37816
38790
|
//#region src/platform/xiaohongshu/comments.ts
|
|
37817
38791
|
/**
|
|
37818
38792
|
* 处理小红书评论数据。
|
|
@@ -38315,8 +39289,11 @@ var XiaohongshuEmoji = (data) => {
|
|
|
38315
39289
|
};
|
|
38316
39290
|
//#endregion
|
|
38317
39291
|
//#region src/platform/douyin/login.ts
|
|
38318
|
-
/**
|
|
38319
|
-
|
|
39292
|
+
/**
|
|
39293
|
+
* 等扫码的时限:撤回窗口是 120s,这里留 10s 余量给网络与程序时延 ——
|
|
39294
|
+
* 顶格写 120s 的话,超时那一刻二维码已经撤不掉了。
|
|
39295
|
+
*/
|
|
39296
|
+
var SCAN_TIMEOUT = 11e4;
|
|
38320
39297
|
/** 等待用户回填短信验证码的时限(秒) */
|
|
38321
39298
|
var CODE_INPUT_TIMEOUT = 90;
|
|
38322
39299
|
/** 短信验证码允许的重试次数 */
|
|
@@ -38466,7 +39443,7 @@ var douyinLogin = async (e) => {
|
|
|
38466
39443
|
try {
|
|
38467
39444
|
const outcome = await getAmagiClient().douyin.login.qrcode().watch({
|
|
38468
39445
|
signal: controller.signal,
|
|
38469
|
-
timeoutMs:
|
|
39446
|
+
timeoutMs: 29e4,
|
|
38470
39447
|
onQrcode: async (qrcode) => {
|
|
38471
39448
|
logger$1.mark(`[抖音登录] 二维码已获取,有效期 ${qrcode.expiresInSec} 秒`);
|
|
38472
39449
|
await sendQrcode(e, qrcode, tracker);
|
|
@@ -38537,6 +39514,18 @@ var handleDouyinLogin = wrapWithErrorHandler(async (e) => {
|
|
|
38537
39514
|
await douyinLogin(e);
|
|
38538
39515
|
return true;
|
|
38539
39516
|
}, { businessName: "抖音登录" });
|
|
39517
|
+
var handleKuaishouLogin = wrapWithErrorHandler(async (e) => {
|
|
39518
|
+
await kuaishouLogin(e);
|
|
39519
|
+
return true;
|
|
39520
|
+
}, { businessName: "快手登录" });
|
|
39521
|
+
var handleXiaohongshuLogin = wrapWithErrorHandler(async (e) => {
|
|
39522
|
+
await xiaohongshuLogin(e);
|
|
39523
|
+
return true;
|
|
39524
|
+
}, { businessName: "小红书登录" });
|
|
39525
|
+
var handleBilibiliRefresh = wrapWithErrorHandler(async (e) => {
|
|
39526
|
+
await bilibiliRefreshLogin(e);
|
|
39527
|
+
return true;
|
|
39528
|
+
}, { businessName: "B站登录态续期" });
|
|
38540
39529
|
var handlTestWrapWithErrorHandler = wrapWithErrorHandler(async (_e) => {
|
|
38541
39530
|
logger$1.trace("测试跟踪日志");
|
|
38542
39531
|
logger$1.debug("测试调试日志");
|
|
@@ -38555,6 +39544,18 @@ var dylogin = karin.command(/^#?(kkk)?抖音(扫码)?登录$/, handleDouyinLogin
|
|
|
38555
39544
|
perm: Config.douyin.loginPerm,
|
|
38556
39545
|
name: "kkk-ck管理"
|
|
38557
39546
|
});
|
|
39547
|
+
var ksLogin = karin.command(/^#?(kkk)?快手(扫码)?登录$/, handleKuaishouLogin, {
|
|
39548
|
+
perm: Config.kuaishou.loginPerm,
|
|
39549
|
+
name: "kkk-ck管理"
|
|
39550
|
+
});
|
|
39551
|
+
var xhsLogin = karin.command(/^#?(kkk)?小红书(扫码)?登录$/, handleXiaohongshuLogin, {
|
|
39552
|
+
perm: Config.xiaohongshu.loginPerm,
|
|
39553
|
+
name: "kkk-ck管理"
|
|
39554
|
+
});
|
|
39555
|
+
var biRefreshLogin = karin.command(/^#?(kkk)?B站(登录态)?(续期|刷新)$/i, handleBilibiliRefresh, {
|
|
39556
|
+
perm: Config.bilibili.loginPerm,
|
|
39557
|
+
name: "kkk-ck管理"
|
|
39558
|
+
});
|
|
38558
39559
|
var testWrapWithErrorHandler = process.env.NODE_ENV === "development" ? karin.command(/^#?(kkk)?\s*测试\s*错误捕获$/i, handlTestWrapWithErrorHandler, {
|
|
38559
39560
|
perm: Config.bilibili.loginPerm,
|
|
38560
39561
|
name: "kkk-测试命令-错误捕获"
|
|
@@ -40115,10 +41116,11 @@ var handleTestPush = wrapWithErrorHandler(async (e) => {
|
|
|
40115
41116
|
return true;
|
|
40116
41117
|
}
|
|
40117
41118
|
const room_data = JSON.parse(user.room_data);
|
|
40118
|
-
const
|
|
41119
|
+
const liveParams = {
|
|
40119
41120
|
room_id: user.room_id_str,
|
|
40120
41121
|
web_rid: room_data.owner.web_rid
|
|
40121
|
-
}
|
|
41122
|
+
};
|
|
41123
|
+
const liveInfo = await douyinFetcher.fetchLiveRoomInfo(liveParams);
|
|
40122
41124
|
images = await renderLiveImage({
|
|
40123
41125
|
e,
|
|
40124
41126
|
Detail_Data: {
|
|
@@ -41837,4 +42839,4 @@ mkdirSync(`${karinPathBase}/${Root.pluginName}/data`);
|
|
|
41837
42839
|
mkdirSync(Common.tempDri.images);
|
|
41838
42840
|
mkdirSync(Common.tempDri.video);
|
|
41839
42841
|
//#endregion
|
|
41840
|
-
export {
|
|
42842
|
+
export { isSoftFailure as $, task as A, getStatisticsDB as B, help as C, dylogin as D, biRefreshLogin as E, bilibiliDBInstance as F, DouyinDBBase as G, METRIC_BUCKETS as H, cleanOldDynamicCache as I, AmagiError as J, BilibiliDBBase as K, douyinDBInstance as L, xhsLogin as M, templates as N, ksLogin as O, webConfig as P, getAmagiClient as Q, getBilibiliDB as R, changelog as S, biLogin as T, StatisticsDBBase as U, initAllDatabases as V, resolveMetricBucket as W, bilibiliFetcher as X, SOFT_ERROR_CODES as Y, douyinFetcher as Z, douyinPushList as _, bilibiliAPP as a, Root as at, setbiliPush as b, prefix as c, globalStatistics as d, kuaishouFetcher as et, groupStatistics as f, douyinPush as g, bilibiliPushList as h, update as i, xiaohongshuFetcher as it, testWrapWithErrorHandler as j, removeOldFiles as k, xiaohongshuAPP as l, bilibiliPush as m, kkkUpdateCommand as n, reloadAmagiConfig as nt, douyinAPP as o, qrLogin as p, AmagiBase as q, kkkUpdateTest as r, softFetch as rt, kuaishouAPP as s, kkkUpdate as t, registerAmagiReloadListener as tt, testPush as u, forcePush as v, version as w, setdyPush as x, globalIgnore as y, getDouyinDB as z };
|