void 0.20.1 → 0.20.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 -1
- package/dist/{auth-W9WII-mN.mjs → auth-DPl6kck4.mjs} +46 -26
- package/dist/{auth-cmd-CAH62yDU.mjs → auth-cmd-gniL2fNt.mjs} +5 -4
- package/dist/auth-link-NZdjCmSc.mjs +28 -0
- package/dist/{build-cmd-CJvZvPQO.mjs → build-cmd-sI18tX_O.mjs} +3 -3
- package/dist/{cache-BlNeQjuP.mjs → cache-IHn5MwBC.mjs} +3 -3
- package/dist/{cancel-deploy-CmlAZ9P6.mjs → cancel-deploy-C5qTOdLi.mjs} +3 -3
- package/dist/cf-access-DRsQRe6k.mjs +75 -0
- package/dist/cli/cli.mjs +308 -1958
- package/dist/cli/env-schema-probe.mjs +11 -2
- package/dist/{client-Clirrol3.mjs → client-dHfSJvAN.mjs} +300 -81
- package/dist/{cloudflare-auth-B1QtTO1b.mjs → cloudflare-auth-6M5llVPC.mjs} +2 -2
- package/dist/{cloudflare-cmd-B6_OZx2V.mjs → cloudflare-cmd-4RPGN3KB.mjs} +2 -2
- package/dist/{cloudflare-connect-j5D4hhrG.mjs → cloudflare-connect-t1UU5svD.mjs} +2 -2
- package/dist/{cloudflare-operations-CPTpRW6d.mjs → cloudflare-operations-BzWnlC1_.mjs} +1 -1
- package/dist/{config-BQFq7QvD.mjs → config-uNGuFsI2.mjs} +1 -1
- package/dist/{connect-C04Wdy_h.mjs → connect-Bfk31O_8.mjs} +6 -6
- package/dist/{create-project-ChGZ1DFd.mjs → create-project-Bk9Z0-Jg.mjs} +6 -5
- package/dist/{db-D2d_mUsB.mjs → db-BkRoptAt.mjs} +47 -30
- package/dist/{delete-D8GigDk8.mjs → delete-DouASY9P.mjs} +3 -3
- package/dist/{deploy-iXZ3F0N6.mjs → deploy-DTaWUS1S.mjs} +121 -110
- package/dist/{dev-inbox-DkgRWLkW.mjs → dev-inbox-P0u4tM8Y.mjs} +1 -1
- package/dist/{domain-B1VmoSr0.mjs → domain-1RhhOVrC.mjs} +4 -4
- package/dist/email-C-lGh51B.mjs +795 -0
- package/dist/{env-D4Emu-M_.mjs → env-DBKmK4vc.mjs} +1 -0
- package/dist/{env-BcQzYgoG.mjs → env-DJHsPE7Z.mjs} +5 -5
- package/dist/{env-validation-ENpMy6Ez.mjs → env-validation-CF6KvTRf.mjs} +3 -1
- package/dist/{gen-DI2YwdBM.mjs → gen-B_wPnVTK.mjs} +2 -2
- package/dist/{github-cmd-xItS5Zwf.mjs → github-cmd-PW7ZnWTp.mjs} +3 -3
- package/dist/{headers-D8QfRX9Y.mjs → headers-BAHwgHdW.mjs} +1 -1
- package/dist/help-CwOX-zmI.mjs +2216 -0
- package/dist/{inbound-afAcWeQ9.d.mts → inbound-CH5Mksyy.d.mts} +34 -48
- package/dist/{inbound-2d0zi2yS.mjs → inbound-aVHEUhKo.mjs} +130 -100
- package/dist/index.mjs +54 -17
- package/dist/{init-BD-9THgn.mjs → init-BWZ7q5Z4.mjs} +11 -11
- package/dist/{link-RMdgjF1v.mjs → link-Rmvu2Wl_.mjs} +4 -4
- package/dist/{list-3F52R_yO.mjs → list-DEE2S6mY.mjs} +4 -4
- package/dist/{login-pV69H-ZO.mjs → login-Uvferzmm.mjs} +28 -10
- package/dist/{logs-DFHHD6wE.mjs → logs-27FenuiC.mjs} +4 -4
- package/dist/{mime-BJD7d_qL.mjs → mime-D5Nmdzf7.mjs} +23 -9
- package/dist/{node-Dk3H2jmU.mjs → node-Ez5KW5rn.mjs} +2 -2
- package/dist/operator-auth-B3e08unv.mjs +52 -0
- package/dist/operator-client-LUZnlnYk.mjs +82 -0
- package/dist/{operator-cmd-DYWRbWUA.mjs → operator-cmd-CjOTmAYE.mjs} +35 -55
- package/dist/{output-tFQLLj26.mjs → output-B0cfNSx5.mjs} +316 -2
- package/dist/pages/index.mjs +2 -2
- package/dist/platform-auth-config-DrbQXXiW.mjs +368 -0
- package/dist/platform-auth-protection-Bhtvp0B_.mjs +219 -0
- package/dist/platform-auth-recovery-CeOKGVeJ.mjs +310 -0
- package/dist/{platform-cmd-DxJ2FRwR.mjs → platform-cmd-BFhieCdV.mjs} +16 -6
- package/dist/{platform-domain-ChvbJkdy.mjs → platform-domain-C74PULqV.mjs} +4 -4
- package/dist/{platform-lifecycle-DN4MzJF_.mjs → platform-lifecycle-BwAIgz-t.mjs} +1667 -191
- package/dist/{platform-management-Db2PXw0B.mjs → platform-management-COogu_Se.mjs} +33 -7
- package/dist/{platform-recovery-C_YO-tIs.mjs → platform-recovery-ewqLefp1.mjs} +6 -5
- package/dist/{prepare-CBetXvsN.mjs → prepare-CtDJjoOj.mjs} +2 -2
- package/dist/{prepare-BfJvFUtJ.mjs → prepare-blNRQvQl.mjs} +2 -2
- package/dist/prerender-render.d.mts +11 -0
- package/dist/prerender-render.mjs +111 -0
- package/dist/{project-cmd-Mo0V9yKS.mjs → project-cmd-DmZK9Hxf.mjs} +32 -14
- package/dist/project-team-D8jOJMUJ.mjs +130 -0
- package/dist/project-token-DA34bf-C.mjs +75 -0
- package/dist/{provision-Blnstcm2.mjs → provision-CSJOjjQk.mjs} +2 -0
- package/dist/{requests-BcKOVpRg.mjs → requests-CUExwGQQ.mjs} +3 -3
- package/dist/{rollback-Bx85-0xh.mjs → rollback-CDNGU1gr.mjs} +4 -4
- package/dist/runtime/ai.mjs +3 -2
- package/dist/runtime/email/testing.d.mts +1 -1
- package/dist/runtime/email/testing.mjs +3 -3
- package/dist/runtime/email-protocol.d.mts +15 -0
- package/dist/runtime/email-protocol.mjs +70 -0
- package/dist/runtime/email.d.mts +2 -2
- package/dist/runtime/email.mjs +189 -96
- package/dist/runtime/remote/index.mjs +5 -3
- package/dist/{secret-ByhJ9AMl.mjs → secret-Bzzi2e9E.mjs} +5 -5
- package/dist/{skills-Q46GZMO-.mjs → skills-C0RvGjeE.mjs} +1 -1
- package/dist/{subcommand-prompt-WfySCQ7S.mjs → subcommand-prompt-Bmyn5Rlc.mjs} +1 -1
- package/package.json +12 -7
- package/skills/void/SKILL.md +35 -4
- package/skills/void/docs/guide/deployment.md +2 -0
- package/skills/void/docs/guide/email.md +102 -110
- package/skills/void/docs/guide/platform-administration.md +214 -2
- package/skills/void/docs/guide/platform-development.md +64 -2
- package/skills/void/docs/guide/project-collaboration.md +94 -0
- package/skills/void/docs/guide/self-hosted-platform.md +184 -30
- package/skills/void/docs/reference/cli.md +249 -21
- package/dist/cf-access-AJ1ehiFR.mjs +0 -42
- package/dist/cf-access-DsSsZUPr.mjs +0 -67
- package/dist/email-uKyQYUVY.mjs +0 -1016
|
@@ -41,7 +41,7 @@ Use this page as a command reference. If you are setting up a project for the fi
|
|
|
41
41
|
| `void build logs` | Stream, tail, or download build logs |
|
|
42
42
|
| `void email status` | Show email readiness on your own Cloudflare account (`--platform cloudflare`) |
|
|
43
43
|
| `void email setup` | Set email up on your own Cloudflare account, without deploying |
|
|
44
|
-
| `void email usage` | Show monthly
|
|
44
|
+
| `void email usage` | Show monthly recipient attempts, inbound receipts, and quota |
|
|
45
45
|
| `void email logs` | Show recent email delivery activity |
|
|
46
46
|
| `void email destinations` | List verified recipient addresses |
|
|
47
47
|
| `void email allow <address>` | Add a recipient and send a verification email |
|
|
@@ -166,7 +166,7 @@ In a non-interactive shell, supply a URL or explicit target. Cloudflare requires
|
|
|
166
166
|
|
|
167
167
|
### `void auth login`
|
|
168
168
|
|
|
169
|
-
|
|
169
|
+
Browser login through one of the platform's currently enabled methods. The token is saved in the operating-system keychain, scoped to the platform origin. Login fails closed when no keychain is available instead of writing the token to a plaintext file; headless environments use `VOID_TOKEN` from their secret manager.
|
|
170
170
|
|
|
171
171
|
Set `VOID_API_URL` alongside `VOID_TOKEN` to identify the platform that issued it.
|
|
172
172
|
A token without an API URL is only used for Void Cloud's production API; a saved
|
|
@@ -175,6 +175,13 @@ saved login instead, unset `VOID_TOKEN`.
|
|
|
175
175
|
|
|
176
176
|
This is optional if you already completed auth during `void connect` or the interactive `void init` flow.
|
|
177
177
|
|
|
178
|
+
### `void auth link [connection-id]`
|
|
179
|
+
|
|
180
|
+
Link another enabled login method to your current account. Sign in again if your
|
|
181
|
+
session is no longer recent, complete the additional provider's browser login,
|
|
182
|
+
and confirm the displayed identity. With no connection ID, choose an enabled
|
|
183
|
+
method interactively. The optional dashboard exposes the same flow in **Account**.
|
|
184
|
+
|
|
178
185
|
### `void auth logout`
|
|
179
186
|
|
|
180
187
|
Removes saved credentials.
|
|
@@ -185,7 +192,11 @@ Prints your current login.
|
|
|
185
192
|
|
|
186
193
|
### `void auth token`
|
|
187
194
|
|
|
188
|
-
Copies your auth token to the system clipboard.
|
|
195
|
+
Copies your human auth token to the system clipboard. It is intended for
|
|
196
|
+
interactive troubleshooting and remains subject to login-method revocation. Do
|
|
197
|
+
not combine it with a Cloudflare Access service token for CI; machine Access
|
|
198
|
+
proof cannot turn a human Void token into an automation identity. Create a
|
|
199
|
+
project-scoped credential with `void project token create` instead.
|
|
189
200
|
|
|
190
201
|
## Cloudflare authentication
|
|
191
202
|
|
|
@@ -217,7 +228,80 @@ Link current directory to an existing hosted Void project by slug, or select int
|
|
|
217
228
|
|
|
218
229
|
### `void project list`
|
|
219
230
|
|
|
220
|
-
List all hosted projects (slug,
|
|
231
|
+
List all accessible hosted projects (slug, role, type, URL). Shared projects are included and the role column distinguishes them from projects you own. For a saved Cloudflare target, this displays the current Worker's versions instead because there is no Void project registry.
|
|
232
|
+
|
|
233
|
+
### `void project team`
|
|
234
|
+
|
|
235
|
+
Manage access to a project hosted on a Void platform:
|
|
236
|
+
|
|
237
|
+
```sh
|
|
238
|
+
void project team list [--project <slug>]
|
|
239
|
+
void project team invite <email> --role <reader|collaborator|admin> [--project <slug>]
|
|
240
|
+
void project team invitations [--project <slug>]
|
|
241
|
+
void project team role <user-id> <reader|collaborator|admin> [--project <slug>]
|
|
242
|
+
void project team remove <user-id> [--project <slug>]
|
|
243
|
+
void project team revoke <invitation-id> [--project <slug>]
|
|
244
|
+
void project team leave [--project <slug>]
|
|
245
|
+
void project team pending
|
|
246
|
+
void project team accept <invitation-id>
|
|
247
|
+
void project team decline <invitation-id>
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Project-scoped commands use `--project`, then `VOID_PROJECT`, then the linked project. Invitations can target only an email address already registered to a user on that platform; they do not create accounts or grant signup access. Only the invited account can accept or decline its invitation.
|
|
251
|
+
|
|
252
|
+
Readers can view the project but cannot deploy. Collaborators can deploy and manage deploy prerequisites. Project administrators can additionally manage domains, email destinations, GitHub configuration, and the project team. The owner alone can delete the project. See [Project Collaboration](../guide/project-collaboration.md) for the full role boundaries.
|
|
253
|
+
|
|
254
|
+
Project-scoped team management commands are not available for projects deployed
|
|
255
|
+
directly to Cloudflare. The account-scoped `pending`, `accept`, and `decline`
|
|
256
|
+
commands use the active connection selected by `void connect <url>`, regardless
|
|
257
|
+
of the current project's link or deploy target. `VOID_API_URL` takes precedence;
|
|
258
|
+
an unscoped `VOID_TOKEN` selects Void Cloud. These commands display their
|
|
259
|
+
platform, and accepting an invitation leaves directory links intact. To link
|
|
260
|
+
the invited application, run `void project link` in an unlinked checkout of
|
|
261
|
+
that application.
|
|
262
|
+
|
|
263
|
+
### `void project token <create|list|renew|revoke>`
|
|
264
|
+
|
|
265
|
+
Manage revocable `aud: deploy` credentials for one Void platform project. The
|
|
266
|
+
credential can only call the endpoints used by `void deploy`; it cannot access
|
|
267
|
+
operator, account, secret-writing, project-deletion, or other projects' routes.
|
|
268
|
+
|
|
269
|
+
```sh
|
|
270
|
+
void project token create --name github-actions --expires-in 30
|
|
271
|
+
void project token list
|
|
272
|
+
void project token renew <credential-id> --expires-in 30
|
|
273
|
+
void project token revoke <credential-id>
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Pass `--project <name>` outside a linked project. Expiry is bounded to 1–90
|
|
277
|
+
days. Create and renew display the bearer value once; replace the stored secret
|
|
278
|
+
immediately after renewal because the previous credential is revoked in the
|
|
279
|
+
same operation. Project deletion and owner suspension also stop its use. Login
|
|
280
|
+
method disablement does not revoke these independent deploy credentials.
|
|
281
|
+
|
|
282
|
+
Store the printed `VOID_TOKEN` and `VOID_API_URL` in the CI secret manager. The
|
|
283
|
+
Access pair passes the perimeter; the scoped Void credential authorizes only
|
|
284
|
+
this project's deploy workflow. When prerendering or remote proxy bindings are
|
|
285
|
+
used on an Access-protected platform, store `VOID_ACCESS_CREDENTIALS` as an
|
|
286
|
+
origin-keyed JSON secret containing both exact HTTPS origins, even if both use
|
|
287
|
+
the same service-token pair:
|
|
288
|
+
|
|
289
|
+
```json
|
|
290
|
+
{
|
|
291
|
+
"https://void-company-api.example.workers.dev": {
|
|
292
|
+
"CF_ACCESS_CLIENT_ID": "<service-token client ID>",
|
|
293
|
+
"CF_ACCESS_CLIENT_SECRET": "<service-token client secret>"
|
|
294
|
+
},
|
|
295
|
+
"https://void-company-proxy.example.workers.dev": {
|
|
296
|
+
"CF_ACCESS_CLIENT_ID": "<service-token client ID>",
|
|
297
|
+
"CF_ACCESS_CLIENT_SECRET": "<service-token client secret>"
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
`VOID_ACCESS_ORIGIN` scopes a pair to one origin, so selecting only the API
|
|
303
|
+
origin is insufficient for a workflow that calls the proxy. Use distinct pairs
|
|
304
|
+
in the two entries when the Access policies require them.
|
|
221
305
|
|
|
222
306
|
### `void project logs`
|
|
223
307
|
|
|
@@ -362,13 +446,78 @@ Void does not automatically retry changes. If a request loses its connection or
|
|
|
362
446
|
Sign in, inspect your session, or sign out:
|
|
363
447
|
|
|
364
448
|
```sh
|
|
365
|
-
void platform auth login [--provider
|
|
449
|
+
void platform auth login [--provider <connection-id>] [--token-stdin]
|
|
366
450
|
void platform auth status
|
|
367
451
|
void platform auth logout
|
|
368
452
|
void platform auth token [--token-stdin]
|
|
369
453
|
```
|
|
370
454
|
|
|
371
|
-
|
|
455
|
+
With no `--provider`, browser login offers the platform's enabled login methods.
|
|
456
|
+
|
|
457
|
+
#### Authentication configuration
|
|
458
|
+
|
|
459
|
+
`void platform config auth` opens interactive configuration. These commands use
|
|
460
|
+
your administrator session from `void platform auth login`:
|
|
461
|
+
|
|
462
|
+
```sh
|
|
463
|
+
void platform config auth list
|
|
464
|
+
void platform config auth show company
|
|
465
|
+
void platform config auth add google
|
|
466
|
+
void platform config auth add oidc --id company
|
|
467
|
+
void platform config auth add cloudflare-access --id access
|
|
468
|
+
void platform config auth configure company
|
|
469
|
+
void platform config auth test company
|
|
470
|
+
void platform config auth link company
|
|
471
|
+
void platform config auth enable company
|
|
472
|
+
void platform config auth disable github
|
|
473
|
+
void platform config auth admission
|
|
474
|
+
void platform config auth protection show
|
|
475
|
+
void platform config auth protection enable --installation <id>
|
|
476
|
+
void platform config auth protection disable --installation <id>
|
|
477
|
+
void platform config auth recover company --installation <id> --file recovery.json
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
When configuring an existing installation for the first time, run
|
|
481
|
+
`void platform config auth initialize`, then sign in again. Its current login
|
|
482
|
+
methods and signup policy are preserved.
|
|
483
|
+
|
|
484
|
+
Adding or editing a method saves a pending configuration. Enabling it verifies the
|
|
485
|
+
login in your browser before applying it. Linking the verified identity to your
|
|
486
|
+
account is a separate, explicit action. Before disabling a method, verify a linked
|
|
487
|
+
alternative; the last method cannot be disabled. Disabling revokes human sessions
|
|
488
|
+
created through that method, including operator sessions. Scoped deployment tokens
|
|
489
|
+
remain valid; a human login token used as `VOID_TOKEN` is still revoked.
|
|
490
|
+
|
|
491
|
+
Commands accept `--connection <registered-id-or-url>` and `--json`. Changes accept
|
|
492
|
+
`--plan` or `--yes`. For scripted configuration, use `--file <path>` for the
|
|
493
|
+
nonsecret fields and `--client-secret-env <name>` for the environment variable
|
|
494
|
+
containing the secret. Omit the secret when editing to retain its saved value.
|
|
495
|
+
For `enable` or `link` in scripts, supply `--test-id <id>` from a completed test.
|
|
496
|
+
`test --json` returns a browser URL, test ID, and expiry without waiting for completion.
|
|
497
|
+
|
|
498
|
+
`admission` chooses invited/allowlisted, company-approved, or public signup.
|
|
499
|
+
Company-approved signup creates ordinary accounts automatically when a user
|
|
500
|
+
passes a configured company rule. Select an enabled, company-restricted OIDC or
|
|
501
|
+
Google Workspace method, or an enabled Cloudflare Access gate. In scripts,
|
|
502
|
+
`admission --file <path> --yes` reads a policy such as
|
|
503
|
+
`{"mode":"company","connections":["company"],"access":false}`.
|
|
504
|
+
|
|
505
|
+
Browser login offers the platform's enabled methods; `--provider <connection-id>` selects one. Login saves a one-hour administrator session in your system keychain. Logout revokes that session and removes its local credential.
|
|
506
|
+
|
|
507
|
+
`protection enable` creates or connects Cloudflare Access applications independently
|
|
508
|
+
of login methods. Its `--file` accepts the `cloudflareAccess` object described in
|
|
509
|
+
[installation setup](../guide/self-hosted-platform.md#configure-github-oauth).
|
|
510
|
+
Protection changes require installation ownership, the saved recovery credentials,
|
|
511
|
+
and a human administrator session. They revoke current human sessions. Before
|
|
512
|
+
removing protection, change any signup rule that depends on that gate. Cloudflare
|
|
513
|
+
applications are retained for deliberate cleanup.
|
|
514
|
+
|
|
515
|
+
`recover <connection-id>` restores an existing administrator when normal login is
|
|
516
|
+
unavailable. Its file contains `administratorUserId`, optional nonsecret provider
|
|
517
|
+
`configuration`, and an `expectedIdentity` object with exact `issuer` and `subject`
|
|
518
|
+
when using `--yes`. Recovery requires Cloudflare management/database authority,
|
|
519
|
+
original recovery keys, and a successful browser provider test. Use
|
|
520
|
+
`--client-secret-env <name>` for new or rotated credentials.
|
|
372
521
|
|
|
373
522
|
`auth token` prints your current operator token. With `--token-stdin`, it exchanges a full administrator API login session from standard input for a new operator token. `auth login --token-stdin` saves the exchanged token to the keychain instead of printing it.
|
|
374
523
|
|
|
@@ -407,10 +556,13 @@ List projects across the platform, filter them by owner, or inspect one project'
|
|
|
407
556
|
void platform project list [--user <user-id>] [--search <text>] [--page <n>] [--limit <n>]
|
|
408
557
|
void platform project show <id>
|
|
409
558
|
void platform project delete <id>
|
|
559
|
+
void platform project owner <project-id> <user-id>
|
|
410
560
|
```
|
|
411
561
|
|
|
412
562
|
Search matches a project's slug, ID, or owner's login. `show` includes resources, domains, the latest 10 deployments, and the latest 20 builds. `delete` removes the project and its resources.
|
|
413
563
|
|
|
564
|
+
`owner` transfers a project to another registered user. Preview it with `--plan`; apply it interactively or with `--yes`. The preview reports active-work blockers and the account plan that will apply. The former owner becomes a project administrator, existing project-scoped CI deploy credentials are revoked, and usage already incurred remains with the former owner.
|
|
565
|
+
|
|
414
566
|
#### Deployments {#operator-deployments}
|
|
415
567
|
|
|
416
568
|
Find a deployment, inspect its manifest, or request cancellation:
|
|
@@ -456,14 +608,24 @@ void platform signup open
|
|
|
456
608
|
void platform signup restrict
|
|
457
609
|
```
|
|
458
610
|
|
|
459
|
-
Add and remove entries by their type and pattern:
|
|
611
|
+
Add and remove GitHub or email entries by their type and pattern:
|
|
460
612
|
|
|
461
613
|
```sh
|
|
462
614
|
void platform signup allow <github|email> <pattern> [--note <text>]
|
|
615
|
+
void platform signup disallow <github|email> <pattern>
|
|
463
616
|
void platform signup remove <github|email> <pattern>
|
|
464
617
|
```
|
|
465
618
|
|
|
466
|
-
GitHub entries match a login. Email entries match an address or a domain pattern such as `*@example.com`, across sign-in providers. Quote wildcard patterns in your shell.
|
|
619
|
+
`remove` remains available as an alias for existing scripts. GitHub entries match a login. Email entries match an address or a domain pattern such as `*@example.com`, across sign-in providers. Quote wildcard patterns in your shell.
|
|
620
|
+
|
|
621
|
+
For an OIDC identity that has no verified email, grant access using its configured connection ID and stable provider subject:
|
|
622
|
+
|
|
623
|
+
```sh
|
|
624
|
+
void platform signup allow identity <connection-id> <subject> [--note <text>]
|
|
625
|
+
void platform signup disallow identity <connection-id> <subject>
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
Connection IDs are shown by `void platform config auth list`. Identity subjects match exactly and case-sensitively; wildcards, email inference, and account linking are not applied. The login method's domain or group restrictions must still pass, and a newly admitted account has the ordinary user role. With restrictions enabled and an empty allowlist, nobody new can sign up.
|
|
467
629
|
|
|
468
630
|
#### Invitations {#operator-invitations}
|
|
469
631
|
|
|
@@ -477,6 +639,61 @@ void platform invitation revoke <id>
|
|
|
477
639
|
|
|
478
640
|
Send accepts up to 100 comma-separated addresses. Invitations grant signup access even if email delivery is unavailable or fails; delivery is reported separately. Revoking a pending invitation removes its exact email grant. A broader domain entry can still allow that person to sign up.
|
|
479
641
|
|
|
642
|
+
#### Email {#operator-email}
|
|
643
|
+
|
|
644
|
+
Decide who mail from the shared sender may reach, who registers email domains, and a project's outbound caps:
|
|
645
|
+
|
|
646
|
+
```sh
|
|
647
|
+
void platform email policy
|
|
648
|
+
void platform email policy-set <verified|domains|any> [--domains <domain[,domain...]>]
|
|
649
|
+
void platform email settings
|
|
650
|
+
void platform email settings-set --domains <self-serve|admin>
|
|
651
|
+
void platform email limit <project-id|slug> [--monthly <n>] [--burst <n>]
|
|
652
|
+
void platform email logs <project-id|slug> [--page <n>] [--limit <n>] [--json]
|
|
653
|
+
void platform email attempts [--project <id|slug>] [--page <n>] [--limit <n>]
|
|
654
|
+
void platform email attempt-resolve <attempt-id> --ended --reason <text>
|
|
655
|
+
void platform email operation-resolve <operation-id> --ended --outcome <applied|not-applied> --reason <text>
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
`policy` decides which recipients a project's `<slug>+tag@<mail domain>` sender reaches: `verified` (the default) means only that project's verified destinations; `domains` adds every address on the listed domains; `any` lifts the check. Neither widens delivery to addresses on the platform's own mail domain: those stay verified-destination-only, so no project reaches another project's inbox without its consent. Cloudflare still refuses a destination it has not verified until the platform mail domain is onboarded for Email Sending, so under `domains` or `any` such refusals arrive as per-recipient `UNVERIFIED_DESTINATION` results. Custom-domain sends are not affected.
|
|
659
|
+
|
|
660
|
+
`settings-set --domains admin` tells `void email domain add` to print the administrator's command instead of starting token setup. `limit` overrides the project's monthly and rolling 60-second caps (defaults 200 and 10); a project page in the admin UI shows and clears them.
|
|
661
|
+
|
|
662
|
+
`logs` inspects retained receipt and recipient outcomes, including operation IDs, provider references, error codes, and policy versions. Pages contain at most 100 records, newest first; use `--json` for all fields. After project deletion, use its project ID to inspect metadata until the 30-day retention period expires. Message content and credentials are never included.
|
|
663
|
+
|
|
664
|
+
`attempts` lists interrupted provider calls and their earliest resolution time. Once
|
|
665
|
+
the original Worker execution has ended and the attempt is at least 24 hours old,
|
|
666
|
+
`attempt-resolve` records `outcome_unknown`, retains its quota charge, and releases
|
|
667
|
+
the project/domain cleanup fence. `--ended` is your attestation that the call is no
|
|
668
|
+
longer active; `--reason` is stored in the operator audit log. Keep recipient
|
|
669
|
+
addresses and message content out of the reason. The send is never retried. Use
|
|
670
|
+
`--plan` to preview and `--yes` to apply without a prompt.
|
|
671
|
+
|
|
672
|
+
`operation-resolve` recovers a Cloudflare routing, Worker, secret, catch-all, or
|
|
673
|
+
Sending mutation whose outcome remains unknown. After the original execution
|
|
674
|
+
has ended and the operation is at least 24 hours old, inspect the exact resource
|
|
675
|
+
named by the preview and attest whether its write was `applied` or `not-applied`.
|
|
676
|
+
Applied writes continue at the next step; not-applied writes retry the same
|
|
677
|
+
persisted intent. The running platform version must match that intent, so restore
|
|
678
|
+
the matching version before recovering an operation created by older code. The
|
|
679
|
+
preview pins the step, attempt, connection and route generations, resource
|
|
680
|
+
identity, and digest used by the apply request. Time alone never retries a write.
|
|
681
|
+
|
|
682
|
+
Register and maintain email domains for projects whose owners hold no Cloudflare credential:
|
|
683
|
+
|
|
684
|
+
```sh
|
|
685
|
+
void platform email domains [--project <id|slug>]
|
|
686
|
+
void platform email domain-add <domain> --project <id|slug> [--token-stdin]
|
|
687
|
+
void platform email domain-status <domain>
|
|
688
|
+
void platform email domain-sync <domain>
|
|
689
|
+
void platform email domain-rotate-secret <domain>
|
|
690
|
+
void platform email domain-remove <domain> [--token-stdin]
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
`domain-add` uses the platform's Cloudflare credential for zones in its account. For another account, pipe a scoped Cloudflare API token on standard input with `--token-stdin --yes`. Name the exact mail domain (`mail.example.com`, or the apex when it receives no mail yet). `domain-status` shows inbound, outbound, and credential-management readiness with the latest operation. A blocked operation resumes through `domain-sync`; a blocked rotation resumes through `domain-rotate-secret`, preserving already confirmed steps and its staged credential. An uncertain operation remains stopped until read-back proves the result or an administrator uses `operation-resolve`. Domains an administrator adds show `managed_by: admin`; their owners can list and inspect them but use these commands for `sync`, `domain-rotate-secret`, and `remove`.
|
|
694
|
+
|
|
695
|
+
If project deletion leaves cleanup blocked by an expired or revoked Cloudflare token, use `domain-remove <domain> --token-stdin --yes` with a replacement scoped to the same account and zone. This resumes the retained cleanup only when no other project uses the connection. For a live project, renew its token through `domain-add` instead.
|
|
696
|
+
|
|
480
697
|
#### System {#operator-system}
|
|
481
698
|
|
|
482
699
|
Inspect activity, check service health, or review administrative changes:
|
|
@@ -517,6 +734,7 @@ void platform install [options] [--yes]
|
|
|
517
734
|
| `--name <slug>` | Installation name used in `void-<name>-<role>` resource names; choose an unused name |
|
|
518
735
|
| `--display-name <name>` | Human-readable platform name |
|
|
519
736
|
| `--account <id>` | Cloudflare account id |
|
|
737
|
+
| `--auth-config <path>` | Login methods, signup policy, and environment references for provider secrets |
|
|
520
738
|
| `--application-domain <domain>` | Base domain for deployed apps |
|
|
521
739
|
| `--workers-dev` | Explicit testing mode; add an application domain later |
|
|
522
740
|
| `--zone <domain>` | Cloudflare zone containing the application domain |
|
|
@@ -533,7 +751,9 @@ Read-only plans, workers.dev installations with the default API hostname, and su
|
|
|
533
751
|
|
|
534
752
|
The installed platform needs a separate runtime token to provision resources for apps. The interactive installer prompts for it and the other setup values. For non-interactive installs, inject the variables listed in [Install from CI](../guide/self-hosted-platform.md#install-from-ci).
|
|
535
753
|
|
|
536
|
-
|
|
754
|
+
To enable email during install or upgrade, set both `VOID_EMAIL_SENDER_DOMAIN` and `VOID_EMAIL_SHARED_ZONE_ID`. Void records the pair for later upgrades; supplying only one is an error.
|
|
755
|
+
|
|
756
|
+
`--plan` prints the actual resource names, selected login methods, login callback, and direct setup links without opening credential pages or saving a draft; Cloudflare browser login still opens if needed. New platform resources use `void-<name>-<role>` names without random suffixes. Existing installations keep their recorded names, and unowned name conflicts stop installation without overwriting resources. After you confirm an interactive install, Void opens each missing credential's setup page and shows a short permission/checklist fallback. The runtime-token link preselects all required account permissions, including Workers Tail, Hyperdrive, and AI Gateway when needed; domain installations must also select the indicated zone. Supplied credentials skip browser opening. Setup drafts pin Worker names and the login callback and save partial credentials encrypted locally. Interactive installs list unfinished installations, including interrupted provisioning, or offer a new install. Entering an existing unfinished name asks to resume it; declining returns to name entry. Starting new leaves previous setup, credentials, and resources untouched. Completed platforms are not offered for resumption. `--resume` skips the choice and is required for non-interactive recovery.
|
|
537
757
|
|
|
538
758
|
Use an empty PostgreSQL database dedicated to the installation. You can correct a failed initial connection, but after the database is claimed or Hyperdrive is provisioned, commands reject a different URL.
|
|
539
759
|
|
|
@@ -575,7 +795,7 @@ void platform uninstall [id] [--plan] [--purge-data] [--keep-zone] [--yes]
|
|
|
575
795
|
|
|
576
796
|
Omit `id` when only one installation is configured, or choose from the interactive picker. Non-interactive commands need an ID when several installations exist. Commands that make changes also require `--yes`; `--plan` only previews changes.
|
|
577
797
|
|
|
578
|
-
After discovery on another machine, set `VOID_PLATFORM_DATABASE_URL`.
|
|
798
|
+
After discovery on another machine, set `VOID_PLATFORM_DATABASE_URL`. An upgrade that preserves every deployed Worker also preserves its secrets. For an email-enabled installation without its encrypted recovery file, restore `VOID_PLATFORM_EMAIL_SIGNING_SECRET`; recreating only the email gateway needs that key and does not need the Cloudflare runtime token or JWT signing key. Recreating the API or proxy also requires the email key when email is enabled, in addition to their normal secrets. Recreating the API requires its original runtime-token, GitHub, R2, JWT, and project-encryption values; recreating the proxy requires the runtime token and JWT signing key.
|
|
579
799
|
|
|
580
800
|
| Command | Behavior |
|
|
581
801
|
| ----------- | --------------------------------------------------------------------------------------------- |
|
|
@@ -599,7 +819,7 @@ Platform migrations only move forward. Void checks compatibility before updating
|
|
|
599
819
|
|
|
600
820
|
An upgrade completes after the new Workers pass health checks. If rollout fails, Void attempts to restore the previous Workers. Retrying does not repeat completed migrations.
|
|
601
821
|
|
|
602
|
-
`platform rollback` restores a compatible earlier runtime without reversing database migrations. Pass its files with `--runtime`. If the installed version is a custom build, also supply that version with `--from-runtime`. Void refuses
|
|
822
|
+
`platform rollback` restores a compatible earlier runtime without reversing database migrations. Pass its files with `--runtime`. If the installed version is a custom build, also supply that version with `--from-runtime`. Void refuses targets that are incompatible with the current database or predate installed authentication, sandbox-drain, or ownership-aware usage protocols. A later `upgrade` can move forward again.
|
|
603
823
|
|
|
604
824
|
Uninstall verifies remote ownership before removing anything. Data resources are retained unless you pass `--purge-data`. Workers, R2, AI Gateway, DNS records, routes, custom domains, adopted resources, external PostgreSQL, and zones are always retained for manual review.
|
|
605
825
|
|
|
@@ -725,7 +945,7 @@ Provisioning reuses known resource IDs and writes newly resolved IDs into `wrang
|
|
|
725
945
|
|
|
726
946
|
Existing remote secrets are preserved. Void also preserves or creates `BETTER_AUTH_SECRET` for auth apps.
|
|
727
947
|
|
|
728
|
-
**Email.** When the app uses email (`sendEmail()` or `email/` handlers) and `void.json` has `email.from`, the deploy reads the state of that address's zone before the build — session scopes, zone, MX records, Email Routing, subaddressing, routing rules, Email Sending, and what `wrangler.jsonc` holds — prints a checklist of what it would change in your account, and asks once (default Yes). On Yes it enables what is missing, writes `send_email: [{ "name": "SEND_EMAIL" }]`, the `__VOID_EMAIL_FROM` var and the `addresses` array into `wrangler.jsonc`, and lets wrangler create the routing rules when the activated version's triggers are synchronized; the deploy ends with the address map. A deploy with nothing left to set up asks nothing. Without `email.from` the deploy prints `add "email": { "from": "you@mail.acme.com" } to void.json` and continues without email. Non-interactive runs (CI, or stdin/stdout not a terminal) never prompt: they print the checklist plus `Run void email setup --platform cloudflare once locally, commit wrangler.jsonc, then redeploy` and deploy without email (or with the setup `wrangler.jsonc` already carries, when the binding is committed
|
|
948
|
+
**Email.** When the app uses email (`sendEmail()` or `email/` handlers) and `void.json` has `email.from`, the deploy reads the state of that address's zone before the build — session scopes, zone, MX records, Email Routing, subaddressing, routing rules, Email Sending, and what `wrangler.jsonc` holds — prints a checklist of what it would change in your account, and asks once (default Yes). On Yes it enables what is missing, writes `send_email: [{ "name": "SEND_EMAIL" }]`, the `__VOID_EMAIL_FROM` var and the `addresses` array into `wrangler.jsonc`, and lets wrangler create the routing rules when the activated version's triggers are synchronized; the deploy ends with the address map. A deploy with nothing left to set up asks nothing. Without `email.from` the deploy prints `add "email": { "from": "you@mail.acme.com" } to void.json` and continues without email. Non-interactive runs (CI, or stdin/stdout not a terminal) never prompt: they print the checklist plus `Run void email setup --platform cloudflare once locally, commit wrangler.jsonc, then redeploy` and deploy without email (or with the setup `wrangler.jsonc` already carries, when the binding is committed) — unless `--require-email` is passed, which fails instead. If setup has committed the exact subdomain `addresses` plan but the deploy's resolver still sees no MX records, Void preserves the plan and stops before build or upload until DNS can be verified. A deploy whose account rows all read ready reconciles the two config rows — `addresses` against the current derivation and `vars.__VOID_EMAIL_FROM` against `email.from` — with a plain file write and no prompt. See [Your own Cloudflare account](../guide/email.md#your-own-cloudflare-account) for the whole flow, including the subdomain-vs-apex rule and what stays manual.
|
|
729
949
|
|
|
730
950
|
See the [Cloudflare guide](../integrations/cloudflare.md#deploy-to-your-own-cloudflare-account) for the complete deployment sequence, first-deploy exceptions, secret precedence, and recovery behavior.
|
|
731
951
|
|
|
@@ -1286,7 +1506,7 @@ Project resolution for email commands follows the same order as deploy (`--proje
|
|
|
1286
1506
|
void email usage [--project <name>]
|
|
1287
1507
|
```
|
|
1288
1508
|
|
|
1289
|
-
Show the current month's
|
|
1509
|
+
Show the current month's recipient attempts and inbound receipts, the monthly attempt limit, and how much of it is left. Reserved submissions count toward the limit; started attempts remain charged even if delivery fails or its outcome is unknown. A suspended project is flagged in the output.
|
|
1290
1510
|
|
|
1291
1511
|
### `void email logs`
|
|
1292
1512
|
|
|
@@ -1294,7 +1514,7 @@ Show the current month's outbound and inbound counts, the monthly outbound limit
|
|
|
1294
1514
|
void email logs [--limit <n>] [--project <name>]
|
|
1295
1515
|
```
|
|
1296
1516
|
|
|
1297
|
-
Show recent email
|
|
1517
|
+
Show recent email operation metadata retained for 30 days: timestamp, direction, operation ID, recipient, and state. `--limit` accepts 1–100. Subjects, bodies, and attachments are not stored. Provider acceptance does not confirm mailbox delivery; inspect unknown outcomes before retrying.
|
|
1298
1518
|
|
|
1299
1519
|
### `void email destinations`
|
|
1300
1520
|
|
|
@@ -1320,12 +1540,12 @@ The project owner's email is added automatically when the project is created, so
|
|
|
1320
1540
|
void email disallow <address> [--project <name>]
|
|
1321
1541
|
```
|
|
1322
1542
|
|
|
1323
|
-
Remove one recipient from the project's destination list.
|
|
1543
|
+
Remove one recipient from the project's destination list. New sends to that address are refused immediately; previously admitted attempts may finish. No deploy is involved.
|
|
1324
1544
|
|
|
1325
1545
|
### `void email domain`
|
|
1326
1546
|
|
|
1327
1547
|
```
|
|
1328
|
-
void email domain <add|status|list|sync|remove> [<domain>] [--project <name>]
|
|
1548
|
+
void email domain <add|status|list|sync|rotate-secret|remove> [<domain>] [--project <name>]
|
|
1329
1549
|
```
|
|
1330
1550
|
|
|
1331
1551
|
Send and receive at your own domain on a Cloudflare zone you own, registered to the project. Void platform only — on your own Cloudflare account the mail domain comes from `email.from` instead (see `void email setup`). The walkthrough is [Your own domain on the platform](../guide/email.md#your-own-domain-on-the-platform).
|
|
@@ -1336,7 +1556,7 @@ Send and receive at your own domain on a Cloudflare zone you own, registered to
|
|
|
1336
1556
|
void email domain add <domain> [--subdomain <label|host>] [--project <name>]
|
|
1337
1557
|
```
|
|
1338
1558
|
|
|
1339
|
-
Register
|
|
1559
|
+
Register an exact domain with the project using a scoped Cloudflare API token. The CLI opens a token template, accepts a masked paste or newly copied token, and asks you to confirm account and zone restrictions. Credentials are encrypted for the zone connection. The CLI proposes `mail.<domain>` when the apex already has MX records; `--subdomain` overrides that proposal. Several domains can share a zone connection, but each domain belongs to one project. Setup returns an operation ID so an interrupted request can be checked without restarting the operation.
|
|
1340
1560
|
|
|
1341
1561
|
#### `void email domain status`
|
|
1342
1562
|
|
|
@@ -1344,7 +1564,7 @@ Register the domain with the project. One credential is required, granted two wa
|
|
|
1344
1564
|
void email domain status <domain> [--project <name>]
|
|
1345
1565
|
```
|
|
1346
1566
|
|
|
1347
|
-
Show
|
|
1567
|
+
Show the recorded inbound, outbound, and management readiness, observation times, and latest operation. Use `sync` to reconcile setup and refresh readiness.
|
|
1348
1568
|
|
|
1349
1569
|
#### `void email domain list`
|
|
1350
1570
|
|
|
@@ -1352,7 +1572,7 @@ Show one registered domain. The platform re-probes the stored credential and the
|
|
|
1352
1572
|
void email domain list [--project <name>]
|
|
1353
1573
|
```
|
|
1354
1574
|
|
|
1355
|
-
List the project's registered email domains
|
|
1575
|
+
List the project's registered email domains and readiness.
|
|
1356
1576
|
|
|
1357
1577
|
#### `void email domain sync`
|
|
1358
1578
|
|
|
@@ -1360,7 +1580,15 @@ List the project's registered email domains with their status and mode.
|
|
|
1360
1580
|
void email domain sync <domain> [--project <name>]
|
|
1361
1581
|
```
|
|
1362
1582
|
|
|
1363
|
-
|
|
1583
|
+
Reconcile the domain connection and refresh readiness. Sync does not rotate its secret. A blocked or uncertain operation exits unsuccessfully and names the operation to inspect.
|
|
1584
|
+
|
|
1585
|
+
#### `void email domain rotate-secret`
|
|
1586
|
+
|
|
1587
|
+
```sh
|
|
1588
|
+
void email domain rotate-secret <domain> [--project <name>]
|
|
1589
|
+
```
|
|
1590
|
+
|
|
1591
|
+
Rotate the ingress secret for the zone connection shared by this domain and its siblings. Inbound must be ready; run `void email domain sync <domain>` first if setup is incomplete. The platform accepts the staged secret before updating the Worker and promotes it only after verifying the deployed generation. An uncertain update stays recorded for reconciliation.
|
|
1364
1592
|
|
|
1365
1593
|
#### `void email domain remove`
|
|
1366
1594
|
|
|
@@ -1368,7 +1596,7 @@ Redeploy the domain's relay worker at the current version and rotate its secret
|
|
|
1368
1596
|
void email domain remove <domain> [--project <name>]
|
|
1369
1597
|
```
|
|
1370
1598
|
|
|
1371
|
-
|
|
1599
|
+
Disable the domain assignment and record cleanup. Zone resources used by another domain remain available. Unfinished or uncertain cleanup remains recorded until it can be reconciled safely.
|
|
1372
1600
|
|
|
1373
1601
|
### `void email status`
|
|
1374
1602
|
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
//#region src/shared/cf-access.ts
|
|
2
|
-
/**
|
|
3
|
-
* Resolve Cloudflare Access headers from an env-like object.
|
|
4
|
-
*
|
|
5
|
-
* Priority:
|
|
6
|
-
* 1. Service token pair (`CF_ACCESS_CLIENT_ID` + `CF_ACCESS_CLIENT_SECRET`) — CI path
|
|
7
|
-
* 2. User JWT (`CF_ACCESS_TOKEN`) — dev path, typically populated via `cloudflared access token`
|
|
8
|
-
* 3. No headers — prod, or unprotected hostnames
|
|
9
|
-
*/
|
|
10
|
-
function isVoidAccessGatedUrl(targetUrl) {
|
|
11
|
-
try {
|
|
12
|
-
const url = new URL(targetUrl);
|
|
13
|
-
return url.protocol === "https:" && (url.hostname.endsWith(".staging.void.cloud") || url.hostname.endsWith(".staging.void.app"));
|
|
14
|
-
} catch {
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
function accessHeaders(env) {
|
|
19
|
-
const id = env.CF_ACCESS_CLIENT_ID;
|
|
20
|
-
const secret = env.CF_ACCESS_CLIENT_SECRET;
|
|
21
|
-
if (typeof id === "string" && typeof secret === "string" && id.length > 0 && secret.length > 0) return {
|
|
22
|
-
"CF-Access-Client-Id": id,
|
|
23
|
-
"CF-Access-Client-Secret": secret
|
|
24
|
-
};
|
|
25
|
-
const token = env.CF_ACCESS_TOKEN;
|
|
26
|
-
if (typeof token === "string" && token.length > 0) return { "cf-access-token": token };
|
|
27
|
-
return {};
|
|
28
|
-
}
|
|
29
|
-
/** Attach shared Void Access credentials only to known hosted staging origins. */
|
|
30
|
-
function cfAccessHeaders(env, targetUrl) {
|
|
31
|
-
return isVoidAccessGatedUrl(targetUrl) ? accessHeaders(env) : {};
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Capture credentials for a Cloudflare Worker readiness request whose target
|
|
35
|
-
* is resolved and constrained by the direct-deploy adapter rather than a
|
|
36
|
-
* user-connected Void platform URL.
|
|
37
|
-
*/
|
|
38
|
-
function trustedCloudflareWorkerAccessHeaders(env) {
|
|
39
|
-
return accessHeaders(env);
|
|
40
|
-
}
|
|
41
|
-
//#endregion
|
|
42
|
-
export { isVoidAccessGatedUrl as n, trustedCloudflareWorkerAccessHeaders as r, cfAccessHeaders as t };
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { n as isVoidAccessGatedUrl } from "./cf-access-AJ1ehiFR.mjs";
|
|
2
|
-
import { spawnSync } from "node:child_process";
|
|
3
|
-
//#region src/cli/cf-access.ts
|
|
4
|
-
const probedHosts = /* @__PURE__ */ new Set();
|
|
5
|
-
/**
|
|
6
|
-
* If the CLI is about to talk to a Cloudflare-Access-gated staging host,
|
|
7
|
-
* probe the locally-installed `cloudflared` binary for a cached user JWT
|
|
8
|
-
* and export it as `CF_ACCESS_TOKEN`. On interactive shells with no cached
|
|
9
|
-
* token, open a browser login flow to populate the cache, then re-read it.
|
|
10
|
-
*
|
|
11
|
-
* Cached per-host so that an early non-gated call (e.g. prod) does not
|
|
12
|
-
* permanently disable the probe for a later gated call (e.g. staging) in
|
|
13
|
-
* the same process. Noop when:
|
|
14
|
-
* - a service-token pair is already set (CI path)
|
|
15
|
-
* - `CF_ACCESS_TOKEN` is already set (manual override or prior probe)
|
|
16
|
-
* - the target host is not gated
|
|
17
|
-
* - `cloudflared` is not installed
|
|
18
|
-
*/
|
|
19
|
-
function ensureCloudflaredToken(apiUrl) {
|
|
20
|
-
if (process.env.CF_ACCESS_CLIENT_ID && process.env.CF_ACCESS_CLIENT_SECRET) return;
|
|
21
|
-
if (process.env.CF_ACCESS_TOKEN) return;
|
|
22
|
-
if (!isVoidAccessGatedUrl(apiUrl)) return;
|
|
23
|
-
const host = new URL(apiUrl).hostname;
|
|
24
|
-
if (probedHosts.has(host)) return;
|
|
25
|
-
probedHosts.add(host);
|
|
26
|
-
let token = runCloudflared([
|
|
27
|
-
"access",
|
|
28
|
-
"token",
|
|
29
|
-
`-app=${apiUrl}`
|
|
30
|
-
]);
|
|
31
|
-
if (!token && process.stdin.isTTY && process.stdout.isTTY) {
|
|
32
|
-
runCloudflared([
|
|
33
|
-
"access",
|
|
34
|
-
"login",
|
|
35
|
-
apiUrl
|
|
36
|
-
], {
|
|
37
|
-
inherit: true,
|
|
38
|
-
timeoutMs: 12e4
|
|
39
|
-
});
|
|
40
|
-
token = runCloudflared([
|
|
41
|
-
"access",
|
|
42
|
-
"token",
|
|
43
|
-
`-app=${apiUrl}`
|
|
44
|
-
]);
|
|
45
|
-
}
|
|
46
|
-
if (token) process.env.CF_ACCESS_TOKEN = token;
|
|
47
|
-
}
|
|
48
|
-
function runCloudflared(args, opts) {
|
|
49
|
-
try {
|
|
50
|
-
const result = spawnSync("cloudflared", args, {
|
|
51
|
-
encoding: "utf-8",
|
|
52
|
-
stdio: opts?.inherit ? "inherit" : [
|
|
53
|
-
"ignore",
|
|
54
|
-
"pipe",
|
|
55
|
-
"pipe"
|
|
56
|
-
],
|
|
57
|
-
timeout: opts?.timeoutMs ?? 5e3
|
|
58
|
-
});
|
|
59
|
-
if (result.error || result.status !== 0) return null;
|
|
60
|
-
const out = (result.stdout ?? "").trim();
|
|
61
|
-
return out.length > 0 ? out : null;
|
|
62
|
-
} catch {
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
//#endregion
|
|
67
|
-
export { ensureCloudflaredToken as t };
|