Skip to content

Commit

Permalink
application.generateProvisioningKey: Change parameters to an object…
Browse files Browse the repository at this point in the history
… and require `keyExpiryDate`

Change-type: major
  • Loading branch information
myarmolinsky committed Jan 15, 2025
1 parent fd8aa4d commit 79133ec
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 49 deletions.
23 changes: 12 additions & 11 deletions DOCUMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ const sdk = fromSharedOptions();
* [.remove(slugOrUuidOrIdOrIds)](#balena.models.application.remove) ⇒ <code>Promise</code>
* [.rename(slugOrUuidOrId, newName)](#balena.models.application.rename) ⇒ <code>Promise</code>
* [.restart(slugOrUuidOrId)](#balena.models.application.restart) ⇒ <code>Promise</code>
* [.generateProvisioningKey(slugOrUuidOrId, [keyName], [keyDescription], [keyExpiryDate])](#balena.models.application.generateProvisioningKey) ⇒ <code>Promise</code>
* [.generateProvisioningKey(generateProvisioningKeyParams)](#balena.models.application.generateProvisioningKey) ⇒ <code>Promise</code>
* [.purge(appId)](#balena.models.application.purge) ⇒ <code>Promise</code>
* [.shutdown(appId, [options])](#balena.models.application.shutdown) ⇒ <code>Promise</code>
* [.reboot(appId, [options])](#balena.models.application.reboot) ⇒ <code>Promise</code>
Expand Down Expand Up @@ -617,7 +617,7 @@ balena.models.device.get(123).catch(function (error) {
* [.remove(slugOrUuidOrIdOrIds)](#balena.models.application.remove) ⇒ <code>Promise</code>
* [.rename(slugOrUuidOrId, newName)](#balena.models.application.rename) ⇒ <code>Promise</code>
* [.restart(slugOrUuidOrId)](#balena.models.application.restart) ⇒ <code>Promise</code>
* [.generateProvisioningKey(slugOrUuidOrId, [keyName], [keyDescription], [keyExpiryDate])](#balena.models.application.generateProvisioningKey) ⇒ <code>Promise</code>
* [.generateProvisioningKey(generateProvisioningKeyParams)](#balena.models.application.generateProvisioningKey) ⇒ <code>Promise</code>
* [.purge(appId)](#balena.models.application.purge) ⇒ <code>Promise</code>
* [.shutdown(appId, [options])](#balena.models.application.shutdown) ⇒ <code>Promise</code>
* [.reboot(appId, [options])](#balena.models.application.reboot) ⇒ <code>Promise</code>
Expand Down Expand Up @@ -869,7 +869,7 @@ balena.models.device.get(123).catch(function (error) {
* [.remove(slugOrUuidOrIdOrIds)](#balena.models.application.remove) ⇒ <code>Promise</code>
* [.rename(slugOrUuidOrId, newName)](#balena.models.application.rename) ⇒ <code>Promise</code>
* [.restart(slugOrUuidOrId)](#balena.models.application.restart) ⇒ <code>Promise</code>
* [.generateProvisioningKey(slugOrUuidOrId, [keyName], [keyDescription], [keyExpiryDate])](#balena.models.application.generateProvisioningKey) ⇒ <code>Promise</code>
* [.generateProvisioningKey(generateProvisioningKeyParams)](#balena.models.application.generateProvisioningKey) ⇒ <code>Promise</code>
* [.purge(appId)](#balena.models.application.purge) ⇒ <code>Promise</code>
* [.shutdown(appId, [options])](#balena.models.application.shutdown) ⇒ <code>Promise</code>
* [.reboot(appId, [options])](#balena.models.application.reboot) ⇒ <code>Promise</code>
Expand Down Expand Up @@ -1880,34 +1880,35 @@ balena.models.application.restart(123);
```
<a name="balena.models.application.generateProvisioningKey"></a>

##### application.generateProvisioningKey(slugOrUuidOrId, [keyName], [keyDescription], [keyExpiryDate]) ⇒ <code>Promise</code>
##### application.generateProvisioningKey(generateProvisioningKeyParams) ⇒ <code>Promise</code>
**Kind**: static method of [<code>application</code>](#balena.models.application)
**Summary**: Generate a device provisioning key for a specific application
**Access**: public
**Fulfil**: <code>String</code> - device provisioning key

| Param | Type | Description |
| --- | --- | --- |
| slugOrUuidOrId | <code>String</code> \| <code>Number</code> | application slug (string), uuid (string) or id (number) |
| [keyName] | <code>String</code> | Provisioning key name |
| [keyDescription] | <code>String</code> | Description for provisioning key |
| [keyExpiryDate] | <code>String</code> | Expiry Date for provisioning key |
| generateProvisioningKeyParams | <code>Object</code> | an object containing the parameters for the provisioning key generation |
| generateProvisioningKeyParams.slugOrUuidOrId | <code>String</code> \| <code>Number</code> | application slug (string), uuid (string) or id (number) |
| generateProvisioningKeyParams.keyExpiryDate | <code>String</code> | Expiry Date for provisioning key |
| [generateProvisioningKeyParams.keyName] | <code>String</code> | Provisioning key name |
| [generateProvisioningKeyParams.keyDescription] | <code>String</code> | Description for provisioning key |

**Example**
```js
balena.models.application.generateProvisioningKey('myorganization/myapp').then(function(key) {
balena.models.application.generateProvisioningKey({slugOrUuidOrId: 'myorganization/myapp', keyExpiryDate: '2030-10-12'}).then(function(key) {
console.log(key);
});
```
**Example**
```js
balena.models.application.generateProvisioningKey(123).then(function(key) {
balena.models.application.generateProvisioningKey({slugOrUuidOrId: 123, keyExpiryDate: '2030-10-12'}).then(function(key) {
console.log(key);
});
```
**Example**
```js
balena.models.application.generateProvisioningKey(123, 'api key name', 'api key long description', '2030-01-01T00:00:00Z').then(function(key) {
balena.models.application.generateProvisioningKey({slugOrUuidOrId: 123, keyExpiryDate: '2030-10-12', keyName: 'api key name', keyDescription: 'api key long description'}).then(function(key) {
console.log(key);
});
```
Expand Down
32 changes: 19 additions & 13 deletions src/models/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -825,34 +825,40 @@ const getApplicationModel = function (
* @function
* @memberof balena.models.application
*
* @param {String|Number} slugOrUuidOrId - application slug (string), uuid (string) or id (number)
* @param {String} [keyName] - Provisioning key name
* @param {String} [keyDescription] - Description for provisioning key
* @param {String} [keyExpiryDate] - Expiry Date for provisioning key
* @param {Object} generateProvisioningKeyParams - an object containing the parameters for the provisioning key generation
* @param {String|Number} generateProvisioningKeyParams.slugOrUuidOrId - application slug (string), uuid (string) or id (number)
* @param {String} generateProvisioningKeyParams.keyExpiryDate - Expiry Date for provisioning key
* @param {String} [generateProvisioningKeyParams.keyName] - Provisioning key name
* @param {String} [generateProvisioningKeyParams.keyDescription] - Description for provisioning key
* @fulfil {String} - device provisioning key
* @returns {Promise}
*
* @example
* balena.models.application.generateProvisioningKey('myorganization/myapp').then(function(key) {
* balena.models.application.generateProvisioningKey({slugOrUuidOrId: 'myorganization/myapp', keyExpiryDate: '2030-10-12'}).then(function(key) {
* console.log(key);
* });
*
* @example
* balena.models.application.generateProvisioningKey(123).then(function(key) {
* balena.models.application.generateProvisioningKey({slugOrUuidOrId: 123, keyExpiryDate: '2030-10-12'}).then(function(key) {
* console.log(key);
* });
*
* @example
* balena.models.application.generateProvisioningKey(123, 'api key name', 'api key long description', '2030-01-01T00:00:00Z').then(function(key) {
* balena.models.application.generateProvisioningKey({slugOrUuidOrId: 123, keyExpiryDate: '2030-10-12', keyName: 'api key name', keyDescription: 'api key long description'}).then(function(key) {
* console.log(key);
* });
*/
generateProvisioningKey: async (
slugOrUuidOrId: string | number,
keyName?: string,
keyDescription?: string,
keyExpiryDate?: string,
): Promise<string> => {
generateProvisioningKey: async ({
slugOrUuidOrId,
keyExpiryDate,
keyName,
keyDescription,
}: {
slugOrUuidOrId: string | number;
keyExpiryDate: string | null;
keyName?: string;
keyDescription?: string;
}): Promise<string> => {
const applicationId = (
await sdkInstance.models.application.get(slugOrUuidOrId, {
$select: 'id',
Expand Down
9 changes: 6 additions & 3 deletions src/models/device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1371,9 +1371,12 @@ const getDeviceModel = function (
const [{ id: userId }, apiKey, application, deviceType] =
await Promise.all([
sdkInstance.auth.getUserInfo(),
sdkInstance.models.application.generateProvisioningKey(
applicationSlugOrUuidOrId,
),
sdkInstance.models.application.generateProvisioningKey({
slugOrUuidOrId: applicationSlugOrUuidOrId,
// Use 10 minute expiry date as we will immediately use the provisioning key to create a device and then not need it
keyExpiryDate: new Date(Date.now() + 1000 * 60 * 10).toISOString(),
keyDescription: 'Created by SDK to register a device',
}),
sdkInstance.models.application.get(
applicationSlugOrUuidOrId,
applicationOptions,
Expand Down
7 changes: 4 additions & 3 deletions tests/integration/models/api-key.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,10 @@ describe('API Key model', function () {
});
ctx.namedUserApiKey = apiKey;

await balena.models.application.generateProvisioningKey(
this.application.id,
);
await balena.models.application.generateProvisioningKey({
slugOrUuidOrId: this.application.id,
keyExpiryDate: new Date(Date.now() + 1000 * 60 * 60).toISOString(),
});

await balena.models.device.generateDeviceKey(this.device.id);
});
Expand Down
55 changes: 39 additions & 16 deletions tests/integration/models/application.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,12 @@ describe('Application Model', function () {
applicationRetrievalFields.forEach((prop) => {
it(`should be able to generate a provisioning key by ${prop}`, function () {
return balena.models.application
.generateProvisioningKey(this.application[prop])
.generateProvisioningKey({
slugOrUuidOrId: this.application[prop],
keyExpiryDate: new Date(
Date.now() + 1000 * 60 * 60,
).toISOString(),
})
.then(function (key) {
expect(_.isString(key)).to.be.true;
return expect(key).to.have.length(32);
Expand All @@ -624,8 +629,13 @@ describe('Application Model', function () {
);

const key = await balena.models.application.generateProvisioningKey(
this.application[prop],
`key_${prop}`,
{
slugOrUuidOrId: this.application[prop],
keyExpiryDate: new Date(
Date.now() + 1000 * 60 * 60,
).toISOString(),
keyName: `key_${prop}`,
},
);

expect(key).to.be.a('string');
Expand Down Expand Up @@ -653,9 +663,14 @@ describe('Application Model', function () {
);

const key = await balena.models.application.generateProvisioningKey(
this.application[prop],
`key_${prop}`,
`Provisioning key generated with name key_${prop}`,
{
slugOrUuidOrId: this.application[prop],
keyExpiryDate: new Date(
Date.now() + 1000 * 60 * 60,
).toISOString(),
keyName: `key_${prop}`,
keyDescription: `Provisioning key generated with name key_${prop}`,
},
);

expect(key).to.be.a('string');
Expand All @@ -682,11 +697,16 @@ describe('Application Model', function () {
this.application[prop],
);

const oneHourDate = new Date(
Date.now() + 1000 * 60 * 60,
).toISOString();
const key = await balena.models.application.generateProvisioningKey(
this.application[prop],
`key_${prop}`,
`Provisioning key generated with name key_${prop}`,
'2030-01-01',
{
slugOrUuidOrId: this.application[prop],
keyExpiryDate: oneHourDate,
keyName: `key_${prop}`,
keyDescription: `Provisioning key generated with name key_${prop}`,
},
);

expect(key).to.be.a('string');
Expand All @@ -705,22 +725,25 @@ describe('Application Model', function () {
expect(provisionKeys[0]).to.have.property('expiry_date');
expect(provisionKeys[0])
.to.have.property('expiry_date')
.to.be.equal('2030-01-01T00:00:00.000Z');
.to.be.equal(oneHourDate);
});
});

it('should be rejected if the application slug does not exist', function () {
const promise = balena.models.application.generateProvisioningKey(
`${this.initialOrg.handle}/helloworldapp`,
);
const promise = balena.models.application.generateProvisioningKey({
slugOrUuidOrId: `${this.initialOrg.handle}/helloworldapp`,
keyExpiryDate: new Date(Date.now() + 1000 * 60 * 60).toISOString(),
});
return expect(promise).to.be.rejectedWith(
`Application not found: ${this.initialOrg.handle}/helloworldapp`,
);
});

it('should be rejected if the application id does not exist', function () {
const promise =
balena.models.application.generateProvisioningKey(999999);
const promise = balena.models.application.generateProvisioningKey({
slugOrUuidOrId: 999999,
keyExpiryDate: new Date(Date.now() + 1000 * 60 * 60).toISOString(),
});
return expect(promise).to.be.rejectedWith(
'Application not found: 999999',
);
Expand Down
7 changes: 4 additions & 3 deletions tests/integration/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,9 +361,10 @@ export function givenLoggedInWithAnApplicationApiKey(
givenAnApplication(beforeFn);

beforeFn(async function () {
const key = await balena.models.application.generateProvisioningKey(
this.application.slug,
);
const key = await balena.models.application.generateProvisioningKey({
slugOrUuidOrId: this.application.slug,
keyExpiryDate: new Date(Date.now() + 1000 * 60 * 60).toISOString(),
});
await balena.auth.logout();
await balena.auth.loginWithToken(key);
});
Expand Down

0 comments on commit 79133ec

Please sign in to comment.