calculateCapabilityHash function

Future<String> calculateCapabilityHash(
  1. HashFunction algorithm,
  2. DiscoInfo info
)

Calculates the Entitiy Capability hash according to XEP-0115 based on the disco information.

Implementation

Future<String> calculateCapabilityHash(
  HashFunction algorithm,
  DiscoInfo info,
) async {
  final buffer = StringBuffer();
  final identitiesSorted = info.identities.map(_identityString).toList();
  // ignore: cascade_invocations
  identitiesSorted.sort(ioctetSortComparator);
  buffer.write('${identitiesSorted.join("<")}<');

  final featuresSorted = List<String>.from(info.features)
    ..sort(ioctetSortComparator);
  buffer.write('${featuresSorted.join("<")}<');

  if (info.extendedInfo.isNotEmpty) {
    final sortedExt = info.extendedInfo
      ..sort(
        (a, b) => ioctetSortComparator(
          a.getFieldByVar('FORM_TYPE')!.values.first,
          b.getFieldByVar('FORM_TYPE')!.values.first,
        ),
      );

    for (final ext in sortedExt) {
      buffer.write('${ext.getFieldByVar("FORM_TYPE")!.values.first}<');

      final sortedFields = ext.fields
        ..sort(
          (a, b) => ioctetSortComparator(
            a.varAttr!,
            b.varAttr!,
          ),
        );

      for (final field in sortedFields) {
        if (field.varAttr == 'FORM_TYPE') continue;

        buffer.write('${field.varAttr!}<');
        final sortedValues = field.values..sort(ioctetSortComparator);
        for (final value in sortedValues) {
          buffer.write('$value<');
        }
      }
    }
  }

  final rawHash = await CryptographicHashManager.hashFromData(
    algorithm,
    utf8.encode(buffer.toString()),
  );
  return base64.encode(rawHash);
}