@c8y/client
Version:
Client application programming interface to access the Cumulocity IoT-Platform REST services.
267 lines • 11 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Client = void 0;
const core_1 = require("./core");
const realtime_1 = require("./realtime");
const services_1 = require("./services");
class Client {
/**
* Authenticates the given user. Determines the tenant by itself via a call to tenant/currentTenant.
*
* **Example**
* ```typescript
*
* let client: Client;
* (async () => {
* client = await Client.authenticate({
* user: 'testuser',
* password: 'password1337!'
* }, 'https://acme.cumulocity.com');
*
* //you have access to the client api now
* const { data, paging, res }); = await client.inventory.list({ pageSize: 100 });
* })();
* ```
*/
static async authenticate(credentials, baseUrl) {
const auth = new services_1.BasicAuth(credentials);
const clientCore = new services_1.FetchClient(auth, baseUrl);
const tenantName = await this.getCurrentTenant(clientCore);
const client = new Client(auth, baseUrl);
client.core.tenant = tenantName;
return client;
}
/**
* Authenticates the given user via OAuth Internal. Determines the tenant by itself via a call to tenant/currentTenant.
* Login call goes to `/tenant/oauth/token` and the retrieved token will be added in the `Authorization` header to subsequent requests.
*
* **Example**
* ```typescript
*
* let client: Client;
* (async () => {
* client = await Client.authenticateViaOAuthInternal({
* user: 'testuser',
* password: 'password1337!'
* }, 'https://acme.cumulocity.com');
*
* //you have access to the client api now
* const { data, paging, res }); = await client.inventory.list({ pageSize: 100 });
* })();
* ```
*/
static async authenticateViaOAuthInternal(credentials, baseUrl) {
const token = await this.loginViaOAuthInternal(credentials, true, baseUrl);
const auth = new core_1.BearerAuth(token);
const clientCore = new services_1.FetchClient(auth, baseUrl);
const tenantName = credentials.tenant || (await this.getCurrentTenant(clientCore));
const client = new Client(auth, baseUrl);
client.core.tenant = tenantName;
return client;
}
/**
* Authenticates the given user via OAuth Internal. Determines the tenant by itself via a call to tenant/currentTenant.
* Login call goes to `/tenant/oauth` and the retrieved token will be attached as a Cookie in browser environments to subsequent requests (using 'CookieAuth').
* In none browser environments (e.g. nodejs) the retrieved token will be added in the `Authorization` header to subsequent requests (using 'NodeJSCookieAuth').
*
* **Example**
* ```typescript
*
* let client: Client;
* (async () => {
* client = await Client.authenticateViaOAuthInternalCookie({
* user: 'testuser',
* password: 'password1337!'
* }, 'https://acme.cumulocity.com');
*
* //you have access to the client api now
* const { data, paging, res }); = await client.inventory.list({ pageSize: 100 });
* })();
* ```
*/
static async authenticateViaOAuthInternalCookie(credentials, baseUrl) {
const response = await this.loginViaOAuthInternal(credentials, false, baseUrl);
let auth;
if (typeof document === 'undefined') {
auth = new core_1.NodeJSCookieAuth(response);
}
else {
auth = new core_1.CookieAuth();
}
const clientCore = new services_1.FetchClient(auth, baseUrl);
const tenantName = credentials.tenant || (await this.getCurrentTenant(clientCore));
const client = new Client(auth, baseUrl);
client.core.tenant = tenantName;
return client;
}
/**
* Allows to use http to register a device on the platform.
*
* **Deprecated** Please use MQTT to bootstrap a device.
*/
static async deviceBootstrap(options) {
const { deviceId, timeout, baseUrl, basicAuthToken } = options;
let { expire } = options;
if (timeout && !expire) {
expire = Date.now() + timeout;
}
const clientCore = new services_1.FetchClient(undefined, baseUrl);
const deviceRegistration = new services_1.DeviceRegistrationService(clientCore);
let client;
try {
const { data } = await deviceRegistration.bootstrap(deviceId, { basicAuthToken });
const { username, password, tenantId } = data;
const auth = new services_1.BasicAuth({ user: username, tenant: tenantId, password });
client = new Client(auth, baseUrl);
client.core.tenant = tenantId;
}
catch (error) {
const retry = (!expire || Date.now() < expire) && error.res.status === 404;
if (retry) {
return Client.deviceBootstrap(Object.assign({ expire }, options));
}
else {
throw error;
}
}
return client;
}
/**
* Retrieves microservice credentials for the subscribed tenants
* using provided bootstrap credentials
*
* **Example**
* ```typescript
*
* (async () => {
* const subscriptions = await Client.getMicroserviceSubscriptions({
* tenant: process.env.C8Y_BOOTSTRAP_TENANT,
* user: process.env.C8Y_BOOTSTRAP_USER,
* password: process.env.C8Y_BOOTSTRAP_PASSWORD
* }, process.env.C8Y_BASEURL);
*
* const clients = subscriptions.map(subscription => new Client(new BasicAuth(subscription), process.env.C8Y_BASEURL));
* // you have access to the client api now
* const promiseArray = clients.map(client => client.options.tenant.detail({
* category: process.env.APPLICATION_KEY,
* key: 'someSetting'
* }));
* })();
* ```
*/
static async getMicroserviceSubscriptions(bootstrapCredentials, baseUrl) {
const microserviceSubscriptionsEndpoint = '/application/currentApplication/subscriptions';
const clientCore = new services_1.FetchClient(new services_1.BasicAuth(bootstrapCredentials), baseUrl);
const res = await clientCore.fetch(microserviceSubscriptionsEndpoint);
const { users } = await res.json();
return users.map(({ tenant, name, password }) => {
return {
tenant,
user: name,
password
};
});
}
static async loginViaOAuthInternal(credentials, bearerAuth = true, baseUrl) {
const auth = new services_1.BasicAuth(credentials);
const clientCore = new services_1.FetchClient(auth, baseUrl);
let url = '/tenant/oauth';
if (bearerAuth) {
url += `/token`;
}
if (credentials.tenant) {
url += `?tenant_id=${credentials.tenant}`;
}
const params = new URLSearchParams({
grant_type: 'PASSWORD',
username: credentials.user,
password: credentials.password,
tfa_code: credentials.tfa
});
const res = await clientCore.fetch(url, {
method: 'POST',
body: params.toString(),
headers: {
'content-type': 'application/x-www-form-urlencoded;charset=UTF-8'
}
});
if (res.status !== 200) {
throw { res };
}
if (bearerAuth) {
const body = await res.json();
return body['access_token'];
}
return res;
}
static async getCurrentTenant(fetchClient) {
const tenantService = new services_1.TenantService(fetchClient);
const { data: tenant } = await tenantService.current();
return tenant.name;
}
/**
* Initializes a new Client, which allows to request data from the API. Differently
* to Client.authenticate([...]) it needs a tenant given and does not verify if the
* login is correct.
*
* **Example**
* ```typescript
*
* const auth = new BasicAuth({
* user: 'youruser',
* password: 'yourpassword',
* tenant: 'acme'
* }); // use CookieAuth() if your platform uses oauth (only in browser!)
*
* const baseUrl = 'https://acme.cumulocity.com';
* const client = new Client(auth, baseUrl);
* (async () => {
* const { data, paging, res }); = await client.inventory.list({ pageSize: 100 });
* })();
* ```
*
* @param auth The Authentication strategy to use (e.g. new BasicAuth())
* @param baseUrl The URL to request (optional in browser, mandatory in node)
*/
constructor(auth, baseUrl) {
const client = new services_1.FetchClient(auth, baseUrl);
this.realtime = new realtime_1.Realtime(client);
this.alarm = new services_1.AlarmService(client, this.realtime);
this.application = new services_1.ApplicationService(client, this.realtime);
this.audit = new services_1.AuditService(client);
this.core = client;
this.deviceRegistration = new services_1.DeviceRegistrationService(client);
this.deviceRegistrationBulk = new services_1.DeviceRegistrationBulkService(client);
this.event = new services_1.EventService(client, this.realtime);
this.inventory = new services_1.InventoryService(client, this.realtime);
this.inventoryBinary = new services_1.InventoryBinaryService(client);
this.inventoryRole = new services_1.InventoryRoleService(client);
this.measurement = new services_1.MeasurementService(client, this.realtime);
this.operation = new services_1.OperationService(client);
this.operationBulk = new services_1.OperationBulkService(client);
this.options = {
security: new services_1.TenantSecurityOptionsService(client),
system: new services_1.SystemOptionsService(client),
login: new services_1.TenantLoginOptionsService(client),
tenant: new services_1.TenantOptionsService(client)
};
this.role = new services_1.InventoryRoleService(client);
this.tenant = new services_1.TenantService(client);
this.user = new services_1.UserService(client);
this.userGroup = new services_1.UserGroupService(client);
this.userRole = new services_1.UserRoleService(client);
this.identity = new services_1.IdentityService(client);
this.smartGroups = new services_1.SmartGroupsService(client);
this.smartRules = new services_1.SmartRulesService(client);
}
/**
* Allows to change the current Authentication
* @param auth The new Authentication information.
*/
setAuth(auth) {
this.core.setAuth(auth);
this.realtime.disconnect();
}
}
exports.Client = Client;
//# sourceMappingURL=Client.js.map