diff --git a/lerna.json b/lerna.json index 2dcf6b9a7..255bd06a7 100644 --- a/lerna.json +++ b/lerna.json @@ -14,7 +14,6 @@ "provisioning/transport/*", "provisioning/device/samples", "provisioning/device/ts-samples", - "provisioning/service/samples", "security/*", "sdklab/longhaultests", "sdklab/mean_time_recovery", diff --git a/provisioning/service/.npmignore b/provisioning/service/.npmignore deleted file mode 100644 index 8177004d4..000000000 --- a/provisioning/service/.npmignore +++ /dev/null @@ -1,7 +0,0 @@ -coverage/ -devdoc/ -test/ -samples/ -src/ -dist/**/*.map -.nyc_output \ No newline at end of file diff --git a/provisioning/service/devdoc/provisioningserviceclient.md b/provisioning/service/devdoc/provisioningserviceclient.md deleted file mode 100644 index 54a5a6475..000000000 --- a/provisioning/service/devdoc/provisioningserviceclient.md +++ /dev/null @@ -1,272 +0,0 @@ -# azure-iot-provisioning-service.ProvisioningServiceClient Requirements - -## Overview -`ProvisioningServiceClient` provides CRUD operations for the service client for the provisioning service - -## Example usage -TBD - -## Constructor/Factory methods - -### ProvisioningServiceClient(config, restApiClient) [constructor] - -The `ProvisioningServiceClient` construction initializes a new instance of a `ProvisioningServiceClient` object that is used to conduct CRUD operations with the provisioning service - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_001: [** The `ProvisioningServiceClient` construction shall throw a `ReferenceError` if the `config` object is falsy. **]** -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_002: [** The `ProvisioningServiceClient` constructor shall throw an `ArgumentError` if the `config` object is missing one or more of the following properties: -- `host`: the IoT Hub hostname -- `sharedAccessSignature`: shared access signature with the permissions for the desired operations. **]** -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_003: [** The `ProvisioningServiceClient` constructor shall use the `restApiClient` provided as a second argument if it is provided. **]** -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_004: [** The `ProvisioningServiceClient` constructor shall use `azure-iot-http-base.RestApiClient` if no `restApiClient` argument is provided. **]** - -### fromConnectionString(value) [static] - -The `fromConnectionString` static method returns a new instance of the `ProvisioningServiceClient` object. - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_005: [** The `fromConnectionString` method shall throw `ReferenceError` if the `value` argument is falsy. **]** -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_006: [** `fromConnectionString` method shall derive and transform the needed parts from the connection string in order to create a `config` object for the constructor (see `SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_002`). **]** -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_007: [** The `fromConnectionString` method shall return a new instance of the `ProvisioningServiceClient` object. **]** - -### createOrUpdateIndividualEnrollment(enrollment, createOrUpdateIndividualEnrollmentCallback) -The `createOrUpdateIndividualEnrollment` method adds a device enrollment. - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_009: [** The `createOrUpdateIndividualEnrollment` method shall throw `ReferenceError` if the `enrollment` argument is falsy. **]** -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_011: [** The `createOrUpdateIndividualEnrollment` method shall throw `ArgumentError` if the `enrollment.registrationId` property is falsy. **]** -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_056: [** If the `enrollment` object contains an `etag` property it will be added as the value of the `If-Match` header of the http request. **]** -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_010: [** The `createOrUpdateIndividualEnrollment` method shall construct an HTTP request using information supplied by the caller, as follows: -``` -PUT /enrollments/?api-version= HTTP/1.1 -Authorization: -Accept: application/json -Content-Type: application/json; charset=utf-8 - - -``` -**]** - -### createOrUpdateEnrollmentGroup(enrollmentGroup, createOrUpdateEnrollmentGroupCallback) -The `createOrUpdateEnrollmentGroup` method adds a device enrollment group. - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_012: [** The `createOrUpdateEnrollmentGroup` method shall throw `ReferenceError` if the `EnrollmentGroup` argument is falsy. **]** -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_013: [** `createOrUpdateEnrollmentGroup` method shall throw `ArgumentError` if the `enrollmentGroup.enrollmentGroupsId` property is falsy. **]** -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_055: [** If the `enrollmentGroup` object contains an `etag` property it will be added as the value of the `If-Match` header of the http request. **]** -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_014: [** The `createOrUpdateEnrollmentGroup` method shall construct an HTTP request using information supplied by the caller, as follows: -``` -PUT /enrollmentGroups/?api-version= HTTP/1.1 -Authorization: -Accept: application/json -Content-Type: application/json; charset=utf-8 - - -``` -**]** - - -### deleteIndividualEnrollment(enrollmentOrId, etagOrCallback, deleteCallback) -The `deleteIndividualEnrollment` method deletes a device enrollment. - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_015: [** The `deleteIndividualEnrollment` method shall throw `ReferenceError` if the `enrollmentOrId` argument is falsy. **]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_040: [** The `deleteIndividualEnrollment` method, if the first argument is a string, the second argument if present, must be a string or a callback, otherwise shall throw `ArgumentError`. **]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_041: [** The `deleteIndividualEnrollment` method, if the first argument is a string and the second argument is a string, the third argument if present, must be a callback, otherwise shall throw `ArgumentError`.**]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_042: [** The `deleteIndividualEnrollment` method, if the first argument is an `IndividualEnrollment` object, the second argument if present, must be a callback, otherwise shall throw `ArgumentError`.**]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_017: [** The `deleteIndividualEnrollment` method, if the first argument is an `IndividualEnrollment` object, shall throw an `ArgumentError`, if the `registrationId` property is falsy. **]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_043: [** The `deleteIndividualEnrollment` method, if the first argument is a string, and the second argument is NOT a string, shall construct an HTTP request using information supplied by the caller as follows: -``` -DELETE /enrollments/?api-version= HTTP/1.1 -Authorization: -``` -**]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_044: [** The `deleteIndividualEnrollment` method, if the first argument is a string, and the second argument is a string, shall construct an HTTP request using information supplied by the caller as follows: -``` -DELETE /enrollments/?api-version= HTTP/1.1 -If-Match: -Authorization: -``` -**]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_021: [** The `deleteIndividualEnrollment` method, if the first argument is an `IndividualEnrollment` object, with a non-falsy `etag` property, shall construct an HTTP request using information supplied by the caller as follows: -``` -DELETE /enrollments/?api-version= HTTP/1.1 -If-Match: enrollmentOrId.etag -Authorization: -``` -**]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_024: [** The `deleteIndividualEnrollment` method, if the first argument is an `IndividualEnrollment` object, with a falsy `etag` property, shall construct an HTTP request using information supplied by the caller as follows: -``` -DELETE /enrollments/?api-version= HTTP/1.1 -Authorization: -``` -**]** - -### deleteEnrollmentGroup(enrollmentGroupOrId, deleteCallback) -The `deleteEnrollmentGroup` method deletes an enrollment group. - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_016: [** The `deleteEnrollmentGroup` method shall throw `ReferenceError` if the `enrollmentGroupOrId` argument is falsy. **]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_045: [** The `deleteEnrollmentGroup` method, if the first argument is a string, the second argument if present, must be a string or a callback, otherwise shall throw `ArgumentError`. **]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_046: [** The `deleteEnrollmentGroup` method, if the first argument is a string and the second argument is a string, the third argument if present, must be a callback, otherwise shall throw `ArgumentError`. **]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_047: [** The `deleteEnrollmentGroup` method, if the first argument is an `EnrollmentGroup` object, the second argument if present, must be a callback, otherwise shall throw `ArgumentError`. **]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_018: [** The `deleteEnrollmentGroup` method, if the first argument is an `EnrollmentGroup` object, shall throw an `ArgumentError`, if the `enrollmentGroupId' property is falsy. **]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_048: [** The `deleteEnrollmentGroup` method, if the first argument is a string, and the second argument is NOT a string, shall construct an HTTP request using information supplied by the caller as follows: -``` -DELETE /enrollmentGroups/?api-version= HTTP/1.1 -Authorization: -``` -**]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_049: [** The `deleteEnrollmentGroup` method, if the first argument is a string, and the second argument is a string, shall construct an HTTP request using information supplied by the caller as follows: -``` -DELETE /enrollmentGroups/?api-version= HTTP/1.1 -If-Match: -Authorization: -``` -**]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_022: [** The `deleteEnrollmentGroup` method, if the first argument is an `EnrollmentGroup` object, with a non-falsy `etag` property, shall construct an HTTP request using information supplied by the caller as follows: -``` -DELETE /enrollmentGroups/?api-version= HTTP/1.1 -If-Match: enrollmentGroupOrId.etag -Authorization: -``` -**]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_023: [** The `deleteEnrollmentGroup` method, if the first argument is an `EnrollmentGroup` object, with a falsy `etag` property, shall construct an HTTP request using information supplied by the caller as follows: -``` -DELETE /enrollmentGroups/?api-version= HTTP/1.1 -Authorization: -``` -**]** - -### deleteDeviceRegistrationState(idOrRegistrationState, deleteCallback) -The `deleteDeviceRegistrationState` method deletes a registration state. - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_025: [** The `deleteDeviceRegistrationState` method shall throw `ReferenceError` if the `idOrRegistrationState` argument is falsy. **]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_050: [** The `deleteDeviceRegistrationState` method, if the first argument is a string, the second argument if present, must be a string or a callback, otherwise shall throw `ArgumentError`. **]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_051: [** The `deleteDeviceRegistrationState` method, if the first argument is a string and the second argument is a string, the third argument if present, must be a callback, otherwise shall throw `ArgumentError`. **]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_052: [** The `deleteDeviceRegistrationState` method, if the first argument is an `DeviceRegistrationState` object, the second argument if present, must be a callback, otherwise shall throw `ArgumentError`. **]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_026: [** The `deleteDeviceRegistrationState` method, if the first argument is a `DeviceRegistrationState` object, shall throw an `ArgumentError`, if the `registrationId' property is falsy. **]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_053: [** The `deleteDeviceRegistrationState` method, if the first argument is a string, and the second argument is NOT a string, shall construct an HTTP request using information supplied by the caller as follows: -``` -DELETE /registrations/?api-version= HTTP/1.1 -Authorization: -``` -**]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_054: [** The `deleteDeviceRegistrationState` method, if the first argument is a string, and the second argument is a string, shall construct an HTTP request using information supplied by the caller as follows: -``` -DELETE /registrations/?api-version= HTTP/1.1 -If-Match: -Authorization: -``` -**]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_028: [** The `deleteDeviceRegistrationState` method, if the first argument is a `DeviceRegistrationState` object, with a non-falsy `etag` property, shall construct an HTTP request using information supplied by the caller as follows: -``` -DELETE /registrations/?api-version= HTTP/1.1 -If-Match: idOrRegistrationState.etag -Authorization: -``` -**]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_029: [** The `deleteDeviceRegistrationState` method, if the first argument is a `DeviceRegistrationState` object, with a falsy `etag` property, shall construct an HTTP request using information supplied by the caller as follows: -``` -DELETE /registrations/?api-version= HTTP/1.1 -Authorization: -``` -**]** - -### getIndividualEnrollment(id, getCallback) -The `getIndividualEnrollment` method returns an `IndividualEnrollment` object. - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_030: [** The `getIndividualEnrollment` method shall throw `ReferenceError` if the `id` argument is falsy. **]** -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_033: [** The `getIndividualEnrollment` method shall construct an HTTP request using information supplied by the caller as follows: -``` -GET /enrollments/?api-version= HTTP/1.1 -Accept: application/json -Authorization: -``` -**]** - -### getEnrollmentGroup(id, getEnrollmentGroupCallback) -The `getEnrollmentGroup` method returns an `EnrollmentGroup` object - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_031: [** The `getEnrollmentGroup` method shall throw `ReferenceError` if the `id` argument is falsy. **]** -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_034: [** The `getEnrollmentGroup` method shall construct an HTTP request using information supplied by the caller as follows: -``` -GET /enrollmentGroups/?api-version= HTTP/1.1 -Authorization: -``` -**]** - -### getDeviceRegistrationState(id, deviceRegistrationsStateCallback) -The `getDeviceRegistrationState` returns a `DeviceRegistrationState`. - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_032: [** The `getDeviceRegistrationState` method shall throw `ReferenceError` if the `id` argument is falsy. **]** -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_035: [** The `getDeviceRegistrationState` method shall construct an HTTP request using information supplied by the caller as follows: -``` -GET /registrations/?api-version= HTTP/1.1 -Authorization: -``` -**]** - -### runBulkEnrollmentOperation(bulkEnrollmentOperation, bulkEnrollmentOperationCallback) -The `runBulkEnrollmentOperation` can perform CRUD operations on IndividualEnrollment objects in bulk. - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_038: [** The `runBulkEnrollmentOperation` method shall throw `ReferenceError` if the `bulkEnrollmentOperation` argument is falsy. **]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_039: [** The `runBulkEnrollmentOperation` method shall construct an HTTP request using information supplied by the caller as follows: -``` -POST /enrollments?api-version= HTTP/1.1 -Authorization: -Accept: application/json -Content-Type: application/json; charset=utf-8 - - -``` -**]** - -### getIndividualEnrollmentAttestationMechanism(enrollementId: string, callback: (err: Error, attestationMechanism?: AttestationMechanism) => void): void; -The `getIndividualEnrollmentAttestationMechanism` method gets the `AttestationMechanism` object of a specific enrollment record. - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_16_001: [** The `getIndividualEnrollmentAttestationMechanism` method shall throw a `ReferenceError` if the `enrollmentId` parameter is falsy. **]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_16_002: [** The `getIndividualEnrollmentAttestationMechanism` shall construct an HTTP request using information supplied by the caller as follows: -``` -POST /enrollments//attestationmechanism?api-version= HTTP/1.1 -Authorization: -``` -**]** - -### getEnrollmentGroupAttestationMechanism(enrollementGroupId: string, callback: (err: Error, attestationMechanism?: AttestationMechanism) => void): void; -The `getEnrollmentGroupAttestationMechanism` method gets the `AttestationMechanism` object of a specific enrollment record. - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_16_003: [** The `getEnrollmentGroupAttestationMechanism` method shall throw a `ReferenceError` if the `enrollementGroupId` parameter is falsy. **]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_16_004: [** The `getEnrollmentGroupAttestationMechanism` shall construct an HTTP request using information supplied by the caller as follows: -``` -POST /enrollmentgroups//attestationmechanism?api-version= HTTP/1.1 -Authorization: -``` -**]** - -### Generic HTTP Requirements - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_036: [** If any device enrollment operation method encounters an error before it can send the request, it shall invoke the `done` callback function and pass the standard JavaScript `Error` object with a text description of the error (err.message). **]** - -**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_037: [** When any registry operation method receives an HTTP response with a status code >= 300, it shall invoke the `done` callback function with an error translated using the requirements detailed in `registry_http_errors_requirements.md` **]** \ No newline at end of file diff --git a/provisioning/service/iotprovisioningservice.d.ts b/provisioning/service/iotprovisioningservice.d.ts deleted file mode 100644 index c8b2e3608..000000000 --- a/provisioning/service/iotprovisioningservice.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -export { ProvisioningServiceClient } from './dist/provisioningserviceclient'; diff --git a/provisioning/service/iotprovisioningservice.js b/provisioning/service/iotprovisioningservice.js deleted file mode 100644 index d69a6fbb0..000000000 --- a/provisioning/service/iotprovisioningservice.js +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -'use strict'; - -/** - * The Azure IoT Provisioning Service SDK for Node.js allows applications to perform - * CRUD operations on enrollments and enrollmentGroups as well as deleting device registration - * status objects. - * @module azure-iot-provisioning-service - */ -module.exports = { - ProvisioningServiceClient: require('./dist/provisioningserviceclient.js').ProvisioningServiceClient -}; \ No newline at end of file diff --git a/provisioning/service/package.json b/provisioning/service/package.json deleted file mode 100644 index 17dfac2be..000000000 --- a/provisioning/service/package.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "name": "azure-iot-provisioning-service", - "version": "1.10.1", - "description": "Azure IoT SDK - Provisioning Service Client", - "author": "Microsoft Corporation", - "license": "MIT", - "main": "iotprovisioningservice.js", - "typings": "iotprovisioningservice.d.ts", - "dependencies": { - "async": "^3.2.3", - "es5-ext": "0.10.53", - "azure-iot-common": "1.13.2", - "azure-iot-http-base": "1.12.2", - "debug": "^4.3.1", - "@azure/core-http": "^1.2.3" - }, - "devDependencies": { - "@types/debug": "^4.1.5", - "@types/node": "^16.10.2", - "chai": "^4.3.3", - "mocha": "^9.2.1", - "nyc": "^15.0.0", - "sinon": "^11.1.2", - "source-map-support": "^0.5.16", - "ts-node": "^8.6.2", - "tslint": "^6.1.3", - "typescript": "4.4.4" - }, - "scripts": { - "npmlockrefresh": "npm i --package-lock-only", - "lint": "tslint --project . -c ../../tslint.json", - "build": "tsc", - "unittest-min": "tsc && nyc --reporter lcov ../../node_modules/mocha/bin/_mocha --reporter dot", - "alltest-min": "tsc && nyc --reporter lcov ../../node_modules/mocha/bin/_mocha --reporter dot test/_*_test*.js", - "unittest": "tsc && nyc --reporter lcov --reporter text ../../node_modules/mocha/bin/_mocha", - "alltest": "tsc && nyc --reporter lcov --reporter text ../../node_modules/mocha/bin/_mocha test/_*_test*.js", - "ci": "npm -s run lint && npm -s run build && npm -s run alltest-min", - "test": "npm -s run lint && npm -s run build && npm -s run alltest" - }, - "nyc": { - "exclude": [ - "coverage/**", - "**/*.d.ts", - "test{,s}/**", - "test{,-*}.{js,cjs,mjs,ts}", - "**/*{.,-}test.{js,cjs,mjs,ts}", - "**/__tests__/**", - "**/{ava,nyc}.config.{js,cjs,mjs}", - "**/jest.config.{js,cjs,mjs,ts}", - "**/{karma,rollup,webpack}.config.js", - "**/{babel.config,.eslintrc,.mocharc}.{js,cjs}" - ], - "extension": [ - ".ts", - ".tsx" - ], - "check-coverage": true, - "lines": 80, - "functions": 78, - "branches": 74, - "statements": 79 - }, - "mocha": { - "require": [ - "ts-node/register", - "source-map-support/register" - ], - "full-trace": true, - "bail": true, - "spec": "test/**/_*_test.js" - }, - "engines": { - "node": ">= 14.0.0" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/Azure/azure-iot-sdk-node.git" - }, - "bugs": { - "url": "https://github.com/Azure/azure-iot-sdk-node/issues" - }, - "homepage": "https://github.com/Azure/azure-iot-sdk-node#readme" -} \ No newline at end of file diff --git a/provisioning/service/readme.md b/provisioning/service/readme.md deleted file mode 100644 index 8d8cabd85..000000000 --- a/provisioning/service/readme.md +++ /dev/null @@ -1,86 +0,0 @@ -# Microsoft Azure IoT Provisioning Service SDK for Node.js - -The Azure IoT Provisioning Service SDK for Node.js helps you build applications that perform CRUD operations with the provisioning service for your enrollments. - -[![npm version](https://badge.fury.io/js/azure-iot-provisioning-service.svg)](https://badge.fury.io/js/azure-iot-provisioning-service) - -## Prerequisites -You need to install the [Node.js][nodejs_lnk] JavaScript runtime environment to run the Azure IoT JavaScript client SDK on your platform. To check if Node.js supports your platform (OS), verify that an install package is available on the [Node.js download page][nodejs_dwld_lnk]. - -[npm][npm_lnk] is a command-line package manager that is installed with Node.js is installed, and will be used to install Azure IoT node.js client side SDK. - -## Installation - -`npm install -g azure-iot-provisioning-service@latest` to get the latest (pre-release) version. - -`npm install -g azure-iot-provisioning-service` to get the latest (release) version. - -## Features - -* Create, update, delete, query, and get individual enrollments and enrollment groups in your provisioning service. Additionally you can query, get and delete device registration states. - -## How to use the Azure IoT Provisioning Service SDK for Node.js - -Once you have installed the package as indicated above, you can start using the features of the Service SDK in your code. Below is a code snippet showing how to add a new enrollment in the provisioning registry: - -Note that for this sample to work, you will need to [setup your IoT Provisioning Service][lnk-setup-iot-provisioning] and retrieve credentials for the service app. - -``` -var provisioningServiceClient = require('azure-iot-provisioning-service').ProvisioningServiceClient; - -var serviceClient = provisioningServiceClient.fromConnectionString(process.argv[2]); - -var enrollment = { - registrationId: 'first', - attestation: { - type: 'tpm', - tpm: { - endorsementKey: 'a' - } - } -}; - -serviceClient.createOrUpdateIndividualEnrollment(enrollment, function(err, enrollmentResponse) { - if (err) { - console.log('error creating the enrollment: ' + err); - } else { - console.log("enrollment record returned: " + JSON.stringify(enrollmentResponse, null, 2)) - } -}); -``` - -Check out the [samples][samples] for details on the various features of the Service SDK - -## Read more - -* [Node.js Provisioning Service API reference documentation][node-api-reference] - - -## Directory structure - -Service SDK subfolders: - -### /devdoc - -Development requirements documentation - -### /lib - -Code for the library - -### /Samples - -Set of simple samples showing how to use the features of the Service SDK - -### /test - -Test files - -[nodejs_lnk]: https://nodejs.org/ -[nodejs_dwld_lnk]: https://nodejs.org/en/download/ -[npm_lnk]:https://docs.npmjs.com/getting-started/what-is-npm -[samples]: ./samples/ -[lnk-setup-iot-provisioning]: https://docs.microsoft.com/en-us/azure/iot-dps/quick-setup-auto-provision -[node-api-reference]: https://docs.microsoft.com/en-us/javascript/api/azure-iot-provisioning-service -[iot-dev-center]: http://azure.com/iotdev -[iot-hub-documentation]: https://docs.microsoft.com/en-us/azure/iot-hub/ diff --git a/provisioning/service/samples/create_delete.js b/provisioning/service/samples/create_delete.js deleted file mode 100644 index 61f24ab01..000000000 --- a/provisioning/service/samples/create_delete.js +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -'use strict'; - -var provisioningServiceClient = require('azure-iot-provisioning-service').ProvisioningServiceClient; - -var argv = require('yargs') - .usage('Usage: $0 --connectionstring ') - .option('connectionstring', { - alias: 'c', - describe: 'The connection string for the Device Provisioning instance', - type: 'string', - demandOption: true - }) - .argv; - -var connectionString = argv.connectionString; -var serviceClient = provisioningServiceClient.fromConnectionString(connectionString); - -var enrollment1 = { - registrationId: 'first', - attestation: { - type: 'tpm', - tpm: { - endorsementKey: 'a' - } - } -}; - -var enrollment2 = { - registrationId: 'second', - attestation: { - type: 'tpm', - tpm: { - endorsementKey: 'a' - } - } -}; - -serviceClient.createOrUpdateIndividualEnrollment(enrollment1, function (err, firstEnrollmentResponse) { - if (err) { - console.log('error creating the first enrollment: ' + err); - } else { - console.log("enrollment record returned for first: " + JSON.stringify(firstEnrollmentResponse, null, 2)); - serviceClient.createOrUpdateIndividualEnrollment(enrollment2, function (err, secondEnrollmentResponse) { - if (err) { - console.log('error creating the second enrollment: ' + err); - } else { - console.log("enrollment record returned for second: " + JSON.stringify(secondEnrollmentResponse, null, 2)); - // - // deleteIndividualEnrollment can take an IndividualEnrollment object or a registrationId with optional etag. - // If the etag is included and it doesn't match, the delete will fail. - // - serviceClient.deleteIndividualEnrollment(firstEnrollmentResponse.registrationId, 'badetag', function (err) { - if (err) { - serviceClient.deleteIndividualEnrollment(firstEnrollmentResponse.registrationId, firstEnrollmentResponse.etag, function (err) { - if (err) { - console.log('error deleting the first enrollment: ' + err); - } else { - serviceClient.deleteIndividualEnrollment(secondEnrollmentResponse, function (err) { - if (err) { - console.log('error deleting the second enrollment: ' + err); - } - }); - } - }); - } else { - console.log('The first delete should have failed because of an etag mismatch!'); - } - }); - } - }); - } -}); diff --git a/provisioning/service/samples/create_enrollment_group.js b/provisioning/service/samples/create_enrollment_group.js deleted file mode 100644 index 6b9350388..000000000 --- a/provisioning/service/samples/create_enrollment_group.js +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -'use strict'; -var fs = require('fs'); - -var provisioningServiceClient = require('azure-iot-provisioning-service').ProvisioningServiceClient; - -var argv = require('yargs') - .usage('Usage: $0 --connectionstring --certificagte ') - .option('connectionstring', { - alias: 'c', - describe: 'The connection string for the Device Provisioning instance', - type: 'string', - demandOption: true - }) - .option('certificate', { - alias: 'ce', - describe: 'certificated used for group enrollment', - type: 'string', - demandOption: true - }) - .argv; - -var connectionString = argv.connectionString; -var certificate = argv.certificate; -var serviceClient = provisioningServiceClient.fromConnectionString(connectionString); - -var enrollment = { - enrollmentGroupId: 'first', - attestation: { - type: 'x509', - x509: { - signingCertificates: { - primary: { - certificate: fs.readFileSync(certificate, 'utf-8').toString() - } - } - } - }, - provisioningStatus: 'disabled' -}; - -serviceClient.createOrUpdateEnrollmentGroup(enrollment, function (err, enrollmentResponse) { - if (err) { - console.log('error creating the group enrollment: ' + err); - } else { - console.log("enrollment record returned: " + JSON.stringify(enrollmentResponse, null, 2)); - enrollmentResponse.provisioningStatus = 'enabled'; - serviceClient.createOrUpdateEnrollmentGroup(enrollmentResponse, function (err, enrollmentResponse) { - if (err) { - console.log('error updating the group enrollment: ' + err); - } else { - console.log("updated enrollment record returned: " + JSON.stringify(enrollmentResponse, null, 2)); - } - }); - } -}); \ No newline at end of file diff --git a/provisioning/service/samples/create_individual_symmetric_enrollment.js b/provisioning/service/samples/create_individual_symmetric_enrollment.js deleted file mode 100644 index 1ba4f49ef..000000000 --- a/provisioning/service/samples/create_individual_symmetric_enrollment.js +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -'use strict'; -var provisioningServiceClient = require('azure-iot-provisioning-service').ProvisioningServiceClient; - -var argv = require('yargs') - .usage('Usage: $0 --deviceid --connectionstring --webhookurl ') - .option('deviceid', { - alias: 'd', - describe: 'Unique identifier for the device that shall be created', - type: 'string', - demandOption: true - }) - .option('connectionstring', { - alias: 'c', - describe: 'The connection string for the Device Provisioning instance', - type: 'string', - demandOption: true - }) - .option('webhookurl', { - alias: 'w', - describe: 'web url of the azure function', - type: 'string', - demandOption: true - }) - .argv; - -var deviceID = argv.deviceid; -var connectionString = argv.connectionstring; -var webHookUrl = argv.webhookurl; - -var serviceClient = provisioningServiceClient.fromConnectionString(connectionString); - -var enrollment = { - registrationId: deviceID, - deviceID: deviceID, - attestation: { - type: 'symmetricKey' - }, - provisioningStatus: 'enabled', - allocationPolicy: 'custom', - customAllocationDefinition: { - webhookUrl: webHookUrl, - apiVersion: '2019-03-31' - } -}; - -serviceClient.createOrUpdateIndividualEnrollment(enrollment, function (err, enrollmentResponse) { - if (err) { - console.log('error creating the individual enrollment: ' + err); - } else { - console.log("enrollment record returned: " + JSON.stringify(enrollmentResponse, null, 2)); - } -}); diff --git a/provisioning/service/samples/create_individual_tpm_enrollment.js b/provisioning/service/samples/create_individual_tpm_enrollment.js deleted file mode 100644 index 74916420e..000000000 --- a/provisioning/service/samples/create_individual_tpm_enrollment.js +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -'use strict'; - -var provisioningServiceClient = require('azure-iot-provisioning-service').ProvisioningServiceClient; - -var argv = require('yargs') - .usage('Usage: $0 --endorsementkey --connectionstring ') - .option('endorsementKey', { - alias: 'e', - describe: 'Endorsment key for TPM', - type: 'string', - demandOption: true - }) - .option('connectionstring', { - alias: 'c', - describe: 'The connection string for the Device Provisioning instance', - type: 'string', - demandOption: true - }) - .argv; - -var endorsementKey = argv.endorsementKey; -var connectionString = argv.connectionString; -var serviceClient = provisioningServiceClient.fromConnectionString(connectionString); - -var enrollment = { - registrationId: 'first', - attestation: { - type: 'tpm', - tpm: { - endorsementKey: endorsementKey - } - } -}; - -serviceClient.createOrUpdateIndividualEnrollment(enrollment, function (err, enrollmentResponse) { - if (err) { - console.log('error creating the individual enrollment: ' + err); - } else { - console.log("enrollment record returned: " + JSON.stringify(enrollmentResponse, null, 2)); - } -}); diff --git a/provisioning/service/samples/create_individual_x509_enrollment.js b/provisioning/service/samples/create_individual_x509_enrollment.js deleted file mode 100644 index 301b8d7e9..000000000 --- a/provisioning/service/samples/create_individual_x509_enrollment.js +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -'use strict'; -var fs = require('fs'); -var provisioningServiceClient = require('azure-iot-provisioning-service').ProvisioningServiceClient; -const path = require('path'); - -var argv = require('yargs') - .usage('Usage: $0 --deviceid --connectionstring ') - .option('deviceid', { - alias: 'd', - describe: 'Unique identifier for the device that shall be created', - type: 'string', - demandOption: true - }) - .option('connectionstring', { - alias: 'c', - describe: 'The connection string for the Device Provisioning instance', - type: 'string', - demandOption: true - }) - .argv; - -var deviceID = argv.deviceid; -var connectionString = argv.connectionstring; - -var serviceClient = provisioningServiceClient.fromConnectionString(connectionString); - -var certFile = path.join(__dirname, "cert", deviceID + "-cert.pem"); - -if (!fs.existsSync(certFile)) { - console.log('Certificate File not found:' + certFile); - process.exit(); -} else { - var certificate = fs.readFileSync(certFile, 'utf-8').toString(); -} - -var enrollment = { - registrationId: deviceID, - deviceID: deviceID, - attestation: { - type: 'x509', - x509: { - clientCertificates: { - primary: { - certificate: certificate - } - } - } - } -}; - -serviceClient.createOrUpdateIndividualEnrollment(enrollment, function (err, enrollmentResponse) { - if (err) { - console.log('error creating the individual enrollment: ' + err); - } else { - console.log("enrollment record returned: " + JSON.stringify(enrollmentResponse, null, 2)); - } -}); diff --git a/provisioning/service/samples/create_tpm_enrollment_with_token_credential.js b/provisioning/service/samples/create_tpm_enrollment_with_token_credential.js deleted file mode 100644 index 4f0ed1bad..000000000 --- a/provisioning/service/samples/create_tpm_enrollment_with_token_credential.js +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -'use strict'; - -const { ClientSecretCredential } = require("@azure/identity"); -const provisioningServiceClient = require('azure-iot-provisioning-service').ProvisioningServiceClient; -const uuid = require('uuid'); - -const argv = require('yargs') - .usage('Usage: $0 --hostname --endorsementKey --tenantid --clientid --clientsecret ') - .option('hostname', { - alias: 'h', - describe: 'The host name for the Device Provisioning instance', - type: 'string', - demandOption: true - }) - .option('tenantid', { - alias: 't', - describe: 'The Azure Active Directory tenant (directory) Id', - type: 'string', - demandOption: true - }) -.option('clientid', { - alias: 'c', - describe: 'The client Id of the Azure Active Directory application', - type: 'string', - demandOption: true - }) - .option('clientsecret', { - alias: 's', - describe: 'A client secret that was generated for the application Registration used to authenticate the client', - type: 'string', - demandOption: true - }) - .argv; - -const credential = new ClientSecretCredential(argv.tenantid, argv.clientid, argv.clientsecret); -const serviceClient = provisioningServiceClient.fromTokenCredential(argv.hostname, credential); - -const enrollment = { - registrationId: 'sample_enrollment-' + uuid.v1(), - attestation: { - type: 'symmetricKey', - symmetricKey: { - primaryKey: '', - secondaryKey: '' - } - }, - capabilities: { - iotEdge: false - } -}; - -serviceClient.createOrUpdateIndividualEnrollment(enrollment).then((enrollmentResponse) => { - console.log("Enrollment record returned: " + JSON.stringify(enrollmentResponse.responseBody, null, 2)), - serviceClient.deleteIndividualEnrollment(enrollmentResponse.responseBody.registrationId).then( - (res) => console.log("Enrollment deleted successfully"), - (err) => console.log("Error deleting enrollment: " + err) - )} - ).catch((err) => console.log("Error creating the individual enrollment: " + err)); diff --git a/provisioning/service/samples/package.json b/provisioning/service/samples/package.json deleted file mode 100644 index 87353aa27..000000000 --- a/provisioning/service/samples/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "azure-iot-provisioning-service-samples", - "version": "0.0.1", - "description": "Azure IoT SDK - Provisioning Service Client samples", - "author": "Microsoft Corporation", - "license": "MIT", - "dependencies": { - "@azure/identity": "^2.0.0", - "azure-iot-provisioning-service": "1.10.1", - "yargs": "^15.3.1" - }, - "devDependencies": { - "jshint": "^2.13.4" - }, - "engines": { - "node": ">= 14.0.0" - }, - "scripts": { - "npmlockrefresh": "npm i --package-lock-only", - "lint": "jshint --show-non-errors ." - }, - "repository": { - "type": "git", - "url": "git+https://github.com/Azure/azure-iot-sdk-node.git" - }, - "bugs": { - "url": "https://github.com/Azure/azure-iot-sdk-node/issues" - }, - "homepage": "https://github.com/Azure/azure-iot-sdk-node#readme" -} \ No newline at end of file diff --git a/provisioning/service/samples/query.js b/provisioning/service/samples/query.js deleted file mode 100644 index 00c285dad..000000000 --- a/provisioning/service/samples/query.js +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -'use strict'; - -var provisioningServiceClient = require('azure-iot-provisioning-service').ProvisioningServiceClient; - -var argv = require('yargs') - .usage('Usage: $0 --connectionString ') - .option('connectionString', { - alias: 'c', - describe: 'The connection string for the Device Provisioning instance', - type: 'string', - demandOption: true - }) - .argv; - -var connectionString = argv.connectionString; -var serviceClient = provisioningServiceClient.fromConnectionString(connectionString); - -var queryForEnrollments = serviceClient.createIndividualEnrollmentQuery({ - "query": "*" -}, 10); -var queryForEnrollmentGroups = serviceClient.createEnrollmentGroupQuery({ - "query": "*" -}, 10); - -var onEnrollmentResults = function (err, results) { - if (err) { - console.error('Failed to fetch the results: ' + err.message); - } else { - // Do something with the results - results.forEach(function (enrollment) { - console.log(JSON.stringify(enrollment, null, 2)); - }); - - if (queryForEnrollments.hasMoreResults) { - queryForEnrollments.next(onEnrollmentResults); - } else { - console.log('Querying for the Enrollment Groups'); - queryForEnrollmentGroups.next(onEnrollmentGroupResults); - } - } -}; - -var onEnrollmentGroupResults = function (err, results) { - if (err) { - console.error('Failed to fetch the results: ' + err.message); - } else { - // Do something with the results - results.forEach(function (enrollmentGroup) { - console.log(JSON.stringify(enrollmentGroup, null, 2)); - var alreadyPrintedSomeDeviceRegistrations = false; - var queryForDeviceRegistrationState = serviceClient.createEnrollmentGroupDeviceRegistrationStateQuery({ - "query": "*" - }, enrollmentGroup.enrollmentGroupId, 10); - var onDeviceRegistrationStateResults = function (err, results) { - if (err) { - console.error('Failed to fetch the results: ' + err.message); - } else { - // Do something with the results - results.forEach(function (deviceRegistrationState) { - if (!alreadyPrintedSomeDeviceRegistrations) { - alreadyPrintedSomeDeviceRegistrations = true; - console.log('For ' + enrollmentGroup.enrollmentGroupId + ', all of its the Device Registrations Status objects: '); - } - console.log(JSON.stringify(deviceRegistrationState, null, 2)); - }); - if (queryForDeviceRegistrationState.hasMoreResults) { - queryForDeviceRegistrationState.next(onDeviceRegistrationStateResults); - } - } - }; - queryForDeviceRegistrationState.next(onDeviceRegistrationStateResults); - }); - - if (queryForEnrollmentGroups.hasMoreResults) { - queryForEnrollmentGroups.next(onEnrollmentGroupResults); - } - } -}; - - -console.log('Querying for the enrollments: '); -queryForEnrollments.next(onEnrollmentResults); diff --git a/provisioning/service/samples/readme.md b/provisioning/service/samples/readme.md deleted file mode 100644 index 5aedc1508..000000000 --- a/provisioning/service/samples/readme.md +++ /dev/null @@ -1,110 +0,0 @@ -# Samples for the Azure IoT Device Provisioning Service SDK for Node.js - -This file can be found in https://github.com/Azure/azure-iot-sdk-node/tree/main/provisioning/service/samples - -This folder contains simple samples showing how to use the various features of the Microsoft Azure IoT Device Provisioning Service from an application running JavaScript code. - -## List of samples - -* Create a simple IndividualEnrollment object based on TPM. - * [create_individual_tpm_enrollment.js][create-individual-tpm-enrollment] -* Create a simple IndividualEnrollment object based on x509 certificate. - * [create_individual_x509_enrollment.js][create-individual-x509-enrollment] -* Create a simple EnrollmentGroup object. - * [create_enrollment_group.js][create-enrollment-group] -* Create a couple of IndividualEnrollments and delete them. - * [create_delete.js][create-delete] -* Create queries for IndividualEnrollments, EnrollmentGroups and DeviceRegistrationStates that belong to an EnrollmentGroup. - * [query.js][query-link] -* Perform BulkEnrollmentOperations to do various CRUD operations. - * [run_bulk_operation.js][run-bulk-operation] - - -## How to run the samples - - -In order to run the device samples you will first need the following prerequisites: -* Node.js v4 or above on your target device. (Check out [Nodejs.org](https://nodejs.org/) for more info) -* [Setup Azure IoT Device Provisioning ][lnk-setup-iot-provisioning] Stop before executing the the Create and provision a simulated device section. The samples below will perform these steps. - -### Using the x509 individual enrollment example -To generate a x509 certificate to run the individual enrollment of a device with x509 you need to create one. See [create-certificate-for-individual-enrollment]. - -### Using the TPM individual enrollmentexample -The following is an endorsement key, used for TPM. It has been generated by a simulator and as it has no corresponding private portion, is only useful as an input to these examples. - -AToAAQALAAMAsgAgg3GXZ0SEs/gakMyNRqXXJP1S124GUgtk8qHaGzMUaaoABgCAAEMAEAgAAAAAAAEAxsj2gUScTk1UjuioeTlfGYZrrimExB+bScH75adUMRIi2UOMxG1kw4y+9RW/IVoMl4e620VxZad0ARX2gUqVjYO7KPVt3dyKhZS3dkcvfBisBhP1XH9B33VqHG9SHnbnQXdBUaCgKAfxome8UmBKfe+naTsE5fkvjb/do3/dD6l4sGBwFCnKRdln4XpM03zLpoHFao8zOwt8l/uP3qUIxmCYv9A7m69Ms+5/pCkTu/rK4mRDsfhZ0QLfbzVI6zQFOKF/rwsfBtFeWlWtcuJMKlXdD8TXWElTzgh7JS4qhFzreL0c1mI0GCj+Aws0usZh7dLIVPnlgZcBhgy1SSDQMQ== - - -Get the following files from the current folder: -* [package.json][package-json] -* **__sample_file.js__** (where **__sample_file.js__** is one of the files listed above and available in this folder) - -Place the files in the folder of your choice on the target machine/device then go through the following steps: - -* From a shell or Node.js command prompt, navigate to the folder where you placed the sample files. For creating an IndividualEnrollment do: - -``` -$ npm install -$ node create_individual_enrollment.js "" "" -``` - -* For the TokenCredential sample: - -For a quick explanation of Role Based Access Control, you can check [this overview][rbac-overview]. - -Get the following files from the current folder: -* [package.json][package-json] -* **__sample_file.js__** (where **__sample_file.js__** is one of the files listed above and available in this folder) - -Place the files in the folder of your choice on the target machine/device then go through the following steps: - -* From a shell or Node.js command prompt, navigate to the folder where you placed the sample files. For creating an IndividualEnrollment do: - -``` -$ npm install -$ node create_tpm_enrollment_with_token_credential.js -h -t -c -s -``` - -* For creating an EnrollmentGroup: - -If you already have a PEM or CER file then simply give the file name below on the command line "node create_enrollment_groupd.js ...". If you need to create a PEM file there are command scripts in this [directory](https://github.com/Azure/azure-iot-sdk-c/tree/master/tools/CACertificates) that could be useful FOR TESTING. Please see the md file in that directory [C SDK cert tools overview.](https://github.com/Azure/azure-iot-sdk-c/blob/master/tools/CACertificates/CACertificateOverview.md) - -``` -$ npm install -$ node create_enrollment_group.js "" "" -``` - -* The other samples simply require the connection string: - -``` -$ npm install -$ node create_delete.js "" -``` - -* In order to monitor the results of running the sample, use the portal for the Device Provisioning Service which can display group or individual enrollments. - - -## Read More -For more information on how to use this library refer to the documents below: -- [Prepare your node.js development environment][node-devbox-setup] -- [Setup IoT Hub][lnk-setup-iot-hub] -- [Provision devices][lnk-manage-iot-hub] -- [Node API reference][node-api-reference] -- [Device Provisioning Service Concepts][dps-service-concepts] - -[lnk-setup-iot-provisioning]: https://docs.microsoft.com/en-us/azure/iot-dps/quick-setup-auto-provision -[lnk-setup-iot-hub]: https://aka.ms/howtocreateazureiothub -[lnk-manage-iot-hub]: https://aka.ms/manageiothub -[node-api-reference]: https://docs.microsoft.com/en-us/javascript/api/azure-iot-device/ -[node-devbox-setup]: ../../doc/node-devbox-setup.md -[create-individual-tpm-enrollment]: https://github.com/azure/azure-iot-sdk-node/tree/main/provisioning/service/samples/create_individual_tpm_enrollment.js -[create-individual-x509-enrollment]: https://github.com/azure/azure-iot-sdk-node/tree/main/provisioning/service/samples/create_individual_x509_enrollment.js -[create-enrollment-group]: https://github.com/azure/azure-iot-sdk-node/tree/main/provisioning/service/samples/create_enrollment_group.js -[dps-service-concepts]: https://docs.microsoft.com/en-us/azure/iot-dps/concepts-service -[create-delete]: https://github.com/azure/azure-iot-sdk-node/tree/main/provisioning/service/samples/create_delete.js -[query-link]: https://github.com/azure/azure-iot-sdk-node/tree/main/provisioning/service/samples/query.js -[run-bulk-operation]: https://github.com/azure/azure-iot-sdk-node/tree/main/provisioning/service/samples/query.js -[package-json]: https://github.com/azure/azure-iot-sdk-node/tree/main/provisioning/service/samples/package.json -[create-certificate-for-individual-enrollment]: https://github.com/Azure/azure-iot-sdk-node/tree/main/provisioning/device/samples#creating-x509-device-certificates-for-individual-enrollment -[rbac-overview]: https://docs.microsoft.com/en-us/azure/role-based-access-control/overview \ No newline at end of file diff --git a/provisioning/service/samples/run_bulk_operation.js b/provisioning/service/samples/run_bulk_operation.js deleted file mode 100644 index fd3ec77e3..000000000 --- a/provisioning/service/samples/run_bulk_operation.js +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -'use strict'; - -var provisioningServiceClient = require('azure-iot-provisioning-service').ProvisioningServiceClient; - -var argv = require('yargs') - .usage('Usage: $0 --connectionstring ') - .option('connectionstring', { - alias: 'c', - describe: 'The connection string for the Device Provisioning instance', - type: 'string', - demandOption: true - }) - .argv; - -var connectionString = argv.connectionString; -var serviceClient = provisioningServiceClient.fromConnectionString(connectionString); - -var enrollment1 = { - registrationId: 'first', - provisioningStatus: 'disabled', - attestation: { - type: 'tpm', - tpm: { - endorsementKey: 'a' - } - } -}; - -var enrollment2 = { - registrationId: 'second', - provisioningStatus: 'disabled', - attestation: { - type: 'tpm', - tpm: { - endorsementKey: 'a' - } - } -}; - -var enrollment3 = { - registrationId: 'third', - provisioningStatus: 'disabled', - attestation: { - type: 'tpm' - } -}; - -var badCreateBulkOperation = { - mode: 'create', - enrollments: [] -}; -badCreateBulkOperation.enrollments.push(enrollment1); -badCreateBulkOperation.enrollments.push(enrollment2); -badCreateBulkOperation.enrollments.push(enrollment2); - -// -// runBulkEnrollmentOperation has two different ways that errors can be indicated to the -// caller. The err parameter on the callback or through the result parameter -// on the callback. -// -// This first runBulkEnrollmentOperation will fail. The reason it fails is because we have -// a duplicate entry in the bulk array. This will NOT produce a BulkEnrollmentOperationResult. -// -serviceClient.runBulkEnrollmentOperation(badCreateBulkOperation, function (err, result) { - if (err) { - console.log('The bulk operation result is: ' + err); - } - console.log('The value of the result operation should be undefined: ', JSON.stringify(result, null, 2)); - // - // Get rid of the duplicate entry and put in an entry without an actual attestation. - // Some of the bulk create will work but we should get a BulkEnrollmentOperationResult - // that indicates the third one failed. - // - badCreateBulkOperation.enrollments.splice(2, 1); - badCreateBulkOperation.enrollments.push(enrollment3); - serviceClient.runBulkEnrollmentOperation(badCreateBulkOperation, function (err, result) { - console.log('The err parameter should be null for this second bulkOperation call, err: ' + err); - console.log('The value of the result operation should indicate the third enrollment was bad: ' + JSON.stringify(result, null, 2)); - serviceClient.getIndividualEnrollment(enrollment1.registrationId, function (err, completeEnrollment1) { - if (err) { - console.log('Unable to get first enrollment: ' + err); - } else { - console.log('Complete enrollment record 1: ' + JSON.stringify(completeEnrollment1, null, 2)); - serviceClient.getIndividualEnrollment(enrollment2.registrationId, function (err, completeEnrollment2) { - if (err) { - console.log('Unable to get second enrollment: ' + err); - } else { - console.log('Complete enrollment record 2: ' + JSON.stringify(completeEnrollment2, null, 2)); - var deleteBulkOperation = { - mode: 'delete', - enrollments: [] - }; - deleteBulkOperation.enrollments.push(completeEnrollment1); - deleteBulkOperation.enrollments.push(completeEnrollment2); - serviceClient.runBulkEnrollmentOperation(deleteBulkOperation, function (err, result) { - console.log('The err parameter should be null for this delete runBulkEnrollmentOperation call, err: ' + err); - console.log('The value of the result operation should indicate success and no errors: ' + JSON.stringify(result, null, 2)); - }); - } - }); - } - }); - }); -}); \ No newline at end of file diff --git a/provisioning/service/src/interfaces.ts b/provisioning/service/src/interfaces.ts deleted file mode 100644 index 6168834aa..000000000 --- a/provisioning/service/src/interfaces.ts +++ /dev/null @@ -1,539 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -'use strict'; - -/** - * Device attestation method. - */ -export interface AttestationMechanism { - /** - * The type of attestation. - */ - type: AttestationTypes; - /** - * This property is an object containing the TPM specific values - * for enrollment. - */ - tpm?: TpmAttestation; - /** - * This property is an object containing the x509 specific values - * for enrollment. - */ - x509?: X509Attestation; - - /** - * This property is an object containing the symmetric keys for an enrollment record. - */ - symmetricKey?: SymmetricKeyAttestation; -} - -export type AttestationTypes = 'none' | 'tpm' | 'x509' | 'symmetricKey'; - -/** - * Attestation via Symmetric Key. - */ -export interface SymmetricKeyAttestation { - /** - * Primary symmetric key. - */ - primaryKey: string; - /** - * Secondary symmetric key. - */ - secondaryKey: string; -} - -/** - * Attestation via TPM. - */ -export interface TpmAttestation { - /** - * The endorsement key is an encryption key that is permanently embedded in the Trusted Platform Module (TPM) - * security hardware, generally at the time of manufacture. This private portion of the endorsement key is never - * released outside of the TPM. The public portion of the endorsement key helps to recognize a genuine TPM. - * - * The endorsement key is a base64 encoded value. - */ - endorsementKey: string; - /** - * The storage root key is embedded in the Trusted Platform Module (TPM) security hardware. - * It is used to protect TPM keys created by applications, so that these keys cannot be used without the TPM. - * Unlike the endorsement key (which is generally created when the TPM is manufactured), the storage root key - * is created when you take ownership of the TPM. This means that if you clear the TPM and a new user takes ownership, - * a new storage root key is created. - * - * This property is not typically manipulated by the service client. - * - * The storageRootKey is a base64 encoded value. - */ - storageRootKey: string; -} - -/** - * Attestation via X509. - */ -export interface X509Attestation { - /** - * x509 certificate object which provides all information for a leaf certificate. - */ - clientCertificates?: X509Certificates; - /** - * x509 certificate object which provides all information needed for a certificate - * suitable for signing other certificates. - */ - signingCertificates?: X509Certificates; - /** - * Primary and secondary CA reference. These will be names rather than - * actual certificates. - */ - caReferences?: X509CAReferences; -} - -/** - * X509 certificate info. - * - * This object is not provided by the application. It is populated by the service from - * a provided certificate. - */ -export interface X509CertificateInfo { - /** - * For clientCertificates the subjectName is used as the deviceId on the IoT Hub. - */ - subjectName: string; - /** - * A 160 bit hash of the certificate. - */ - sha1Thumbprint: string; - /** - * A 256 bit hash of the certificate. - */ - sha256Thumbprint: string; - /** - * The name of certificate used to sign the certificate that is the basis - * for this info. - */ - issuerName: string; - /** - * The date and time before which this certificate is not valid for authentication - * purposes. - */ - notBeforeUtc: Date; - /** - * The date and time after which this certificate is not valid for authentication - * purposes. - */ - notAfterUtc: Date; - /** - * A value that should be unique to the issuing CA for this certificate. Note that - * this serial number is not unique over all certificates world wide. - */ - serialNumber: string; - /** - * The version specifies what capabilities are supported by the particular certificate. - * Version 3 is currently the highest version number. - */ - version: number; -} - -/** - * Certificate and Certificate info - */ -export interface X509CertificateWithInfo { - /** - * PEM or CER representation of a certificate. - */ - certificate: string; - /** - * This property is populated by the service from the information - * provided by the certificate property of this object. - */ - info?: X509CertificateInfo; -} - -/** - * Primary and secondary certificates - */ -export interface X509Certificates { - /** - * Would typically be the certificate used to provide the identification - * and authentication for an enrollment. - */ - primary: X509CertificateWithInfo; - /** - * Would typically be the certificate used to provide the identification - * and authentication for an enrollment in the case that the primary is - * revoked. - */ - secondary?: X509CertificateWithInfo; -} - -export interface X509CAReferences { - /** - * The name of the primary CA certificate. - */ - primary: string; - /** - * The name of the secondary CA certificate. - */ - secondary: string; -} - -/** - * Bulk operation - */ -export interface BulkEnrollmentOperation { - /** - * The mode property specifies the operation that will be performed upon all - * of the IndividualEnrollment elements in the enrollments property. - */ - mode: BulkOperationMode; - /** - * The enrollments property is an array of IndividualEnrollment objects. The size of this - * array is limited. - */ - enrollments: Array; -} - -/** - * The kind of operations that can be performed with a BulkOperation. - * Only one kind of operation may be performed on any instance of a - * BulkOperation. - */ -export type BulkOperationMode = 'create' | 'update' | 'updateIfMatchEtag' | 'delete'; - -/** - * Bulk operation result - */ -export interface BulkEnrollmentOperationResult { - /** - * If isSuccessful is true then all CRUD operations for a bulkOperation - * were successful. Otherwise there will be at least one element in the - * errors array. - */ - isSuccessful: boolean; - /** - * Will provide information as to why particular CRUD operations failed for - * a runBulkEnrollmentOperation invocation. The array will be zero length if - * isSuccessful is true. - */ - errors: Array; -} - -/** - * Bulk enrollment operation error - */ -export interface BulkEnrollmentOperationError { - /** - * The id of the the IndividualEnrollment object that was in error during a runBulkEnrollmentOperation invocation. - */ - registrationId: string; - /** - * The status code that is associated with the error for a particular CRUD operation. - */ - errorCode: number; - /** - * The helpful text associated with the error for a particular CRUD operation. - */ - errorStatus: string; -} - -/** - * Device registration status. - */ -export interface DeviceRegistrationState { - /** - * The unique identifier associated with an enrollment object. - * - * The value is all lowercase alphanumeric with embedded `-` permitted. - */ - registrationId: string; - /** - * The date that the device registration was created. - */ - createdDateTimeUtc: Date; - /** - * The IoT Hub that the device was provisioned to. - */ - assignedHub: string; - /** - * The unique identifier (per hub) used for the device registration. - */ - deviceId: string; - /** - * What is the provisioning state of the device at the moment of the request. - */ - status: RegistrationStatus; - /** - * Substatus for 'Assigned' devices. Possible values include: - * - 'initialAssignment': Device has been assigned to an IoT hub for the first time. - * - 'deviceDataMigrated': Device has been assigned to a different IoT hub and its device data was migrated from the previously assigned IoT hub. Device data was removed from the previously assigned IoT hub. - * - 'deviceDataReset': Device has been assigned to a different IoT hub and its device data was populated from the initial state stored in the enrollment. Device data was removed from the previously assigned IoT hub. - */ - substatus: RegistrationSubstatus; - /** - * The last time that this registration status was updated. - */ - lastUpdatedDateTimeUtc: Date; - /** - * A numeric value for the error associated with this registration. - */ - errorCode: number; - /** - * The helpful text for the error associated with this registration. - */ - errorMessage: string; - /** - * An opaque value suitable to uniquely identify a particular generation - * of this object for use during a CRUD operation. - */ - etag: string; -} - -/** - * The provisioning state of the device at the moment of the request. - */ -export type RegistrationStatus = 'unassigned' | 'assigning' | 'assigned' | 'failed' | 'disabled'; - -/** - * Substatus for 'Assigned' devices. Possible values include: - * - 'initialAssignment': Device has been assigned to an IoT hub for the first time. - * - 'deviceDataMigrated': Device has been assigned to a different IoT hub and its device data was migrated from the previously assigned IoT hub. Device data was removed from the previously assigned IoT hub. - * - 'deviceDataReset': Device has been assigned to a different IoT hub and its device data was populated from the initial state stored in the enrollment. Device data was removed from the previously assigned IoT hub. - */ -export type RegistrationSubstatus = 'initialAssignment' | 'deviceDataMigrated' | 'deviceDataReset'; - -/** - * The behavior the service should adopt when a device is re-provisioned to another IoT Hub. - */ -export interface ReprovisionPolicy { - /** - * When set to true (default) the Device Provisioning Service will evaluate the device's hub assignment and update it if necessary - * for any provisioning request beyond the first from a given device. If set to false the device will stay assigned to its current IoT hub. - */ - updateHubAssignment: boolean; - /** - * When set to true (default) the Device Provisioning Service will migrate the device data (twin, device capabilities and device id) - * from one hub to another during an IoT hub assignment update. If set to false the Device Provisioning Service will reset the device data to its - * initial configuration stored in its corresponding enrollment. - */ - migrateDeviceData: boolean; -} - -/** - * Capabilities of the device that will be provisioned using this enrollment record. - */ -export interface DeviceCapabilities { - /** - * Boolean indicating whether the provisioned device is an Azure IoT Edge device. - */ - iotEdge: boolean; -} - -/** - * The individual enrollment record. - */ -export interface IndividualEnrollment { - /** - * A unique identifier for this object. - * - * The value is all lowercase alphanumeric with embedded `-` permitted. - */ - registrationId: string; - /** - * The unique identifier (per hub) used for the device registration. - * - * If this object is using x509 attestation, this property should be - * undefined. - */ - deviceId: string; - /** - * The state of the device registration associated with this object. - */ - registrationState: DeviceRegistrationState; - /** - * The security mechanism associated with this object. - */ - attestation: AttestationMechanism; - /** - * The IoT Hub that will be the destination of the provisioning for the device - * associated with this object. - */ - iotHubHostName: string; - /** - * The initial twin document that will be created for this device upon its provisioning. - */ - initialTwin: InitialTwin; - /** - * An opaque value suitable to uniquely identify a particular generation - * of this object for use during a CRUD operation. - */ - etag: string; - /** - * Indicates whether this enrollment can be used as the basis for a device - * provisioning. - */ - provisioningStatus: ProvisioningStatus; - /** - * The date and time that this object was created. - */ - createdDateTimeUtc: string; - /** - * The date and time that this enrollment record was last updated. This - * could include an update or an actual registration. - */ - lastUpdatedDateTimeUtc: string; - - /** - * The capabilities of the device that will be provisioned using this enrollment record. - */ - capabilities?: DeviceCapabilities; - - /** - * The behavior when a device is re-provisioned to an IoT hub. - */ - reprovisionPolicy?: ReprovisionPolicy; - - /** - * The allocation policy of this individual enrollment. This policy overrides the tenant-level allocation policy. - * - 'hashed': Linked IoT hubs are equally likely to have devices provisioned to them. - * - 'geoLatency': Devices are provisioned to an IoT hub with the lowest latency to the device.If multiple linked IoT hubs would provide the same lowest latency, the provisioning service hashes devices across those hubs. - * - 'static' : Specification of the desired IoT hub in the enrollment list takes priority over the service-level allocation policy. - * - 'custom': Devices are provisioned to an IoT hub based on your own custom logic. The provisioning service passes information about the device to the logic, and the logic returns the desired IoT hub as well as the desired initial configuration. We recommend using Azure Functions to host your logic. - */ - allocationPolicy?: AllocationPolicyType; - - /** - * The list of names of IoT hubs the device(s) in this resource can be allocated to. It must be a subset of tenant level list of IoT hubs. - */ - iotHubs: string[]; - - /** - * Custom allocation definition. - */ - customAllocationDefinition?: CustomAllocationDefinition; -} - -/** - * The allocation policy of this individual enrollment. This policy overrides the tenant-level allocation policy. - * - 'hashed': Linked IoT hubs are equally likely to have devices provisioned to them. - * - 'geoLatency': Devices are provisioned to an IoT hub with the lowest latency to the device.If multiple linked IoT hubs would provide the same lowest latency, the provisioning service hashes devices across those hubs. - * - 'static' : Specification of the desired IoT hub in the enrollment list takes priority over the service-level allocation policy. - * - 'custom': Devices are provisioned to an IoT hub based on your own custom logic. The provisioning service passes information about the device to the logic, and the logic returns the desired IoT hub as well as the desired initial configuration. We recommend using Azure Functions to host your logic. - */ -export type AllocationPolicyType = 'hashed' | 'geoLatency' | 'static' | 'custom'; - -export type ProvisioningStatus = 'enabled' | 'disabled'; - -/** - * The enrollment group object. - */ -export interface EnrollmentGroup { - /** - * A unique identifier for this object. - * - * The value is all lowercase alphanumeric with embedded `-` permitted. - */ - enrollmentGroupId: string; - /** - * The security mechanism associated with this object. - */ - attestation: AttestationMechanism; - /** - * The IoT Hub that will be the destination of the provisioning for devices - * associated with this object. - */ - iotHubHostName?: string; - /** - * The initial twin document that will be created for devices upon their provisioning. - */ - initialTwin?: InitialTwin; - /** - * An opaque value suitable to uniquely identify a particular generation - * of this object for use during a CRUD operation. - */ - etag?: string; - /** - * Indicates whether this object can be used as the basis for a device - * provisioning. - */ - provisioningStatus: ProvisioningStatus; - /** - * The date and time that this object was created. - */ - createdDateTimeUtc?: string; - /** - * The date and time that this object was last updated. This - * could include an update or an actual registration. - */ - lastUpdatedDateTimeUtc?: string; - - /** - * The capabilities of the device that will be provisioned using this enrollment record. - */ - capabilities?: DeviceCapabilities; - - /** - * The behavior when a device is re-provisioned to an IoT hub. - */ - reprovisionPolicy?: ReprovisionPolicy; - - /** - * The allocation policy of this enrollment group. This policy overrides the tenant-level allocation policy. - * - 'hashed': Linked IoT hubs are equally likely to have devices provisioned to them. - * - 'geoLatency': Devices are provisioned to an IoT hub with the lowest latency to the device.If multiple linked IoT hubs would provide the same lowest latency, the provisioning service hashes devices across those hubs. - * - 'static' : Specification of the desired IoT hub in the enrollment list takes priority over the service-level allocation policy. - * - 'custom': Devices are provisioned to an IoT hub based on your own custom logic. The provisioning service passes information about the device to the logic, and the logic returns the desired IoT hub as well as the desired initial configuration. We recommend using Azure Functions to host your logic. - */ - allocationPolicy?: AllocationPolicyType; - - /** - * The list of names of IoT hubs the device(s) in this resource can be allocated to. It must be a subset of tenant level list of IoT hubs. - */ - iotHubs?: string[]; - - /** - * Custom allocation definition. - */ - customAllocationDefinition?: CustomAllocationDefinition; -} - -/** - * Custom allocation definition. - */ -export interface CustomAllocationDefinition { - /** - * The webhook URL used for allocation requests. - */ - webhookUrl: string; - /** - * The API version of the provisioning service types (such as IndividualEnrollment) sent in the custom allocation request. Supported versions include: - * - "2019-03-31" - */ - apiVersion: string; -} - -export interface Metadata { - lastUpdated: Date; - /** - * This SHOULD be null for Reported properties metadata and MUST not be null for Desired properties metadata. - */ - lastUpdatedVersion: number; -} - -export interface TwinCollection { - version: number; - count: number; - metadata: Metadata; - [key: string]: any; -} - -/** - * Device twin state. - */ -export interface InitialTwin { - tags: TwinCollection; - properties: { - desired: TwinCollection; - }; -} diff --git a/provisioning/service/src/provisioningserviceclient.ts b/provisioning/service/src/provisioningserviceclient.ts deleted file mode 100644 index d5af341fe..000000000 --- a/provisioning/service/src/provisioningserviceclient.ts +++ /dev/null @@ -1,631 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -'use strict'; - -import { errors, SharedAccessSignature, ConnectionString, httpCallbackToPromise, encodeUriComponentStrict } from 'azure-iot-common'; -import { RestApiClient } from 'azure-iot-http-base'; -import { QuerySpecification, Query, QueryResult } from './query'; -// tslint seems to think AttestationMechanism isn't used on the next import statement so disabling this warning. -// tslint:disable-next-line:no-unused-variable -import { IndividualEnrollment, EnrollmentGroup, DeviceRegistrationState, BulkEnrollmentOperation, BulkEnrollmentOperationResult, AttestationMechanism } from './interfaces'; -import { ErrorCallback, errorCallbackToPromise, HttpResponseCallback, ResultWithHttpResponse } from 'azure-iot-common'; -import { TokenCredential } from '@azure/core-http'; - -// tslint:disable-next-line:no-var-requires -const packageJson = require('../package.json'); - -const ArgumentError = errors.ArgumentError; - -export class ProvisioningServiceClient { - - private readonly _enrollmentGroupsPrefix: string = '/enrollmentGroups/'; - private readonly _enrollmentsPrefix: string = '/enrollments/'; - private readonly _registrationsPrefix: string = '/registrations/'; - private _restApiClient: RestApiClient; - - constructor(config: RestApiClient.TransportConfig, restApiClient?: RestApiClient) { - if (!config) { - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_001: [The `ProvisioningServiceClient` construction shall throw a `ReferenceError` if the `config` object is falsy.] */ - throw new ReferenceError('The \'config\' parameter cannot be \'' + config + '\''); - } else if (!config.host) { - throw new ArgumentError('The \'config\' argument is missing the host property'); - } else if (!config.sharedAccessSignature && !config.tokenCredential) { - throw new ArgumentError('The \'config\' argument must define either the sharedAccessSignature or tokenCredential property'); - } else if (config.tokenCredential && !config.tokenScope) { - throw new ArgumentError('The \'config\' argument must define the tokenScope property if it defines the tokenCredential property'); - } - - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_003: [The `ProvisioningServiceClient` constructor shall use the `restApiClient` provided as a second argument if it is provided.] */ - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_004: [The `ProvisioningServiceClient` constructor shall use `azure-iot-http-base.RestApiClient` if no `restApiClient` argument is provided.] */ - this._restApiClient = restApiClient || new RestApiClient(config, packageJson.name + '/' + packageJson.version); - } - - /** - * @method module:azure-iot-provisioning-service.ProvisioningServiceClient#createOrUpdateIndividualEnrollment - * @description Create or update a device enrollment record. - * @param {object} enrollment The device enrollment record. - * @param {function} [callback] Invoked upon completion of the operation. - * @returns {Promise> | void} Promise if no callback function was passed, void otherwise. - */ - public createOrUpdateIndividualEnrollment(enrollment: IndividualEnrollment, callback: HttpResponseCallback): void; - public createOrUpdateIndividualEnrollment(enrollment: IndividualEnrollment): Promise>; - public createOrUpdateIndividualEnrollment(enrollment: IndividualEnrollment, callback?: HttpResponseCallback): Promise> | void { - return httpCallbackToPromise((_callback) => { - this._createOrUpdate(this._enrollmentsPrefix, enrollment, _callback); - }, callback); - } - - /** - * @method module:azure-iot-provisioning-service.ProvisioningServiceClient#deleteIndividualEnrollment - * @description Delete a device enrollment record. - * @param {string | object} enrollmentOrId An IndividualEnrollment object or a string containing the registration id. - * @param {string | function} etagOrCallback In the case of the first argument being a string this could be an etag (or the callback). - * @param {function} [deleteCallback] Invoked upon completion of the operation. - * @returns {Promise | void} Promise if no callback function was passed, void otherwise. - */ - public deleteIndividualEnrollment(enrollmentOrId: string | IndividualEnrollment, etag: string, deleteCallback: ErrorCallback): void; - public deleteIndividualEnrollment(enrollmentOrId: string | IndividualEnrollment, deleteCallback: ErrorCallback): void; - public deleteIndividualEnrollment(enrollmentOrId: string | IndividualEnrollment, etag: string): Promise; - public deleteIndividualEnrollment(enrollmentOrId: string | IndividualEnrollment): Promise; - public deleteIndividualEnrollment(enrollmentOrId: string | IndividualEnrollment, etagOrCallback?: string | ErrorCallback, deleteCallback?: ErrorCallback): Promise | void { - if (deleteCallback && !(typeof deleteCallback === 'function')) { - throw new ArgumentError('Callback has to be a Function'); - } - - if (!deleteCallback && (typeof etagOrCallback === 'function')) { - deleteCallback = etagOrCallback as ErrorCallback; - etagOrCallback = undefined; - } - - return errorCallbackToPromise((_callback) => { - this._delete(this._enrollmentsPrefix, enrollmentOrId, etagOrCallback, _callback); - }, deleteCallback); - } - - /** - * @method module:azure-iot-provisioning-service.ProvisioningServiceClient#getIndividualEnrollment - * @description Get a device enrollment record. - * @param {string} id Registration ID. - * @param {function} [getCallback] Invoked upon completion of the operation. - * @returns {Promise> | void} Promise if no callback function was passed, void otherwise. - */ - public getIndividualEnrollment(id: string, getCallback: HttpResponseCallback): void; - public getIndividualEnrollment(id: string): Promise>; - public getIndividualEnrollment(id: string, getCallback?: HttpResponseCallback): Promise> | void { - return httpCallbackToPromise((_callback) => { - this._get(this._enrollmentsPrefix, id, _callback); - }, getCallback); - } - - /** - * @method module:azure-iot-provisioning-service.ProvisioningServiceClient#createIndividualEnrollmentQuery - * @description Creates a query that can be used to return pages of existing enrollments. - * @param {object} querySpecification The query specification. - * @param {number} pageSize The maximum number of elements to return per page. - */ - createIndividualEnrollmentQuery(querySpecification: QuerySpecification, pageSize?: number): Query { - return new Query(this._getEnrollFunc(this._enrollmentsPrefix, querySpecification, pageSize)); - } - - /** - * @method module:azure-iot-provisioning-service.ProvisioningServiceClient#getDeviceRegistrationState - * @description Gets the device registration status. - * @param {string} id Registration ID. - * @param {function} [callback] Invoked upon completion of the operation. - * @returns {Promise> | void} Promise if no callback function was passed, void otherwise. - */ - public getDeviceRegistrationState(id: string, callback: HttpResponseCallback): void; - public getDeviceRegistrationState(id: string): Promise>; - public getDeviceRegistrationState(id: string, callback?: HttpResponseCallback): Promise> | void { - return httpCallbackToPromise((_callback) => { - this._get(this._registrationsPrefix, id, _callback); - }, callback); - } - - /** - * @method module:azure-iot-provisioning-service.ProvisioningServiceClient#createOrUpdateEnrollmentGroup - * @description Create or update a device enrollment group. - * @param {object} enrollmentGroup The device enrollment group. - * @param {function} [callback] Invoked upon completion of the operation. - * @returns {Promise> | void} Promise if no callback function was passed, void otherwise. - */ - public createOrUpdateEnrollmentGroup(enrollmentGroup: EnrollmentGroup, callback: HttpResponseCallback): void; - public createOrUpdateEnrollmentGroup(enrollmentGroup: EnrollmentGroup): Promise>; - public createOrUpdateEnrollmentGroup(enrollmentGroup: EnrollmentGroup, callback?: HttpResponseCallback): Promise> | void { - return httpCallbackToPromise((_callback) => { - this._createOrUpdate(this._enrollmentGroupsPrefix, enrollmentGroup, _callback); - }, callback); - } - - /** - * @method module:azure-iot-provisioning-service.ProvisioningServiceClient#deleteEnrollmentGroup - * @description Delete a device enrollment group. - * @param {object | string} enrollmentGroupOrId EnrollmentGroup object or a string containing the enrollment Group Id. - * @param {string | function} [etagOrCallback] In the case of the first argument being a string this could be an etag (or the callback). - * @param {function} [deleteCallback] Invoked upon completion of the operation. - * @returns {Promise | void} Promise if no callback function was passed, void otherwise. - */ - public deleteEnrollmentGroup(enrollmentGroupOrId: string | EnrollmentGroup, etag: string, deleteCallback: ErrorCallback): void; - public deleteEnrollmentGroup(enrollmentGroupOrId: string | EnrollmentGroup, deleteCallback: ErrorCallback): void; - public deleteEnrollmentGroup(enrollmentGroupOrId: string | EnrollmentGroup, etag: string): Promise; - public deleteEnrollmentGroup(enrollmentGroupOrId: string | EnrollmentGroup): Promise; - public deleteEnrollmentGroup(enrollmentGroupOrId: string | EnrollmentGroup, etagOrCallback?: string | ErrorCallback, deleteCallback?: ErrorCallback): Promise | void { - if (deleteCallback && !(typeof deleteCallback === 'function')) { - throw new ArgumentError('Callback has to be a Function'); - } - - if (typeof etagOrCallback === 'function') { - deleteCallback = etagOrCallback as ErrorCallback; - etagOrCallback = undefined; - } - - return errorCallbackToPromise((_callback) => { - this._delete(this._enrollmentGroupsPrefix, enrollmentGroupOrId, etagOrCallback, _callback); - }, deleteCallback); - } - - /** - * @method module:azure-iot-provisioning-service.ProvisioningServiceClient#getEnrollmentGroup - * @description Get a device enrollment group. - * @param {string} id IndividualEnrollment group ID. - * @param {function} [getCallback] Invoked upon completion of the operation. - * @returns {ResultWithHttpResponse | void} Promise if no callback function was passed, void otherwise. - */ - public getEnrollmentGroup(id: string, getCallback: HttpResponseCallback): void; - public getEnrollmentGroup(id: string): Promise>; - public getEnrollmentGroup(id: string, getCallback?: HttpResponseCallback): Promise> | void { - return httpCallbackToPromise((_callback) => { - this._get(this._enrollmentGroupsPrefix, id, _callback); - }, getCallback); - } - - /** - * @method module:azure-iot-provisioning-service.ProvisioningServiceClient#createEnrollmentGroupQuery - * @description Creates a query that can be used to return pages of existing enrollment groups. - * @param {object} querySpecification The query specification. - * @param {number} pageSize The maximum number of elements to return per page. - */ - createEnrollmentGroupQuery(querySpecification: QuerySpecification, pageSize?: number): Query { - return new Query(this._getEnrollFunc(this._enrollmentGroupsPrefix, querySpecification, pageSize)); - } - - /** - * @method module:azure-iot-provisioning-service.ProvisioningServiceClient#createEnrollmentGroupDeviceRegistrationStateQuery - * @description Creates a query that can be used to return, for a specific EnrollmentGroup, pages of existing device registration status. - * @param {object} querySpecification The query specification. - * @param {string} enrollmentGroupId The EnrollmentGroup id that provides the scope for the query. - * @param {number} pageSize The maximum number of elements to return per page. - */ - createEnrollmentGroupDeviceRegistrationStateQuery(querySpecification: QuerySpecification, enrollmentGroupId: string, pageSize?: number): Query { - if (!enrollmentGroupId) { - throw new ReferenceError('Required enrollmentGroupId parameter was falsy.'); - } - return new Query(this._getEnrollFunc(this._registrationsPrefix + encodeURIComponent(enrollmentGroupId) + '/', querySpecification, pageSize)); - } - - /** - * @method module:azure-iot-provisioning-service.ProvisioningServiceClient#runBulkEnrollmentOperation - * @description Runs a number CRUD operations on an array of enrollment records. - * @param {object} bulkEnrollmentOperation An object that specifies the single kind of CRUD operations on the array of IndividualEnrollment objects that are also part of the object. - * @param {function} callback Invoked upon completion of the operation. - */ - public runBulkEnrollmentOperation(bulkEnrollmentOperation: BulkEnrollmentOperation, callback: HttpResponseCallback): void; - public runBulkEnrollmentOperation(bulkEnrollmentOperation: BulkEnrollmentOperation): Promise>; - public runBulkEnrollmentOperation(bulkEnrollmentOperation: BulkEnrollmentOperation, callback?: HttpResponseCallback): Promise> | void { - return httpCallbackToPromise((_callback) => { - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_038: [The `runBulkEnrollmentOperation` method shall throw `ReferenceError` if the `bulkEnrollmentOperation` argument is falsy.] */ - if (!bulkEnrollmentOperation) { - throw new ReferenceError('Required bulkEnrollmentOperation parameter was falsy when calling runBulkEnrollmentOperation.'); - } - - const path = this._enrollmentsPrefix + this._versionQueryString(); - - const httpHeaders = { - 'Accept': 'application/json', - 'Content-Type': 'application/json; charset=utf-8' - }; - - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_039: [** The `runBulkEnrollmentOperation` method shall construct an HTTP request using information supplied by the caller as follows: - POST /enrollments?api-version= HTTP/1.1 - Authorization: - Accept: application/json - Content-Type: application/json; charset=utf-8 - - - ] */ - this._restApiClient.executeApiCall('POST', path, httpHeaders, bulkEnrollmentOperation, (err, bulkEnrollmentOperationResult, httpResponse) => { - if (callback) { - if (err) { - _callback(err); - } else { - _callback(null, bulkEnrollmentOperationResult, httpResponse); - } - } - }); - }, callback); - } - - /** - * @method module:azure-iot-provisioning-service.ProvisioningServiceClient#deleteDeviceRegistrationState - * @description Delete a device registration status. - * @param {object | string} idOrRegistrationState A string containing the registration id OR an actual DeviceRegistrationState. - * @param {string | function} etagOrCallback In the case of the first argument being a string this could be an etag (or the callback). - * @param {function} [deleteCallback] Invoked upon completion of the operation. - * @returns {Promise | void} Promise if no callback function was passed, void otherwise. - */ - public deleteDeviceRegistrationState(idOrRegistrationState: string | DeviceRegistrationState, etag: string, deleteCallback: ErrorCallback): void; - public deleteDeviceRegistrationState(idOrRegistrationState: string | DeviceRegistrationState, deleteCallback: ErrorCallback): void; - public deleteDeviceRegistrationState(idOrRegistrationState: string | DeviceRegistrationState, etag: string): Promise; - public deleteDeviceRegistrationState(idOrRegistrationState: string | DeviceRegistrationState): Promise; - public deleteDeviceRegistrationState(idOrRegistrationState: string | DeviceRegistrationState, etagOrCallback?: string | ErrorCallback, deleteCallback?: ErrorCallback): Promise | void { - if (deleteCallback && !(typeof deleteCallback === 'function')) { - throw new ArgumentError('Callback has to be a Function'); - } - - if (typeof etagOrCallback === 'function') { - deleteCallback = etagOrCallback as ErrorCallback; - etagOrCallback = undefined; - } - - return errorCallbackToPromise((_callback) => { - this._delete(this._registrationsPrefix, idOrRegistrationState, etagOrCallback, _callback); - }, deleteCallback); - } - - /** - * Gets the attestation mechanism for an IndividualEnrollment record. - * @param enrollementId Unique identifier of the enrollment. - * @param callback Function called when the request is completed, either with an error or with an AttestationMechanism object. - * @returns {Promise> | void} Promise if no callback function was passed, void otherwise. - */ - public getIndividualEnrollmentAttestationMechanism(enrollementId: string, callback: HttpResponseCallback): void; - public getIndividualEnrollmentAttestationMechanism(enrollementId: string): Promise>; - public getIndividualEnrollmentAttestationMechanism(enrollementId: string, callback?: HttpResponseCallback): Promise> | void { - /*SRS_NODE_PROVISIONING_SERVICE_CLIENT_16_001: [The `getIndividualEnrollmentAttestationMechanism` method shall throw a `ReferenceError` if the `enrollmentId` parameter is falsy.]*/ - if (!enrollementId) { - throw new ReferenceError('enrollmentId cannot be \'' + enrollementId + '\''); - } - - /*SRS_NODE_PROVISIONING_SERVICE_CLIENT_16_002: [The `getIndividualEnrollmentAttestationMechanism` shall construct an HTTP request using information supplied by the caller as follows: - ``` - POST /enrollments//attestationmechanism?api-version= HTTP/1.1 - Authorization: - ```]*/ - const path = '/enrollments/' + encodeUriComponentStrict(enrollementId) + '/attestationmechanism' + this._versionQueryString(); - const headers = {}; - - return httpCallbackToPromise((_callback) => { - // for some reason we have to specify types in this callback to avoid the typescript compiler complaining about not using AttestationMechanism (even if it's in the method signature) - this._restApiClient.executeApiCall('POST', path, headers, undefined, _callback); - }, callback); - } - - /** - * Gets the attestation mechanism for an EnrollmentGroup record. - * @param enrollementGroupId Unique identifier of the EnrollmentGroup. - * @param callback Function called when the request is completed, either with an error or with an AttestationMechanism object. - * @returns {Promise> | void} Promise if no callback function was passed, void otherwise. - */ - public getEnrollmentGroupAttestationMechanism(enrollmentGroupId: string, callback: HttpResponseCallback): void; - public getEnrollmentGroupAttestationMechanism(enrollmentGroupId: string): Promise>; - public getEnrollmentGroupAttestationMechanism(enrollmentGroupId: string, callback?: HttpResponseCallback): Promise> | void { - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_16_003: [The `getEnrollmentGroupAttestationMechanism` method shall throw a `ReferenceError` if the `enrollementGroupId` parameter is falsy.]*/ - if (!enrollmentGroupId) { - throw new ReferenceError('enrollmentGroupId cannot be \'' + enrollmentGroupId + '\''); - } - - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_16_004: [The `getEnrollmentGroupAttestationMechanism` shall construct an HTTP request using information supplied by the caller as follows: - ``` - POST /enrollmentgroups//attestationmechanism?api-version= HTTP/1.1 - Authorization: - ```]*/ - const path = '/enrollmentgroups/' + encodeUriComponentStrict(enrollmentGroupId) + '/attestationmechanism' + this._versionQueryString(); - const headers = {}; - - return httpCallbackToPromise((_callback) => { - // for some reason we have to specify types in this callback to avoid the typescript compiler complaining about not using AttestationMechanism (even if it's in the method signature) - this._restApiClient.executeApiCall('POST', path, headers, undefined, _callback); - }, callback); - } - - private _getEnrollFunc(prefix: string, querySpecification: QuerySpecification, pageSize: number): (continuationToken: string, done: HttpResponseCallback) => void { - return (continuationToken, done) => { - const path = prefix + 'query' + this._versionQueryString(); - - let headers = { - 'Accept': 'application/json', - 'Content-Type': 'application/json; charset=utf-8' - }; - - if (continuationToken) { - headers['x-ms-continuation'] = continuationToken; - } - - if (pageSize) { - headers['x-ms-max-item-count'] = pageSize; - } - - this._restApiClient.executeApiCall('POST', path, headers, querySpecification, done); - }; - } - - private _versionQueryString(): string { - return '?api-version=2021-10-01'; - } - - private _createOrUpdate(endpointPrefix: string, enrollment: any, callback?: (err: Error, enrollmentResponse?: any, response?: any) => void): void { - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_009: [The `createOrUpdateIndividualEnrollment` method shall throw `ReferenceError` if the `IndividualEnrollment` argument is falsy.]*/ - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_012: [The `createOrUpdateEnrollmentGroup` method shall throw `ReferenceError` if the `EnrollmentGroup` argument is falsy.] */ - if (!enrollment) { - throw new ReferenceError('Required parameter enrollment was null or undefined when calling createOrUpdate.'); - } - - let id: string; - if (endpointPrefix === this._enrollmentGroupsPrefix) { - id = enrollment.enrollmentGroupId; - } else { - id = enrollment.registrationId; - } - - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_011: [The `createOrUpdateIndividualEnrollment` method shall throw `ArgumentError` if the `enrollment.registrationId` property is falsy.] */ - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_013: [`createOrUpdateEnrollmentGroup` method shall throw `ArgumentError` if the `enrollmentGroup.enrollmentGroupsId` property is falsy.] */ - if (!id) { - throw new ArgumentError('Required id property was null or undefined when calling createOrUpdate.'); - } - const path = endpointPrefix + encodeURIComponent(id) + this._versionQueryString(); - - const httpHeaders = { - 'Accept': 'application/json', - 'Content-Type': 'application/json; charset=utf-8' - }; - - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_055: [If the `enrollmentGroup` object contains an `etag` property it will be added as the value of the `If-Match` header of the http request.] */ - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_056: [If the `enrollment` object contains an `etag` property it will be added as the value of the `If-Match` header of the http request.] */ - if (enrollment.etag) { - httpHeaders['If-Match'] = enrollment.etag; - } - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_010: [The `createOrUpdateIndividualEnrollment` method shall construct an HTTP request using information supplied by the caller, as follows: - PUT /enrollments/?api-version= HTTP/1.1 - Authorization: - Accept: application/json - Content-Type: application/json; charset=utf-8 - - ]*/ - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_014: [The `createOrUpdateEnrollmentGroup` method shall construct an HTTP request using information supplied by the caller, as follows: - PUT /enrollmentGroups/?api-version= HTTP/1.1 - Authorization: - Accept: application/json - Content-Type: application/json; charset=utf-8 - - - ] */ - this._restApiClient.executeApiCall('PUT', path, httpHeaders, enrollment, (err, enrollmentResponse, httpResponse) => { - if (callback) { - if (err) { - callback(err); - } else { - callback(null, enrollmentResponse, httpResponse); - } - } - }); - } - - private _delete(endpointPrefix: string, enrollmentOrIdOrRegistration: string | any, etagOrCallback?: string | ErrorCallback, deleteCallback?: ErrorCallback): void { - let ifMatch: string; - let suppliedCallback: ErrorCallback | undefined; - let id: string; - - suppliedCallback = deleteCallback || ((typeof etagOrCallback === 'function') ? etagOrCallback as ErrorCallback : undefined); - if (!suppliedCallback) { - throw new ArgumentError('No callback was passed.'); - } - - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_015: [The `deleteIndividualEnrollment` method shall throw `ReferenceError` if the `enrollmentOrId` argument is falsy.] */ - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_016: [The `deleteEnrollmentGroup` method shall throw `ReferenceError` if the `enrollmentGroupOrId` argument is falsy.] */ - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_025: [The `deleteDeviceRegistrationState` method shall throw `ReferenceError` if the `idOrRegistrationState` argument is falsy.] */ - if (!enrollmentOrIdOrRegistration) { - throw new ReferenceError('Required parameter \'' + enrollmentOrIdOrRegistration + '\' was null or undefined when calling delete.'); - } - - if (typeof enrollmentOrIdOrRegistration === 'string') { - id = enrollmentOrIdOrRegistration; - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_040: [The `deleteIndividualEnrollment` method, if the first argument is a string, the second argument if present, must be a string or a callback, otherwise shall throw `ArgumentError`. .] */ - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_045: [The `deleteEnrollmentGroup` method, if the first argument is a string, the second argument if present, must be a string or a callback, otherwise shall throw `ArgumentError`.] */ - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_050: [The `deleteDeviceRegistrationState` method, if the first argument is a string, the second argument if present, must be a string or a callback, otherwise shall throw `ArgumentError`.] */ - if (!etagOrCallback) { - ifMatch = undefined; - } else if (typeof etagOrCallback === 'string') { - /*Codes_**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_044: [** The `deleteIndividualEnrollment` method, if the first argument is a string, and the second argument is a string, shall construct an HTTP request using information supplied by the caller as follows: - DELETE /enrollments/?api-version= HTTP/1.1 - If-Match: - Authorization: - */ - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_049: [** The `deleteEnrollmentGroup` method, if the first argument is a string, and the second argument is a string, shall construct an HTTP request using information supplied by the caller as follows: - DELETE /enrollmentGroups/?api-version= HTTP/1.1 - If-Match: - Authorization: - ] */ - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_054: [** The `deleteDeviceRegistrationState` method, if the first argument is a string, and the second argument is a string, shall construct an HTTP request using information supplied by the caller as follows: - DELETE /registrations/?api-version= HTTP/1.1 - If-Match: - Authorization: - ] */ - ifMatch = etagOrCallback; - } else if (typeof etagOrCallback === 'function') { - /*Codes_**SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_043: [** The `deleteIndividualEnrollment` method, if the first argument is a string, and the second argument is NOT a string, shall construct an HTTP request using information supplied by the caller as follows: - DELETE /enrollments/?api-version= HTTP/1.1 - Authorization: - */ - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_048: [** The `deleteEnrollmentGroup` method, if the first argument is a string, and the second argument is NOT a string, shall construct an HTTP request using information supplied by the caller as follows: - DELETE /enrollmentGroups/?api-version= HTTP/1.1 - Authorization: - ] */ - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_053: [** The `deleteDeviceRegistrationState` method, if the first argument is a string, and the second argument is NOT a string, shall construct an HTTP request using information supplied by the caller as follows: - DELETE /registrations/?api-version= HTTP/1.1 - Authorization: - ] */ - ifMatch = undefined; - suppliedCallback = etagOrCallback; - } else { - throw new ArgumentError('Second argument of this delete method must be a string or function.'); - } - } else { - if (endpointPrefix === this._enrollmentsPrefix) { - if (!enrollmentOrIdOrRegistration.registrationId) { - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_017: [The `deleteIndividualEnrollment` method, if the first argument is an `IndividualEnrollment` object, shall throw an `ArgumentError`, if the `registrationId` property is falsy.] */ - throw new ArgumentError('Required property \'registrationId\' was null or undefined when calling delete.'); - } - id = enrollmentOrIdOrRegistration.registrationId; - } else if (endpointPrefix === this._enrollmentGroupsPrefix) { - if (!enrollmentOrIdOrRegistration.enrollmentGroupId) { - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_018: [The `deleteEnrollmentGroup` method, if the first argument is an `EnrollmentGroup` object, shall throw an `ArgumentError`, if the `enrollmentGroupId' property is falsy.] */ - throw new ArgumentError('Required property \'enrollmentGroupId\' was null or undefined when calling delete.'); - } - id = enrollmentOrIdOrRegistration.enrollmentGroupId; - } else if (endpointPrefix === this._registrationsPrefix) { - if (!enrollmentOrIdOrRegistration.registrationId) { - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_026: [The `deleteDeviceRegistrationState` method, if the first argument is a `DeviceRegistrationState` object, shall throw an `ArgumentError`, if the `registrationId' property is falsy.] */ - throw new ArgumentError('Required property \'registrationId\' was null or undefined when calling delete.'); - } - id = enrollmentOrIdOrRegistration.registrationId; - } else { - throw new ArgumentError('Invalid path specified for delete operation.'); - } - - if (enrollmentOrIdOrRegistration.etag) { - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_021: [The `deleteIndividualEnrollment` method, if the first argument is an `IndividualEnrollment` object, with a non-falsy `etag` property, shall construct an HTTP request using information supplied by the caller as follows: - DELETE /enrollments/?api-version= HTTP/1.1 - If-Match: enrollmentOrIdOrRegistration.etag - Authorization: - ] */ - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_022: [The `deleteEnrollmentGroup` method, if the first argument is an `EnrollmentGroup` object, with a non-falsy `etag` property, shall construct an HTTP request using information supplied by the caller as follows: - DELETE /enrollmentGroups/?api-version= HTTP/1.1 - If-Match: enrollmentParameter.etag - Authorization: - ] */ - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_028: [** The `deleteDeviceRegistrationState` method, if the first argument is a `DeviceRegistrationState` object, with a non-falsy `etag` property, shall construct an HTTP request using information supplied by the caller as follows: - DELETE /registrations/?api-version= HTTP/1.1 - If-Match: idOrRegistrationState.etag - Authorization: - ] */ - ifMatch = enrollmentOrIdOrRegistration.etag; - } else { - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_023: [The `deleteEnrollmentGroup` method, if the first argument is an `EnrollmentGroup` object, with a falsy `etag` property, shall construct an HTTP request using information supplied by the caller as follows: - DELETE /enrollmentGroups/?api-version= HTTP/1.1 - Authorization: - ] */ - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_024: [The `deleteIndividualEnrollment` method, if the first argument is an `enrollment` object, with a falsy `etag` property, shall construct an HTTP request using information supplied by the caller as follows: - DELETE /enrollments/?api-version= HTTP/1.1 - Authorization: - ] */ - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_029: [** The `deleteDeviceRegistrationState` method, if the first argument is a `DeviceRegistrationState` object, with a falsy `etag` property, shall construct an HTTP request using information supplied by the caller as follows: - DELETE /registrations/?api-version= HTTP/1.1 - Authorization: - ] */ - ifMatch = undefined; - } - } - - const path = endpointPrefix + encodeURIComponent(id) + this._versionQueryString(); - - let httpHeaders = {}; - - if (ifMatch) { - httpHeaders['If-Match'] = ifMatch; - } - - this._restApiClient.executeApiCall('DELETE', path, httpHeaders, null, (err) => { - if (suppliedCallback) { - if (err) { - suppliedCallback(err); - } else { - suppliedCallback(null); - } - } - }); - } - - private _get(endpointPrefix: string, id: string, getCallback: HttpResponseCallback | HttpResponseCallback | HttpResponseCallback): void { - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_030: [The `getIndividualEnrollment` method shall throw `ReferenceError` if the `id` argument is falsy.] */ - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_031: [The `getEnrollmentGroup` method shall throw `ReferenceError` if the `id` argument is falsy.] */ - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_032: [The `getDeviceRegistrationState` method shall throw `ReferenceError` if the `id` argument is falsy.] */ - if (!id) { - throw new ReferenceError('Required parameter \'' + id + '\' was null or undefined when calling get.'); - } - - const path = endpointPrefix + encodeURIComponent(id) + this._versionQueryString(); - - const httpHeaders = { - 'Accept': 'application/json' - }; - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_033: [** The `getIndividualEnrollment` method shall construct an HTTP request using information supplied by the caller as follows: - GET /enrollments/?api-version= HTTP/1.1 - Accept: application/json - Authorization: - ] */ - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_034: [** The `getEnrollmentGroup` method shall construct an HTTP request using information supplied by the caller as follows: - GET /enrollmentGroups/?api-version= HTTP/1.1 - Authorization: - ] */ - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_035: [** The `getDeviceRegistrationState` method shall construct an HTTP request using information supplied by the caller as follows: - GET /registrations/?api-version= HTTP/1.1 - Authorization: - ] */ - this._restApiClient.executeApiCall('GET', path, httpHeaders, null, (err?: Error, enrollmentOrRegistrationState?: DeviceRegistrationState | IndividualEnrollment | EnrollmentGroup, httpResponse?: any) => { - const callback = (getCallback as HttpResponseCallback); - if (err) { - callback(err); - } else { - callback(null, enrollmentOrRegistrationState, httpResponse); - } - }); - } - - /** - * @method module:azure-iot-provisioning-service.ProvisioningServiceClient#fromConnectionString - * @description Constructs a ProvisioningServiceClient object from the given connection - * string using the default transport - * ({@link module:azure-iothub.Http|Http}). - * @param {String} value A connection string which encapsulates the - * appropriate (read and/or write) ProvisioningServiceClient - * permissions. - * @returns {module:azure-iot-provisioning-service.ProvisioningServiceClient} - */ - static fromConnectionString(value: string): ProvisioningServiceClient { - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_005: [The `fromConnectionString` method shall throw `ReferenceError` if the `value` argument is falsy.]*/ - if (!value) throw new ReferenceError('value is \'' + value + '\''); - - const cn = ConnectionString.parse(value); - - const config: RestApiClient.TransportConfig = { - host: cn.HostName, - sharedAccessSignature: SharedAccessSignature.create(cn.HostName, cn.SharedAccessKeyName, cn.SharedAccessKey, Date.now()), - tokenCredential: undefined - }; - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_006: [`fromConnectionString` method shall derive and transform the needed parts from the connection string in order to create a `config` object for the constructor (see `SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_002`).] */ - /*Codes_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_007: [The `fromConnectionString` method shall return a new instance of the `ProvisioningServiceClient` object.] */ - return new ProvisioningServiceClient(config); - } - - /** - * @method module:azure-iot-provisioning-service.ProvisioningServiceClient#fromTokenCredential - * @description Constructs a ProvisioningServiceClient object from the given Azure TokenCredential - * using the default transport - * ({@link module:azure-iothub.Http|Http}). - * @param {String} hostName Host name of the Azure service. - * @param {String} tokenCredential An Azure TokenCredential used to authenticate - * with the Azure service - * @returns {module:azure-iot-provisioning-service.ProvisioningServiceClient} - */ - static fromTokenCredential(hostName: string, tokenCredential: TokenCredential): ProvisioningServiceClient { - const config: RestApiClient.TransportConfig = { - host: hostName, - tokenCredential, - tokenScope: 'https://azure-devices-provisioning.net/.default' - }; - return new ProvisioningServiceClient(config); - } -} - -export type _tsLintWorkaround = { query: QueryResult, results: BulkEnrollmentOperationResult }; diff --git a/provisioning/service/src/query.ts b/provisioning/service/src/query.ts deleted file mode 100644 index a08b2a58d..000000000 --- a/provisioning/service/src/query.ts +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -'use strict'; - -import { IndividualEnrollment, EnrollmentGroup, DeviceRegistrationState } from './interfaces'; -import { ResultWithHttpResponse, HttpResponseCallback, httpCallbackToPromise } from 'azure-iot-common'; - -/** - * The query result. - */ -export interface QueryResult { - /** - * The query result items, as a collection. - */ - items: Array; -} - -/** - * A Json query request - */ -export interface QuerySpecification { - /** - * The query. - */ - query: string; -} - -export type QueryCallback = HttpResponseCallback; - -export class Query { - continuationToken: string; - hasMoreResults: boolean; - - private _executeQueryFn: (continuationToken: string, done: QueryCallback) => void; - - constructor(executeQueryFn: (continuationToken: string, done: QueryCallback) => void) { - if (!executeQueryFn) throw new ReferenceError('executeQueryFn cannot be \'' + executeQueryFn + '\''); - if (typeof executeQueryFn !== 'function') throw new TypeError('executeQueryFn cannot be \'' + typeof executeQueryFn + '\''); - - this._executeQueryFn = executeQueryFn; - this.hasMoreResults = true; - this.continuationToken = null; - } - - /** - * @method module:azure-iot-provisioning-service.Query#next - * @description Gets the next page of results for this query. - * @param {string} continuationToken Continuation Token used for paging through results (optional) - * @param {Function} [done] The optional callback that will be called with either an Error object or - * the results of the query. - * @returns {Promise> | void} Promise if no callback function was passed, void otherwise. - */ - next(done: QueryCallback): void; - next(continuationToken: string, done: QueryCallback): void; - next(): Promise>; - next(continuationToken: string): Promise>; - next(continuationTokenOrCallback?: string | QueryCallback, done?: QueryCallback): Promise> | void { - let actualContinuationToken = this.continuationToken; - let actualCallback: QueryCallback; - - if (typeof continuationTokenOrCallback === 'function' && !done) { - actualCallback = continuationTokenOrCallback as QueryCallback; - } else { - actualContinuationToken = continuationTokenOrCallback as string; - actualCallback = done as QueryCallback; - } - - return httpCallbackToPromise((_callback) => { - this._executeQueryFn(actualContinuationToken, (err, result, response) => { - if (err) { - _callback(err); - } else { - this.continuationToken = response.headers['x-ms-continuation'] as string; - this.hasMoreResults = this.continuationToken !== undefined; - - /*Codes_SRS_NODE_SERVICE_QUERY_16_007: [The `next` method shall call the `done` callback with a `null` error object, the results of the query and the response of the underlying transport if the request was successful.]*/ - _callback(null, result, response); - } - }); - }, actualCallback); - } -} diff --git a/provisioning/service/test/_provisioningserviceclient_test.js b/provisioning/service/test/_provisioningserviceclient_test.js deleted file mode 100644 index 3111f3c8b..000000000 --- a/provisioning/service/test/_provisioningserviceclient_test.js +++ /dev/null @@ -1,745 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -"use strict"; - -var assert = require('chai').assert; -var errors = require('azure-iot-common').errors; -var ProvisioningServiceClient = require('../dist/provisioningserviceclient.js').ProvisioningServiceClient; -var encodeURIComponentStrict = require('azure-iot-common').encodeUriComponentStrict; - -var fakeRegistrationId = 'fakeId'; -var fakeDeviceId = 'sample-device'; -var fakeEnrollment = { - registrationId: fakeRegistrationId, - deviceId: fakeDeviceId, - etag: 'etag', - attestation: { - type: 'tpm', - tpm: { - endorsementKey: 'endorsementkey' - } - }, - initialTwinState: null, - capabilities: { - iotEdge: false - } -}; - -var fakeEnrollmentNoEtag = { - registrationId: fakeRegistrationId, - deviceId: fakeDeviceId, - attestation: { - type: 'tpm', - tpm: { - endorsementKey: 'endorsementkey' - } - }, - initialTwinState: null -}; - -var fakeGroupId = 'fakeGroup'; -var fakeEnrollmentGroup = { - enrollmentGroupId: fakeGroupId, - etag: 'etag' -}; - -var fakeEnrollmentGroupNoEtag = { - enrollmentGroupId: fakeGroupId, -}; - -var fakeRegistration = { - registrationId: 'fakeId', - etag: 'etag' -}; - -var fakeRegistrationNoEtag = { - registrationId: 'fakeId' -}; - -function _versionQueryString() { - return '?api-version=2021-10-01'; -} - - -function testFalsyArg(methodUnderTest, argName, argValue, ExpectedErrorType) { - var errorName = ExpectedErrorType ? ExpectedErrorType.name : 'Error'; - it('Throws a ' + errorName + ' if \'' + argName + '\' is \'' + JSON.stringify(argValue) + '\' (type:' + typeof (argValue) + ')', function () { - var de = new ProvisioningServiceClient({ - host: 'host', - sharedAccessSignature: 'sas' - }); - assert.throws(function () { - de[methodUnderTest](argValue, function () {}); - }, ExpectedErrorType); - }); -} - -function testErrorCallback(methodUnderTest, arg1, arg2, arg3) { - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_037: [When any registry operation method receives an HTTP response with a status code >= 300, it shall invoke the `done` callback function with an error translated using the requirements detailed in `registry_http_errors_requirements.md`] */ - it('Calls the done callback with a proper error if an HTTP error occurs', function (testCallback) { - var FakeHttpErrorHelper = { - executeApiCall: function (method, path, httpHeaders, body, done) { - done(new errors.DeviceNotFoundError('Not found')); - } - }; - - var de = new ProvisioningServiceClient({ - host: 'host', - sharedAccessSignature: 'sas' - }, FakeHttpErrorHelper); - var callback = function (err, result, response) { - assert.instanceOf(err, errors.DeviceNotFoundError); - assert.isUndefined(result); - assert.isUndefined(response); - testCallback(); - }; - - if (arg1 && arg2 && arg3) { - de[methodUnderTest](arg1, arg2, arg3, callback); - } else if (arg1 && arg2) { - de[methodUnderTest](arg1, arg2, callback); - } else if (arg1 && !arg2) { - de[methodUnderTest](arg1, callback); - } else { - de[methodUnderTest](callback); - } - }); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_036: [If any device enrollment operation method encounters an error before it can send the request, it shall invoke the `done` callback function and pass the standard JavaScript `Error` object with a text description of the error (err.message).] */ - it('Calls the done callback with a standard error if not an HTTP error', function (testCallback) { - var FakeGenericErrorHelper = { - executeApiCall: function (method, path, httpHeaders, body, done) { - done(new Error('Fake Error')); - } - }; - - var de = new ProvisioningServiceClient({ - host: 'host', - sharedAccessSignature: 'sas' - }, FakeGenericErrorHelper); - var callback = function (err, result, response) { - assert.instanceOf(err, Error); - assert.isUndefined(result); - assert.isUndefined(response); - testCallback(); - }; - - if (arg1 && arg2 && arg3) { - de[methodUnderTest](arg1, arg2, arg3, callback); - } else if (arg1 && arg2) { - de[methodUnderTest](arg1, arg2, callback); - } else if (arg1 && !arg2) { - de[methodUnderTest](arg1, callback); - } else { - de[methodUnderTest](callback); - } - }); -} - -describe('ProvisioningServiceClient', function () { - describe('#constructor', function () { - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_001: [The `ProvisioningServiceClient` construction shall throw a `ReferenceError` if the `config` object is falsy.] */ - [undefined, null].forEach(function (badConfig) { - it('Throws if \'config\' is \'' + badConfig + '\'', function () { - assert.throws(function () { - return new ProvisioningServiceClient(badConfig); - }, ReferenceError); - }); - }); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_002: [The `ProvisioningServiceClient` constructor shall throw an `ArgumentError` if the `config` object is missing one or more of the following properties: - - `host`: the IoT Hub hostname - - `sharedAccessSignature`: shared access signature with the permissions for the desired operations.] */ - - [undefined, null, ''].forEach(function (badConfigProperty) { - it('Throws if \'config.host\' is \'' + badConfigProperty + '\'', function () { - assert.throws(function () { - return new ProvisioningServiceClient({ - host: badConfigProperty, - sharedAccessSignature: 'sharedAccessSignature' - }); - }, errors.ArgumentError); - }); - - it('Throws if \'config.sharedAccessSignature\' is \'' + badConfigProperty + '\' and \'config.tokenCredential\' is not defined', function () { - assert.throws(function () { - return new ProvisioningServiceClient({ - host: 'host', - sharedAccessSignature: badConfigProperty - }); - }, errors.ArgumentError); - }); - - it('Throws if \'config.tokenCredential\' is \'' + badConfigProperty + '\' and \'config.sharedAccessSignature\' is not defined', function () { - assert.throws(function () { - return new ProvisioningServiceClient({ - host: 'host', - tokenCredential: badConfigProperty - }); - }, errors.ArgumentError); - }); - - it('Throws if \'config.tokenCredential\' is \'' + badConfigProperty + '\' and \'config.sharedAccessSignature\' is not defined', function () { - assert.throws(function () { - return new ProvisioningServiceClient({ - host: 'host', - tokenCredential: badConfigProperty - }); - }, errors.ArgumentError); - }); - - it('Throws if \'config.tokenCredential\' is defined and \'config.tokenScope\' is falsy', function () { - assert.throws(function () { - return new ProvisioningServiceClient({ - host: 'host', - tokenCredential: {getToken: () => Promise.resolve({token: "fake_token", expiresOnTimestamp: 2456})}, - tokenScope: badConfigProperty - }); - }, errors.ArgumentError); - }); - }); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_003: [The `ProvisioningServiceClient` constructor shall use the `restApiClient` provided as a second argument if it is provided.] */ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_004: [The `ProvisioningServiceClient` constructor shall use `azure-iot-http-base.RestApiClient` if no `restApiClient` argument is provided.] */ - }); - - describe('#fromConnectionString', function () { - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_005: [** The `fromConnectionString` method shall throw `ReferenceError` if the `value` argument is falsy. **]*/ - [undefined, null, ''].forEach(function (falsyConnectionString) { - it('Throws if \'value\' is \'' + falsyConnectionString + '\'', function () { - assert.throws(function () { - return ProvisioningServiceClient.fromConnectionString(falsyConnectionString); - }, ReferenceError); - }); - }); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_006: [`fromConnectionString` method shall derive and transform the needed parts from the connection string in order to create a `config` object for the constructor (see `SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_002`). **] */ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_007: [The `fromConnectionString` method shall return a new instance of the `ProvisioningServiceClient` object.] */ - it('Returns a new instance of the ProvisioningServiceClient object', function () { - var de = ProvisioningServiceClient.fromConnectionString('HostName=a.b.c;SharedAccessKeyName=name;SharedAccessKey=key'); - assert.instanceOf(de, ProvisioningServiceClient); - }); - }); - - describe('#fromTokenCredential', function () { - it('Returns a new instance of the ProvisioningServiceClient object', function () { - const client = ProvisioningServiceClient.fromTokenCredential( - 'my_host.com', - {getToken: () => Promise.resolve({token: 'fake_token', expiresOnTimestamp: 342})} - ); - assert.instanceOf(client, ProvisioningServiceClient); - }); - - it('Correctly creates the config for the RestApiClient', async function () { - const client = ProvisioningServiceClient.fromTokenCredential( - 'my_host.com', - {getToken: () => Promise.resolve({token: 'fake_token', expiresOnTimestamp: 342})} - ); - assert.strictEqual(client._restApiClient._config.host, 'my_host.com'); - assert.strictEqual(client._restApiClient._config.tokenScope, 'https://azure-devices-provisioning.net/.default'); - const token = await client._restApiClient._config.tokenCredential.getToken(client._restApiClient._config.tokenScope); - assert.strictEqual(token.token, 'fake_token'); - assert.strictEqual(token.expiresOnTimestamp, 342); - }); - }); - - describe('#createOrUpdateIndividualEnrollment', function () { - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_009: [The `createOrUpdateIndividualEnrollment` method shall throw `ReferenceError` if the `enrollment` argument is falsy.]*/ - [undefined, null].forEach(function (falsyEnrollment) { - testFalsyArg('createOrUpdateIndividualEnrollment', 'enrollment', falsyEnrollment, ReferenceError); - }); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_011: [The `createOrUpdateIndividualEnrollment` method shall throw `ArgumentError` if the `enrollment.registrationId` property is falsy.] */ - [undefined, null].forEach(function (badRegistrationId) { - var badEnrollment = {}; - badEnrollment.registrationId = badRegistrationId; - testFalsyArg('createOrUpdateIndividualEnrollment', 'enrollment', badEnrollment, errors.ArgumentError); - }); - - testErrorCallback('createOrUpdateIndividualEnrollment', fakeEnrollmentNoEtag); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_010: [** The `createOrUpdateIndividualEnrollment` method shall construct an HTTP request using information supplied by the caller, as follows: - PUT /enrollments/?api-version= HTTP/1.1 - Authorization: - Accept: application/json - Content-Type: application/json; charset=utf-8 - - - ] */ - - it('Constructs a valid HTTP request', function (testCallback) { - var fakeHttpHelper = { - executeApiCall: function (method, path, httpHeaders, body, done) { - assert.equal(method, 'PUT'); - assert.equal(path, '/enrollments/' + encodeURIComponent(fakeRegistrationId) + _versionQueryString()); - assert.equal(httpHeaders['Content-Type'], 'application/json; charset=utf-8'); - assert.equal(httpHeaders['Accept'], 'application/json'); - assert.equal(Object.keys(httpHeaders).length, 2, 'Should be only two headers'); - assert.deepEqual(body, fakeEnrollmentNoEtag); - - done(); - } - }; - - var de = new ProvisioningServiceClient({ - host: 'host', - sharedAccessSignature: 'sas' - }, fakeHttpHelper); - de.createOrUpdateIndividualEnrollment(fakeEnrollmentNoEtag, testCallback); - }); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_056: [If the `enrollment` object contains an `etag` property it will be added as the value of the `If-Match` header of the http request.] */ - it('Add If-Match if etag property present', function (testCallback) { - var fakeHttpHelper = { - executeApiCall: function (method, path, httpHeaders, body, done) { - assert.equal(method, 'PUT'); - assert.equal(path, '/enrollments/' + encodeURIComponent(fakeRegistrationId) + _versionQueryString()); - assert.equal(httpHeaders['Content-Type'], 'application/json; charset=utf-8'); - assert.equal(httpHeaders['Accept'], 'application/json'); - assert.equal(httpHeaders['If-Match'], 'etag'); - assert.equal(Object.keys(httpHeaders).length, 3, 'Should be only three headers'); - assert.deepEqual(body, fakeEnrollment); - - done(); - } - }; - - var de = new ProvisioningServiceClient({ - host: 'host', - sharedAccessSignature: 'sas' - }, fakeHttpHelper); - de.createOrUpdateIndividualEnrollment(fakeEnrollment, testCallback); - }); - - - }); - - describe('#createOrUpdateEnrollmentGroup', function () { - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_012: [The `createOrUpdateEnrollmentGroup` method shall throw `ReferenceError` if the `EnrollmentGroup` argument is falsy.] */ - [undefined, null].forEach(function (falsyEnrollmentGroup) { - testFalsyArg('createOrUpdateEnrollmentGroup', 'enrollmentGroup', falsyEnrollmentGroup, ReferenceError); - }); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_013: [`createOrUpdateEnrollmentGroup` method shall throw `ArgumentError` if the `enrollmentGroup.enrollmentGroupsId` property is falsy.] */ - [undefined, null].forEach(function (badGroupId) { - var badEnrollmentGroup = {}; - badEnrollmentGroup.enrollmentGroupId = badGroupId; - testFalsyArg('createOrUpdateEnrollmentGroup', 'enrollmentGroup', badEnrollmentGroup, errors.ArgumentError); - }); - - testErrorCallback('createOrUpdateEnrollmentGroup', fakeEnrollmentGroupNoEtag); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_014: [The `createOrUpdateEnrollmentGroup` method shall construct an HTTP request using information supplied by the caller, as follows: - PUT /enrollmentGroups/?api-version= HTTP/1.1 - Authorization: - Accept: application/json - Content-Type: application/json; charset=utf-8 - - - ] */ - it('Constructs a valid HTTP request', function (testCallback) { - var fakeHttpHelper = { - executeApiCall: function (method, path, httpHeaders, body, done) { - assert.equal(method, 'PUT'); - assert.equal(path, '/enrollmentGroups/' + encodeURIComponent(fakeGroupId) + _versionQueryString()); - assert.equal(httpHeaders['Content-Type'], 'application/json; charset=utf-8'); - assert.equal(httpHeaders['Accept'], 'application/json'); - assert.equal(Object.keys(httpHeaders).length, 2, 'Should be only two headers'); - assert.deepEqual(body, fakeEnrollmentGroupNoEtag); - - done(); - } - }; - - var de = new ProvisioningServiceClient({ - host: 'host', - sharedAccessSignature: 'sas' - }, fakeHttpHelper); - de.createOrUpdateEnrollmentGroup(fakeEnrollmentGroupNoEtag, testCallback); - }); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_055: [If the `enrollmentGroup` object contains an `etag` property it will be added as the value of the `If-Match` header of the http request.] */ - it('Add If-Match if etag property present', function (testCallback) { - var fakeHttpHelper = { - executeApiCall: function (method, path, httpHeaders, body, done) { - assert.equal(method, 'PUT'); - assert.equal(path, '/enrollmentGroups/' + encodeURIComponent(fakeGroupId) + _versionQueryString()); - assert.equal(httpHeaders['Content-Type'], 'application/json; charset=utf-8'); - assert.equal(httpHeaders['Accept'], 'application/json'); - assert.equal(httpHeaders['If-Match'], 'etag'); - assert.equal(Object.keys(httpHeaders).length, 3, 'Should be only three headers'); - assert.deepEqual(body, fakeEnrollmentGroup); - - done(); - } - }; - - var de = new ProvisioningServiceClient({ - host: 'host', - sharedAccessSignature: 'sas' - }, fakeHttpHelper); - de.createOrUpdateEnrollmentGroup(fakeEnrollmentGroup, testCallback); - }); - - }); - - function testDeleteAPI(methodUnderTest, uriPath, falsyArgArgumentName, firstArgumentObject, firstArgumentObjectNoEtag, firstArgumentObjectIdPropertyName) { - - describe('#' + methodUnderTest, function () { - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_015: [The `deleteIndividualEnrollment` method shall throw `ReferenceError` if the `enrollmentOrId` argument is falsy.] */ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_016: [The `deleteEnrollmentGroup` method shall throw `ReferenceError` if the `enrollmentGroupOrId` argument is falsy.] */ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_025: [The `deleteDeviceRegistrationState` method shall throw `ReferenceError` if the `idOrRegistrationState` argument is falsy.] */ - [undefined, null, 0, false].forEach(function (invalidFirstArgument) { - testFalsyArg(methodUnderTest, falsyArgArgumentName, invalidFirstArgument, ReferenceError); - }); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_040: [The `deleteIndividualEnrollment` method, if the first argument is a string, the second argument if present, must be a string or a callback, otherwise shall throw `ArgumentError`.] */ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_045: [The `deleteEnrollmentGroup` method, if the first argument is a string, the second argument if present, must be a string or a callback, otherwise shall throw `ArgumentError`.] */ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_050: [The `deleteDeviceRegistrationState` method, if the first argument is a string, the second argument if present, must be a string or a callback, otherwise shall throw `ArgumentError`.] */ - it('Throws argument error if second parameter is wrong type when using a string as first argument', function () { - var de = new ProvisioningServiceClient({ - host: 'host', - sharedAccessSignature: 'sas' - }); - assert.throws(function () { - de[methodUnderTest]('fake-registration', 1, function () {}); - }, errors.ArgumentError); - }); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_041: [The `deleteIndividualEnrollment` method, if the first argument is a string and the second argument is a string, the third argument if present, must be a callback, otherwise shall throw `ArgumentError`.] */ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_046: [The `deleteEnrollmentGroup` method, if the first argument is a string and the second argument is a string, the third argument if present, must be a callback, otherwise shall throw `ArgumentError`.] */ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_051: [The `deleteDeviceRegistrationState` method, if the first argument is a string and the second argument is a string, the third argument if present, must be a callback, otherwise shall throw `ArgumentError`.] */ - it('Throws argument error if third parameter is wrong type when using a string first argument and etag', function () { - var de = new ProvisioningServiceClient({ - host: 'host', - sharedAccessSignature: 'sas' - }); - assert.throws(function () { - de[methodUnderTest]('fake-registration', 'etag', 'not the correct type'); - }, errors.ArgumentError); - }); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_042: [The `deleteIndividualEnrollment` method, if the first argument is an IndividualEnrollment object, the second argument if present, must be a callback, otherwise shall return a Promise.] */ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_047: [The `deleteEnrollmentGroup` method, if the first argument is an EnrollmentGroup object, the second argument if present, must be a callback, otherwise shall return a Promise.] */ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_052: [The `deleteDeviceRegistrationState` method, if the first argument is an `DeviceRegistrationState` object, the second argument if present, must be a callback, otherwise shall return a Promise.] */ - it('Returns a promise if first parameter is an object and second parameter is NOT a callback', function (done) { - var fakeHttpHelper = { - executeApiCall: function (method, path, httpHeaders, body, done) { - done(); - } - }; - - var de = new ProvisioningServiceClient({ - host: 'host', - sharedAccessSignature: 'sas' - }, fakeHttpHelper); - const promise = de[methodUnderTest](firstArgumentObjectNoEtag, 'etag'); - - assert.instanceOf(promise, Promise) - promise.then((result) => { - done() - }).catch(err => { - done(err) - }); - }); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_017: [The `deleteIndividualEnrollment` method, if the first argument is an `IndividualEnrollment` object, shall throw an `ArgumentError`, if the `registrationId` property is falsy.] */ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_018: [The `deleteEnrollmentGroup` method, if the first argument is an `EnrollmentGroup` object, shall throw an `ArgumentError`, if the `enrollmentGroupId' property is falsy.] */ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_026: [The `deleteDeviceRegistrationState` method, if the first argument is a `DeviceRegistrationState` object, shall throw an `ArgumentError`, if the `registrationId' property is falsy.] */ - [undefined, null].forEach(function (badId) { - var badObject = {}; - badObject[firstArgumentObjectIdPropertyName] = badId; - testFalsyArg(methodUnderTest, falsyArgArgumentName, badObject, errors.ArgumentError); - }); - - testErrorCallback(methodUnderTest, firstArgumentObject); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_043: [** The `deleteIndividualEnrollment` method, if the first argument is a string, and the second argument is NOT a string, shall construct an HTTP request using information supplied by the caller as follows: - DELETE /enrollments/?api-version= HTTP/1.1 - Authorization: - ] */ - it('Constructs a valid HTTP request for a STRING first parameter with NO etag', function (testCallback) { - var stringIdName = 'fake-enrollment'; - var fakeHttpHelper = { - executeApiCall: function (method, path, httpHeaders, body, done) { - assert.equal(method, 'DELETE'); - assert.equal(path, uriPath + encodeURIComponent(stringIdName) + _versionQueryString()); - assert.equal(body, null); - done(); - } - }; - var de = new ProvisioningServiceClient({ - host: 'host', - sharedAccessSignature: 'sas' - }, fakeHttpHelper); - de[methodUnderTest](stringIdName, testCallback); - }); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_044: [** The `deleteIndividualEnrollment` method, if the first argument is a string, and the second argument is a string, shall construct an HTTP request using information supplied by the caller as follows: - DELETE /enrollments/?api-version= HTTP/1.1 - If-Match: - Authorization: - ] */ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_048: [** The `deleteEnrollmentGroup` method, if the first argument is a string, and the second argument is NOT a string, shall construct an HTTP request using information supplied by the caller as follows: - DELETE /enrollmentGroups/?api-version= HTTP/1.1 - Authorization: - ] */ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_053: [** The `deleteDeviceRegistrationState` method, if the first argument is a string, and the second argument is NOT a string, shall construct an HTTP request using information supplied by the caller as follows: - DELETE /registrations/?api-version= HTTP/1.1 - Authorization: - ] */ - it('Constructs a valid HTTP request for a STRING first parameter and a STRING second parameter', function (testCallback) { - var stringIdName = 'fake-enrollment'; - var etag = 'etag'; - var fakeHttpHelper = { - executeApiCall: function (method, path, httpHeaders, body, done) { - assert.equal(method, 'DELETE'); - assert.equal(path, uriPath + encodeURIComponent(stringIdName) + _versionQueryString()); - assert.deepEqual(httpHeaders, { - 'If-Match': etag - }); - assert.equal(Object.keys(httpHeaders).length, 1, 'Should be only one header'); - assert.equal(body, null); - done(); - } - }; - var de = new ProvisioningServiceClient({ - host: 'host', - sharedAccessSignature: 'sas' - }, fakeHttpHelper); - de[methodUnderTest](stringIdName, etag, testCallback); - }); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_021: [The `deleteIndividualEnrollment` method, if the first argument is an `IndividualEnrollment` object, with a non-falsy `etag` property, shall construct an HTTP request using information supplied by the caller as follows: - DELETE /enrollments/?api-version= HTTP/1.1 - If-Match: enrollmentOrId.etag - Authorization: - ] */ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_022: [The `deleteEnrollmentGroup` method, if the first argument is an `EnrollmentGroup` object, with a non-falsy `etag` property, shall construct an HTTP request using information supplied by the caller as follows: - DELETE /enrollmentGroups/?api-version= HTTP/1.1 - If-Match: enrollmentParameter.etag - Authorization: - ] */ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_028: [** The `deleteDeviceRegistrationState` method, if the first argument is a `DeviceRegistrationState` object, with a non-falsy `etag` property, shall construct an HTTP request using information supplied by the caller as follows: - DELETE /registrations/?api-version= HTTP/1.1 - If-Match: idOrRegistrationState.etag - Authorization: - ] */ - it('constructs a valid HTTP request for ' + falsyArgArgumentName + ' parameter with etag', function (testCallback) { - var fakeHttpHelper = { - executeApiCall: function (method, path, httpHeaders, body, done) { - assert.equal(method, 'DELETE'); - assert.equal(path, uriPath + encodeURIComponent(firstArgumentObject[firstArgumentObjectIdPropertyName]) + _versionQueryString()); - assert.deepEqual(httpHeaders, { - 'If-Match': firstArgumentObject.etag - }); - assert.equal(Object.keys(httpHeaders).length, 1, 'Should be only one header'); - assert.equal(body, null); - done(); - } - }; - - var de = new ProvisioningServiceClient({ - host: 'host', - sharedAccessSignature: 'sas' - }, fakeHttpHelper); - de[methodUnderTest](firstArgumentObject, undefined, () => { - testCallback(); - }); - }); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_024: [The `deleteIndividualEnrollment` method, if the first argument is an `IndividualEnrollment` object, with a falsy `etag` property, shall construct an HTTP request using information supplied by the caller as follows: - DELETE /enrollments/?api-version= HTTP/1.1 - Authorization: - ] */ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_023: [The `deleteEnrollmentGroup` method, if the first argument is an `EnrollmentGroup` object, with a falsy `etag` property, shall construct an HTTP request using information supplied by the caller as follows: - DELETE /enrollmentGroups/?api-version= HTTP/1.1 - Authorization: - ] */ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_029: [** The `deleteDeviceRegistrationState` method, if the first argument is a `DeviceRegistrationState` object, with a falsy `etag` property, shall construct an HTTP request using information supplied by the caller as follows: - DELETE /registrations/?api-version= HTTP/1.1 - Authorization: - ] */ - it('constructs a valid HTTP request for ' + falsyArgArgumentName + ' parameter without etag', function (testCallback) { - var fakeHttpHelper = { - executeApiCall: function (method, path, httpHeaders, body, done) { - assert.equal(method, 'DELETE'); - assert.equal(path, uriPath + encodeURIComponent(firstArgumentObjectNoEtag[firstArgumentObjectIdPropertyName]) + _versionQueryString()); - assert.equal(Object.keys(httpHeaders).length, 0, 'Should be zero headers'); - assert.equal(body, null); - done(); - } - }; - - var de = new ProvisioningServiceClient({ - host: 'host', - sharedAccessSignature: 'sas' - }, fakeHttpHelper); - de[methodUnderTest](firstArgumentObjectNoEtag, testCallback); - }); - }); - } - - testDeleteAPI('deleteIndividualEnrollment', '/enrollments/', 'enrollment', fakeEnrollment, fakeEnrollmentNoEtag, 'registrationId'); - testDeleteAPI('deleteEnrollmentGroup', '/enrollmentGroups/', 'enrollmentGroup', fakeEnrollmentGroup, fakeEnrollmentGroupNoEtag, 'enrollmentGroupId'); - testDeleteAPI('deleteDeviceRegistrationState', '/registrations/', 'registrationState', fakeRegistration, fakeRegistrationNoEtag, 'registrationId'); - - function testGetAPI(methodUnderTest, uriPath) { - - describe('#' + methodUnderTest, function () { - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_030: [The `getIndividualEnrollment` method shall throw `ReferenceError` if the `id` argument is falsy.] */ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_031: [The `getEnrollmentGroup` method shall throw `ReferenceError` if the `id` argument is falsy.] */ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_032: [The `getDeviceRegistrationState` method shall throw `ReferenceError` if the `id` argument is falsy.] */ - [undefined, null, 0, false].forEach(function (id) { - testFalsyArg(methodUnderTest, 'id', id, ReferenceError); - }); - - testErrorCallback(methodUnderTest, 'fakeId'); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_033: [** The `getIndividualEnrollment` method shall construct an HTTP request using information supplied by the caller as follows: - GET /enrollments/?api-version= HTTP/1.1 - Accept: application/json - Authorization: - ] */ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_034: [** The `getEnrollmentGroup` method shall construct an HTTP request using information supplied by the caller as follows: - GET /enrollmentGroups/?api-version= HTTP/1.1 - Authorization: - ] */ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_035: [** The `getDeviceRegistrationState` method shall construct an HTTP request using information supplied by the caller as follows: - GET /registrations/?api-version= HTTP/1.1 - Authorization: - ] */ - it('Constructs a valid HTTP request for id parameter', function (testCallback) { - var id = 'fakeRegistration'; - var fakeHttpHelper = { - executeApiCall: function (method, path, httpHeaders, body, done) { - assert.equal(method, 'GET'); - assert.equal(path, uriPath + encodeURIComponent(id) + _versionQueryString()); - assert.equal(httpHeaders['Accept'], 'application/json'); - assert.equal(Object.keys(httpHeaders).length, 1, 'Should be one headers'); - assert.equal(body, null); - done(); - } - }; - - var de = new ProvisioningServiceClient({ - host: 'host', - sharedAccessSignature: 'sas' - }, fakeHttpHelper); - de[methodUnderTest](id, testCallback); - }); - }); - } - - testGetAPI('getIndividualEnrollment', '/enrollments/'); - testGetAPI('getEnrollmentGroup', '/enrollmentGroups/'); - testGetAPI('getDeviceRegistrationState', '/registrations/'); - - - describe('#runBulkEnrollmentOperation', function () { - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_038: [The `runBulkEnrollmentOperation` method shall throw `ReferenceError` if the `bulkEnrollmentOperation` argument is falsy.] */ - [undefined, null].forEach(function (bo) { - testFalsyArg('runBulkEnrollmentOperation', 'bulkEnrollmentOperation', bo, ReferenceError); - }); - - var fakeBo = { - mode: 'update', - enrollments: [fakeEnrollment] - }; - testErrorCallback('runBulkEnrollmentOperation', fakeBo); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_039: [** The `runBulkEnrollmentOperation` method shall construct an HTTP request using information supplied by the caller as follows: - POST /enrollments?api-version= HTTP/1.1 - Authorization: - Accept: application/json - Content-Type: application/json; charset=utf-8 - - - ] */ - it('Constructs a valid HTTP request for bulkEnrollmentOperation parameter', function (testCallback) { - var fakeHttpHelper = { - executeApiCall: function (method, path, httpHeaders, body, done) { - assert.equal(method, 'POST'); - assert.equal(path, '/enrollments/' + _versionQueryString()); - assert.equal(httpHeaders['Content-Type'], 'application/json; charset=utf-8'); - assert.equal(httpHeaders['Accept'], 'application/json'); - assert.equal(Object.keys(httpHeaders).length, 2, 'Should be two headers'); - assert.deepEqual(body, fakeBo); - done(); - } - }; - - var de = new ProvisioningServiceClient({ - host: 'host', - sharedAccessSignature: 'sas' - }, fakeHttpHelper); - de.runBulkEnrollmentOperation(fakeBo, testCallback); - }); - }); - - - describe('#getIndividualEnrollmentAttestationMechanism', function () { - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_16_001: [The `getIndividualEnrollmentAttestationMechanism` method shall throw a `ReferenceError` if the `enrollmentId` parameter is falsy.]*/ - [undefined, null, ''].forEach(function(badEnrollmentId) { - testFalsyArg('getIndividualEnrollmentAttestationMechanism', 'enrollmentId', badEnrollmentId, ReferenceError); - }); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_036: [If any device enrollment operation method encounters an error before it can send the request, it shall invoke the `done` callback function and pass the standard JavaScript `Error` object with a text description of the error (err.message). ]*/ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_037: [When any registry operation method receives an HTTP response with a status code >= 300, it shall invoke the `done` callback function with an error translated using the requirements detailed in `registry_http_errors_requirements.md` ]*/ - testErrorCallback('getIndividualEnrollmentAttestationMechanism', 'enrollment-id'); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_16_002: [** The `getIndividualEnrollmentAttestationMechanism` shall construct an HTTP request using information supplied by the caller as follows: - ``` - POST /enrollments//attestationmechanism?api-version= HTTP/1.1 - Authorization: - ```]*/ - it('creates a valid HTTP request', function (testCallback) { - var testEnrollmentId = 'test-#-enrollment'; - var fakeHttpHelper = { - executeApiCall: function (method, path, httpHeaders, body, done) { - assert.equal(method, 'POST'); - assert.equal(path, '/enrollments/' + encodeURIComponentStrict(testEnrollmentId) + '/attestationmechanism' + _versionQueryString()); - - done(); - } - }; - - var de = new ProvisioningServiceClient({ host: 'host', sharedAccessSignature: 'sas' }, fakeHttpHelper); - de.getIndividualEnrollmentAttestationMechanism(testEnrollmentId, testCallback); - }); - }); - - - describe('#getEnrollmentGroupAttestationMechanism', function () { - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_16_003: [The `getEnrollmentGroupAttestationMechanism` method shall throw a `ReferenceError` if the `enrollementGroupId` parameter is falsy.]*/ - [undefined, null, ''].forEach(function(badEnrollmentId) { - testFalsyArg('getEnrollmentGroupAttestationMechanism', 'enrollmentGroupId', badEnrollmentId, ReferenceError); - }); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_036: [If any device enrollment operation method encounters an error before it can send the request, it shall invoke the `done` callback function and pass the standard JavaScript `Error` object with a text description of the error (err.message). ]*/ - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_06_037: [When any registry operation method receives an HTTP response with a status code >= 300, it shall invoke the `done` callback function with an error translated using the requirements detailed in `registry_http_errors_requirements.md` ]*/ - testErrorCallback('getEnrollmentGroupAttestationMechanism', 'enrollment-id'); - - /*Tests_SRS_NODE_PROVISIONING_SERVICE_CLIENT_16_004: [** The `getEnrollmentGroupAttestationMechanism` shall construct an HTTP request using information supplied by the caller as follows: - ``` - POST /enrollmentgroups//attestationmechanism?api-version= HTTP/1.1 - Authorization: - ```]*/ - it('creates a valid HTTP request', function (testCallback) { - var testEnrollmentGroupId = 'test-#-enrollment'; - var fakeHttpHelper = { - executeApiCall: function (method, path, httpHeaders, body, done) { - assert.equal(method, 'POST'); - assert.equal(path, '/enrollmentgroups/' + encodeURIComponentStrict(testEnrollmentGroupId) + '/attestationmechanism' + _versionQueryString()); - - done(); - } - }; - - var de = new ProvisioningServiceClient({ host: 'host', sharedAccessSignature: 'sas' }, fakeHttpHelper); - de.getEnrollmentGroupAttestationMechanism(testEnrollmentGroupId, testCallback); - }); - }); -}); \ No newline at end of file diff --git a/provisioning/service/tsconfig.json b/provisioning/service/tsconfig.json deleted file mode 100644 index 6b661f748..000000000 --- a/provisioning/service/tsconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "compilerOptions": { - "outDir": "./dist", - "target":"es2018", - "module": "commonjs", - "sourceMap": true, - "declaration": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "removeComments": false - }, - "include": [ - "./src/**/*.ts" - ], - "exclude": [ - "./dist", - "./samples" - ] -}