Skip to content

Commit

Permalink
Merge pull request #1370 from balena-io/v-18-major
Browse files Browse the repository at this point in the history
V18 Major
  • Loading branch information
thgreasi authored Aug 17, 2023
2 parents 40faed4 + 447aa40 commit f1482fd
Show file tree
Hide file tree
Showing 21 changed files with 376 additions and 314 deletions.
4 changes: 2 additions & 2 deletions .github/actions/test/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ inputs:
runs:
using: "composite"
steps:
- name: Setup Node.js 14
- name: Setup Node.js 16
if: ${{ env.os_value == 'ubuntu-20.04' }}
uses: actions/setup-node@v3
with:
node-version: 14
node-version: 16

- name: Setup Node.js lts
if: ${{ env.os_value != 'ubuntu-20.04' }}
Expand Down
63 changes: 23 additions & 40 deletions DOCUMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -429,9 +429,8 @@ const sdk = fromSharedOptions();
* [.loginWithToken(authToken)](#balena.auth.loginWithToken) ⇒ <code>Promise</code>
* [.isLoggedIn()](#balena.auth.isLoggedIn) ⇒ <code>Promise</code>
* [.getToken()](#balena.auth.getToken) ⇒ <code>Promise</code>
* [.getUserId()](#balena.auth.getUserId) ⇒ <code>Promise</code>
* [.getUserActorId()](#balena.auth.getUserActorId) ⇒ <code>Promise</code>
* [.getEmail()](#balena.auth.getEmail) ⇒ <code>Promise</code>
* [.getUserInfo()](#balena.auth.getUserInfo) ⇒ <code>Promise</code>
* [.getActorId()](#balena.auth.getActorId) ⇒ <code>Promise</code>
* [.logout()](#balena.auth.logout) ⇒ <code>Promise</code>
* [.register(credentials)](#balena.auth.register) ⇒ <code>Promise</code>
* [.verifyEmail(verificationPayload)](#balena.auth.verifyEmail) ⇒ <code>Promise</code>
Expand Down Expand Up @@ -6483,9 +6482,8 @@ balena.models.billing.downloadInvoice(orgId, '0000').then(function(stream) {
* [.loginWithToken(authToken)](#balena.auth.loginWithToken) ⇒ <code>Promise</code>
* [.isLoggedIn()](#balena.auth.isLoggedIn) ⇒ <code>Promise</code>
* [.getToken()](#balena.auth.getToken) ⇒ <code>Promise</code>
* [.getUserId()](#balena.auth.getUserId) ⇒ <code>Promise</code>
* [.getUserActorId()](#balena.auth.getUserActorId) ⇒ <code>Promise</code>
* [.getEmail()](#balena.auth.getEmail) ⇒ <code>Promise</code>
* [.getUserInfo()](#balena.auth.getUserInfo) ⇒ <code>Promise</code>
* [.getActorId()](#balena.auth.getActorId) ⇒ <code>Promise</code>
* [.logout()](#balena.auth.logout) ⇒ <code>Promise</code>
* [.register(credentials)](#balena.auth.register) ⇒ <code>Promise</code>
* [.verifyEmail(verificationPayload)](#balena.auth.verifyEmail) ⇒ <code>Promise</code>
Expand Down Expand Up @@ -6630,19 +6628,19 @@ balena.auth.loginWithToken(token);
<a name="balena.auth.whoami"></a>
#### auth.whoami() ⇒ <code>Promise</code>
This will only work if you used [login](#balena.auth.login) to log in.
This will only work if you used [login](#balena.auth.login) or [loginWithToken](#balena.auth.loginWithToken) to log in.
**Kind**: static method of [<code>auth</code>](#balena.auth)
**Summary**: Return current logged in username
**Summary**: Return current logged in information
**Access**: public
**Fulfil**: <code>(String\|undefined)</code> - username, if it exists
**Fulfil**: <code>(Object\|undefined)</code> - actor information, if it exists
**Example**
```js
balena.auth.whoami().then(function(username) {
if (!username) {
balena.auth.whoami().then(function(result) {
if (!result) {
console.log('I\'m not logged in!');
} else {
console.log('My username is:', username);
console.log('My result is:', result);
}
});
```
Expand Down Expand Up @@ -6740,49 +6738,34 @@ balena.auth.getToken().then(function(token) {
console.log(token);
});
```
<a name="balena.auth.getUserId"></a>
<a name="balena.auth.getUserInfo"></a>

#### auth.getUserId() ⇒ <code>Promise</code>
#### auth.getUserInfo() ⇒ <code>Promise</code>
This will only work if you used [login](#balena.auth.login) to log in.

**Kind**: static method of [<code>auth</code>](#balena.auth)
**Summary**: Get current logged in user's id
**Summary**: Get current logged in user's info
**Access**: public
**Fulfil**: <code>Number</code> - user id
**Fulfil**: <code>Object</code> - user info
**Example**
```js
balena.auth.getUserId().then(function(userId) {
console.log(userId);
balena.auth.getUserInfo().then(function(userInfo) {
console.log(userInfo);
});
```
<a name="balena.auth.getUserActorId"></a>

#### auth.getUserActorId() ⇒ <code>Promise</code>
This will only work if you used [login](#balena.auth.login) to log in.
<a name="balena.auth.getActorId"></a>

**Kind**: static method of [<code>auth</code>](#balena.auth)
**Summary**: Get current logged in user's actor id
**Access**: public
**Fulfil**: <code>Number</code> - user id
**Example**
```js
balena.auth.getUserActorId().then(function(userActorId) {
console.log(userActorId);
});
```
<a name="balena.auth.getEmail"></a>

#### auth.getEmail() ⇒ <code>Promise</code>
This will only work if you used [login](#balena.auth.login) to log in.
#### auth.getActorId() ⇒ <code>Promise</code>
This will only work if you used [login](#balena.auth.login) or [loginWithToken](#balena.auth.loginWithToken) to log in.

**Kind**: static method of [<code>auth</code>](#balena.auth)
**Summary**: Get current logged in user's email
**Summary**: Get current logged in actor id
**Access**: public
**Fulfil**: <code>String</code> - user email
**Fulfil**: <code>Number</code> - actor id
**Example**
```js
balena.auth.getEmail().then(function(email) {
console.log(email);
balena.auth.getActorId().then(function(actorId) {
console.log(actorId);
});
```
<a name="balena.auth.logout"></a>
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ $ npm install --save balena-sdk

## Platforms

We currently support NodeJS (14+) and the browser.
We currently support NodeJS (16+) and the browser.

The following features are node-only:
- OS image streaming download (`balena.models.os.download`),
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"author": "Juan Cruz Viotti <[email protected]>",
"license": "Apache-2.0",
"engines": {
"node": ">=14.0"
"node": ">=16.0"
},
"devDependencies": {
"@balena/lint": "^6.1.1",
Expand Down Expand Up @@ -119,7 +119,7 @@
"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",
Expand Down
120 changes: 47 additions & 73 deletions src/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
import * as errors from 'balena-errors';
import memoizee from 'memoizee';
import type { InjectedDependenciesParam, InjectedOptionsParam } from '.';
import { UserInfo, WhoamiResult } from './types/auth';

const getAuth = function (
deps: InjectedDependenciesParam,
Expand Down Expand Up @@ -65,62 +66,55 @@ const getAuth = function (
opts,
);

interface WhoamiResult {
id: number;
username: string;
email: string;
}

const userWhoami = async () => {
const actorWhoami = async () => {
const { body } = await request.send<WhoamiResult>({
method: 'GET',
url: '/user/v1/whoami',
url: '/actor/v1/whoami',
baseUrl: apiUrl,
});
return body;
};

const memoizedUserWhoami = memoizee(userWhoami, {
const memoizedActorWhoami = memoizee(actorWhoami, {
primitive: true,
promise: true,
});

const getUserDetails = async (noCache = false) => {
const getActorDetails = async (noCache = false) => {
if (noCache) {
memoizedUserWhoami.clear();
memoizedActorWhoami.clear();
}
try {
return await memoizedUserWhoami();
return await memoizedActorWhoami();
} catch (err) {
throw normalizeAuthError(err);
}
};

/**
* @summary Return current logged in username
* @summary Return current logged in information
* @name whoami
* @public
* @function
* @memberof balena.auth
*
* @description This will only work if you used {@link balena.auth.login} to log in.
* @description This will only work if you used {@link balena.auth.login} or {@link balena.auth.loginWithToken} to log in.
*
* @fulfil {(String|undefined)} - username, if it exists
* @fulfil {(Object|undefined)} - actor information, if it exists
* @returns {Promise}
*
* @example
* balena.auth.whoami().then(function(username) {
* if (!username) {
* balena.auth.whoami().then(function(result) {
* if (!result) {
* console.log('I\'m not logged in!');
* } else {
* console.log('My username is:', username);
* console.log('My result is:', result);
* }
* });
*/
async function whoami(): Promise<string | undefined> {
async function whoami(): Promise<WhoamiResult | undefined> {
try {
const userDetails = await getUserDetails();
return userDetails?.username;
return await getActorDetails();
} catch (err) {
if (err instanceof errors.BalenaNotLoggedIn) {
return;
Expand Down Expand Up @@ -203,7 +197,7 @@ const getAuth = function (
email: string;
password: string;
}): Promise<void> {
memoizedUserWhoami.clear();
memoizedActorWhoami.clear();
const token = await authenticate(credentials);
await auth.setKey(token);
}
Expand All @@ -224,7 +218,7 @@ const getAuth = function (
* balena.auth.loginWithToken(authToken);
*/
function loginWithToken(authToken: string): Promise<void> {
memoizedUserWhoami.clear();
memoizedActorWhoami.clear();
return auth.setKey(authToken);
}

Expand All @@ -249,7 +243,7 @@ const getAuth = function (
*/
async function isLoggedIn(): Promise<boolean> {
try {
await getUserDetails(true);
await getActorDetails(true);
return true;
} catch (err) {
if (
Expand Down Expand Up @@ -286,75 +280,56 @@ const getAuth = function (
}

/**
* @summary Get current logged in user's id
* @name getUserId
* @summary Get current logged in user's info
* @name getUserInfo
* @public
* @function
* @memberof balena.auth
*
* @description This will only work if you used {@link balena.auth.login} to log in.
*
* @fulfil {Number} - user id
* @fulfil {Object} - user info
* @returns {Promise}
*
* @example
* balena.auth.getUserId().then(function(userId) {
* console.log(userId);
* balena.auth.getUserInfo().then(function(userInfo) {
* console.log(userInfo);
* });
*/
async function getUserId(): Promise<number> {
const { id } = await getUserDetails();
return id;
}
async function getUserInfo(): Promise<UserInfo> {
const actor = await getActorDetails();

/**
* @summary Get current logged in user's actor id
* @name getUserActorId
* @public
* @function
* @memberof balena.auth
*
* @description This will only work if you used {@link balena.auth.login} to log in.
*
* @fulfil {Number} - user id
* @returns {Promise}
*
* @example
* balena.auth.getUserActorId().then(function(userActorId) {
* console.log(userActorId);
* });
*/
async function getUserActorId(): Promise<number> {
const { actor } = (await pine.get({
resource: 'user',
id: await getUserId(),
options: {
$select: 'actor',
},
}))!;
return actor;
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 email
* @name getEmail
* @summary Get current logged in actor id
* @name getActorId
* @public
* @function
* @memberof balena.auth
*
* @description This will only work if you used {@link balena.auth.login} to log in.
* @description This will only work if you used {@link balena.auth.login} or {@link balena.auth.loginWithToken} to log in.
*
* @fulfil {String} - user email
* @fulfil {Number} - actor id
* @returns {Promise}
*
* @example
* balena.auth.getEmail().then(function(email) {
* console.log(email);
* balena.auth.getActorId().then(function(actorId) {
* console.log(actorId);
* });
*/
async function getEmail(): Promise<string> {
const { email } = await getUserDetails();
return email;
async function getActorId(): Promise<number> {
return (await getActorDetails()).id;
}

/**
Expand All @@ -370,7 +345,7 @@ const getAuth = function (
* balena.auth.logout();
*/
function logout(): Promise<void> {
memoizedUserWhoami.clear();
memoizedActorWhoami.clear();
return auth.removeKey();
}

Expand Down Expand Up @@ -474,7 +449,7 @@ const getAuth = function (
*
*/
async function requestVerificationEmail() {
const id = await getUserId();
const { id } = await getUserInfo();
await pine.patch({
resource: 'user',
id,
Expand All @@ -492,9 +467,8 @@ const getAuth = function (
loginWithToken,
isLoggedIn,
getToken,
getUserId,
getUserActorId,
getEmail,
getActorId,
getUserInfo,
logout,
register,
verifyEmail,
Expand Down
Loading

0 comments on commit f1482fd

Please sign in to comment.