invite method

Future<CreatedInvitation> invite({
  1. Map<String, dynamic> publicDetails = const {},
  2. Map<String, dynamic>? content,
  3. bool contentOutOfBand = false,
  4. Duration expiresIn = const Duration(days: 7),
})

Creates an invitation. The app links its own records, such as a contact, to it by the id in the returned link.

publicDetails travel in the preview, so anyone holding the link reads them; anything private belongs in content, which is encrypted and fixed here. With contentOutOfBand the encrypted content is returned for the app to send alongside the link rather than published in the preview. expiresIn must be at least a millisecond.

Implementation

Future<CreatedInvitation> invite({
  Map<String, dynamic> publicDetails = const {},
  Map<String, dynamic>? content,
  bool contentOutOfBand = false,
  Duration expiresIn = const Duration(days: 7),
}) async {
  // NOTE: a preview ttl of 0 would never expire.
  if (expiresIn.inMilliseconds < 1) {
    throw ArgumentError.value(
        expiresIn, 'expiresIn', 'must be at least a millisecond');
  }
  final id = _randomHex(16);
  final code = _randomCode();
  final expiresAt = DateTime.now().toUtc().add(expiresIn);

  InvitationKey? contentKey;
  SealedInvitationContent? sealed;
  if (content != null) {
    contentKey = InvitationKey.mint();
    sealed = await contentKey.seal(jsonEncode(content),
        inviter: me, invitationId: id);
  }

  await (await sentInvitations).create(
    id: id,
    obj: SentInvitation(
      code: code,
      expiresAt: expiresAt,
      publicDetails: publicDetails,
      contentKey: contentKey?.base64,
    ),
    expiresAt: expiresAt.add(_afterExpiry),
  );

  final preview = InvitationPreview(
    publicDetails: publicDetails,
    expiresAt: expiresAt,
    content: contentOutOfBand ? null : sealed,
  );
  final previewKey = _previewKey(me, id);
  previewKey.metadata.ttl = expiresIn.inMilliseconds;
  await atClient.put(
    previewKey,
    jsonEncode(preview.toJson()),
    putRequestOptions: PutRequestOptions()..useRemoteAtServer = true,
  );

  return CreatedInvitation(
    link: InvitationLink(inviter: me, id: id),
    code: code,
    outOfBandContent: contentOutOfBand ? sealed : null,
  );
}