@tillstack/cli 0.3.0 → 0.3.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/dist/api.d.ts +47 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +23 -0
- package/dist/api.js.map +1 -1
- package/dist/index.js +93 -2
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -338,7 +338,13 @@ ${c.bold('TILLFORGE')} ${c.dim('(sovereign code hosting)')} ${c.gray('tilldev f
|
|
|
338
338
|
${c.bold('TILLAUTH')} ${c.dim('(auth)')} ${c.gray('tilldev auth …')}
|
|
339
339
|
auth apps List auth apps
|
|
340
340
|
auth apps create <name> [--slug <s>] Create an auth app
|
|
341
|
-
auth app <
|
|
341
|
+
auth app <appRef> Show an auth app (by slug or id)
|
|
342
|
+
auth invite <appRef> <email> [--role <r>] Invite a user to an app
|
|
343
|
+
auth clients <appRef> List OIDC clients registered on an app
|
|
344
|
+
auth clients <appRef> create <name> --redirect <uri>[,<uri>] [--scopes …] [--public] [--no-consent]
|
|
345
|
+
auth clients <appRef> rm <clientId> Remove an OIDC client
|
|
346
|
+
auth scim <appRef> [rotate] Mint/rotate the SCIM provisioning token (shown once)
|
|
347
|
+
auth scim <appRef> disable Turn SCIM provisioning off
|
|
342
348
|
|
|
343
349
|
${c.bold('WORKSPACE')}
|
|
344
350
|
team List org members
|
|
@@ -757,11 +763,96 @@ async function cmdAuth(flags) {
|
|
|
757
763
|
return;
|
|
758
764
|
}
|
|
759
765
|
case 'app': {
|
|
760
|
-
const appId = need(flags.positional[2], 'tilldev auth app <
|
|
766
|
+
const appId = need(flags.positional[2], 'tilldev auth app <appRef>');
|
|
761
767
|
const r = await api.getAuthApp(opts, appId);
|
|
762
768
|
printJson(r);
|
|
763
769
|
return;
|
|
764
770
|
}
|
|
771
|
+
case 'invite': {
|
|
772
|
+
const appRef = need(flags.positional[2], 'tilldev auth invite <appRef> <email> [--role <r>]');
|
|
773
|
+
const email = need(flags.positional[3], 'tilldev auth invite <appRef> <email> [--role <r>]');
|
|
774
|
+
const role = flags.named['role']?.trim();
|
|
775
|
+
const r = await api.inviteAuthUser(opts, appRef, email, role);
|
|
776
|
+
render(flags, r, () => {
|
|
777
|
+
ok(`Invited ${c.bold(r.invite.email)} as ${c.dim(r.invite.role)}`);
|
|
778
|
+
if (r.delivered)
|
|
779
|
+
console.log(c.dim('An invitation email is on its way.'));
|
|
780
|
+
else if (r.accept_link)
|
|
781
|
+
console.log(`Share this link:\n ${c.bold(r.accept_link)}`);
|
|
782
|
+
});
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
case 'clients': {
|
|
786
|
+
const appRef = need(flags.positional[2], 'tilldev auth clients <appRef> [create|rm]');
|
|
787
|
+
const action = flags.positional[3];
|
|
788
|
+
if (action === 'create') {
|
|
789
|
+
const name = need(flags.positional[4], 'tilldev auth clients <appRef> create <name> --redirect <uri>[,<uri>…] [--scopes openid,email,profile] [--public] [--no-consent]');
|
|
790
|
+
// Comma-separate multiple redirect URIs in a single --redirect flag.
|
|
791
|
+
const redirect_uris = (flags.named['redirect'] ?? '').split(',').map((s) => s.trim()).filter(Boolean);
|
|
792
|
+
if (redirect_uris.length === 0)
|
|
793
|
+
throw new Error('At least one --redirect <uri> is required');
|
|
794
|
+
const scopes = flags.named['scopes']?.split(',').map((s) => s.trim()).filter(Boolean);
|
|
795
|
+
const body = {
|
|
796
|
+
name,
|
|
797
|
+
redirect_uris,
|
|
798
|
+
...(scopes ? { scopes } : {}),
|
|
799
|
+
...(flags.bool.has('public') ? { public: true } : {}),
|
|
800
|
+
...(flags.bool.has('no-consent') ? { require_consent: false } : {}),
|
|
801
|
+
};
|
|
802
|
+
const r = await api.createOidcClient(opts, appRef, body);
|
|
803
|
+
render(flags, r, () => {
|
|
804
|
+
ok(`Registered OIDC client ${c.bold(r.client_id)} (${c.dim(r.client_type)})`);
|
|
805
|
+
console.log(kv([
|
|
806
|
+
['client_id', r.client_id],
|
|
807
|
+
['redirect_uris', r.redirect_uris.join(', ')],
|
|
808
|
+
['scopes', r.scopes.join(' ')],
|
|
809
|
+
]));
|
|
810
|
+
if (r.client_secret) {
|
|
811
|
+
console.log(`\n${c.yellow('client_secret (shown once — store it now):')}\n ${c.bold(r.client_secret)}`);
|
|
812
|
+
}
|
|
813
|
+
else {
|
|
814
|
+
console.log(c.dim('\nPublic client — no secret; authenticate with PKCE (S256).'));
|
|
815
|
+
}
|
|
816
|
+
});
|
|
817
|
+
return;
|
|
818
|
+
}
|
|
819
|
+
if (action === 'rm' || action === 'delete') {
|
|
820
|
+
const clientId = need(flags.positional[4], 'tilldev auth clients <appRef> rm <clientId>');
|
|
821
|
+
const r = await api.deleteOidcClient(opts, appRef, clientId);
|
|
822
|
+
render(flags, r, () => ok(`Removed client ${c.dim(clientId)}`));
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
const r = await api.listOidcClients(opts, appRef);
|
|
826
|
+
render(flags, r, () => {
|
|
827
|
+
const cols = [
|
|
828
|
+
{ header: 'CLIENT ID', get: (x) => c.bold(x.client_id) },
|
|
829
|
+
{ header: 'NAME', get: (x) => x.name },
|
|
830
|
+
{ header: 'TYPE', get: (x) => c.dim(x.client_type) },
|
|
831
|
+
{ header: 'SCOPES', get: (x) => (x.scopes ?? []).join(' ') },
|
|
832
|
+
{ header: 'ENABLED', get: (x) => (x.enabled ? c.green('yes') : c.red('no')) },
|
|
833
|
+
];
|
|
834
|
+
console.log(table(r.clients, cols));
|
|
835
|
+
});
|
|
836
|
+
return;
|
|
837
|
+
}
|
|
838
|
+
case 'scim': {
|
|
839
|
+
const appRef = need(flags.positional[2], 'tilldev auth scim <appRef> [rotate|disable]');
|
|
840
|
+
const action = flags.positional[3] ?? 'rotate';
|
|
841
|
+
if (action === 'disable') {
|
|
842
|
+
const r = await api.scimDisable(opts, appRef);
|
|
843
|
+
render(flags, r, () => ok('SCIM provisioning disabled for this app.'));
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
// rotate (also the enable path — mints a fresh token, shown once)
|
|
847
|
+
const r = await api.scimRotate(opts, appRef);
|
|
848
|
+
render(flags, r, () => {
|
|
849
|
+
ok('SCIM provisioning token minted.');
|
|
850
|
+
console.log(kv([['scim_base_url', r.scim_base_url]]));
|
|
851
|
+
console.log(`\n${c.yellow('bearer token (shown once — store it now):')}\n ${c.bold(r.token)}`);
|
|
852
|
+
console.log(c.dim('\nConfigure your IdP (Okta, Entra ID, …) with the base URL + this token.'));
|
|
853
|
+
});
|
|
854
|
+
return;
|
|
855
|
+
}
|
|
765
856
|
default:
|
|
766
857
|
throw new Error(`unknown: tilldev auth ${sub}`);
|
|
767
858
|
}
|