pinokiod 3.148.0 → 3.151.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.
@@ -75,7 +75,6 @@ class Proto {
75
75
  await fs.promises.rm(this.kernel.path("prototype"), { recursive: true })
76
76
  }
77
77
  async create(req, ondata) {
78
- console.log("CREATE", req)
79
78
  try {
80
79
  if (req.client) {
81
80
  this.kernel.client = req.client
@@ -11,6 +11,7 @@ class Common extends Processor {
11
11
  "headers": {
12
12
  "request": {
13
13
  "set": {
14
+ "Host": ["{http.request.host}"],
14
15
  "X-Forwarded-Proto": ["https"],
15
16
  "X-Forwarded-Host": ["{http.request.host}"]
16
17
  }
@@ -16,6 +16,7 @@ class Connector extends Processor {
16
16
  "headers": {
17
17
  "request": {
18
18
  "set": {
19
+ "Host": ["{http.request.header.X-Forwarded-Host}"],
19
20
  "X-Forwarded-Proto": ["{http.request.header.X-Forwarded-Proto}"],
20
21
  //"X-Forwarded-Proto": ["{http.request.scheme}"],
21
22
  //"X-Forwarded-Proto": ["https"],
@@ -55,6 +56,7 @@ class Connector extends Processor {
55
56
  "headers": {
56
57
  "request": {
57
58
  "set": {
59
+ "Host": ["{http.request.host}"],
58
60
  //"X-Forwarded-Proto": ["https"],
59
61
  //"Origin": "localhost",
60
62
  "X-Forwarded-Proto": ["{http.request.scheme}"],
package/kernel/shell.js CHANGED
@@ -1061,20 +1061,20 @@ class Shell {
1061
1061
  this.monitor = this.monitor + data
1062
1062
  this.monitor = this.monitor.slice(-300) // last 300
1063
1063
 
1064
- let notifications = this.parser.processData(data)
1065
- if (notifications.length > 0) {
1066
- console.log({ notifications })
1067
- for(let notif of notifications) {
1068
- if (notif.type !== "bell") {
1069
- Util.push({
1070
- image: path.resolve(__dirname, "../server/public/pinokio-black.png"),
1071
- message: notif.title,
1072
- sound: true,
1073
- timeout: 30,
1074
- })
1075
- }
1076
- }
1077
- }
1064
+ // let notifications = this.parser.processData(data)
1065
+ // if (notifications.length > 0) {
1066
+ // console.log({ notifications })
1067
+ // for(let notif of notifications) {
1068
+ // if (notif.type !== "bell") {
1069
+ // Util.push({
1070
+ // image: path.resolve(__dirname, "../server/public/pinokio-black.png"),
1071
+ // message: notif.title,
1072
+ // sound: true,
1073
+ // timeout: 30,
1074
+ // })
1075
+ // }
1076
+ // }
1077
+ // }
1078
1078
 
1079
1079
  if (!this.done) {
1080
1080
 
package/kernel/util.js CHANGED
@@ -711,7 +711,6 @@ function push(params) {
711
711
 
712
712
  emitPushEvent(eventPayload)
713
713
 
714
- console.log("notifyParams", notifyParams)
715
714
  notifier.notify(notifyParams)
716
715
  }
717
716
  function p2u(localPath) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "3.148.0",
3
+ "version": "3.151.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/server/index.js CHANGED
@@ -25,6 +25,7 @@ const QRCode = require('qrcode')
25
25
  const axios = require('axios')
26
26
  const crypto = require('crypto')
27
27
  const serveIndex = require('./serveIndex')
28
+ const registerFileRoutes = require('./routes/files')
28
29
 
29
30
  const git = require('isomorphic-git')
30
31
  const http = require('isomorphic-git/http/node')
@@ -812,6 +813,12 @@ class Server {
812
813
  let dev_tab = "/p/" + name + "/dev"
813
814
  let review_tab = "/p/" + name + "/review"
814
815
 
816
+ let editor_tab = `/pinokio/fileview/${encodeURIComponent(name)}`
817
+ let savedTabs = []
818
+ if (Array.isArray(this.tabs[name])) {
819
+ savedTabs = this.tabs[name].filter((url) => url !== editor_tab)
820
+ }
821
+
815
822
  let dynamic_url = "/pinokio/dynamic/" + name;
816
823
  if (Object.values(req.query).length > 0) {
817
824
  let index = 0
@@ -852,7 +859,8 @@ class Server {
852
859
  name,
853
860
  // profile,
854
861
  // feed,
855
- tabs: (this.tabs[name] || []),
862
+ tabs: savedTabs,
863
+ editor_tab: editor_tab,
856
864
  config,
857
865
  // sidebar_url: "/pinokio/sidebar/" + name,
858
866
  home: req.originalUrl,
@@ -3182,61 +3190,180 @@ class Server {
3182
3190
  }
3183
3191
  }
3184
3192
  add_extra_urls(info) {
3185
- // get only the parts not from this peer
3186
- for(let host in this.kernel.peer.info) {
3187
- let host_info = this.kernel.peer.info[host]
3193
+ if (!this.kernel.peer || !this.kernel.peer.info) {
3194
+ return
3195
+ }
3188
3196
 
3189
- let host_rewrites = host_info.rewrite_mapping
3190
- for(let key in host_rewrites) {
3191
- info.push({
3192
- online: true,
3193
- host: {
3194
- ip: host,
3195
- local: this.kernel.peer.host === host,
3196
- name: host_info.name,
3197
- platform: host_info.platform,
3198
- arch: host_info.arch
3199
- },
3200
- name: `[Files] ${host_rewrites[key].name}`,
3201
- ip: host_rewrites[key].external_ip
3202
- })
3197
+ const ensureArray = (value) => {
3198
+ if (!value) return []
3199
+ return Array.isArray(value) ? value.filter(Boolean) : [value].filter(Boolean)
3200
+ }
3201
+
3202
+ const normalizeHttpUrl = (value) => {
3203
+ if (!value) return null
3204
+ const str = String(value).trim()
3205
+ if (!str) return null
3206
+ if (/^https?:\/\//i.test(str)) {
3207
+ return str.replace(/^https:/i, 'http:')
3203
3208
  }
3204
- if (this.kernel.peer.host !== host) {
3205
- let host_routers = host_info.router_info
3206
- for(let host_router of host_routers) {
3207
- let ip
3208
- // the peer sharing works only if external_ip is available (caddy is installed)
3209
- if (host_router.external_ip) {
3210
- ip = host_router.external_ip
3211
- } else {
3212
- // if caddy is not turned on, set ip as null, so that it suggests turning on peer sharing
3213
- ip = null
3209
+ return `http://${str}`
3210
+ }
3211
+
3212
+ const normalizeHttpsUrl = (value) => {
3213
+ if (!value) return null
3214
+ const str = String(value).trim()
3215
+ if (!str) return null
3216
+ if (/^https?:\/\//i.test(str)) {
3217
+ return str.replace(/^http:/i, 'https:')
3218
+ }
3219
+ return `https://${str}`
3220
+ }
3221
+
3222
+ const seen = new Set()
3223
+
3224
+ const pushEntry = ({ host, name, ip, httpUrl, httpsUrls, description, icon, online = true }) => {
3225
+ const normalizedHttp = normalizeHttpUrl(httpUrl)
3226
+ const hostNameForAlias = host && host.name ? String(host.name).trim() : ''
3227
+ const peerSuffix = hostNameForAlias ? `.${hostNameForAlias}.localhost` : null
3228
+
3229
+ const normalizedHttpsSet = new Set(
3230
+ ensureArray(httpsUrls)
3231
+ .map(normalizeHttpsUrl)
3232
+ .filter(Boolean)
3233
+ )
3234
+
3235
+ if (host && host.local && peerSuffix) {
3236
+ for (const originalUrl of normalizedHttpsSet) {
3237
+ try {
3238
+ const parsed = new URL(originalUrl)
3239
+ if (parsed.hostname.endsWith(peerSuffix)) {
3240
+ const aliasHost = `${parsed.hostname.slice(0, -peerSuffix.length)}.localhost`
3241
+ if (aliasHost && aliasHost !== parsed.hostname) {
3242
+ let pathname = parsed.pathname || ''
3243
+ if (pathname === '/' || pathname === '') {
3244
+ pathname = ''
3245
+ }
3246
+ const aliasUrl = `${parsed.protocol}//${aliasHost}${pathname}${parsed.search}${parsed.hash}`
3247
+ normalizedHttpsSet.add(aliasUrl)
3248
+ }
3249
+ }
3250
+ } catch (_) {
3251
+ // continue
3214
3252
  }
3215
- info.push({
3216
- online: true,
3217
- host: {
3218
- ip: host,
3219
- name: host_info.name,
3220
- platform: host_info.platform,
3221
- arch: host_info.arch
3222
- },
3223
- name: host_router.title || host_router.name,
3224
- ip
3253
+ }
3254
+ }
3255
+
3256
+ const normalizedHttps = Array.from(normalizedHttpsSet)
3257
+ const ipValue = typeof ip === 'string' ? ip : (normalizedHttp ? normalizedHttp.replace(/^https?:\/\//i, '') : null)
3258
+ const selectedUrl = normalizedHttps[0] || normalizedHttp || null
3259
+ const protocol = normalizedHttps.length > 0 ? 'https' : (normalizedHttp ? 'http' : undefined)
3260
+ const hostKey = host && (host.ip || host.name) ? `${host.ip || host.name}` : 'unknown'
3261
+ const uniquenessKey = `${hostKey}|${name}|${ipValue || ''}|${selectedUrl || ''}`
3262
+ if (seen.has(uniquenessKey)) {
3263
+ return
3264
+ }
3265
+ seen.add(uniquenessKey)
3266
+
3267
+ const entry = {
3268
+ online,
3269
+ host: { ...host },
3270
+ name,
3271
+ ip: ipValue,
3272
+ url: selectedUrl,
3273
+ protocol,
3274
+ urls: {
3275
+ http: normalizedHttp,
3276
+ https: normalizedHttps
3277
+ }
3278
+ }
3279
+ if (description) {
3280
+ entry.description = description
3281
+ }
3282
+ if (icon) {
3283
+ entry.icon = icon
3284
+ }
3285
+ info.push(entry)
3286
+ }
3287
+
3288
+ for (const host of Object.keys(this.kernel.peer.info)) {
3289
+ const hostInfo = this.kernel.peer.info[host]
3290
+ if (!hostInfo) {
3291
+ continue
3292
+ }
3293
+
3294
+ const hostMeta = {
3295
+ ip: host,
3296
+ local: this.kernel.peer.host === host,
3297
+ name: hostInfo.name,
3298
+ platform: hostInfo.platform,
3299
+ arch: hostInfo.arch
3300
+ }
3301
+
3302
+ const rewrites = hostInfo.rewrite_mapping
3303
+ if (rewrites && typeof rewrites === 'object') {
3304
+ for (const key of Object.keys(rewrites)) {
3305
+ const rewrite = rewrites[key]
3306
+ if (!rewrite) {
3307
+ continue
3308
+ }
3309
+ const externalIp = Array.isArray(rewrite.external_ip) ? rewrite.external_ip[0] : rewrite.external_ip
3310
+ const httpsSources = [
3311
+ ...ensureArray(rewrite.external_router),
3312
+ ...ensureArray(rewrite.internal_router)
3313
+ ]
3314
+ pushEntry({
3315
+ host: hostMeta,
3316
+ name: `[Files] ${rewrite.name || key}`,
3317
+ ip: externalIp || null,
3318
+ httpUrl: externalIp,
3319
+ httpsUrls: Array.from(new Set(httpsSources))
3225
3320
  })
3226
3321
  }
3227
3322
  }
3228
3323
 
3229
- for(let app of host_info.installed) {
3230
- info.push({
3231
- host: {
3232
- ip: host,
3233
- local: this.kernel.peer.host === host,
3234
- name: host_info.name,
3235
- platform: host_info.platform,
3236
- arch: host_info.arch
3237
- },
3238
- name: app.title || app.folder,
3239
- ip: app.http_href.replace("http://", "")
3324
+ const hostRouters = Array.isArray(hostInfo.router_info) ? hostInfo.router_info : []
3325
+ for (const route of hostRouters) {
3326
+ if (!route) {
3327
+ continue
3328
+ }
3329
+ const externalIp = Array.isArray(route.external_ip) ? route.external_ip[0] : route.external_ip
3330
+ const httpUrl = externalIp || null
3331
+ const httpsCandidates = Array.from(new Set([
3332
+ ...ensureArray(route.external_router),
3333
+ ...ensureArray(route.internal_router)
3334
+ ]))
3335
+ if (httpsCandidates.length === 0 && !httpUrl) {
3336
+ continue
3337
+ }
3338
+ pushEntry({
3339
+ host: hostMeta,
3340
+ name: route.title || route.name,
3341
+ ip: externalIp || null,
3342
+ httpUrl,
3343
+ httpsUrls: httpsCandidates,
3344
+ description: route.description,
3345
+ icon: route.icon || route.https_icon || route.http_icon
3346
+ })
3347
+ }
3348
+
3349
+ const installedApps = Array.isArray(hostInfo.installed) ? hostInfo.installed : []
3350
+ for (const app of installedApps) {
3351
+ if (!app) {
3352
+ continue
3353
+ }
3354
+ const httpHref = Array.isArray(app.http_href) ? app.http_href[0] : app.http_href
3355
+ const httpsCandidates = Array.from(new Set([
3356
+ ...ensureArray(app.app_href),
3357
+ ...ensureArray(app.https_href)
3358
+ ]))
3359
+ pushEntry({
3360
+ host: hostMeta,
3361
+ name: app.title || app.name || app.folder,
3362
+ ip: httpHref ? httpHref.replace(/^https?:\/\//i, '') : null,
3363
+ httpUrl: httpHref || null,
3364
+ httpsUrls: httpsCandidates,
3365
+ description: app.description,
3366
+ icon: app.https_icon || app.http_icon || app.icon
3240
3367
  })
3241
3368
  }
3242
3369
  }
@@ -3267,14 +3394,14 @@ class Server {
3267
3394
  }
3268
3395
  terminal = {
3269
3396
  icon: "fa-solid fa-terminal",
3270
- title: "Terminal",
3397
+ title: "User Terminal",
3271
3398
  subtitle: "Open the terminal in the browser",
3272
3399
  menu: terminals
3273
3400
  }
3274
3401
  } else {
3275
3402
  terminal = {
3276
3403
  icon: "fa-solid fa-terminal",
3277
- title: "Terminal",
3404
+ title: "User Terminal",
3278
3405
  subtitle: "Work with the terminal directly in the browser",
3279
3406
  menu: [this.renderShell(filepath, 0, 0, {
3280
3407
  icon: "fa-solid fa-terminal",
@@ -3730,6 +3857,11 @@ class Server {
3730
3857
  };
3731
3858
  next();
3732
3859
  });
3860
+ registerFileRoutes(this.app, {
3861
+ kernel: this.kernel,
3862
+ getTheme: () => this.theme,
3863
+ exists: (target) => this.exists(target),
3864
+ });
3733
3865
  /*
3734
3866
  this.app.get("/asset/*", ex((req, res) => {
3735
3867
  let pathComponents = req.params[0].split("/")
@@ -4527,7 +4659,6 @@ class Server {
4527
4659
  }
4528
4660
  }))
4529
4661
  this.app.post("/push", ex(async (req, res) => {
4530
- console.log("Push", req.body)
4531
4662
  try {
4532
4663
  const payload = { ...(req.body || {}) }
4533
4664
  const resolveAssetPath = (raw) => {
@@ -6222,6 +6353,7 @@ class Server {
6222
6353
  menu: exec_menus
6223
6354
  },
6224
6355
  ]
6356
+
6225
6357
  let spec = ""
6226
6358
  try {
6227
6359
  spec = await fs.promises.readFile(path.resolve(filepath, "SPEC.md"), "utf8")
@@ -6610,6 +6742,7 @@ class Server {
6610
6742
  if (preferHttps) {
6611
6743
  httpsHosts = resolveHttpsHosts(item)
6612
6744
  }
6745
+ console.log("httpsHosts", httpsHosts)
6613
6746
  const httpsUrls = httpsHosts.map((host) => {
6614
6747
  if (!host) {
6615
6748
  return null
@@ -6620,6 +6753,7 @@ class Server {
6620
6753
  }
6621
6754
  return `https://${trimmed}`
6622
6755
  }).filter(Boolean)
6756
+ console.log("httpsUrls", httpsUrls)
6623
6757
 
6624
6758
  const preferredHttpsUrl = preferFriendlyHost(httpsHosts)
6625
6759
  const displayHttpsUrl = preferredHttpsUrl
@@ -6648,7 +6782,7 @@ class Server {
6648
6782
  }
6649
6783
  })
6650
6784
 
6651
- // this.add_extra_urls(info)
6785
+ this.add_extra_urls(info)
6652
6786
  res.json({
6653
6787
  info
6654
6788
  })