Path: blob/main/SignalServiceKit/Protos/Specifications/Groups.proto
1 views
//
// Copyright 2019 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
syntax = "proto3";
// iOS - package name determines class prefix
package GroupsProtos;
option java_package = "org.signal.storageservice.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;
}
// MARK: - Stored data
// Represents a member of the group.
message Member {
enum Role {
UNKNOWN = 0;
// A normal member.
DEFAULT = 1;
// A group admin.
ADMINISTRATOR = 2;
}
// The member's encrypted ServiceId.
bytes userId = 1;
Role role = 2;
// The member's encrypted profile key.
bytes profileKey = 3;
// The group revision at which this member joined.
uint32 joinedAtRevision = 5;
// A `LibSignalClient.ProfileKeyCredentialPresentation` created by the
// client and used by the server to populate the other fields.
bytes presentation = 4;
// These two fields each decrypt to a UTF8 string
bytes label_emoji = 6;
bytes label_string = 7;
}
// An invited member of the group.
//
// Here, "pending" refers to "pending profile key", as invited members'
// profile keys will be missing; to become a full member, they must add their
// profile key to the group.
message PendingMember {
// The invited member.
Member member = 1;
// The encrypted ACI of the group member who invited this member.
bytes addedByUserId = 2;
// The timestamp of the invite, in epoch milliseconds.
uint64 timestamp = 3;
}
// A user who has requested to join the group, and is pending admin approval.
message RequestingMember {
// The user's encrypted ACI.
bytes userId = 1;
// The user's encrypted profile key.
bytes profileKey = 2;
// The timestamp at which they requested to join, in epoch milliseconds.
uint64 timestamp = 4;
// A `LibSignalClient.ProfileKeyCredentialPresentation` created by the
// client and used by the server to populate the other fields.
bytes presentation = 3;
}
// A user who has been banned from the group.
message BannedMember {
// The user's encrypted ServiceId.
bytes userId = 1;
// The time at which the user was banned, in epoch milliseconds.
uint64 bannedAtTimestamp = 2;
}
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;
AccessRequired member_label = 4;
}
message Group {
// `LibSignalClient.GroupPublicParams`.
bytes publicKey = 1;
// The encrypted title of the group as a `GroupAttributeBlob`.
bytes title = 2;
// Pointer to the encrypted avatar.
//
// - SeeAlso `key` from `AvatarUploadAttributes`.
//
// - Note:
// The data downloaded from this pointer is a `GroupAttributeBlob`.
string avatar = 3;
// The encrypted disappearing message timer of the group as a
// `GroupAttributeBlob`.
bytes disappearingMessagesTimer = 4;
// The encrypted description of the group as a `GroupAttributeBlob`.
bytes descriptionBytes = 11;
AccessControl accessControl = 5;
// The current revision number of the group.
uint32 revision = 6;
repeated Member members = 7;
repeated PendingMember pendingMembers = 8;
repeated RequestingMember requestingMembers = 9;
bytes inviteLinkPassword = 10;
bool announcementsOnly = 12;
repeated BannedMember bannedMembers = 13;
bool terminated = 14;
}
message GroupAttributeBlob {
oneof content {
string title = 1;
bytes avatar = 2;
uint32 disappearingMessagesDuration = 3;
string descriptionText = 4;
}
}
message GroupInviteLink {
message GroupInviteLinkContentsV1 {
bytes groupMasterKey = 1;
bytes inviteLinkPassword = 2;
}
oneof contents {
GroupInviteLinkContentsV1 contentsV1 = 1;
}
}
message GroupJoinInfo {
bytes publicKey = 1;
bytes title = 2;
string avatar = 3;
uint32 memberCount = 4;
AccessControl.AccessRequired addFromInviteLink = 5;
uint32 revision = 6;
bool pendingAdminApproval = 7;
bytes descriptionBytes = 8;
}
// MARK: - Group changes
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 ModifyMemberLabelAction {
bytes user_id = 1;
// These two fields each decrypt to a UTF8 string
bytes label_emoji = 2;
bytes label_string = 3;
}
message ModifyMemberProfileKeyAction {
bytes presentation = 1;
bytes user_id = 2;
bytes profile_key = 3;
}
message AddPendingMemberAction {
PendingMember added = 1;
}
message DeletePendingMemberAction {
bytes deletedUserId = 1;
}
message PromotePendingMemberAction {
bytes presentation = 1;
bytes user_id = 2;
bytes profile_key = 3;
}
message PromoteMemberPendingPniAciProfileKeyAction {
// The encrypted ACI.
bytes user_id = 2;
// The encrypted PNI.
bytes pni = 3;
// The encrypted profile key.
bytes profile_key = 4;
// A `LibSignalClient.ProfileKeyCredentialPresentation` created by the
// client and used by the server to populate the other fields.
bytes presentation = 1;
}
message AddRequestingMemberAction {
RequestingMember added = 1;
}
message DeleteRequestingMemberAction {
bytes deletedUserId = 1;
}
message PromoteRequestingMemberAction {
bytes userId = 1;
Member.Role role = 2;
}
message AddBannedMemberAction {
BannedMember added = 1;
}
message DeleteBannedMemberAction {
bytes deletedUserId = 1;
}
message ModifyTitleAction {
// The encrypted title of the group as a `GroupAttributeBlob`.
bytes title = 1;
}
message ModifyAvatarAction {
// Pointer to the new encrypted avatar.
string avatar = 1;
}
message ModifyDisappearingMessagesTimerAction {
// The encrypted disappearing message timer of the group as a
// `GroupAttributeBlob`.
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 ModifyMemberLabelAccessControlAction {
AccessControl.AccessRequired member_label_access = 1;
}
message ModifyInviteLinkPasswordAction {
bytes inviteLinkPassword = 1;
}
message ModifyDescriptionAction {
// The encrypted description of the group as a `GroupAttributeBlob`.
bytes descriptionBytes = 1;
}
message ModifyAnnouncementsOnlyAction {
bool announcementsOnly = 1;
}
message TerminateGroupAction {
}
bytes sourceUserId = 1; // Encrypted ServiceId for who made the change
// clients should not provide this value; the server will provide it in the response buffer to ensure the signature is binding to a particular group
// if clients set it during a request the server will respond with 400.
bytes group_id = 25;
uint32 revision = 2; // The change revision 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 AddPendingMemberAction addPendingMembers = 7; // Pending members added
repeated DeletePendingMemberAction deletePendingMembers = 8; // Pending members deleted
repeated PromotePendingMemberAction 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
ModifyMemberLabelAccessControlAction modify_member_label_access = 27; // change epoch = 6
repeated AddRequestingMemberAction addRequestingMembers = 16; // change epoch = 1
repeated DeleteRequestingMemberAction deleteRequestingMembers = 17; // change epoch = 1
repeated PromoteRequestingMemberAction promoteRequestingMembers = 18; // change epoch = 1
ModifyInviteLinkPasswordAction modifyInviteLinkPassword = 19; // change epoch = 1
ModifyDescriptionAction modifyDescription = 20; // change epoch = 2
ModifyAnnouncementsOnlyAction modifyAnnouncementsOnly = 21; // change epoch = 3
repeated AddBannedMemberAction addBannedMembers = 22; // change epoch = 4
repeated DeleteBannedMemberAction deleteBannedMembers = 23; // change epoch = 4
repeated PromoteMemberPendingPniAciProfileKeyAction promotePniPendingMembers = 24; // change epoch = 5
repeated ModifyMemberLabelAction modifyMemberLabel = 26; // change epoch = 6;
TerminateGroupAction terminate_group = 28; // change epoch = 7
}
bytes actions = 1; // The serialized actions
bytes serverSignature = 2; // Server’s signature over serialized actions
uint32 changeEpoch = 3;
}
// External credentials
message GroupExternalCredential {
string token = 1;
}
// API responses
message GroupResponse {
Group group = 1;
bytes group_send_endorsements_response = 2;
}
message GroupChanges {
message GroupChangeState {
GroupChange groupChange = 1;
Group groupState = 2;
}
repeated bytes /*GroupChangeState*/ groupChanges = 1;
bytes group_send_endorsements_response = 2;
}
message GroupChangeResponse {
GroupChange group_change = 1;
bytes group_send_endorsements_response = 2;
}