device/core/src/sas_authentication_provider.ts (41 lines of code) (raw):
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
import { EventEmitter } from 'events';
import { AuthenticationProvider, AuthenticationType, SharedAccessSignature, TransportConfig, Callback, callbackToPromise } from 'azure-iot-common';
/**
* Provides an `AuthenticationProvider` object that can be created simply with a shared access signature and is then used by the device client and transports to authenticate
* with the Azure IoT hub instance.
*
* The `SharedAccessSignatureAuthenticationProvider` object does not renew the shared access signature token automatically, so the user needs to feed non-expired shared access signature
* tokens to it using the `updateSharedAccessSignature` method. For each call to this method, the `SharedAccessSignatureAuthenticationProvider` will emit a `newTokenAvailable` event that
* transports will use to authenticate with the Azure IoT hub instance.
*/
export class SharedAccessSignatureAuthenticationProvider extends EventEmitter implements AuthenticationProvider {
type: AuthenticationType = AuthenticationType.Token;
private _credentials: TransportConfig;
/**
* @private
*
* Initializes a new instance of the SharedAccessSignatureAuthenticationProvider - users should only use the factory methods though.
*
* @param credentials Credentials to be used by the device to connect to the IoT hub.
* @param securityProvider Object used to sign the tokens that are going to be used during authentication.
*/
constructor(credentials: TransportConfig) {
super();
/*Codes_SRS_NODE_SAS_AUTHENTICATION_PROVIDER_16_001: [The `constructor` shall store the credentials passed in the `credentials` argument.]*/
this._credentials = credentials;
}
/**
* This method is used by the transports to gets the most current device credentials in the form of a `TransportConfig` object.
*
* @param [callback] optional function that will be called with either an error or a set of device credentials that can be used to authenticate with the IoT hub.
* @returns {Promise<TransportConfig> | void} Promise if no callback function was passed, void otherwise.
*/
getDeviceCredentials(callback: Callback<TransportConfig>): void;
getDeviceCredentials(): Promise<TransportConfig>;
getDeviceCredentials(callback?: Callback<TransportConfig>): Promise<TransportConfig> | void {
return callbackToPromise((_callback) => {
/*Codes_SRS_NODE_SAS_AUTHENTICATION_PROVIDER_16_002: [The `getDeviceCredentials` method shall call its callback with a `null` error parameter and the stored `credentials` object containing the current device credentials.]*/
_callback(null, this._credentials);
}, callback);
}
/**
* does nothing and returns - this is part of the token-based authentication provider API but there are no resources to stop/free here.
*/
stop(): void {
/*Codes_SRS_NODE_SAS_AUTHENTICATION_PROVIDER_16_007: [The `stop` method shall simply return since there is no timeout or resources to clear.]*/
return;
}
/**
* Updates the shared access signature token that transports should use to authenticate. When called, the `SharedAccessSignatureAuthenticationProvider` will emit
* a `newTokenAvailable` event that the transports can then use to authenticate with the Azure IoT hub instance.
*
* @param sharedAccessSignature A shared access signature string containing the required parameters for authentication with the IoT hub.
*/
updateSharedAccessSignature(sharedAccessSignature: string): void {
/*Codes_SRS_NODE_SAS_AUTHENTICATION_PROVIDER_16_003: [The `updateSharedAccessSignature` method shall update the stored credentials with the new `sharedAccessSignature` value passed as an argument.]*/
this._credentials.sharedAccessSignature = sharedAccessSignature;
/*Codes_SRS_NODE_SAS_AUTHENTICATION_PROVIDER_16_004: [The `updateSharedAccessSignature` method shall emit a `newTokenAvailable` event with the updated credentials.]*/
this.emit('newTokenAvailable', this._credentials);
}
/**
* Creates a new `SharedAccessSignatureAuthenticationProvider` from a connection string
*
* @param sharedAccessSignature A shared access signature string containing the required parameters for authentication with the IoT hub.
*/
static fromSharedAccessSignature(sharedAccessSignature: string): SharedAccessSignatureAuthenticationProvider {
if (!sharedAccessSignature) {
/*Codes_SRS_NODE_SAS_AUTHENTICATION_PROVIDER_16_005: [The `fromSharedAccessSignature` method shall throw a `ReferenceError` if the `sharedAccessSignature` argument is falsy.]*/
throw new ReferenceError('sharedAccessSignature cannot be \'' + sharedAccessSignature + '\'');
}
const sas: SharedAccessSignature = SharedAccessSignature.parse(sharedAccessSignature);
const decodedUri = decodeURIComponent(sas.sr);
const uriSegments = decodedUri.split('/');
const uriDeviceId = (uriSegments.length >= 3 && uriSegments[1] === 'devices') ? (uriSegments[2]) : null;
const uriModuleId = (uriSegments.length >= 5 && uriSegments[3] === 'modules') ? (uriSegments[4]) : null;
const credentials: TransportConfig = {
host: uriSegments[0],
deviceId: uriDeviceId,
moduleId: uriModuleId,
sharedAccessSignature: sharedAccessSignature
};
/*Codes_SRS_NODE_SAS_AUTHENTICATION_PROVIDER_16_006: [The `fromSharedAccessSignature` shall return a new `SharedAccessSignatureAuthenticationProvider` object initialized with the credentials parsed from the `sharedAccessSignature` argument.]*/
return new SharedAccessSignatureAuthenticationProvider(credentials);
}
}