@tillstack/cli 0.3.1 → 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 +38 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +16 -0
- package/dist/api.js.map +1 -1
- package/dist/index.js +76 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -340,6 +340,11 @@ ${c.bold('TILLAUTH')} ${c.dim('(auth)')} ${c.gray('tilldev auth …')
|
|
|
340
340
|
auth apps create <name> [--slug <s>] Create an auth app
|
|
341
341
|
auth app <appRef> Show an auth app (by slug or id)
|
|
342
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
|
|
343
348
|
|
|
344
349
|
${c.bold('WORKSPACE')}
|
|
345
350
|
team List org members
|
|
@@ -777,6 +782,77 @@ async function cmdAuth(flags) {
|
|
|
777
782
|
});
|
|
778
783
|
return;
|
|
779
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
|
+
}
|
|
780
856
|
default:
|
|
781
857
|
throw new Error(`unknown: tilldev auth ${sub}`);
|
|
782
858
|
}
|