pinokiod 3.259.0 → 3.261.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.
- package/kernel/peer.js +56 -2
- package/package.json +1 -1
- package/server/index.js +0 -4
- package/server/public/common.js +8 -5
- package/server/public/urldropdown.css +28 -0
- package/server/public/urldropdown.js +8 -6
- package/server/views/connect.ejs +4 -2
- package/server/views/index.ejs +6 -2
- package/server/views/index2.ejs +4 -2
- package/server/views/net.ejs +9 -4
- package/server/views/network.ejs +4 -2
package/kernel/peer.js
CHANGED
|
@@ -37,8 +37,16 @@ class PeerDiscovery {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
announce() {
|
|
40
|
-
if (this.socket) {
|
|
41
|
-
|
|
40
|
+
if (!this.socket) {
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
const targets = this._broadcastTargets()
|
|
44
|
+
for (const target of targets) {
|
|
45
|
+
try {
|
|
46
|
+
this.socket.send(this.message, 0, this.message.length, this.port, target)
|
|
47
|
+
} catch (err) {
|
|
48
|
+
console.error('peer broadcast failed', { target, err })
|
|
49
|
+
}
|
|
42
50
|
}
|
|
43
51
|
}
|
|
44
52
|
async check(kernel) {
|
|
@@ -641,6 +649,7 @@ class PeerDiscovery {
|
|
|
641
649
|
const classification = this.classifyAddress(address, Boolean(iface.internal))
|
|
642
650
|
results.push({
|
|
643
651
|
address,
|
|
652
|
+
netmask: String(iface.netmask || '').trim() || null,
|
|
644
653
|
interface: ifaceName,
|
|
645
654
|
internal: Boolean(iface.internal),
|
|
646
655
|
scope: classification.scope,
|
|
@@ -731,6 +740,51 @@ class PeerDiscovery {
|
|
|
731
740
|
}
|
|
732
741
|
return entries
|
|
733
742
|
}
|
|
743
|
+
_broadcastTargets() {
|
|
744
|
+
const addresses = this._collectInterfaceAddresses()
|
|
745
|
+
this.interface_addresses = addresses
|
|
746
|
+
const targets = new Set()
|
|
747
|
+
for (const entry of addresses) {
|
|
748
|
+
if (!entry || !entry.shareable) {
|
|
749
|
+
continue
|
|
750
|
+
}
|
|
751
|
+
const broadcast = this._deriveBroadcastAddress(entry.address, entry.netmask)
|
|
752
|
+
if (broadcast) {
|
|
753
|
+
targets.add(broadcast)
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
targets.add('255.255.255.255')
|
|
757
|
+
return Array.from(targets)
|
|
758
|
+
}
|
|
759
|
+
_deriveBroadcastAddress(address, netmask) {
|
|
760
|
+
const addrOctets = this._parseIPv4(address)
|
|
761
|
+
if (!addrOctets) {
|
|
762
|
+
return null
|
|
763
|
+
}
|
|
764
|
+
let maskOctets = this._parseIPv4(netmask)
|
|
765
|
+
if (!maskOctets) {
|
|
766
|
+
maskOctets = [255, 255, 255, 0]
|
|
767
|
+
}
|
|
768
|
+
const broadcastOctets = addrOctets.map((octet, idx) => {
|
|
769
|
+
const mask = maskOctets[idx]
|
|
770
|
+
return ((octet & mask) | (~mask & 255)) & 255
|
|
771
|
+
})
|
|
772
|
+
const candidate = broadcastOctets.join('.')
|
|
773
|
+
if (candidate.startsWith('127.') || candidate.startsWith('169.254.') || candidate === '0.0.0.0') {
|
|
774
|
+
return null
|
|
775
|
+
}
|
|
776
|
+
return candidate
|
|
777
|
+
}
|
|
778
|
+
_parseIPv4(value) {
|
|
779
|
+
if (!value || typeof value !== 'string') {
|
|
780
|
+
return null
|
|
781
|
+
}
|
|
782
|
+
const octets = value.split('.').map(Number)
|
|
783
|
+
if (octets.length !== 4 || octets.some((val) => Number.isNaN(val) || val < 0 || val > 255)) {
|
|
784
|
+
return null
|
|
785
|
+
}
|
|
786
|
+
return octets
|
|
787
|
+
}
|
|
734
788
|
}
|
|
735
789
|
|
|
736
790
|
module.exports = PeerDiscovery;
|
package/package.json
CHANGED
package/server/index.js
CHANGED
|
@@ -3250,7 +3250,6 @@ class Server {
|
|
|
3250
3250
|
this.kernel.store.set("theme", config.theme)
|
|
3251
3251
|
//this.theme = config.theme
|
|
3252
3252
|
}
|
|
3253
|
-
console.log("THEME CHANGED", theme_changed)
|
|
3254
3253
|
// 2. Handle HOME
|
|
3255
3254
|
if (config.home) {
|
|
3256
3255
|
// set "new_home"
|
|
@@ -3335,9 +3334,7 @@ class Server {
|
|
|
3335
3334
|
this.kernel.store.set("NO_PROXY", config.NO_PROXY)
|
|
3336
3335
|
|
|
3337
3336
|
if (theme_changed) {
|
|
3338
|
-
console.log("> syncConfig")
|
|
3339
3337
|
await this.syncConfig()
|
|
3340
|
-
console.log("onrefresh", this.onrefresh)
|
|
3341
3338
|
if (this.onrefresh) {
|
|
3342
3339
|
try {
|
|
3343
3340
|
this.onrefresh({ theme: this.theme, colors: this.colors })
|
|
@@ -8208,7 +8205,6 @@ class Server {
|
|
|
8208
8205
|
|
|
8209
8206
|
this.app.post("/config", ex(async (req, res) => {
|
|
8210
8207
|
try {
|
|
8211
|
-
console.log("POST /config", req.body)
|
|
8212
8208
|
let message = await this.setConfig(req.body)
|
|
8213
8209
|
res.json({ success: true, message })
|
|
8214
8210
|
} catch (e) {
|
package/server/public/common.js
CHANGED
|
@@ -2932,6 +2932,13 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
|
2932
2932
|
header.appendChild(iconWrapper);
|
|
2933
2933
|
header.appendChild(headingStack);
|
|
2934
2934
|
|
|
2935
|
+
const closeButton = document.createElement('button');
|
|
2936
|
+
closeButton.type = 'button';
|
|
2937
|
+
closeButton.className = 'create-launcher-modal-close';
|
|
2938
|
+
closeButton.setAttribute('aria-label', 'Close create launcher modal');
|
|
2939
|
+
closeButton.innerHTML = '<i class="fa-solid fa-xmark"></i>';
|
|
2940
|
+
header.appendChild(closeButton);
|
|
2941
|
+
|
|
2935
2942
|
const promptLabel = document.createElement('label');
|
|
2936
2943
|
promptLabel.className = 'create-launcher-modal-label';
|
|
2937
2944
|
promptLabel.textContent = 'What do you want to do?';
|
|
@@ -3190,12 +3197,8 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
|
3190
3197
|
});
|
|
3191
3198
|
|
|
3192
3199
|
cancelButton.addEventListener('click', hideCreateLauncherModal);
|
|
3200
|
+
closeButton.addEventListener('click', hideCreateLauncherModal);
|
|
3193
3201
|
confirmButton.addEventListener('click', submitCreateLauncherModal);
|
|
3194
|
-
overlay.addEventListener('click', (event) => {
|
|
3195
|
-
if (event.target === overlay) {
|
|
3196
|
-
hideCreateLauncherModal();
|
|
3197
|
-
}
|
|
3198
|
-
});
|
|
3199
3202
|
|
|
3200
3203
|
advancedLink.addEventListener('click', () => {
|
|
3201
3204
|
hideCreateLauncherModal();
|
|
@@ -200,6 +200,7 @@ body.dark .url-dropdown-empty-description {
|
|
|
200
200
|
font-family: "SF Pro Text", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
201
201
|
-webkit-backdrop-filter: blur(28px);
|
|
202
202
|
backdrop-filter: blur(28px);
|
|
203
|
+
position: relative;
|
|
203
204
|
}
|
|
204
205
|
body.dark .create-launcher-modal {
|
|
205
206
|
background: rgba(17, 24, 39, 0.82);
|
|
@@ -215,6 +216,33 @@ body.dark .create-launcher-modal {
|
|
|
215
216
|
align-items: center;
|
|
216
217
|
gap: 18px;
|
|
217
218
|
padding-bottom: 4px;
|
|
219
|
+
position: relative;
|
|
220
|
+
}
|
|
221
|
+
.create-launcher-modal-close {
|
|
222
|
+
position: absolute;
|
|
223
|
+
top: 0;
|
|
224
|
+
right: 0;
|
|
225
|
+
border: none;
|
|
226
|
+
background: transparent;
|
|
227
|
+
color: #6b7280;
|
|
228
|
+
font-size: 18px;
|
|
229
|
+
padding: 6px;
|
|
230
|
+
cursor: pointer;
|
|
231
|
+
line-height: 1;
|
|
232
|
+
}
|
|
233
|
+
.create-launcher-modal-close:hover {
|
|
234
|
+
color: #4f46e5;
|
|
235
|
+
}
|
|
236
|
+
.create-launcher-modal-close:focus-visible {
|
|
237
|
+
outline: 2px solid #4f46e5;
|
|
238
|
+
outline-offset: 2px;
|
|
239
|
+
border-radius: 4px;
|
|
240
|
+
}
|
|
241
|
+
body.dark .create-launcher-modal-close {
|
|
242
|
+
color: rgba(255,255,255,0.75);
|
|
243
|
+
}
|
|
244
|
+
body.dark .create-launcher-modal-close:hover {
|
|
245
|
+
color: #a5b4fc;
|
|
218
246
|
}
|
|
219
247
|
.create-launcher-modal-icon {
|
|
220
248
|
width: 44px;
|
|
@@ -1163,6 +1163,12 @@ function initUrlDropdown(config = {}) {
|
|
|
1163
1163
|
modalContent.setAttribute('role', 'dialog');
|
|
1164
1164
|
modalContent.setAttribute('aria-modal', 'true');
|
|
1165
1165
|
|
|
1166
|
+
const closeButton = document.createElement('button');
|
|
1167
|
+
closeButton.type = 'button';
|
|
1168
|
+
closeButton.className = 'create-launcher-modal-close';
|
|
1169
|
+
closeButton.setAttribute('aria-label', 'Close create launcher modal');
|
|
1170
|
+
closeButton.innerHTML = '<i class="fa-solid fa-xmark"></i>';
|
|
1171
|
+
|
|
1166
1172
|
const title = document.createElement('h3');
|
|
1167
1173
|
title.id = 'quick-create-launcher-title';
|
|
1168
1174
|
title.textContent = 'Create';
|
|
@@ -1204,6 +1210,7 @@ function initUrlDropdown(config = {}) {
|
|
|
1204
1210
|
actions.appendChild(confirmButton);
|
|
1205
1211
|
|
|
1206
1212
|
label.appendChild(input);
|
|
1213
|
+
modalContent.appendChild(closeButton);
|
|
1207
1214
|
modalContent.appendChild(title);
|
|
1208
1215
|
modalContent.appendChild(description);
|
|
1209
1216
|
modalContent.appendChild(label);
|
|
@@ -1212,13 +1219,8 @@ function initUrlDropdown(config = {}) {
|
|
|
1212
1219
|
overlay.appendChild(modalContent);
|
|
1213
1220
|
document.body.appendChild(overlay);
|
|
1214
1221
|
|
|
1215
|
-
overlay.addEventListener('click', function(event) {
|
|
1216
|
-
if (event.target === overlay) {
|
|
1217
|
-
hideCreateLauncherModal();
|
|
1218
|
-
}
|
|
1219
|
-
});
|
|
1220
|
-
|
|
1221
1222
|
cancelButton.addEventListener('click', hideCreateLauncherModal);
|
|
1223
|
+
closeButton.addEventListener('click', hideCreateLauncherModal);
|
|
1222
1224
|
confirmButton.addEventListener('click', confirmCreateLauncherModal);
|
|
1223
1225
|
input.addEventListener('keydown', handleCreateModalKeydown);
|
|
1224
1226
|
|
package/server/views/connect.ejs
CHANGED
|
@@ -322,8 +322,10 @@ body.dark .browser-options-row {
|
|
|
322
322
|
}
|
|
323
323
|
*/
|
|
324
324
|
body.dark .context-menu-wrapper {
|
|
325
|
-
background: rgba(0,0,0,0.9);
|
|
326
|
-
color: white;
|
|
325
|
+
background: rgba(0,0,0,0.9) !important;
|
|
326
|
+
color: white !important;
|
|
327
|
+
border: 1px solid rgba(255,255,255,0.1);
|
|
328
|
+
box-shadow: 0 12px 30px rgba(0,0,0,0.45);
|
|
327
329
|
}
|
|
328
330
|
.context-menu-wrapper {
|
|
329
331
|
background: rgba(0,0,0,0.06) !important;
|
package/server/views/index.ejs
CHANGED
|
@@ -158,8 +158,10 @@ body.dark .browser-options-row {
|
|
|
158
158
|
}
|
|
159
159
|
*/
|
|
160
160
|
body.dark .context-menu-wrapper {
|
|
161
|
-
background: rgba(0,0,0,0.9);
|
|
162
|
-
color: white;
|
|
161
|
+
background: rgba(0,0,0,0.9) !important;
|
|
162
|
+
color: white !important;
|
|
163
|
+
border: 1px solid rgba(255,255,255,0.1);
|
|
164
|
+
box-shadow: 0 12px 30px rgba(0,0,0,0.45);
|
|
163
165
|
}
|
|
164
166
|
.context-menu-wrapper {
|
|
165
167
|
background: whitesmoke !important;
|
|
@@ -194,6 +196,7 @@ body.dark .context-menu-wrapper {
|
|
|
194
196
|
padding: 6px 10px !important;
|
|
195
197
|
text-align: left;
|
|
196
198
|
color: black;
|
|
199
|
+
margin: 0 !important;
|
|
197
200
|
}
|
|
198
201
|
body.dark .btn {
|
|
199
202
|
background: rgba(255,255,255,0.05) !important;
|
|
@@ -209,6 +212,7 @@ body.dark .btn {
|
|
|
209
212
|
}
|
|
210
213
|
body.dark .context-menu .btn {
|
|
211
214
|
color: white;
|
|
215
|
+
background: none !important;
|
|
212
216
|
}
|
|
213
217
|
body.dark .open-menu, body.dark .browse {
|
|
214
218
|
border: none !important;
|
package/server/views/index2.ejs
CHANGED
|
@@ -128,8 +128,10 @@ body.dark .browser-options-row {
|
|
|
128
128
|
}
|
|
129
129
|
*/
|
|
130
130
|
body.dark .context-menu-wrapper {
|
|
131
|
-
background: rgba(0,0,0,0.9);
|
|
132
|
-
color: white;
|
|
131
|
+
background: rgba(0,0,0,0.9) !important;
|
|
132
|
+
color: white !important;
|
|
133
|
+
border: 1px solid rgba(255,255,255,0.1);
|
|
134
|
+
box-shadow: 0 12px 30px rgba(0,0,0,0.45);
|
|
133
135
|
}
|
|
134
136
|
.context-menu-wrapper {
|
|
135
137
|
background: rgba(0,0,0,0.06) !important;
|
package/server/views/net.ejs
CHANGED
|
@@ -135,8 +135,10 @@ body.dark .browser-options-row {
|
|
|
135
135
|
}
|
|
136
136
|
*/
|
|
137
137
|
body.dark .context-menu-wrapper {
|
|
138
|
-
background: rgba(0,0,0,0.9);
|
|
139
|
-
color: white;
|
|
138
|
+
background: rgba(0,0,0,0.9) !important;
|
|
139
|
+
color: white !important;
|
|
140
|
+
border: 1px solid rgba(255,255,255,0.1);
|
|
141
|
+
box-shadow: 0 12px 30px rgba(0,0,0,0.45);
|
|
140
142
|
}
|
|
141
143
|
.context-menu-wrapper {
|
|
142
144
|
background: rgba(0,0,0,0.06) !important;
|
|
@@ -782,9 +784,12 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
782
784
|
%>
|
|
783
785
|
<% if (directHosts.length > 0) { %>
|
|
784
786
|
<ul class="access-point-list">
|
|
785
|
-
<% directHosts.forEach((point) => {
|
|
787
|
+
<% directHosts.forEach((point) => {
|
|
788
|
+
const hasProtocol = /^https?:\/\//i.test(point.url)
|
|
789
|
+
const hrefValue = hasProtocol ? point.url : `http://${point.url}`
|
|
790
|
+
%>
|
|
786
791
|
<li>
|
|
787
|
-
<a class='net' target="_blank" href="<%=
|
|
792
|
+
<a class='net' target="_blank" href="<%= hrefValue %>"><%= point.url %></a>
|
|
788
793
|
<% if (point.badge) { %>
|
|
789
794
|
<span class="badge"><%= point.badge %></span>
|
|
790
795
|
<% } %>
|
package/server/views/network.ejs
CHANGED
|
@@ -651,8 +651,10 @@ body.dark .browser-options-row {
|
|
|
651
651
|
}
|
|
652
652
|
*/
|
|
653
653
|
body.dark .context-menu-wrapper {
|
|
654
|
-
background: rgba(0,0,0,0.9);
|
|
655
|
-
color: white;
|
|
654
|
+
background: rgba(0,0,0,0.9) !important;
|
|
655
|
+
color: white !important;
|
|
656
|
+
border: 1px solid rgba(255,255,255,0.1);
|
|
657
|
+
box-shadow: 0 12px 30px rgba(0,0,0,0.45);
|
|
656
658
|
}
|
|
657
659
|
.context-menu-wrapper {
|
|
658
660
|
background: rgba(0,0,0,0.06) !important;
|