pinokiod 1.3.91 → 1.3.93
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/api/cloudflare/index.js +31 -3
- package/kernel/api/index.js +5 -1
- package/kernel/api/local/index.js +3 -0
- package/kernel/environment.js +42 -25
- package/kernel/index.js +28 -1
- package/kernel/shell.js +5 -4
- package/kernel/sysinfo.js +1 -2
- package/package.json +4 -2
- package/pipe/index.js +102 -0
- package/pipe/views/login.ejs +78 -0
- package/server/index.js +12 -63
- package/server/views/share_editor.ejs +2 -1
|
@@ -1,18 +1,37 @@
|
|
|
1
1
|
const { yellow, green, blue } = require('kleur');
|
|
2
2
|
const QRCode = require('qrcode');
|
|
3
|
+
const path = require('path')
|
|
4
|
+
const Util = require('../../util')
|
|
3
5
|
class C {
|
|
4
6
|
async tunnel (req, ondata, kernel) {
|
|
5
7
|
/*
|
|
6
8
|
{
|
|
7
9
|
"method": "cloundflare.tunnel",
|
|
8
10
|
"params": {
|
|
9
|
-
"uri": "{{local.url}}"
|
|
11
|
+
"uri": "{{local.url}}",
|
|
12
|
+
"passcode": (optional)
|
|
10
13
|
}
|
|
11
14
|
}
|
|
12
15
|
|
|
13
16
|
=> cloudflared tunnel --url http://localhost:8080
|
|
14
17
|
*/
|
|
15
|
-
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
let pipe_uri
|
|
21
|
+
if (req.params.passcode) {
|
|
22
|
+
// 1. start a pipe server => needed for authentication
|
|
23
|
+
const api_path = Util.api_path(req.parent.path, kernel)
|
|
24
|
+
const pinokio_path = path.resolve(api_path, "pinokio.js")
|
|
25
|
+
const config = (await kernel.loader.load(pinokio_path)).resolved
|
|
26
|
+
pipe_uri = await kernel.pipe.start(req.params.uri, req.parent.path, req.params.passcode, config)
|
|
27
|
+
} else {
|
|
28
|
+
// 2. if no passcode required, no need for a pipe server just use the original
|
|
29
|
+
pipe_uri = req.params.uri
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
// 2. run cloudflare tunnel on the proxy
|
|
34
|
+
const message = `cloudflared tunnel --url ${pipe_uri}`
|
|
16
35
|
let params = {
|
|
17
36
|
id: message,
|
|
18
37
|
message
|
|
@@ -65,15 +84,24 @@ class C {
|
|
|
65
84
|
if (!kernel.memory.local[req.parent.path].$share.cloudflare) {
|
|
66
85
|
kernel.memory.local[req.parent.path].$share.cloudflare = {}
|
|
67
86
|
}
|
|
68
|
-
kernel.memory.local[req.parent.path].$share.cloudflare[
|
|
87
|
+
kernel.memory.local[req.parent.path].$share.cloudflare[pipe_uri] = cloudflare_url
|
|
69
88
|
|
|
70
89
|
return { uri: cloudflare_url }
|
|
71
90
|
}
|
|
72
91
|
async stop (req, ondata, kernel) {
|
|
92
|
+
// stop the cloudflare shell
|
|
73
93
|
const message = `cloudflared tunnel --url ${req.params.uri}`
|
|
74
94
|
await kernel.shell.kill({
|
|
75
95
|
id: message
|
|
76
96
|
})
|
|
97
|
+
|
|
98
|
+
// stop pipe server
|
|
99
|
+
await kernel.pipe.stop(req.params.uri, req.parent.path)
|
|
100
|
+
|
|
101
|
+
// delete the local variable
|
|
102
|
+
delete kernel.memory.local[req.parent.path].$share.cloudflare[req.params.uri]
|
|
103
|
+
|
|
77
104
|
}
|
|
105
|
+
|
|
78
106
|
}
|
|
79
107
|
module.exports = C
|
package/kernel/api/index.js
CHANGED
|
@@ -128,6 +128,10 @@ class Api {
|
|
|
128
128
|
// stop all proxies
|
|
129
129
|
this.stopProxy({ script: requestPath })
|
|
130
130
|
|
|
131
|
+
// stop all cloudflare tunnels
|
|
132
|
+
|
|
133
|
+
await this.kernel.stopCloudflare({ path: requestPath })
|
|
134
|
+
|
|
131
135
|
// if there are any pending waiters, delete them
|
|
132
136
|
|
|
133
137
|
if (this.waiter[requestPath]) {
|
|
@@ -538,7 +542,7 @@ class Api {
|
|
|
538
542
|
// get fully resolved env
|
|
539
543
|
let env = await Environment.get2(request.path, this.kernel)
|
|
540
544
|
// set template
|
|
541
|
-
this.kernel.template.update(env)
|
|
545
|
+
this.kernel.template.update({ env })
|
|
542
546
|
|
|
543
547
|
// render until `{{ }}` pattern does not exist
|
|
544
548
|
// 1. render once
|
|
@@ -74,6 +74,9 @@ class Local {
|
|
|
74
74
|
if (val === "true" || val === "1") {
|
|
75
75
|
const c = new Cloudflare()
|
|
76
76
|
req.params.uri = req.params[KEY]
|
|
77
|
+
if ("PINOKIO_SHARE_PASSCODE" in current_env) {
|
|
78
|
+
req.params.passcode = current_env.PINOKIO_SHARE_PASSCODE
|
|
79
|
+
}
|
|
77
80
|
await c.tunnel(req, ondata, kernel)
|
|
78
81
|
}
|
|
79
82
|
}
|
package/kernel/environment.js
CHANGED
|
@@ -102,6 +102,48 @@ const ENVS = [{
|
|
|
102
102
|
"#",
|
|
103
103
|
"##########################################################################",
|
|
104
104
|
],
|
|
105
|
+
}, {
|
|
106
|
+
type: ["system", "app"],
|
|
107
|
+
key: "PINOKIO_SHARE_CLOUDFLARE",
|
|
108
|
+
val: "false",
|
|
109
|
+
comment: [
|
|
110
|
+
"##########################################################################",
|
|
111
|
+
"#",
|
|
112
|
+
"# PINOKIO_SHARE_CLOUDFLARE",
|
|
113
|
+
"# Set this variable to share the app publicly via cloudflare tunnel.",
|
|
114
|
+
"#",
|
|
115
|
+
"##########################################################################",
|
|
116
|
+
]
|
|
117
|
+
}, {
|
|
118
|
+
type: ["app"],
|
|
119
|
+
key: "PINOKIO_SHARE_PASSCODE",
|
|
120
|
+
val: "",
|
|
121
|
+
comment: [
|
|
122
|
+
"##########################################################################",
|
|
123
|
+
"#",
|
|
124
|
+
"# PINOKIO_SHARE_PASSCODE",
|
|
125
|
+
"#",
|
|
126
|
+
"# By default, your publicly shared app will be 100% open to anyone",
|
|
127
|
+
"# with the link via Cloudflare.",
|
|
128
|
+
"#",
|
|
129
|
+
"# You can add authorization by protecting it with a passcode.",
|
|
130
|
+
"# Set this value, and any access to the app will require a pass code input",
|
|
131
|
+
"#",
|
|
132
|
+
"##########################################################################",
|
|
133
|
+
],
|
|
134
|
+
}, {
|
|
135
|
+
type: ["system", "app"],
|
|
136
|
+
key: "PINOKIO_SCRIPT_DEFAULT",
|
|
137
|
+
val: "true",
|
|
138
|
+
comment: [
|
|
139
|
+
"##########################################################################",
|
|
140
|
+
"#",
|
|
141
|
+
"# PINOKIO_SCRIPT_DEFAULT",
|
|
142
|
+
"# If this variable is false, 'default': true menu items in pinokio.js",
|
|
143
|
+
"# will NOT automatically run",
|
|
144
|
+
"#",
|
|
145
|
+
"##########################################################################",
|
|
146
|
+
]
|
|
105
147
|
}, {
|
|
106
148
|
type: ["system"],
|
|
107
149
|
key: "PINOKIO_DRIVE",
|
|
@@ -194,31 +236,6 @@ const ENVS = [{
|
|
|
194
236
|
"#",
|
|
195
237
|
"##########################################################################",
|
|
196
238
|
],
|
|
197
|
-
}, {
|
|
198
|
-
type: ["system", "app"],
|
|
199
|
-
key: "PINOKIO_SHARE_CLOUDFLARE",
|
|
200
|
-
val: "false",
|
|
201
|
-
comment: [
|
|
202
|
-
"##########################################################################",
|
|
203
|
-
"#",
|
|
204
|
-
"# PINOKIO_SHARE_CLOUDFLARE",
|
|
205
|
-
"# Set this variable to share the app publicly via cloudflare tunnel.",
|
|
206
|
-
"#",
|
|
207
|
-
"##########################################################################",
|
|
208
|
-
]
|
|
209
|
-
}, {
|
|
210
|
-
type: ["system", "app"],
|
|
211
|
-
key: "PINOKIO_SCRIPT_DEFAULT",
|
|
212
|
-
val: "true",
|
|
213
|
-
comment: [
|
|
214
|
-
"##########################################################################",
|
|
215
|
-
"#",
|
|
216
|
-
"# PINOKIO_SCRIPT_DEFAULT",
|
|
217
|
-
"# If this variable is false, 'default': true menu items in pinokio.js",
|
|
218
|
-
"# will NOT automatically run",
|
|
219
|
-
"#",
|
|
220
|
-
"##########################################################################",
|
|
221
|
-
]
|
|
222
239
|
}];
|
|
223
240
|
//const ENV = (homedir) => {
|
|
224
241
|
// const lines = ENVS.map((e) => {
|
package/kernel/index.js
CHANGED
|
@@ -22,6 +22,8 @@ const Environment = require("./environment")
|
|
|
22
22
|
const Util = require('./util')
|
|
23
23
|
const Config = require("./pinokio.json")
|
|
24
24
|
const Info = require('./info')
|
|
25
|
+
const Pipe = require("../pipe")
|
|
26
|
+
const Cloudflare = require('./api/cloudflare')
|
|
25
27
|
const VARS = {
|
|
26
28
|
pip: {
|
|
27
29
|
install: {
|
|
@@ -45,11 +47,33 @@ class Kernel {
|
|
|
45
47
|
this.exposed = {}
|
|
46
48
|
this.envs = {}
|
|
47
49
|
this.info = new Info(this)
|
|
50
|
+
this.pipe = new Pipe(this)
|
|
51
|
+
this.cloudflare = new Cloudflare()
|
|
48
52
|
}
|
|
49
53
|
/*
|
|
50
54
|
kernel.env() => return the system environment
|
|
51
55
|
kernel.env("api/stablediffusion") => returns the full environment object
|
|
52
56
|
*/
|
|
57
|
+
async stopCloudflare(option) {
|
|
58
|
+
if (option.uri) {
|
|
59
|
+
} else if (option.path) {
|
|
60
|
+
let scriptPath = option.path
|
|
61
|
+
if (this.memory.local[scriptPath] && this.memory.local[scriptPath].$share) {
|
|
62
|
+
let cf = this.memory.local[scriptPath].$share.cloudflare
|
|
63
|
+
let uris = Object.keys(cf)
|
|
64
|
+
for(let uri of uris) {
|
|
65
|
+
await this.cloudflare.stop({
|
|
66
|
+
parent: {
|
|
67
|
+
path: scriptPath
|
|
68
|
+
},
|
|
69
|
+
params: { uri }
|
|
70
|
+
}, (e) => {
|
|
71
|
+
process.stdout.write(e.raw)
|
|
72
|
+
}, this)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
53
77
|
async env(...args) {
|
|
54
78
|
let folderpath
|
|
55
79
|
if (args) {
|
|
@@ -114,7 +138,10 @@ class Kernel {
|
|
|
114
138
|
* let available_port = await kernel.port()
|
|
115
139
|
*
|
|
116
140
|
**********************************************/
|
|
117
|
-
return portfinder.getPortPromise(
|
|
141
|
+
return portfinder.getPortPromise({
|
|
142
|
+
port: 42000
|
|
143
|
+
})
|
|
144
|
+
//return portfinder.getPortPromise()
|
|
118
145
|
}
|
|
119
146
|
path(...args) {
|
|
120
147
|
return path.resolve(this.homedir, ...args)
|
package/kernel/shell.js
CHANGED
|
@@ -736,9 +736,7 @@ class Shell {
|
|
|
736
736
|
# index: ${this.index}
|
|
737
737
|
# cmd: ${this.cmd}
|
|
738
738
|
# timestamp: ${time}
|
|
739
|
-
#
|
|
740
|
-
|
|
741
|
-
${infoYAML}
|
|
739
|
+
# ${infoYAML.replaceAll("\n", "\n# ")}
|
|
742
740
|
|
|
743
741
|
`
|
|
744
742
|
|
|
@@ -757,8 +755,11 @@ ${buf}
|
|
|
757
755
|
|
|
758
756
|
data.cleaned = `######################################################################
|
|
759
757
|
#
|
|
758
|
+
# group: ${this.group}
|
|
759
|
+
# id: ${this.id}
|
|
760
|
+
# index: ${this.index}
|
|
761
|
+
# cmd: ${this.cmd}
|
|
760
762
|
# timestamp: ${time}
|
|
761
|
-
# ${infoYAML.replaceAll("\n", "\n# ")}
|
|
762
763
|
|
|
763
764
|
${cleaned}
|
|
764
765
|
|
package/kernel/sysinfo.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pinokiod",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.93",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"7zip-min-win-asar-support": "^1.4.4",
|
|
13
13
|
"async-retry": "^1.3.3",
|
|
14
14
|
"axios": "^1.4.0",
|
|
15
|
+
"bcrypt": "^5.1.1",
|
|
15
16
|
"clear-module": "^4.1.2",
|
|
16
17
|
"compressing": "^1.10.0",
|
|
17
18
|
"cookie-parser": "^1.4.6",
|
|
@@ -33,9 +34,10 @@
|
|
|
33
34
|
"glob-gitignore": "^1.0.14",
|
|
34
35
|
"handlebars": "^4.7.7",
|
|
35
36
|
"http-proxy": "^1.18.1",
|
|
37
|
+
"http-proxy-middleware": "^3.0.0",
|
|
36
38
|
"http-terminator": "^3.2.0",
|
|
37
39
|
"isomorphic-git": "^1.23.0",
|
|
38
|
-
"jimini": "^0.0.
|
|
40
|
+
"jimini": "^0.0.6",
|
|
39
41
|
"jsdom": "^24.0.0",
|
|
40
42
|
"jsonpath-plus": "^7.2.0",
|
|
41
43
|
"key-store": "^1.2.0",
|
package/pipe/index.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
const { createProxyMiddleware } = require('http-proxy-middleware');
|
|
2
|
+
|
|
3
|
+
const path = require('path')
|
|
4
|
+
const { createHttpTerminator } = require('http-terminator')
|
|
5
|
+
const express = require('express')
|
|
6
|
+
const session = require('express-session');
|
|
7
|
+
const bcrypt = require('bcrypt');
|
|
8
|
+
const cors = require('cors');
|
|
9
|
+
class Pipe {
|
|
10
|
+
constructor(kernel) {
|
|
11
|
+
this.kernel = kernel
|
|
12
|
+
this.terminators = {}
|
|
13
|
+
this.procs = {}
|
|
14
|
+
}
|
|
15
|
+
authenticate (req, res, next) {
|
|
16
|
+
if (req.session.authenticated) {
|
|
17
|
+
next();
|
|
18
|
+
} else {
|
|
19
|
+
console.log("not authenticated. redirect /pionkio/login")
|
|
20
|
+
res.redirect('/pinokio/login');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// a pipe server for creating publicly shareable endpoints
|
|
24
|
+
async start(url, scriptPath, passcode, config) {
|
|
25
|
+
|
|
26
|
+
if (!config) config = {}
|
|
27
|
+
if (config.icon) {
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
let port = await this.kernel.port()
|
|
32
|
+
let app = express();
|
|
33
|
+
app.use(cors({ origin: '*' }));
|
|
34
|
+
app.use(express.urlencoded({ extended: true }));
|
|
35
|
+
app.set('view engine', 'ejs');
|
|
36
|
+
app.set("views", path.resolve(__dirname, "views"))
|
|
37
|
+
// app.use(express.static(path.resolve(__dirname, 'public')));
|
|
38
|
+
app.use(session({
|
|
39
|
+
secret: 'oikonip',
|
|
40
|
+
resave: false,
|
|
41
|
+
saveUninitialized: true
|
|
42
|
+
}));
|
|
43
|
+
app.get('/pinokio/login', (req, res) => {
|
|
44
|
+
res.render("login", { error: null, ...config })
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
app.post('/pinokio/login', async (req, res) => {
|
|
48
|
+
|
|
49
|
+
const { password } = req.body;
|
|
50
|
+
|
|
51
|
+
//if (await bcrypt.compare(password, hashedPassword)) {
|
|
52
|
+
if (password === passcode) {
|
|
53
|
+
req.session.authenticated = true;
|
|
54
|
+
res.redirect('/');
|
|
55
|
+
} else {
|
|
56
|
+
res.status(401).render("login", { error: "Invalid passcode", ...config })
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
app.get('/pinokio/logout', (req, res) => {
|
|
61
|
+
req.session.authenticated = false;
|
|
62
|
+
res.redirect('/login');
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
const proxy = createProxyMiddleware({
|
|
67
|
+
pathFilter: '/',
|
|
68
|
+
target: url,
|
|
69
|
+
ws: true
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
app.use('/', this.authenticate, proxy)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
await new Promise((resolve, reject) => {
|
|
76
|
+
console.log("starting pipe server at port", port)
|
|
77
|
+
let server = app.listen(port, () => {
|
|
78
|
+
console.log(`Pipe server listening on port ${port}`)
|
|
79
|
+
resolve()
|
|
80
|
+
});
|
|
81
|
+
let terminator = createHttpTerminator({ server });
|
|
82
|
+
this.terminators[url] = terminator
|
|
83
|
+
})
|
|
84
|
+
let pipe_uri = `http://localhost:${port}`
|
|
85
|
+
|
|
86
|
+
// original url => pipe url
|
|
87
|
+
if (!this.procs[scriptPath]) {
|
|
88
|
+
this.procs[scriptPath] = {}
|
|
89
|
+
}
|
|
90
|
+
this.procs[scriptPath][url] = pipe_uri
|
|
91
|
+
return pipe_uri
|
|
92
|
+
}
|
|
93
|
+
async stop(url, scriptPath) {
|
|
94
|
+
console.log("stop pipe", { scriptPath, url, terminator: this.terminators[url] })
|
|
95
|
+
if (this.terminators[url]) {
|
|
96
|
+
await this.terminators[url].terminate()
|
|
97
|
+
delete this.terminators[url]
|
|
98
|
+
delete this.procs[scriptPath][url]
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
module.exports = Pipe
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
<head>
|
|
3
|
+
<title>Pinokio</title>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
|
|
6
|
+
<style>
|
|
7
|
+
body {
|
|
8
|
+
display: flex;
|
|
9
|
+
justify-content: center;
|
|
10
|
+
align-items: center;
|
|
11
|
+
height: 100%;
|
|
12
|
+
font-family: sans-serif;
|
|
13
|
+
font-size: 14px;
|
|
14
|
+
background: rgb(27, 28, 29);
|
|
15
|
+
color: white;
|
|
16
|
+
}
|
|
17
|
+
main {
|
|
18
|
+
max-width: 500px;
|
|
19
|
+
width: 100%;
|
|
20
|
+
text-align: center;
|
|
21
|
+
text-transform: lowercase;
|
|
22
|
+
}
|
|
23
|
+
main img {
|
|
24
|
+
width: 80px;
|
|
25
|
+
margin-bottom: 20px;
|
|
26
|
+
}
|
|
27
|
+
main form {
|
|
28
|
+
display: flex;
|
|
29
|
+
}
|
|
30
|
+
main input {
|
|
31
|
+
flex-grow: 1;
|
|
32
|
+
padding: 10px;
|
|
33
|
+
box-sizing: border-box;
|
|
34
|
+
border: none;
|
|
35
|
+
/*
|
|
36
|
+
background: rgba(0,0,0,0.06);
|
|
37
|
+
*/
|
|
38
|
+
font-size: 14px;
|
|
39
|
+
border-radius: 0;
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
main button {
|
|
43
|
+
color: white;
|
|
44
|
+
background: royalblue;
|
|
45
|
+
padding: 10px;
|
|
46
|
+
box-sizing: border-box;
|
|
47
|
+
border: none;
|
|
48
|
+
}
|
|
49
|
+
.error {
|
|
50
|
+
border-left: 3px solid red;
|
|
51
|
+
color: red;
|
|
52
|
+
text-align: left;
|
|
53
|
+
padding: 5px 10px;
|
|
54
|
+
box-sizing: border-box;
|
|
55
|
+
font-size: 14px;
|
|
56
|
+
}
|
|
57
|
+
h1 {
|
|
58
|
+
letter-spacing: -1px;
|
|
59
|
+
margin-bottom: 20px;
|
|
60
|
+
}
|
|
61
|
+
</style>
|
|
62
|
+
</head>
|
|
63
|
+
<body>
|
|
64
|
+
<main>
|
|
65
|
+
<!--
|
|
66
|
+
<img src="/pinokio-black.png"/>
|
|
67
|
+
-->
|
|
68
|
+
<h1>PINOKIO</h1>
|
|
69
|
+
<form method="POST" action="/pinokio/login">
|
|
70
|
+
<input placeholder="enter passcode" type="password" name="password" required>
|
|
71
|
+
<button type="submit">Login</button>
|
|
72
|
+
</form>
|
|
73
|
+
<% if (error) { %>
|
|
74
|
+
<div class='error'><%=error%></div>
|
|
75
|
+
<% } %>
|
|
76
|
+
<main>
|
|
77
|
+
</body>
|
|
78
|
+
</html>
|
package/server/index.js
CHANGED
|
@@ -173,11 +173,9 @@ class Server {
|
|
|
173
173
|
})
|
|
174
174
|
}
|
|
175
175
|
async init_env(env_dir_path) {
|
|
176
|
-
console.log("env_path",env_dir_path)
|
|
177
176
|
let current = this.kernel.path(env_dir_path, "ENVIRONMENT")
|
|
178
177
|
// if environment.json doesn't exist,
|
|
179
178
|
let exists = await this.exists(current)
|
|
180
|
-
console.log({ current, exists })
|
|
181
179
|
if (exists) {
|
|
182
180
|
// if ENVIRONMENT already exists, don't do anything
|
|
183
181
|
} else {
|
|
@@ -187,11 +185,10 @@ class Server {
|
|
|
187
185
|
// if _ENVIRONMENT exists,
|
|
188
186
|
let _environment = this.kernel.path(env_dir_path, "_ENVIRONMENT")
|
|
189
187
|
let _exists = await this.exists(_environment)
|
|
190
|
-
console.log({ _environment, _exists })
|
|
191
188
|
let content = await Environment.ENV("app")
|
|
192
189
|
if (_exists) {
|
|
193
190
|
let _environmentStr = await fs.promises.readFile(_environment, "utf8")
|
|
194
|
-
await fs.promises.writeFile(current, _environmentStr + "\n
|
|
191
|
+
await fs.promises.writeFile(current, _environmentStr + "\n\n\n" + content)
|
|
195
192
|
} else {
|
|
196
193
|
await fs.promises.writeFile(current, content)
|
|
197
194
|
}
|
|
@@ -1878,9 +1875,15 @@ class Server {
|
|
|
1878
1875
|
// stop proxies
|
|
1879
1876
|
for(let scriptPath in this.kernel.api.proxies) {
|
|
1880
1877
|
try {
|
|
1878
|
+
// Turn off local sharing
|
|
1881
1879
|
await this.kernel.api.stopProxy({
|
|
1882
1880
|
script: scriptPath
|
|
1883
1881
|
})
|
|
1882
|
+
|
|
1883
|
+
// Turn off cloudflare sharing
|
|
1884
|
+
await this.kernel.stopCloudflare({
|
|
1885
|
+
path: scriptPath
|
|
1886
|
+
})
|
|
1884
1887
|
} catch (e) {
|
|
1885
1888
|
}
|
|
1886
1889
|
}
|
|
@@ -2171,7 +2174,6 @@ class Server {
|
|
|
2171
2174
|
}
|
|
2172
2175
|
})
|
|
2173
2176
|
this.app.post("/env", async (req, res) => {
|
|
2174
|
-
console.log("req.body", req.body)
|
|
2175
2177
|
let fullpath = path.resolve(this.kernel.homedir, req.body.filepath, "ENVIRONMENT")
|
|
2176
2178
|
let updated = req.body.vals
|
|
2177
2179
|
await Util.update_env(fullpath, updated)
|
|
@@ -2206,12 +2208,7 @@ class Server {
|
|
|
2206
2208
|
let pathComponents = req.params[0].split("/")
|
|
2207
2209
|
let filepath = path.resolve(this.kernel.homedir, req.params[0], "ENVIRONMENT")
|
|
2208
2210
|
let editorpath = "/edit/" + req.params[0] + "/ENVIRONMENT"
|
|
2209
|
-
|
|
2210
|
-
console.log({ pathComponents, filepath, editorpath, })
|
|
2211
2211
|
const items = await Util.parse_env_detail(filepath)
|
|
2212
|
-
|
|
2213
|
-
console.log(items)
|
|
2214
|
-
|
|
2215
2212
|
let p = path.resolve(this.kernel.homedir, env_path, "pinokio.js")
|
|
2216
2213
|
let config = (await this.kernel.loader.load(p)).resolved
|
|
2217
2214
|
if (config.icon) {
|
|
@@ -2234,16 +2231,13 @@ class Server {
|
|
|
2234
2231
|
agent: this.agent,
|
|
2235
2232
|
})
|
|
2236
2233
|
})
|
|
2237
|
-
this.app.get("/pre/:name", async (req, res) => {
|
|
2238
|
-
let p = path.resolve(this.kernel.homedir,
|
|
2234
|
+
this.app.get("/pre/api/:name", async (req, res) => {
|
|
2235
|
+
let p = path.resolve(this.kernel.homedir, req.params.name, "pinokio.js")
|
|
2239
2236
|
let config = (await this.kernel.loader.load(p)).resolved
|
|
2240
|
-
console.log("config", config)
|
|
2241
2237
|
if (config && config.pre) {
|
|
2242
|
-
|
|
2243
2238
|
config.pre.forEach((item) => {
|
|
2244
2239
|
item.icon = `/api/${req.params.name}/${item.icon}?raw=true`
|
|
2245
2240
|
})
|
|
2246
|
-
|
|
2247
2241
|
res.render("pre", {
|
|
2248
2242
|
name: req.params.name,
|
|
2249
2243
|
theme: this.theme,
|
|
@@ -2252,7 +2246,7 @@ class Server {
|
|
|
2252
2246
|
items: config.pre
|
|
2253
2247
|
})
|
|
2254
2248
|
} else {
|
|
2255
|
-
res.redirect("/env/" + req.params.name)
|
|
2249
|
+
res.redirect("/env/" + req.params.name + "?init=true")
|
|
2256
2250
|
}
|
|
2257
2251
|
})
|
|
2258
2252
|
this.app.get("/initialize/:name", async (req, res) => {
|
|
@@ -2262,10 +2256,10 @@ class Server {
|
|
|
2262
2256
|
// if pinokio.js exists
|
|
2263
2257
|
if (config.pre && Array.isArray(config.pre)) {
|
|
2264
2258
|
// if pre exists, redirect to /pre/:name
|
|
2265
|
-
res.redirect(`/pre/${req.params.name}`)
|
|
2259
|
+
res.redirect(`/pre/api/${req.params.name}`)
|
|
2266
2260
|
} else {
|
|
2267
2261
|
// if pre doesn't exist, redirect to /env/:name
|
|
2268
|
-
res.redirect(`/env/${req.params.name}`)
|
|
2262
|
+
res.redirect(`/env/api/${req.params.name}?init=true`)
|
|
2269
2263
|
}
|
|
2270
2264
|
} else {
|
|
2271
2265
|
// if pinokio.js doesn't exist, send to /browser/:name
|
|
@@ -2275,9 +2269,7 @@ class Server {
|
|
|
2275
2269
|
this.app.get("/share/:name", async (req, res) => {
|
|
2276
2270
|
let filepath = path.resolve(this.kernel.homedir, "api", req.params.name, "ENVIRONMENT")
|
|
2277
2271
|
//let filepath = path.resolve(this.kernel.homedir, req.params[0])
|
|
2278
|
-
console.log("filepath", filepath)
|
|
2279
2272
|
const config = await Util.parse_env(filepath)
|
|
2280
|
-
console.log("config", config)
|
|
2281
2273
|
const keys = [
|
|
2282
2274
|
"PINOKIO_SHARE_CLOUDFLARE",
|
|
2283
2275
|
"PINOKIO_SHARE_LOCAL",
|
|
@@ -2294,10 +2286,8 @@ class Server {
|
|
|
2294
2286
|
})
|
|
2295
2287
|
let cloudflare_links = []
|
|
2296
2288
|
let local_links = []
|
|
2297
|
-
console.log({ app_path, scripts })
|
|
2298
2289
|
for(let script in this.kernel.memory.local) {
|
|
2299
2290
|
let mem = this.kernel.memory.local[script]
|
|
2300
|
-
console.log({ script, mem })
|
|
2301
2291
|
if (mem.$share) {
|
|
2302
2292
|
if (mem.$share.cloudflare) {
|
|
2303
2293
|
for(let key in mem.$share.cloudflare) {
|
|
@@ -2890,47 +2880,6 @@ class Server {
|
|
|
2890
2880
|
});
|
|
2891
2881
|
})
|
|
2892
2882
|
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
// this.expose_app = express();
|
|
2896
|
-
// this.expose_app.use(cors({
|
|
2897
|
-
// origin: '*'
|
|
2898
|
-
// }));
|
|
2899
|
-
// this.expose_app.use('/', proxy(async (req) => {
|
|
2900
|
-
// console.log("req.url", req.url)
|
|
2901
|
-
// let tokens = req.url.split("/")
|
|
2902
|
-
// console.log({ tokens })
|
|
2903
|
-
// if (tokens.length >=2 ) {
|
|
2904
|
-
// let app = tokens[1]
|
|
2905
|
-
// console.log({ app })
|
|
2906
|
-
// console.log("resolved = ", this.kernel.exposed[app])
|
|
2907
|
-
// return this.kernel.exposed[app]
|
|
2908
|
-
// }
|
|
2909
|
-
// }, {
|
|
2910
|
-
//// proxyReqPathResolver: (req) => {
|
|
2911
|
-
//// console.log("proxyReqPathResolver", req.url)
|
|
2912
|
-
//// let chunks = req.url.split("/")
|
|
2913
|
-
//// let transformed
|
|
2914
|
-
//// if (chunks.length > 3) {
|
|
2915
|
-
//// transformed = "/" + chunks.slice(3).join("/")
|
|
2916
|
-
//// } else {
|
|
2917
|
-
//// transformed = "/"
|
|
2918
|
-
//// }
|
|
2919
|
-
//// console.log({ chunks, transformed })
|
|
2920
|
-
//// return transformed
|
|
2921
|
-
//// }
|
|
2922
|
-
// }))
|
|
2923
|
-
// this.expose_port = await portfinder.getPortPromise({ port: this.port })
|
|
2924
|
-
// console.log("EXPOSE_PORT", this.expose_port)
|
|
2925
|
-
// await new Promise((resolve, reject) => {
|
|
2926
|
-
// this.expose_server = this.expose_app.listen(this.expose_port, () => {
|
|
2927
|
-
// console.log(`Server listening on port ${this.expose_port}`)
|
|
2928
|
-
// resolve()
|
|
2929
|
-
// });
|
|
2930
|
-
// this.exposeTerminator = createHttpTerminator({
|
|
2931
|
-
// server: this.expose_server
|
|
2932
|
-
// });
|
|
2933
|
-
// })
|
|
2934
2883
|
}
|
|
2935
2884
|
}
|
|
2936
2885
|
module.exports = Server
|
|
@@ -164,7 +164,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
164
164
|
"Content-Type": "application/json"
|
|
165
165
|
},
|
|
166
166
|
body: JSON.stringify({
|
|
167
|
-
filepath: "api/" + location.pathname.slice(7)
|
|
167
|
+
filepath: "api/" + location.pathname.slice(7),
|
|
168
168
|
vals
|
|
169
169
|
})
|
|
170
170
|
}).then((res) => {
|
|
@@ -194,6 +194,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
194
194
|
<li>This will let you share your local Pinokio app to the public internet, which anyone with a URL can access.</li>
|
|
195
195
|
<li>Powered by <a href="https://www.cloudflare.com/products/tunnel/" target="_blank" features="browser">Cloudflare Tunnel</a></li>
|
|
196
196
|
<li>You can manually configure this in through the Configure menu (set PINOKIO_SHARE_CLOUDFLARE to true)</li>
|
|
197
|
+
<li>You can add <strong>authentication</strong> by adding a passcode (set PINOKIO_SHARE_PASSCODE in the <strong>Configure</strong> tab)</li>
|
|
197
198
|
</ul>
|
|
198
199
|
<% cloudflare_links.forEach((link) => { %>
|
|
199
200
|
<div class='shared'>
|