runcloud 0.1.10 → 0.1.11

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.
@@ -3,7 +3,7 @@ import crypto from 'node:crypto';
3
3
  import { hostname } from 'node:os';
4
4
  import { spawn } from 'node:child_process';
5
5
  import { ApiClient, ApiError } from '../api.js';
6
- import { clearCredentials, credentialsDisplayPath, normalizeApiUrl, saveCredentials } from '../config.js';
6
+ import { clearCredentials, credentialsDisplayPath, loadCredentials, normalizeApiUrl, saveCredentials, } from '../config.js';
7
7
  import { acquirePromptIO, ask, PromptAbortedError, select, } from '../prompt.js';
8
8
  import { AuthError, createApiKey, fetchProviders, isValidEmail, isValidOtp, normalizeOtp, sendEmailCode, verifyEmailCode, } from '../runCloudAuth.js';
9
9
  const LOGIN_TIMEOUT_MS = 5 * 60 * 1000;
@@ -201,6 +201,20 @@ export async function verifyRunCloudCredential(apiUrl, token) {
201
201
  `(${e instanceof Error ? e.message : String(e)}). Saving it anyway.`);
202
202
  }
203
203
  }
204
+ export async function revokeRunCloudCredential(apiUrl, token) {
205
+ try {
206
+ await new ApiClient(normalizeApiUrl(apiUrl), token).delete('/run-cloud/api-keys/self');
207
+ return 'Credential revoked.';
208
+ }
209
+ catch (e) {
210
+ if (e instanceof ApiError && (e.status === 401 || e.status === 403)) {
211
+ return 'Credential was already invalid.';
212
+ }
213
+ return (`Warning: could not reach ${apiUrl} to revoke this credential ` +
214
+ `(${e instanceof Error ? e.message : String(e)}). It may still be valid — ` +
215
+ 'revoke it from the run.cloud dashboard.');
216
+ }
217
+ }
204
218
  export function registerLogin(program) {
205
219
  const isRunCloud = program.name() === 'runcloud';
206
220
  const defaultAppUrl = isRunCloud
@@ -288,6 +302,7 @@ export function registerLogin(program) {
288
302
  apiUrl: authApiUrl,
289
303
  appUrl: opts.appUrl,
290
304
  expiresAt: Number.MAX_SAFE_INTEGER,
305
+ revocable: true,
291
306
  });
292
307
  console.log(`\n Signed in as ${email}`);
293
308
  console.log(` Credential saved to ${credentialsDisplayPath()}\n`);
@@ -321,6 +336,7 @@ export function registerLogin(program) {
321
336
  apiUrl: payload.apiUrl,
322
337
  appUrl: opts.appUrl,
323
338
  expiresAt: Math.floor(Date.now() / 1000) + payload.expiresIn,
339
+ revocable: true,
324
340
  });
325
341
  console.log(`Logged in. Credentials saved to ${credentialsDisplayPath()}`);
326
342
  return;
@@ -360,8 +376,14 @@ export function registerLogin(program) {
360
376
  });
361
377
  program
362
378
  .command('logout')
363
- .description('Delete the stored CLI credential')
364
- .action(() => {
379
+ .description(isRunCloud
380
+ ? 'Revoke this machine’s credential and delete it locally'
381
+ : 'Delete the stored CLI credential')
382
+ .action(async () => {
383
+ const creds = loadCredentials();
384
+ if (isRunCloud && creds?.revocable) {
385
+ console.log(await revokeRunCloudCredential(creds.apiUrl, creds.token));
386
+ }
365
387
  clearCredentials();
366
388
  console.log('Logged out.');
367
389
  });
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const CLI_VERSION = '0.1.10';
1
+ export const CLI_VERSION = '0.1.11';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "runcloud",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "description": "Create and control run.cloud remote mobile simulators and cloud sandboxes",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",