diff --git a/lib/commands/api-keys/index.ts b/lib/commands/api-keys/index.ts index 2383b4e9..6fc1d07f 100644 --- a/lib/commands/api-keys/index.ts +++ b/lib/commands/api-keys/index.ts @@ -62,7 +62,7 @@ export default class ApiKeysCmd extends Command { $select: 'actor', }) ).actor - : await getBalenaSdk().auth.getUserActorId(); + : await getBalenaSdk().auth.getActorId(); const keys = await getBalenaSdk().pine.get({ resource: 'api_key', options: { diff --git a/lib/commands/deploy.ts b/lib/commands/deploy.ts index c562ec5e..c44f7602 100644 --- a/lib/commands/deploy.ts +++ b/lib/commands/deploy.ts @@ -346,9 +346,9 @@ ${dockerignoreHelp} ); logger.logWarn(msg); - const [token, username, url, options] = await Promise.all([ + const [token, { username }, url, options] = await Promise.all([ sdk.auth.getToken(), - sdk.auth.whoami(), + sdk.auth.getUserInfo(), sdk.settings.get('balenaUrl'), { // opts.appName may be prefixed by 'owner/', unlike opts.app.app_name @@ -371,8 +371,8 @@ ${dockerignoreHelp} $select: ['commit'], }); } else { - const [userId, auth, apiEndpoint] = await Promise.all([ - sdk.auth.getUserId(), + const [{ id: userId }, auth, apiEndpoint] = await Promise.all([ + sdk.auth.getUserInfo(), sdk.auth.getToken(), sdk.settings.get('apiUrl'), ]); diff --git a/lib/commands/login.ts b/lib/commands/login.ts index 3830b4f7..24484a40 100644 --- a/lib/commands/login.ts +++ b/lib/commands/login.ts @@ -137,7 +137,7 @@ export default class LoginCmd extends Command { console.log(`\nLogging in to ${balenaUrl}`); await this.doLogin(options, balenaUrl, params.token); - const username = await balena.auth.whoami(); + const { username } = await balena.auth.getUserInfo(); console.info(`Successfully logged in as: ${username}`); console.info(`\ @@ -165,7 +165,12 @@ ${messages.reachingOut}`); } const balena = getBalenaSdk(); await balena.auth.loginWithToken(token!); - if (!(await balena.auth.whoami())) { + try { + await balena.auth.getUserInfo(); + } catch (err) { + if (process.env.DEBUG) { + console.error(`Get user info failed with: ${err.message}`); + } throw new ExpectedError('Token authentication failed'); } return; diff --git a/lib/commands/ssh.ts b/lib/commands/ssh.ts index 3c2f4864..cdd09468 100644 --- a/lib/commands/ssh.ts +++ b/lib/commands/ssh.ts @@ -152,9 +152,9 @@ export default class SshCmd extends Command { const { which } = await import('../utils/which'); - const [whichProxytunnel, username, proxyUrl] = await Promise.all([ + const [whichProxytunnel, { username }, proxyUrl] = await Promise.all([ useProxy ? which('proxytunnel', false) : undefined, - sdk.auth.whoami(), + sdk.auth.getUserInfo(), // note that `proxyUrl` refers to the balenaCloud "resin-proxy" // service, currently "balena-devices.com", rather than some // local proxy server URL @@ -208,7 +208,7 @@ export default class SshCmd extends Command { port: options.port || 'cloud', proxyCommand, service: params.service, - username: username!, + username, }); } diff --git a/lib/commands/whoami.ts b/lib/commands/whoami.ts index 17915d40..c4f0600f 100644 --- a/lib/commands/whoami.ts +++ b/lib/commands/whoami.ts @@ -36,11 +36,11 @@ export default class WhoamiCmd extends Command { const balena = getBalenaSdk(); - const [username, email, url] = await Promise.all([ - balena.auth.whoami(), - balena.auth.getEmail(), + const [{ username, email }, url] = await Promise.all([ + balena.auth.getUserInfo(), balena.settings.get('balenaUrl'), ]); + console.log( getVisuals().table.vertical({ username, email, url }, [ '$account information$', diff --git a/lib/utils/bootstrap.ts b/lib/utils/bootstrap.ts index 5f9845bd..bcf5c587 100644 --- a/lib/utils/bootstrap.ts +++ b/lib/utils/bootstrap.ts @@ -167,7 +167,7 @@ export async function getCachedUsername(): Promise { // ignore } try { - const username = await getBalenaSdk().auth.whoami(); + const { username } = await getBalenaSdk().auth.getUserInfo(); if (username) { cachedUsername = { token, username }; await storage.set('cachedUsername', cachedUsername); diff --git a/lib/utils/promote.ts b/lib/utils/promote.ts index 3e585531..74d2a7f0 100644 --- a/lib/utils/promote.ts +++ b/lib/utils/promote.ts @@ -386,8 +386,11 @@ async function createApplication( ): Promise { const validation = await import('./validation'); - const username = await sdk.auth.whoami(); - if (!username) { + let username: string; + try { + const userInfo = await sdk.auth.getUserInfo(); + username = userInfo.username; + } catch (err) { throw new sdk.errors.BalenaNotLoggedIn(); } @@ -404,7 +407,7 @@ async function createApplication( try { await sdk.models.application.getDirectlyAccessible(appName, { $filter: { - slug: { $startswith: `${username!.toLowerCase()}/` }, + slug: { $startswith: `${username.toLowerCase()}/` }, }, }); // TODO: This is the only example in the codebase where `printErrorMessage()` diff --git a/lib/utils/sdk.ts b/lib/utils/sdk.ts index 4d37c703..f8544b7a 100644 --- a/lib/utils/sdk.ts +++ b/lib/utils/sdk.ts @@ -105,7 +105,7 @@ export async function getOwnOrganizations( $alias: 'orm', $expr: { orm: { - user: await sdk.auth.getUserId(), + user: (await sdk.auth.getUserInfo()).id, }, }, }, diff --git a/lib/utils/tunnel.ts b/lib/utils/tunnel.ts index 288a0e6f..5e37863a 100644 --- a/lib/utils/tunnel.ts +++ b/lib/utils/tunnel.ts @@ -51,7 +51,7 @@ export const tunnelConnectionToDevice = ( sdk.auth.getToken(), ]).then(([tunnelUrl, whoami, token]) => { const auth = { - user: whoami || 'root', + user: whoami?.actorType === 'user' ? whoami.username : 'root', password: token, }; diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 10e03758..5c33e108 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -22,9 +22,9 @@ "balena-device-init": "^6.0.0", "balena-errors": "^4.7.3", "balena-image-fs": "^7.0.6", - "balena-image-manager": "^9.0.0", - "balena-preload": "^14.0.0", - "balena-sdk": "^17.12.1", + "balena-image-manager": "^9.0.2", + "balena-preload": "^14.0.2", + "balena-sdk": "^18.0.0", "balena-semver": "^2.3.0", "balena-settings-client": "^5.0.2", "balena-settings-storage": "^8.1.0", @@ -3082,9 +3082,9 @@ } }, "node_modules/@types/node": { - "version": "16.18.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.41.tgz", - "integrity": "sha512-YZJjn+Aaw0xihnpdImxI22jqGbp0DCgTFKRycygjGx/Y27NnWFJa5FJ7P+MRT3u07dogEeMVh70pWpbIQollTA==" + "version": "16.18.42", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.42.tgz", + "integrity": "sha512-IrFfX/1oxDFQNpQzgt/BoP/hbMuQT68DPsNwzJmw8y3K8lfnPp0XymVN9GLFz+LobFmJGZ/peRzq+9wXYfCCtw==" }, "node_modules/@types/node-cleanup": { "version": "2.1.2", @@ -4019,11 +4019,11 @@ } }, "node_modules/balena-image-manager": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/balena-image-manager/-/balena-image-manager-9.0.0.tgz", - "integrity": "sha512-DOtcpqnLhRcEETqFPlfM6XDmsgexr0ykahtrYki9DU0JNuK5OJlhgkE2/HgVOFWHWnslmcqnCTmGHkh7mJd1Dw==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/balena-image-manager/-/balena-image-manager-9.0.2.tgz", + "integrity": "sha512-1q52zABKh8X2rFQsWXSlfJH/b10wfA+T5YFnYfUohomW/G+GPUANxx0ma9zidJCrcyNx46vqalrzPzKEKtpeHw==", "dependencies": { - "balena-sdk": "^17.0.0", + "balena-sdk": "^18.0.0", "mime": "^2.4.6", "mkdirp": "^1.0.4", "rimraf": "^3.0.2" @@ -4033,12 +4033,12 @@ } }, "node_modules/balena-preload": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/balena-preload/-/balena-preload-14.0.0.tgz", - "integrity": "sha512-LWA/WgckfWxI2VFrefatUlMsYuM+zVbUqoDhPx95VQh4ArJXxbo8s9ADgl/yQGt0e4qUciMu8fuzxaZXZvwS2A==", + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/balena-preload/-/balena-preload-14.0.2.tgz", + "integrity": "sha512-1JjVf+V0obEU3g+0pcgYTPwMZMJudrb86VjOmsYOVxMiUKW9wlOEj2AcceUQpB1B/xfFgMCJaUuWYxGVELvhew==", "dependencies": { "archiver": "^3.1.1", - "balena-sdk": "^17.0.0", + "balena-sdk": "^18.0.0", "bluebird": "^3.7.2", "compare-versions": "^3.6.0", "docker-progress": "^5.0.0", @@ -4189,13 +4189,13 @@ } }, "node_modules/balena-sdk": { - "version": "17.12.1", - "resolved": "https://registry.npmjs.org/balena-sdk/-/balena-sdk-17.12.1.tgz", - "integrity": "sha512-cpfAa+OPltp1+609cBKuTiDWI6tTxXpllitLfqCmAqqu6fVni8m2LLoNvg+2FxfxhRi1OXKoTX6HNTCctSeSNQ==", + "version": "18.0.2", + "resolved": "https://registry.npmjs.org/balena-sdk/-/balena-sdk-18.0.2.tgz", + "integrity": "sha512-J7mggg/PJjagX9ML2MT1xf0blS5+x6dNVfVNAKpf7pf5HiGRMCRmOVaLF+tDD5Gq9Mrb8l1O8jIHGwW7s1VuzA==", "dependencies": { "@balena/es-version": "^1.0.0", "@types/json-schema": "^7.0.9", - "@types/node": "^14.0.0", + "@types/node": "^16.0.0", "abortcontroller-polyfill": "^1.7.1", "balena-auth": "^5.1.0", "balena-errors": "^4.8.0", @@ -4214,14 +4214,9 @@ "tslib": "^2.1.0" }, "engines": { - "node": ">=14.0" + "node": ">=16.0" } }, - "node_modules/balena-sdk/node_modules/@types/node": { - "version": "14.18.54", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.54.tgz", - "integrity": "sha512-uq7O52wvo2Lggsx1x21tKZgqkJpvwCseBBPtX/nKQfpVlEsLOb11zZ1CRsWUKvJF0+lzuA9jwvA7Pr2Wt7i3xw==" - }, "node_modules/balena-sdk/node_modules/date-fns": { "version": "2.30.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", @@ -24787,9 +24782,9 @@ } }, "@types/node": { - "version": "16.18.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.41.tgz", - "integrity": "sha512-YZJjn+Aaw0xihnpdImxI22jqGbp0DCgTFKRycygjGx/Y27NnWFJa5FJ7P+MRT3u07dogEeMVh70pWpbIQollTA==" + "version": "16.18.42", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.42.tgz", + "integrity": "sha512-IrFfX/1oxDFQNpQzgt/BoP/hbMuQT68DPsNwzJmw8y3K8lfnPp0XymVN9GLFz+LobFmJGZ/peRzq+9wXYfCCtw==" }, "@types/node-cleanup": { "version": "2.1.2", @@ -25579,23 +25574,23 @@ } }, "balena-image-manager": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/balena-image-manager/-/balena-image-manager-9.0.0.tgz", - "integrity": "sha512-DOtcpqnLhRcEETqFPlfM6XDmsgexr0ykahtrYki9DU0JNuK5OJlhgkE2/HgVOFWHWnslmcqnCTmGHkh7mJd1Dw==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/balena-image-manager/-/balena-image-manager-9.0.2.tgz", + "integrity": "sha512-1q52zABKh8X2rFQsWXSlfJH/b10wfA+T5YFnYfUohomW/G+GPUANxx0ma9zidJCrcyNx46vqalrzPzKEKtpeHw==", "requires": { - "balena-sdk": "^17.0.0", + "balena-sdk": "^18.0.0", "mime": "^2.4.6", "mkdirp": "^1.0.4", "rimraf": "^3.0.2" } }, "balena-preload": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/balena-preload/-/balena-preload-14.0.0.tgz", - "integrity": "sha512-LWA/WgckfWxI2VFrefatUlMsYuM+zVbUqoDhPx95VQh4ArJXxbo8s9ADgl/yQGt0e4qUciMu8fuzxaZXZvwS2A==", + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/balena-preload/-/balena-preload-14.0.2.tgz", + "integrity": "sha512-1JjVf+V0obEU3g+0pcgYTPwMZMJudrb86VjOmsYOVxMiUKW9wlOEj2AcceUQpB1B/xfFgMCJaUuWYxGVELvhew==", "requires": { "archiver": "^3.1.1", - "balena-sdk": "^17.0.0", + "balena-sdk": "^18.0.0", "bluebird": "^3.7.2", "compare-versions": "^3.6.0", "docker-progress": "^5.0.0", @@ -25718,13 +25713,13 @@ } }, "balena-sdk": { - "version": "17.12.1", - "resolved": "https://registry.npmjs.org/balena-sdk/-/balena-sdk-17.12.1.tgz", - "integrity": "sha512-cpfAa+OPltp1+609cBKuTiDWI6tTxXpllitLfqCmAqqu6fVni8m2LLoNvg+2FxfxhRi1OXKoTX6HNTCctSeSNQ==", + "version": "18.0.2", + "resolved": "https://registry.npmjs.org/balena-sdk/-/balena-sdk-18.0.2.tgz", + "integrity": "sha512-J7mggg/PJjagX9ML2MT1xf0blS5+x6dNVfVNAKpf7pf5HiGRMCRmOVaLF+tDD5Gq9Mrb8l1O8jIHGwW7s1VuzA==", "requires": { "@balena/es-version": "^1.0.0", "@types/json-schema": "^7.0.9", - "@types/node": "^14.0.0", + "@types/node": "^16.0.0", "abortcontroller-polyfill": "^1.7.1", "balena-auth": "^5.1.0", "balena-errors": "^4.8.0", @@ -25743,11 +25738,6 @@ "tslib": "^2.1.0" }, "dependencies": { - "@types/node": { - "version": "14.18.54", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.54.tgz", - "integrity": "sha512-uq7O52wvo2Lggsx1x21tKZgqkJpvwCseBBPtX/nKQfpVlEsLOb11zZ1CRsWUKvJF0+lzuA9jwvA7Pr2Wt7i3xw==" - }, "date-fns": { "version": "2.30.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", diff --git a/package.json b/package.json index 8a97ba6b..2b10a45e 100644 --- a/package.json +++ b/package.json @@ -205,9 +205,9 @@ "balena-device-init": "^6.0.0", "balena-errors": "^4.7.3", "balena-image-fs": "^7.0.6", - "balena-image-manager": "^9.0.0", - "balena-preload": "^14.0.0", - "balena-sdk": "^17.12.1", + "balena-image-manager": "^9.0.2", + "balena-preload": "^14.0.2", + "balena-sdk": "^18.0.0", "balena-semver": "^2.3.0", "balena-settings-client": "^5.0.2", "balena-settings-storage": "^8.1.0", diff --git a/tests/nock/balena-api-mock.ts b/tests/nock/balena-api-mock.ts index 9d3b4d43..3fd53f58 100644 --- a/tests/nock/balena-api-mock.ts +++ b/tests/nock/balena-api-mock.ts @@ -430,8 +430,10 @@ export class BalenaAPIMock extends NockMock { // User details are cached in the SDK // so often we don't know if we can expect the whoami request public expectGetWhoAmI(opts: ScopeOpts = { optional: true }) { - this.optGet('/user/v1/whoami', opts).reply(200, { - id: 99999, + this.optGet('/actor/v1/whoami', opts).reply(200, { + id: 1234, + actorType: 'user', + actorTypeId: 99999, username: 'gh_user', email: 'testuser@test.com', });