diff --git a/src/auth.ts b/src/auth.ts index a6c13a2cc..7b3444878 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -17,7 +17,7 @@ limitations under the License. import * as errors from 'balena-errors'; import memoizee from 'memoizee'; import type { InjectedDependenciesParam, InjectedOptionsParam } from '.'; -import { WhoamiResult } from './types/auth'; +import { UserInfo, WhoamiResult } from './types/auth'; const getAuth = function ( deps: InjectedDependenciesParam, @@ -279,6 +279,21 @@ const getAuth = function ( }); } + async function getUserInfo(): Promise { + const actor = await getActorDetails(); + + if (actor.actorType !== 'user') { + throw new Error( + 'The authentication credentials in use are not of a user', + ); + } + return { + id: actor.actorTypeId, + email: actor.email, + username: actor.username, + }; + } + /** * @summary Get current logged in user's id * @name getUserId @@ -501,6 +516,7 @@ const getAuth = function ( getUserId, getUserActorId, getEmail, + getUserInfo, logout, register, verifyEmail, diff --git a/src/types/auth.ts b/src/types/auth.ts index b5f28acb9..0f0dc257b 100644 --- a/src/types/auth.ts +++ b/src/types/auth.ts @@ -24,3 +24,9 @@ export type WhoamiResult = | UserKeyWhoAmIResponse | ApplicationKeyWhoAmIResponse | DeviceKeyWhoAmIResponse; + +export interface UserInfo { + id: number; + username: string; + email: string | null; +} diff --git a/tests/integration/auth.spec.ts b/tests/integration/auth.spec.ts index f22abb222..74e441575 100644 --- a/tests/integration/auth.spec.ts +++ b/tests/integration/auth.spec.ts @@ -99,6 +99,16 @@ describe('SDK authentication', function () { }); }); + describe('balena.auth.getUserInfo()', () => { + it('should be rejected with an error', async function () { + const promise = balena.auth.getUserInfo(); + await expect(promise).to.be.rejected.and.eventually.have.property( + 'code', + 'BalenaNotLoggedIn', + ); + }); + }); + describe('balena.auth.getUserId()', () => { it('should be rejected with an error', async function () { const promise = balena.auth.getUserId(); @@ -215,6 +225,16 @@ describe('SDK authentication', function () { }); }); + describe('balena.auth.getUserInfo()', () => { + it('should be rejected with an error', async function () { + const promise = balena.auth.getUserInfo(); + await expect(promise).to.be.rejected.and.eventually.have.property( + 'code', + 'BalenaNotLoggedIn', + ); + }); + }); + describe('balena.auth.getUserId()', () => { it('should be rejected with an error', async function () { const promise = balena.auth.getUserId(); @@ -265,6 +285,16 @@ describe('SDK authentication', function () { }); }); + describe('balena.auth.getUserInfo()', () => { + it('should be rejected with an error', async function () { + const userInfo = await balena.auth.getUserInfo(); + expect(userInfo.email).to.equal(credentials.email); + expect(userInfo.username).to.equal(credentials.username); + expect(userInfo.id).to.be.a('number'); + expect(userInfo.id).to.be.greaterThan(0); + }); + }); + describe('balena.auth.getUserId()', () => { it('should eventually be a user id', async () => { const userId = await balena.auth.getUserId(); @@ -321,6 +351,16 @@ describe('SDK authentication', function () { }); }); + describe('balena.auth.getUserInfo()', () => { + it('should be rejected with an error', async function () { + const promise = balena.auth.getUserInfo(); + await expect(promise).to.be.rejected.and.eventually.have.property( + 'message', + 'The authentication credentials in use are not of a user', + ); + }); + }); + describe('balena.auth.getUserId()', () => { it('should be rejected with an error', async () => { const promise = balena.auth.getUserId(); @@ -389,6 +429,16 @@ describe('SDK authentication', function () { }); }); + describe('balena.auth.getUserInfo()', () => { + it('should be rejected with an error', async function () { + const promise = balena.auth.getUserInfo(); + await expect(promise).to.be.rejected.and.eventually.have.property( + 'message', + 'The authentication credentials in use are not of a user', + ); + }); + }); + describe('balena.auth.getUserId()', () => { it('should be rejected with an error', async () => { const promise = balena.auth.getUserId(); @@ -453,6 +503,16 @@ describe('SDK authentication', function () { }); }); + describe('balena.auth.getUserInfo()', () => { + it('should be rejected with an error', async function () { + const userInfo = await balena.auth.getUserInfo(); + expect(userInfo.email).to.equal(credentials.email); + expect(userInfo.username).to.equal(credentials.username); + expect(userInfo.id).to.be.a('number'); + expect(userInfo.id).to.be.greaterThan(0); + }); + }); + describe('balena.auth.getUserId()', () => { it('should eventually be a user id', async () => { const userId = await balena.auth.getUserId();