rankrunners-cms 0.0.43 → 0.0.45
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/package.json +4 -4
- package/src/captcha/api.ts +1 -5
- package/src/next/CaptchaBadge.tsx +162 -0
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rankrunners-cms",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.45",
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"@puckeditor/core": "^0.21.1",
|
|
7
|
-
"@tanstack/react-router": "^1.
|
|
8
|
-
"@tanstack/router-core": "^1.
|
|
7
|
+
"@tanstack/react-router": "^1.167.0",
|
|
8
|
+
"@tanstack/router-core": "^1.167.0",
|
|
9
9
|
"lucide-react": "^0.577.0",
|
|
10
10
|
"next": "^16.1.6",
|
|
11
11
|
"react": "^19.2.4",
|
|
12
12
|
"valibot": "^1.2.0",
|
|
13
|
-
"hono": "^4.12.
|
|
13
|
+
"hono": "^4.12.8"
|
|
14
14
|
},
|
|
15
15
|
"peerDependenciesMeta": {
|
|
16
16
|
"next": {
|
package/src/captcha/api.ts
CHANGED
|
@@ -9,9 +9,6 @@ import type {
|
|
|
9
9
|
RedeemResponse,
|
|
10
10
|
ValidateResponse,
|
|
11
11
|
} from "./types.ts";
|
|
12
|
-
// Not ideal, due to this bug: https://github.com/vitejs/vite/issues/15618
|
|
13
|
-
// https://github.com/vitejs/vite/discussions/15547
|
|
14
|
-
import CapWorker from "./worker.ts?worker&inline";
|
|
15
12
|
|
|
16
13
|
export async function getChallenge(
|
|
17
14
|
context: Pick<CapHookProps, "endpoint" | "challengeHeaders">,
|
|
@@ -201,8 +198,7 @@ function prng(seed: string, length: number) {
|
|
|
201
198
|
}
|
|
202
199
|
|
|
203
200
|
function createWorker() {
|
|
204
|
-
|
|
205
|
-
return new CapWorker();
|
|
201
|
+
return new Worker(new URL("./worker.ts", import.meta.url));
|
|
206
202
|
}
|
|
207
203
|
|
|
208
204
|
export function isTokenExpired(token: CapToken) {
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import Image from "next/image";
|
|
3
|
+
import rankrunners from "../assets/rankrunners.webp";
|
|
4
|
+
|
|
5
|
+
export const CaptchaBadge: React.FC = () => {
|
|
6
|
+
const [isHovered, setIsHovered] = useState(false);
|
|
7
|
+
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
|
8
|
+
const [isLearnMoreHovered, setIsLearnMoreHovered] = useState(false);
|
|
9
|
+
const [isCloseHovered, setIsCloseHovered] = useState(false);
|
|
10
|
+
|
|
11
|
+
const handleMouseEnter = () => setIsHovered(true);
|
|
12
|
+
const handleMouseLeave = () => setIsHovered(false);
|
|
13
|
+
const handleLearnMoreClick = () => setIsDialogOpen(true);
|
|
14
|
+
const handleCloseDialog = () => setIsDialogOpen(false);
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<>
|
|
18
|
+
<div
|
|
19
|
+
style={{
|
|
20
|
+
position: "fixed",
|
|
21
|
+
right: isHovered ? 0 : -48,
|
|
22
|
+
bottom: 16,
|
|
23
|
+
zIndex: 50,
|
|
24
|
+
display: "flex",
|
|
25
|
+
alignItems: "center",
|
|
26
|
+
width: isHovered ? 256 : 104,
|
|
27
|
+
overflow: "hidden",
|
|
28
|
+
border: "1.5px solid #d1d5db",
|
|
29
|
+
borderRadius: 8,
|
|
30
|
+
background: "#ffffff",
|
|
31
|
+
padding: 8,
|
|
32
|
+
boxShadow:
|
|
33
|
+
"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -2px rgb(0 0 0 / 0.05)",
|
|
34
|
+
transition: "all 0.3s ease-in-out",
|
|
35
|
+
}}
|
|
36
|
+
onMouseEnter={handleMouseEnter}
|
|
37
|
+
onMouseLeave={handleMouseLeave}
|
|
38
|
+
>
|
|
39
|
+
<Image
|
|
40
|
+
src={rankrunners}
|
|
41
|
+
alt="RankRunners Logo"
|
|
42
|
+
style={{
|
|
43
|
+
width: 40,
|
|
44
|
+
height: 40,
|
|
45
|
+
borderRadius: 9999,
|
|
46
|
+
flexShrink: 0,
|
|
47
|
+
}}
|
|
48
|
+
/>
|
|
49
|
+
<div
|
|
50
|
+
style={{
|
|
51
|
+
display: "flex",
|
|
52
|
+
width: "100%",
|
|
53
|
+
justifyContent: "center",
|
|
54
|
+
flexDirection: "column",
|
|
55
|
+
transform: isHovered ? "translateX(0)" : "translateX(100%)",
|
|
56
|
+
opacity: isHovered ? 1 : 0,
|
|
57
|
+
transition: "all 0.3s ease-in-out",
|
|
58
|
+
}}
|
|
59
|
+
>
|
|
60
|
+
<div
|
|
61
|
+
style={{
|
|
62
|
+
display: "flex",
|
|
63
|
+
flexDirection: "column",
|
|
64
|
+
alignItems: "center",
|
|
65
|
+
justifyContent: "center",
|
|
66
|
+
}}
|
|
67
|
+
>
|
|
68
|
+
<span
|
|
69
|
+
style={{
|
|
70
|
+
color: "#374151",
|
|
71
|
+
fontSize: 14,
|
|
72
|
+
fontWeight: 500,
|
|
73
|
+
whiteSpace: "nowrap",
|
|
74
|
+
}}
|
|
75
|
+
>
|
|
76
|
+
Protected by RankRunners
|
|
77
|
+
</span>
|
|
78
|
+
<button
|
|
79
|
+
style={{
|
|
80
|
+
marginLeft: 8,
|
|
81
|
+
border: "none",
|
|
82
|
+
background: "transparent",
|
|
83
|
+
color: "#2563eb",
|
|
84
|
+
fontSize: 14,
|
|
85
|
+
cursor: "pointer",
|
|
86
|
+
textDecoration: isLearnMoreHovered ? "underline" : "none",
|
|
87
|
+
}}
|
|
88
|
+
onClick={handleLearnMoreClick}
|
|
89
|
+
onMouseEnter={() => setIsLearnMoreHovered(true)}
|
|
90
|
+
onMouseLeave={() => setIsLearnMoreHovered(false)}
|
|
91
|
+
>
|
|
92
|
+
Learn more
|
|
93
|
+
</button>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
{isDialogOpen && (
|
|
99
|
+
<div
|
|
100
|
+
style={{
|
|
101
|
+
position: "fixed",
|
|
102
|
+
inset: 0,
|
|
103
|
+
zIndex: 100,
|
|
104
|
+
display: "flex",
|
|
105
|
+
alignItems: "center",
|
|
106
|
+
justifyContent: "center",
|
|
107
|
+
background: "rgb(0 0 0 / 0.5)",
|
|
108
|
+
}}
|
|
109
|
+
>
|
|
110
|
+
<div
|
|
111
|
+
style={{
|
|
112
|
+
margin: "0 auto",
|
|
113
|
+
maxWidth: 384,
|
|
114
|
+
borderRadius: 8,
|
|
115
|
+
background: "#ffffff",
|
|
116
|
+
padding: 24,
|
|
117
|
+
boxShadow:
|
|
118
|
+
"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -2px rgb(0 0 0 / 0.05)",
|
|
119
|
+
}}
|
|
120
|
+
>
|
|
121
|
+
<h3
|
|
122
|
+
style={{
|
|
123
|
+
margin: "0 0 16px",
|
|
124
|
+
fontSize: 18,
|
|
125
|
+
fontWeight: 700,
|
|
126
|
+
}}
|
|
127
|
+
>
|
|
128
|
+
About RankRunners Captcha
|
|
129
|
+
</h3>
|
|
130
|
+
<p
|
|
131
|
+
style={{
|
|
132
|
+
margin: "0 0 16px",
|
|
133
|
+
color: "#374151",
|
|
134
|
+
}}
|
|
135
|
+
>
|
|
136
|
+
RankRunners Captcha helps protect this site from spam and abuse.
|
|
137
|
+
<br />
|
|
138
|
+
<br /> It works by analyzing user behavior to distinguish between
|
|
139
|
+
humans and bots without interrupting the user experience.
|
|
140
|
+
</p>
|
|
141
|
+
<button
|
|
142
|
+
style={{
|
|
143
|
+
border: "none",
|
|
144
|
+
borderRadius: 6,
|
|
145
|
+
background: isCloseHovered ? "#1d4ed8" : "#3b82f6",
|
|
146
|
+
padding: "8px 16px",
|
|
147
|
+
color: "#ffffff",
|
|
148
|
+
fontWeight: 700,
|
|
149
|
+
cursor: "pointer",
|
|
150
|
+
}}
|
|
151
|
+
onClick={handleCloseDialog}
|
|
152
|
+
onMouseEnter={() => setIsCloseHovered(true)}
|
|
153
|
+
onMouseLeave={() => setIsCloseHovered(false)}
|
|
154
|
+
>
|
|
155
|
+
Close
|
|
156
|
+
</button>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
)}
|
|
160
|
+
</>
|
|
161
|
+
);
|
|
162
|
+
};
|