vercel-vm-factory 0.1.1 → 0.1.2
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/README.md +5 -0
- package/deploy-vm.mjs +69 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@ Create a tiny Vercel Container deployment: copy `wsterm` from `ghcr.io/v1xingyue
|
|
|
6
6
|
npx vercel-vm-factory create \
|
|
7
7
|
--base ubuntu \
|
|
8
8
|
--project ws-shell-ubuntu \
|
|
9
|
+
--auth-mode basic \
|
|
9
10
|
--auth-user admin \
|
|
10
11
|
--auth-password change-me
|
|
11
12
|
```
|
|
@@ -14,6 +15,7 @@ GitHub OAuth is optional:
|
|
|
14
15
|
|
|
15
16
|
```bash
|
|
16
17
|
npx vercel-vm-factory create \
|
|
18
|
+
--auth-mode github \
|
|
17
19
|
--client-id YOUR_GITHUB_CLIENT_ID \
|
|
18
20
|
--client-secret YOUR_GITHUB_CLIENT_SECRET \
|
|
19
21
|
--github-userid 12345678
|
|
@@ -25,6 +27,8 @@ Run without flags for prompts:
|
|
|
25
27
|
npx vercel-vm-factory create
|
|
26
28
|
```
|
|
27
29
|
|
|
30
|
+
The prompt asks for authentication first: `basic`, `github`, `both`, or `none`, then only asks for the fields that mode needs.
|
|
31
|
+
|
|
28
32
|
Check local setup:
|
|
29
33
|
|
|
30
34
|
```bash
|
|
@@ -72,6 +76,7 @@ https://x-shell.vercel.app/auth/github/callback
|
|
|
72
76
|
|
|
73
77
|
GitHub OAuth fields:
|
|
74
78
|
|
|
79
|
+
- Auth mode -> `--auth-mode basic|github|both|none`
|
|
75
80
|
- Username -> `--auth-user`
|
|
76
81
|
- Password -> `--auth-password`
|
|
77
82
|
- Client ID -> `--client-id`
|
package/deploy-vm.mjs
CHANGED
|
@@ -64,6 +64,7 @@ async function main() {
|
|
|
64
64
|
const prod = args.prod !== "false";
|
|
65
65
|
const dryRun = Boolean(args["dry-run"]);
|
|
66
66
|
const skipLink = Boolean(args["skip-link"]);
|
|
67
|
+
const authMode = await chooseAuthMode(defaultAuthMode());
|
|
67
68
|
|
|
68
69
|
const oauthRedirectUrl =
|
|
69
70
|
args["redirect-url"] ??
|
|
@@ -83,7 +84,8 @@ async function main() {
|
|
|
83
84
|
project,
|
|
84
85
|
scope: scope || "default",
|
|
85
86
|
source: wsShellImage,
|
|
86
|
-
|
|
87
|
+
auth: authMode,
|
|
88
|
+
...(usesGitHubAuth(authMode) ? { callback: oauthRedirectUrl } : {}),
|
|
87
89
|
dockerfile: path.join(appDir, "Dockerfile.vercel"),
|
|
88
90
|
target: prod ? "production" : "preview",
|
|
89
91
|
});
|
|
@@ -94,17 +96,23 @@ async function main() {
|
|
|
94
96
|
}
|
|
95
97
|
|
|
96
98
|
await ensureVercelReady();
|
|
97
|
-
printOAuthGuide(oauthRedirectUrl);
|
|
98
|
-
|
|
99
|
-
const authUsername =
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const
|
|
103
|
-
"
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
99
|
+
if (usesGitHubAuth(authMode)) printOAuthGuide(oauthRedirectUrl);
|
|
100
|
+
|
|
101
|
+
const authUsername = usesBasicAuth(authMode)
|
|
102
|
+
? await secret("auth-user", "Basic auth username", process.env.AUTH_USERNAME ?? defaults["auth-user"])
|
|
103
|
+
: "";
|
|
104
|
+
const authPassword = usesBasicAuth(authMode)
|
|
105
|
+
? await secret("auth-password", "Basic auth password", process.env.AUTH_PASSWORD ?? defaults["auth-password"])
|
|
106
|
+
: "";
|
|
107
|
+
const githubClientId = usesGitHubAuth(authMode)
|
|
108
|
+
? await secret("client-id", "GitHub client id", process.env.GITHUB_CLIENT_ID ?? defaults["client-id"])
|
|
109
|
+
: "";
|
|
110
|
+
const githubClientSecret = usesGitHubAuth(authMode)
|
|
111
|
+
? await secret("client-secret", "GitHub client secret", process.env.GITHUB_CLIENT_SECRET ?? defaults["client-secret"])
|
|
112
|
+
: "";
|
|
113
|
+
const allowedUserIds = usesGitHubAuth(authMode)
|
|
114
|
+
? await secret("github-userid", "Allowed GitHub numeric user id(s)", process.env.ALLOWED_USER_IDS ?? defaults["github-userid"])
|
|
115
|
+
: "";
|
|
108
116
|
|
|
109
117
|
await writeDefaults(defaultsPath, {
|
|
110
118
|
...defaults,
|
|
@@ -112,6 +120,7 @@ async function main() {
|
|
|
112
120
|
scope: scope || undefined,
|
|
113
121
|
project,
|
|
114
122
|
from: wsShellImage,
|
|
123
|
+
"auth-mode": authMode,
|
|
115
124
|
"auth-user": authUsername,
|
|
116
125
|
"auth-password": authPassword,
|
|
117
126
|
"client-id": githubClientId,
|
|
@@ -138,12 +147,11 @@ async function main() {
|
|
|
138
147
|
appDir,
|
|
139
148
|
"--yes",
|
|
140
149
|
"--logs",
|
|
141
|
-
"--env",
|
|
142
|
-
`OAUTH_REDIRECT_URL=${oauthRedirectUrl}`,
|
|
143
150
|
];
|
|
144
151
|
|
|
145
152
|
if (authUsername) vercelArgs.push("--env", `AUTH_USERNAME=${authUsername}`);
|
|
146
153
|
if (authPassword) vercelArgs.push("--env", `AUTH_PASSWORD=${authPassword}`);
|
|
154
|
+
if (usesGitHubAuth(authMode)) vercelArgs.push("--env", `OAUTH_REDIRECT_URL=${oauthRedirectUrl}`);
|
|
147
155
|
if (githubClientId) vercelArgs.push("--env", `GITHUB_CLIENT_ID=${githubClientId}`);
|
|
148
156
|
if (githubClientSecret) vercelArgs.push("--env", `GITHUB_CLIENT_SECRET=${githubClientSecret}`);
|
|
149
157
|
if (allowedUserIds) vercelArgs.push("--env", `ALLOWED_USER_IDS=${allowedUserIds}`);
|
|
@@ -199,6 +207,7 @@ async function doctor() {
|
|
|
199
207
|
printKeyValue("project", defaults.project || "not set");
|
|
200
208
|
printKeyValue("scope", defaults.scope || "not set");
|
|
201
209
|
printKeyValue("source image", defaults.from || "ghcr.io/v1xingyue/ws-shell:v1.1.alpine");
|
|
210
|
+
printKeyValue("auth mode", defaults["auth-mode"] || "not set");
|
|
202
211
|
printKeyValue("auth user", defaults["auth-user"] ? mask(defaults["auth-user"]) : "not set");
|
|
203
212
|
printKeyValue("auth password", defaults["auth-password"] ? mask(defaults["auth-password"]) : "not set");
|
|
204
213
|
printKeyValue("client id", defaults["client-id"] ? mask(defaults["client-id"]) : "not set");
|
|
@@ -256,6 +265,51 @@ async function optionalValue(name, question, fallback) {
|
|
|
256
265
|
return answer;
|
|
257
266
|
}
|
|
258
267
|
|
|
268
|
+
function defaultAuthMode() {
|
|
269
|
+
if (args["auth-mode"]) return args["auth-mode"];
|
|
270
|
+
const hasBasic = Boolean(args["auth-user"] || args["auth-password"] || process.env.AUTH_USERNAME || process.env.AUTH_PASSWORD);
|
|
271
|
+
const hasGitHub = Boolean(args["client-id"] || args["client-secret"] || args["github-userid"] || process.env.GITHUB_CLIENT_ID || process.env.GITHUB_CLIENT_SECRET);
|
|
272
|
+
if (hasBasic && hasGitHub) return "both";
|
|
273
|
+
if (hasBasic) return "basic";
|
|
274
|
+
if (hasGitHub) return "github";
|
|
275
|
+
return defaults["auth-mode"] || (input.isTTY ? "basic" : "none");
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
async function chooseAuthMode(fallback) {
|
|
279
|
+
const modes = new Set(["basic", "github", "both", "none"]);
|
|
280
|
+
if (args["auth-mode"]) {
|
|
281
|
+
if (!modes.has(args["auth-mode"])) throw new Error("--auth-mode must be basic, github, both, or none");
|
|
282
|
+
return args["auth-mode"];
|
|
283
|
+
}
|
|
284
|
+
if (!input.isTTY) return modes.has(fallback) ? fallback : "basic";
|
|
285
|
+
|
|
286
|
+
console.log(color.bold("Choose authentication"));
|
|
287
|
+
console.log(` ${color.cyan("1")}. basic username/password`);
|
|
288
|
+
console.log(` ${color.cyan("2")}. GitHub OAuth`);
|
|
289
|
+
console.log(` ${color.cyan("3")}. both`);
|
|
290
|
+
console.log(` ${color.cyan("4")}. none`);
|
|
291
|
+
|
|
292
|
+
const rl = createInterface({ input, output });
|
|
293
|
+
const answer = (await rl.question(`Authentication [${fallback}]: `)).trim();
|
|
294
|
+
rl.close();
|
|
295
|
+
|
|
296
|
+
if (!answer) return modes.has(fallback) ? fallback : "basic";
|
|
297
|
+
if (modes.has(answer)) return answer;
|
|
298
|
+
if (answer === "1") return "basic";
|
|
299
|
+
if (answer === "2") return "github";
|
|
300
|
+
if (answer === "3") return "both";
|
|
301
|
+
if (answer === "4") return "none";
|
|
302
|
+
throw new Error("Authentication must be basic, github, both, or none");
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function usesBasicAuth(mode) {
|
|
306
|
+
return mode === "basic" || mode === "both";
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function usesGitHubAuth(mode) {
|
|
310
|
+
return mode === "github" || mode === "both";
|
|
311
|
+
}
|
|
312
|
+
|
|
259
313
|
async function chooseBase(fallback) {
|
|
260
314
|
if (args.base) return args.base;
|
|
261
315
|
if (!input.isTTY) return fallback;
|
|
@@ -432,6 +486,7 @@ Options:
|
|
|
432
486
|
--project NAME Vercel project name
|
|
433
487
|
--scope SLUG Optional Vercel team/user scope slug
|
|
434
488
|
--from IMAGE Source image for /app/bin/wsterm
|
|
489
|
+
--auth-mode MODE basic, github, both, or none
|
|
435
490
|
--auth-user VALUE Username/password auth user
|
|
436
491
|
--auth-password VAL Username/password auth password
|
|
437
492
|
--client-id VALUE GitHub OAuth client id
|