onedeploy-cli 0.1.11 → 0.1.14
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/dist/nebula.js +32 -46
- package/package.json +1 -1
- package/dist/success.js +0 -201
package/dist/nebula.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { execFile, spawn } from "node:child_process";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { access, chmod, mkdir, readFile, rm, writeFile, } from "node:fs/promises";
|
|
4
|
-
import { createServer } from "node:http";
|
|
5
4
|
import { tmpdir } from "node:os";
|
|
6
5
|
import path from "node:path";
|
|
7
6
|
import { Readable } from "node:stream";
|
|
@@ -9,7 +8,6 @@ import { promisify } from "node:util";
|
|
|
9
8
|
import { parse } from "yaml";
|
|
10
9
|
import { openBrowser } from "./browser.js";
|
|
11
10
|
import { configDir } from "./config.js";
|
|
12
|
-
import { successPage } from "./success.js";
|
|
13
11
|
const getNebulaPackageName = () => {
|
|
14
12
|
switch (process.platform) {
|
|
15
13
|
case "linux":
|
|
@@ -124,51 +122,39 @@ export const getNebulaCert = async (instance, session) => {
|
|
|
124
122
|
};
|
|
125
123
|
export let isNebulaRunning = false;
|
|
126
124
|
export let nebulaIp = null;
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
return "http://localhost:70000";
|
|
134
|
-
}
|
|
135
|
-
return `http://localhost:${addr.port}`;
|
|
136
|
-
};
|
|
137
|
-
const server = createServer((req, res) => {
|
|
138
|
-
const url = new URL(req.url ?? "/", "http://localhost");
|
|
139
|
-
if (url.pathname === "/authenticated") {
|
|
140
|
-
const token = url.searchParams.get("token");
|
|
141
|
-
if (token === null) {
|
|
142
|
-
throw new Error("Missing token in callback URL");
|
|
143
|
-
}
|
|
144
|
-
// authentication complete
|
|
145
|
-
res.writeHead(200, "OK", {
|
|
146
|
-
"content-type": "text/html",
|
|
147
|
-
});
|
|
148
|
-
res.write(successPage);
|
|
149
|
-
res.end();
|
|
150
|
-
server.close();
|
|
151
|
-
resolve(token);
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
154
|
-
const target = `${getServerAddr()}/authenticated`;
|
|
155
|
-
res.writeHead(302, {
|
|
156
|
-
location: `${instance.url}/auth/nebula?redirect=${encodeURIComponent(target)}`,
|
|
157
|
-
});
|
|
158
|
-
res.end();
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
server.on("listening", async () => {
|
|
162
|
-
const addr = server.address();
|
|
163
|
-
if (addr === null || typeof addr === "string") {
|
|
164
|
-
throw new Error("Unexpected address type");
|
|
165
|
-
}
|
|
166
|
-
const authUrl = getServerAddr();
|
|
167
|
-
console.log(`Visit ${authUrl} to authenticate (opened in browser)`);
|
|
168
|
-
await openBrowser(authUrl);
|
|
169
|
-
});
|
|
170
|
-
server.listen();
|
|
125
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
126
|
+
export const getSession = async (instance) => {
|
|
127
|
+
const createRes = await fetch(`${instance.url}/api/auth/nebula/device`, {
|
|
128
|
+
method: "POST",
|
|
129
|
+
headers: { "content-type": "application/json" },
|
|
130
|
+
body: "{}",
|
|
171
131
|
});
|
|
132
|
+
if (!createRes.ok) {
|
|
133
|
+
throw new Error(`Failed to create device code: ${createRes.status}`);
|
|
134
|
+
}
|
|
135
|
+
const { code, verificationUrl } = (await createRes.json());
|
|
136
|
+
console.log(`Visit ${verificationUrl} to authenticate`);
|
|
137
|
+
await openBrowser(verificationUrl);
|
|
138
|
+
const deadline = Date.now() + 10 * 60 * 1000;
|
|
139
|
+
while (Date.now() < deadline) {
|
|
140
|
+
await sleep(2000);
|
|
141
|
+
const pollRes = await fetch(`${instance.url}/api/auth/nebula/device/${code}`, {
|
|
142
|
+
method: "POST",
|
|
143
|
+
headers: { "content-type": "application/json" },
|
|
144
|
+
body: "{}",
|
|
145
|
+
});
|
|
146
|
+
if (pollRes.status === 404) {
|
|
147
|
+
throw new Error("Device code expired or not found.");
|
|
148
|
+
}
|
|
149
|
+
if (!pollRes.ok) {
|
|
150
|
+
throw new Error(`Poll failed: ${pollRes.status}`);
|
|
151
|
+
}
|
|
152
|
+
const result = (await pollRes.json());
|
|
153
|
+
if (result.status === "complete") {
|
|
154
|
+
return result.token;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
throw new Error("Authentication timed out after 10 minutes.");
|
|
172
158
|
};
|
|
173
159
|
export const startNebula = async (instance, session) => {
|
|
174
160
|
await getNebulaCert(instance, session);
|
package/package.json
CHANGED
package/dist/success.js
DELETED
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
export const successPage = `<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
|
|
4
|
-
<head>
|
|
5
|
-
<meta charset="UTF-8">
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
-
<title>oneDeploy</title>
|
|
8
|
-
<link rel="icon" type="image/svg+xml"
|
|
9
|
-
href="data:image/svg+xml,%3Csvg width='48' height='48' viewBox='0 0 48 48' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='14' cy='27' r='14' fill='%2322C55E'/%3E%3Ccircle cx='38' cy='10' r='10' fill='%234ADE80'/%3E%3Ccircle cx='40' cy='40' r='8' fill='%2316A34A'/%3E%3Cline x1='26' y1='19' x2='30' y2='14' stroke='%2386EFAC' stroke-width='3' stroke-linecap='round'/%3E%3Cline x1='26' y1='36' x2='34' y2='38' stroke='%2386EFAC' stroke-width='3' stroke-linecap='round'/%3E%3Cpath d='M9 20V34L21 27L9 20Z' fill='white'/%3E%3C/svg%3E">
|
|
10
|
-
<style>
|
|
11
|
-
* {
|
|
12
|
-
margin: 0;
|
|
13
|
-
padding: 0;
|
|
14
|
-
box-sizing: border-box;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
body {
|
|
18
|
-
font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
|
19
|
-
margin: 0;
|
|
20
|
-
padding: 0;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
.page-container {
|
|
24
|
-
min-height: 100vh;
|
|
25
|
-
background-color: #0b0b0f;
|
|
26
|
-
color: #f3f4f6;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.navbar {
|
|
30
|
-
padding: 1rem;
|
|
31
|
-
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
|
32
|
-
background-color: #0e0e14;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.logo-container {
|
|
36
|
-
display: flex;
|
|
37
|
-
align-items: center;
|
|
38
|
-
gap: 0.75rem;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
.logo-container img {
|
|
42
|
-
width: 2.5rem;
|
|
43
|
-
height: 2.5rem;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
.logo-text {
|
|
47
|
-
font-size: 1.5rem;
|
|
48
|
-
font-weight: 700;
|
|
49
|
-
letter-spacing: -0.025em;
|
|
50
|
-
line-height: 1.2;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
@media (min-width: 768px) {
|
|
54
|
-
.logo-text {
|
|
55
|
-
font-size: 1.875rem;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
.logo-one {
|
|
60
|
-
color: #4ade80;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
.logo-deploy {
|
|
64
|
-
color: #f3f4f6;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
.content-wrapper {
|
|
68
|
-
padding: 1rem;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
.container {
|
|
72
|
-
min-height: 80vh;
|
|
73
|
-
display: flex;
|
|
74
|
-
align-items: center;
|
|
75
|
-
justify-content: center;
|
|
76
|
-
padding-left: 1rem;
|
|
77
|
-
padding-right: 1rem;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
.card {
|
|
81
|
-
width: 100%;
|
|
82
|
-
max-width: 28rem;
|
|
83
|
-
background-color: #14141c;
|
|
84
|
-
border: 1px solid rgba(255, 255, 255, 0.05);
|
|
85
|
-
border-radius: 1rem;
|
|
86
|
-
padding: 2rem;
|
|
87
|
-
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
.header {
|
|
91
|
-
text-align: center;
|
|
92
|
-
margin-bottom: 2rem;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
.icon-container {
|
|
96
|
-
display: inline-flex;
|
|
97
|
-
align-items: center;
|
|
98
|
-
justify-content: center;
|
|
99
|
-
width: 4rem;
|
|
100
|
-
height: 4rem;
|
|
101
|
-
border-radius: 1rem;
|
|
102
|
-
background-color: rgba(139, 92, 246, 0.1);
|
|
103
|
-
color: #a78bfa;
|
|
104
|
-
margin-bottom: 1.5rem;
|
|
105
|
-
border: 1px solid rgba(255, 255, 255, 0.05);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
.icon-container svg {
|
|
109
|
-
width: 2rem;
|
|
110
|
-
height: 2rem;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
h1 {
|
|
114
|
-
font-size: 1.875rem;
|
|
115
|
-
font-weight: 700;
|
|
116
|
-
color: #f3f4f6;
|
|
117
|
-
letter-spacing: -0.025em;
|
|
118
|
-
margin: 0 0 0.5rem 0;
|
|
119
|
-
line-height: 2.25rem;
|
|
120
|
-
text-align: center;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
.description {
|
|
124
|
-
color: #9ca3af;
|
|
125
|
-
font-size: 1rem;
|
|
126
|
-
line-height: 1.5rem;
|
|
127
|
-
text-align: center;
|
|
128
|
-
margin: 0;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
.status-container {
|
|
132
|
-
min-height: 60px;
|
|
133
|
-
display: flex;
|
|
134
|
-
align-items: center;
|
|
135
|
-
justify-content: center;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
.success-box {
|
|
139
|
-
width: 100%;
|
|
140
|
-
display: flex;
|
|
141
|
-
align-items: center;
|
|
142
|
-
justify-content: center;
|
|
143
|
-
padding-top: 0.75rem;
|
|
144
|
-
padding-bottom: 0.75rem;
|
|
145
|
-
font-size: 1rem;
|
|
146
|
-
font-weight: 500;
|
|
147
|
-
background-color: rgba(34, 197, 94, 0.1);
|
|
148
|
-
border: 1px solid rgba(34, 197, 94, 0.2);
|
|
149
|
-
border-radius: 0.5rem;
|
|
150
|
-
color: #4ade80;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
.success-box svg {
|
|
154
|
-
width: 1.25rem;
|
|
155
|
-
height: 1.25rem;
|
|
156
|
-
}
|
|
157
|
-
</style>
|
|
158
|
-
</head>
|
|
159
|
-
|
|
160
|
-
<body>
|
|
161
|
-
<div class="page-container">
|
|
162
|
-
<div class="navbar">
|
|
163
|
-
<div class="logo-container">
|
|
164
|
-
<img alt="oneDeploy Logo"
|
|
165
|
-
src="data:image/svg+xml,%3Csvg width='48' height='48' viewBox='0 0 48 48' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='14' cy='27' r='14' fill='%2322C55E'/%3E%3Ccircle cx='38' cy='10' r='10' fill='%234ADE80'/%3E%3Ccircle cx='40' cy='40' r='8' fill='%2316A34A'/%3E%3Cline x1='26' y1='19' x2='30' y2='14' stroke='%2386EFAC' stroke-width='3' stroke-linecap='round'/%3E%3Cline x1='26' y1='36' x2='34' y2='38' stroke='%2386EFAC' stroke-width='3' stroke-linecap='round'/%3E%3Cpath d='M9 20V34L21 27L9 20Z' fill='white'/%3E%3C/svg%3E">
|
|
166
|
-
<div class="logo-text">
|
|
167
|
-
<span class="logo-one">one</span><span class="logo-deploy">Deploy</span>
|
|
168
|
-
</div>
|
|
169
|
-
</div>
|
|
170
|
-
</div>
|
|
171
|
-
<div class="content-wrapper">
|
|
172
|
-
<div class="container">
|
|
173
|
-
<div class="card">
|
|
174
|
-
<div class="header">
|
|
175
|
-
<div class="icon-container">
|
|
176
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
|
177
|
-
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
178
|
-
<circle cx="12" cy="12" r="10" />
|
|
179
|
-
<line x1="2" y1="12" x2="22" y2="12" />
|
|
180
|
-
<path
|
|
181
|
-
d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" />
|
|
182
|
-
</svg>
|
|
183
|
-
</div>
|
|
184
|
-
<h1>Network Access Request</h1>
|
|
185
|
-
<p class="description">oneDeploy CLI is requesting access to the oneDeploy network</p>
|
|
186
|
-
</div>
|
|
187
|
-
|
|
188
|
-
<div class="status-container">
|
|
189
|
-
<div class="success-box">
|
|
190
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
|
191
|
-
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
192
|
-
<path d="M20 6 9 17l-5-5" />
|
|
193
|
-
</svg>
|
|
194
|
-
</div>
|
|
195
|
-
</div>
|
|
196
|
-
</div>
|
|
197
|
-
</div>
|
|
198
|
-
</div>
|
|
199
|
-
</div>
|
|
200
|
-
</body>
|
|
201
|
-
`;
|