in source/packages/services/assetlibrary/src/devices/devices.full.service.ts [594:696]
public async update(device: DeviceItem, applyProfile?: string): Promise<void> {
logger.debug(
`device.full.service update: in: model: ${JSON.stringify(
device
)}, applyProfile:${applyProfile}`
);
ow(device, ow.object.nonEmpty);
ow(device.deviceId, ow.string.nonEmpty);
// if a profile to apply has been provided, apply it first
if (applyProfile !== undefined) {
const existing = await this.get(device.deviceId);
if (existing === undefined) {
throw new DeviceNotFoundError(device.deviceId);
}
const merged = Object.assign(new DeviceItem(), existing, device);
device = await this.applyProfile(merged, applyProfile);
}
// any ids need to be lowercase
this.setIdsToLowercase(device);
// authz check
const deviceIds = device.listRelatedDeviceIds();
deviceIds.push(device.deviceId);
await this.authServiceFull.authorizationCheck(
deviceIds,
device.listRelatedGroupPaths(),
ClaimAccess.U
);
const labels = await this.devicesDao.getLabels([device.deviceId]);
const templateId = labels[device.deviceId]?.[0];
if (templateId === undefined) {
throw new TemplateNotFoundError(templateId);
}
// schema validation
const template = await this.typesService.get(
templateId,
TypeCategory.Device,
TypeDefinitionStatus.published
);
const validate = await this.validator.validateSubType(template, device, Operation.UPDATE);
if (!validate.isValid) {
throw new SchemaValidationError(validate.errors);
}
// Validate relationships for this device to specified groups in update
const validateRelationships = await this.validator.validateRelationshipsByIds(
template,
device.groups,
device.devices
);
if (!validateRelationships.isValid) {
throw new RelationValidationError(validateRelationships);
}
// if fgac is enabled, we need to ensure any relations configured as identifying auth in its template are flagged to be saved as so
if (this.isAuthzEnabled) {
const incomingAuthRelations = template.schema.relations.incomingAuthRelations();
const outgoingAuthRelations = template.schema.relations.outgoingAuthRelations();
this.authServiceFull.updateRelsIdentifyingAuth(
device.groups?.in,
validateRelationships.groupLabels,
incomingAuthRelations
);
this.authServiceFull.updateRelsIdentifyingAuth(
device.groups?.out,
validateRelationships.groupLabels,
outgoingAuthRelations
);
this.authServiceFull.updateRelsIdentifyingAuth(
device.devices?.in,
validateRelationships.deviceLabels,
incomingAuthRelations
);
this.authServiceFull.updateRelsIdentifyingAuth(
device.devices?.out,
validateRelationships.deviceLabels,
outgoingAuthRelations
);
}
// Assemble devicemodel into node
device.category = TypeCategory.Device;
device.templateId = templateId;
const node = this.devicesAssembler.toNode(device);
// Save to datastore
await this.devicesDao.update(node, device.groups, device.devices);
// fire event
await this.eventEmitter.fire({
objectId: device.deviceId,
type: Type.device,
event: Event.modify,
payload: JSON.stringify(device),
});
logger.debug(`device.full.service update: exit:`);
}