syntax = "proto3"; // Copyright 2020-2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only package signalservice; option java_package = "org.whispersystems.signalservice.protos.groups"; option java_multiple_files = true; message AvatarUploadAttributes { string key = 1; string credential = 2; string acl = 3; string algorithm = 4; string date = 5; string policy = 6; string signature = 7; } message Member { enum Role { UNKNOWN = 0; DEFAULT = 1; // Normal member ADMINISTRATOR = 2; // Group admin } bytes userId = 1; // The UuidCiphertext Role role = 2; bytes profileKey = 3; // The ProfileKeyCiphertext bytes presentation = 4; // ProfileKeyCredentialPresentation uint32 joinedAtVersion = 5; // The Group.version this member joined at } message MemberPendingProfileKey { Member member = 1; // The “invited” member bytes addedByUserId = 2; // The UID who invited this member uint64 timestamp = 3; // The time the invitation occurred } message MemberPendingAdminApproval { bytes userId = 1; bytes profileKey = 2; bytes presentation = 3; uint64 timestamp = 4; } message MemberBanned { bytes userId = 1; uint64 timestamp = 2; // ms since epoch } message AccessControl { enum AccessRequired { UNKNOWN = 0; ANY = 1; MEMBER = 2; // Any group member can make the modification ADMINISTRATOR = 3; // Only administrators can make the modification UNSATISFIABLE = 4; } AccessRequired attributes = 1; // Who can modify the group title, avatar, disappearing messages timer AccessRequired members = 2; // Who can add people to the group AccessRequired addFromInviteLink = 3; } message Group { bytes publicKey = 1; // GroupPublicParams bytes title = 2; // Encrypted title string avatar = 3; // Pointer to encrypted avatar (‘key’ from AvatarUploadAttributes) bytes disappearingMessagesTimer = 4; // Encrypted timer AccessControl accessControl = 5; uint32 version = 6; // Current group version number repeated Member members = 7; repeated MemberPendingProfileKey membersPendingProfileKey = 8; repeated MemberPendingAdminApproval membersPendingAdminApproval = 9; bytes inviteLinkPassword = 10; bytes descriptionBytes = 11; bool announcementsOnly = 12; repeated MemberBanned membersBanned = 13; // next: 14 } message GroupChange { message Actions { message AddMemberAction { Member added = 1; bool joinFromInviteLink = 2; } message DeleteMemberAction { bytes deletedUserId = 1; } message ModifyMemberRoleAction { bytes userId = 1; Member.Role role = 2; } message ModifyMemberProfileKeyAction { bytes presentation = 1; bytes user_id = 2; bytes profile_key = 3; } message AddMemberPendingProfileKeyAction { MemberPendingProfileKey added = 1; } message DeleteMemberPendingProfileKeyAction { bytes deletedUserId = 1; } message PromoteMemberPendingProfileKeyAction { bytes presentation = 1; bytes user_id = 2; bytes profile_key = 3; } message PromoteMemberPendingPniAciProfileKeyAction { bytes presentation = 1; bytes user_id = 2; bytes pni = 3; bytes profile_key = 4; } message AddMemberPendingAdminApprovalAction { MemberPendingAdminApproval added = 1; } message DeleteMemberPendingAdminApprovalAction { bytes deletedUserId = 1; } message PromoteMemberPendingAdminApprovalAction { bytes userId = 1; Member.Role role = 2; } message AddMemberBannedAction { MemberBanned added = 1; } message DeleteMemberBannedAction { bytes deletedUserId = 1; } message ModifyTitleAction { bytes title = 1; } message ModifyAvatarAction { string avatar = 1; } message ModifyDisappearingMessagesTimerAction { bytes timer = 1; } message ModifyAttributesAccessControlAction { AccessControl.AccessRequired attributesAccess = 1; } message ModifyAvatarAccessControlAction { AccessControl.AccessRequired avatarAccess = 1; } message ModifyMembersAccessControlAction { AccessControl.AccessRequired membersAccess = 1; } message ModifyAddFromInviteLinkAccessControlAction { AccessControl.AccessRequired addFromInviteLinkAccess = 1; } message ModifyInviteLinkPasswordAction { bytes inviteLinkPassword = 1; } message ModifyDescriptionAction { bytes descriptionBytes = 1; } message ModifyAnnouncementsOnlyAction { bool announcementsOnly = 1; } bytes sourceUuid = 1; // Who made the change uint32 version = 2; // The change version number repeated AddMemberAction addMembers = 3; // Members added repeated DeleteMemberAction deleteMembers = 4; // Members deleted repeated ModifyMemberRoleAction modifyMemberRoles = 5; // Modified member roles repeated ModifyMemberProfileKeyAction modifyMemberProfileKeys = 6; // Modified member profile keys repeated AddMemberPendingProfileKeyAction addPendingMembers = 7; // Pending members added repeated DeleteMemberPendingProfileKeyAction deletePendingMembers = 8; // Pending members deleted repeated PromoteMemberPendingProfileKeyAction promotePendingMembers = 9; // Pending invitations accepted ModifyTitleAction modifyTitle = 10; // Changed title ModifyAvatarAction modifyAvatar = 11; // Changed avatar ModifyDisappearingMessagesTimerAction modifyDisappearingMessagesTimer = 12; // Changed timer ModifyAttributesAccessControlAction modifyAttributesAccess = 13; // Changed attributes access control ModifyMembersAccessControlAction modifyMemberAccess = 14; // Changed membership access control ModifyAddFromInviteLinkAccessControlAction modifyAddFromInviteLinkAccess = 15; // change epoch = 1 repeated AddMemberPendingAdminApprovalAction addMemberPendingAdminApprovals = 16; // change epoch = 1 repeated DeleteMemberPendingAdminApprovalAction deleteMemberPendingAdminApprovals = 17; // change epoch = 1 repeated PromoteMemberPendingAdminApprovalAction promoteMemberPendingAdminApprovals = 18; // change epoch = 1 ModifyInviteLinkPasswordAction modifyInviteLinkPassword = 19; // change epoch = 1 ModifyDescriptionAction modifyDescription = 20; // change epoch = 2 ModifyAnnouncementsOnlyAction modifyAnnouncementsOnly = 21; // change epoch = 3 repeated AddMemberBannedAction addMembersBanned = 22; // change epoch = 4 repeated DeleteMemberBannedAction deleteMembersBanned = 23; // change epoch = 4 repeated PromoteMemberPendingPniAciProfileKeyAction promoteMembersPendingPniAciProfileKey = 24; // change epoch = 5 // next: 25 } bytes actions = 1; // The serialized actions bytes serverSignature = 2; // Server’s signature over serialized actions uint32 changeEpoch = 3; // Allows clients to decide whether their change logic can successfully apply this diff } message GroupChanges { message GroupChangeState { GroupChange groupChange = 1; Group groupState = 2; } repeated GroupChangeState groupChanges = 1; } message GroupAttributeBlob { oneof content { string title = 1; bytes avatar = 2; uint32 disappearingMessagesDuration = 3; string descriptionText = 4; } } message GroupExternalCredential { string token = 1; } message GroupInviteLink { message GroupInviteLinkContentsV1 { bytes groupMasterKey = 1; bytes inviteLinkPassword = 2; } oneof contents { GroupInviteLinkContentsV1 v1Contents = 1; } } message GroupJoinInfo { bytes publicKey = 1; bytes title = 2; string avatar = 3; uint32 memberCount = 4; AccessControl.AccessRequired addFromInviteLink = 5; uint32 version = 6; bool pendingAdminApproval = 7; bytes descriptionBytes = 8; }