4sp-dv 1.1.12 → 1.1.13

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.
@@ -0,0 +1,248 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" class="dark">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>4SP - URL Tester</title>
7
+
8
+ <link rel="preconnect" href="https://fonts.googleapis.com">
9
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
+ <link href="https://fonts.googleapis.com/css2?family=Geist:wght@100..900&display=swap" rel="stylesheet">
11
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
12
+ <script src="https://cdn.tailwindcss.com"></script>
13
+
14
+ <style>
15
+ body {
16
+ font-family: 'Geist', sans-serif;
17
+ background-color: #040404;
18
+ color: #c0c0c0;
19
+ font-weight: 300;
20
+ height: 100vh;
21
+ display: flex;
22
+ flex-direction: column;
23
+ overflow: hidden;
24
+ }
25
+
26
+ /* --- UI COMPONENTS --- */
27
+ .btn-toolbar-style {
28
+ background: #000000;
29
+ border: 1px solid #333;
30
+ border-radius: 0.75rem;
31
+ color: #d1d5db;
32
+ padding: 0.75rem 1.25rem;
33
+ font-weight: 500;
34
+ cursor: pointer;
35
+ transition: all 0.2s;
36
+ display: inline-flex;
37
+ align-items: center;
38
+ justify-content: center;
39
+ gap: 0.5rem;
40
+ }
41
+ .btn-toolbar-style:hover {
42
+ border-color: #fff;
43
+ color: #ffffff;
44
+ transform: translateY(-1px);
45
+ }
46
+ .btn-toolbar-style:active {
47
+ transform: scale(0.98);
48
+ }
49
+
50
+ .btn-primary-override {
51
+ background-color: rgba(79, 70, 229, 0.1);
52
+ border: 1px solid #4f46e5;
53
+ color: #4f46e5;
54
+ }
55
+ .btn-primary-override:hover {
56
+ background-color: rgba(79, 70, 229, 0.2);
57
+ border-color: #6366f1;
58
+ color: #6366f1;
59
+ }
60
+
61
+ .input-text-style {
62
+ width: 100%;
63
+ padding: 0.75rem;
64
+ border: 1px solid #252525;
65
+ background-color: #111111;
66
+ border-radius: 0.75rem;
67
+ color: #c0c0c0;
68
+ transition: all 0.2s;
69
+ outline: none;
70
+ }
71
+ .input-text-style:focus {
72
+ border-color: #505050;
73
+ box-shadow: 0 0 0 2px rgba(80, 80, 80, 0.5);
74
+ transform: scale(1.01);
75
+ }
76
+
77
+ .card-box {
78
+ background-color: #0d0d0d;
79
+ border: 1px solid #1a1a1a;
80
+ border-radius: 1rem;
81
+ padding: 2rem;
82
+ width: 100%;
83
+ max-width: 600px;
84
+ box-shadow: 0 10px 30px rgba(0,0,0,0.5);
85
+ }
86
+
87
+ /* Status Colors */
88
+ .status-box {
89
+ padding: 1rem;
90
+ border-radius: 0.75rem;
91
+ text-align: center;
92
+ font-weight: 500;
93
+ margin-top: 1.5rem;
94
+ border: 1px solid transparent;
95
+ transition: all 0.3s;
96
+ }
97
+ .status-blocked {
98
+ background-color: rgba(185, 28, 28, 0.1);
99
+ border-color: #7f1d1d;
100
+ color: #fca5a5;
101
+ }
102
+ .status-allowed {
103
+ background-color: rgba(21, 128, 61, 0.1);
104
+ border-color: #14532d;
105
+ color: #86efac;
106
+ }
107
+ .status-info {
108
+ background-color: #1a1a1a;
109
+ border-color: #333;
110
+ color: #9ca3af;
111
+ }
112
+
113
+ .loading-spinner {
114
+ animation: spin 1s linear infinite;
115
+ }
116
+ @keyframes spin { 100% { transform: rotate(360deg); } }
117
+ </style>
118
+ </head>
119
+ <body>
120
+
121
+ <div class="flex-grow flex flex-col items-center justify-center p-4">
122
+
123
+ <div class="mb-8 text-center">
124
+ <h1 class="text-3xl text-white font-light tracking-tight mb-2">Securly URL Tester</h1>
125
+ <p class="text-gray-500 text-sm">Check if a website is blocked on the US-EAST server.</p>
126
+ </div>
127
+
128
+ <div class="card-box">
129
+
130
+ <div class="mb-6">
131
+ <label class="block text-gray-500 text-xs uppercase tracking-wider mb-2 font-semibold">Student Email</label>
132
+ <input type="email" id="email-input" class="input-text-style font-mono text-sm !bg-[#1a1a1a] !border-[#333]" placeholder="student@school.edu">
133
+ </div>
134
+
135
+ <div class="mb-6">
136
+ <label class="block text-gray-500 text-xs uppercase tracking-wider mb-2 font-semibold">Target URL</label>
137
+ <input type="text" id="url-input" class="input-text-style" placeholder="example.com" value="zapatopi.net/treeoctopus/">
138
+ </div>
139
+
140
+ <button id="check-btn" class="btn-toolbar-style btn-primary-override w-full justify-center">
141
+ <i class="fa-solid fa-search"></i> Check Status
142
+ </button>
143
+
144
+ <div id="result-box" class="status-box status-info">
145
+ Ready to check
146
+ </div>
147
+
148
+ <p class="mt-4 text-xs text-center text-gray-600">
149
+ <i class="fa-solid fa-shield-halved mr-1"></i> Uses CORS Proxy to bypass local restrictions.
150
+ </p>
151
+
152
+ </div>
153
+ </div>
154
+
155
+ <script>
156
+ const emailInput = document.getElementById('email-input');
157
+ const urlInput = document.getElementById('url-input');
158
+ const checkBtn = document.getElementById('check-btn');
159
+ const resultBox = document.getElementById('result-box');
160
+
161
+ const SECURLY_SERVER = 'https://useast-www.securly.com';
162
+ const CORS_PROXY = 'https://corsproxy.io/?';
163
+
164
+ // --- AUTH DETECTION ---
165
+ function detectUser() {
166
+ let userEmail = '';
167
+ // 1. Try injected window.currentUser (from 4simpleproblems_v5.html)
168
+ if (window.currentUser && window.currentUser.email) {
169
+ userEmail = window.currentUser.email;
170
+ }
171
+ // 2. Try parent scope if accessible
172
+ else if (window.parent && window.parent.currentUser && window.parent.currentUser.email) {
173
+ userEmail = window.parent.currentUser.email;
174
+ }
175
+ // 3. Fallback/Default
176
+ else {
177
+ userEmail = 'client@4sp'; // Default for testing/unauthed
178
+ }
179
+
180
+ emailInput.value = userEmail;
181
+ }
182
+
183
+ // --- CHECK LOGIC ---
184
+ async function checkStatus() {
185
+ const rawUrl = urlInput.value.trim();
186
+ const userEmail = emailInput.value.trim();
187
+ if (!rawUrl || !userEmail) return;
188
+
189
+ // Normalize URL
190
+ let targetUrl = rawUrl;
191
+ if (!targetUrl.startsWith('http')) {
192
+ targetUrl = 'https://' + targetUrl;
193
+ }
194
+ urlInput.value = targetUrl; // Update input
195
+
196
+ // UI Loading
197
+ checkBtn.disabled = true;
198
+ checkBtn.innerHTML = '<i class="fa-solid fa-spinner loading-spinner"></i> Checking...';
199
+ resultBox.className = 'status-box status-info';
200
+ resultBox.innerHTML = 'Connecting to Securly...';
201
+
202
+ try {
203
+ // Construct Securly Broker URL
204
+ let hostname;
205
+ try { hostname = new URL(targetUrl).hostname; } catch(e) { hostname = targetUrl; }
206
+
207
+ const securlyUrl = `${SECURLY_SERVER}/crextn/broker?useremail=${encodeURIComponent(userEmail)}&reason=crextn&host=${encodeURIComponent(hostname)}&url=${btoa(targetUrl)}&msg=&ver=2.97.13&cu=${encodeURIComponent(SECURLY_SERVER + "/crextn")}&uf=1&cf=1`;
208
+
209
+ const proxyUrl = CORS_PROXY + encodeURIComponent(securlyUrl);
210
+
211
+ const response = await fetch(proxyUrl);
212
+ const text = await response.text();
213
+
214
+ if (text.includes('DENY')) {
215
+ resultBox.className = 'status-box status-blocked';
216
+ resultBox.innerHTML = '<i class="fa-solid fa-ban mr-2"></i> BLOCKED (DENY)';
217
+ } else if (text.includes('ALLOW')) {
218
+ resultBox.className = 'status-box status-allowed';
219
+ resultBox.innerHTML = '<i class="fa-solid fa-check-circle mr-2"></i> ALLOWED';
220
+ } else {
221
+ resultBox.className = 'status-box status-info';
222
+ resultBox.innerHTML = '<i class="fa-solid fa-question-circle mr-2"></i> STATUS UNKNOWN';
223
+ console.log('Securly Response:', text);
224
+ }
225
+
226
+ } catch (err) {
227
+ console.error(err);
228
+ resultBox.className = 'status-box status-blocked';
229
+ resultBox.innerHTML = '<i class="fa-solid fa-exclamation-triangle mr-2"></i> NETWORK ERROR';
230
+ } finally {
231
+ checkBtn.disabled = false;
232
+ checkBtn.innerHTML = '<i class="fa-solid fa-search"></i> Check Status';
233
+ }
234
+ }
235
+
236
+ // --- INIT ---
237
+ window.addEventListener('load', () => {
238
+ detectUser();
239
+ });
240
+
241
+ checkBtn.addEventListener('click', checkStatus);
242
+ urlInput.addEventListener('keypress', (e) => {
243
+ if (e.key === 'Enter') checkStatus();
244
+ });
245
+
246
+ </script>
247
+ </body>
248
+ </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "4sp-dv",
3
- "version": "1.1.12",
3
+ "version": "1.1.13",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "homepage": "https://github.com/v5-4simpleproblems/v5-4simpleproblems-dv#readme",