mirror of
https://github.com/mautrix/signal.git
synced 2026-09-18 08:34:16 -04:00
608 lines
22 KiB
Protocol Buffer
608 lines
22 KiB
Protocol Buffer
|
|
syntax = "proto3";
|
||
|
|
|
||
|
|
option java_multiple_files = true;
|
||
|
|
|
||
|
|
package org.signal.chat.account;
|
||
|
|
|
||
|
|
import "google/protobuf/empty.proto";
|
||
|
|
|
||
|
|
import "org/signal/chat/common.proto";
|
||
|
|
import "org/signal/chat/errors.proto";
|
||
|
|
import "org/signal/chat/messages.proto";
|
||
|
|
import "org/signal/chat/require.proto";
|
||
|
|
import "org/signal/chat/tag.proto";
|
||
|
|
|
||
|
|
// Provides methods for working with Signal accounts.
|
||
|
|
service Accounts {
|
||
|
|
option (require.auth) = AUTH_ONLY_AUTHENTICATED;
|
||
|
|
|
||
|
|
// Returns basic identifiers for the authenticated account.
|
||
|
|
rpc GetAccountIdentity(GetAccountIdentityRequest) returns (GetAccountIdentityResponse) {}
|
||
|
|
|
||
|
|
// Returns entitlements for the authenticated account.
|
||
|
|
rpc GetEntitlements(GetEntitlementsRequest) returns (GetEntitlementsResponse) {}
|
||
|
|
|
||
|
|
// Deletes the authenticated account, purging all associated data in the
|
||
|
|
// process.
|
||
|
|
rpc DeleteAccount(DeleteAccountRequest) returns (DeleteAccountResponse) {}
|
||
|
|
|
||
|
|
// Sets the registration lock secret for the authenticated account. To remove
|
||
|
|
// a registration lock, please use `ClearRegistrationLock`.
|
||
|
|
rpc SetRegistrationLock(SetRegistrationLockRequest) returns (SetRegistrationLockResponse) {}
|
||
|
|
|
||
|
|
// Removes any registration lock credentials from the authenticated account.
|
||
|
|
rpc ClearRegistrationLock(ClearRegistrationLockRequest) returns (ClearRegistrationLockResponse) {}
|
||
|
|
|
||
|
|
// Attempts to reserve one of multiple given username hashes. Reserved
|
||
|
|
// usernames may be claimed later via `ConfirmUsernameHash`.
|
||
|
|
rpc ReserveUsernameHash(ReserveUsernameHashRequest) returns (ReserveUsernameHashResponse) {}
|
||
|
|
|
||
|
|
// Sets the username hash/encrypted username to a previously-reserved value
|
||
|
|
// (see `ReserveUsernameHash`).
|
||
|
|
rpc ConfirmUsernameHash(ConfirmUsernameHashRequest) returns (ConfirmUsernameHashResponse) {}
|
||
|
|
|
||
|
|
// Clears the current username hash, ciphertext, and link for the
|
||
|
|
// authenticated user.
|
||
|
|
rpc DeleteUsernameHash(DeleteUsernameHashRequest) returns (DeleteUsernameHashResponse) {}
|
||
|
|
|
||
|
|
// Associates the given username ciphertext with the account, replacing any
|
||
|
|
// previously stored ciphertext. A new link handle will optionally be created,
|
||
|
|
// and the link handle to use will be returned in any event.
|
||
|
|
rpc SetUsernameLink(SetUsernameLinkRequest) returns (SetUsernameLinkResponse) {}
|
||
|
|
|
||
|
|
// Clears any username link associated with the authenticated account.
|
||
|
|
rpc DeleteUsernameLink(DeleteUsernameLinkRequest) returns (DeleteUsernameLinkResponse) {}
|
||
|
|
|
||
|
|
// Configures "unidentified access" keys and preferences for the authenticated
|
||
|
|
// account. Other users permitted to interact with this account anonymously
|
||
|
|
// may take actions like fetching pre-keys and profiles for this account or
|
||
|
|
// sending sealed-sender messages without providing identifying credentials.
|
||
|
|
rpc ConfigureUnidentifiedAccess(ConfigureUnidentifiedAccessRequest) returns (ConfigureUnidentifiedAccessResponse) {}
|
||
|
|
|
||
|
|
// Sets whether the authenticated account may be discovered by phone number
|
||
|
|
// via the Contact Discovery Service (CDS).
|
||
|
|
rpc SetDiscoverableByPhoneNumber(SetDiscoverableByPhoneNumberRequest) returns (SetDiscoverableByPhoneNumberResponse) {}
|
||
|
|
|
||
|
|
// Sets the registration recovery password for the authenticated account.
|
||
|
|
rpc SetRegistrationRecoveryPassword(SetRegistrationRecoveryPasswordRequest) returns (SetRegistrationRecoveryPasswordResponse) {}
|
||
|
|
|
||
|
|
// Store a public key used to issue and verify zero-knowledge (anonymous) credentials for the account.
|
||
|
|
rpc SetZkCredentialKey(SetZkCredentialKeyRequest) returns (SetZkCredentialKeyResponse) {}
|
||
|
|
|
||
|
|
// Changes the phone number associated with the authenticated account.
|
||
|
|
rpc ChangeNumber(ChangeNumberRequest) returns (ChangeNumberResponse) {}
|
||
|
|
|
||
|
|
// Produces a report of non-ephemeral account data stored by the service
|
||
|
|
rpc GetAccountDataReport(GetAccountDataReportRequest) returns (GetAccountDataReportResponse) {}
|
||
|
|
|
||
|
|
// Gets the capabilities for the authenticated account.
|
||
|
|
rpc GetCapabilities(GetCapabilitiesRequest) returns (GetCapabilitiesResponse) {}
|
||
|
|
|
||
|
|
// Generates and stores a pending TOTP key for the authenticated account.
|
||
|
|
// To "activate" the key, callers must call the `ConfirmTotpKey` endpoint.
|
||
|
|
rpc GenerateTotpKey(GenerateTotpKeyRequest) returns (GenerateTotpKeyResponse) {}
|
||
|
|
|
||
|
|
// Confirms that the caller has stored and can derive one-time passwords from
|
||
|
|
// a pending TOTP key generated via `GenerateTotpKey` and stores/activates the
|
||
|
|
// key for the caller's account
|
||
|
|
rpc ConfirmTotpKey(ConfirmTotpKeyRequest) returns (ConfirmTotpKeyResponse) {}
|
||
|
|
|
||
|
|
// Returns a list of confirmed TOTP keys for the authenticated account
|
||
|
|
rpc ListTotpKeys(ListTotpKeysRequest) returns (ListTotpKeysResponse) {}
|
||
|
|
|
||
|
|
// Updates encrypted, user-supplied metadata (e.g. a human-readable name and
|
||
|
|
// creation timestamp) for an existing, confirmed TOTP key
|
||
|
|
rpc SetTotpKeyMetadata(SetTotpKeyMetadataRequest) returns (SetTotpKeyMetadataResponse) {}
|
||
|
|
|
||
|
|
// Removes a TOTP from the authenticated account
|
||
|
|
rpc RemoveTotpKey(RemoveTotpKeyRequest) returns (RemoveTotpKeyResponse) {}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Provides methods for looking up Signal accounts. Callers must not provide
|
||
|
|
// identifying credentials when calling methods in this service.
|
||
|
|
service AccountsAnonymous {
|
||
|
|
option (require.auth) = AUTH_ONLY_ANONYMOUS;
|
||
|
|
|
||
|
|
// Checks whether an account with the given service identifier exists.
|
||
|
|
rpc CheckAccountExistence(CheckAccountExistenceRequest) returns (CheckAccountExistenceResponse) {}
|
||
|
|
|
||
|
|
// Finds the service identifier of the account associated with the given
|
||
|
|
// username hash.
|
||
|
|
rpc LookupUsernameHash(LookupUsernameHashRequest) returns (LookupUsernameHashResponse) {}
|
||
|
|
|
||
|
|
// Finds the encrypted username identified by a given username link handle.
|
||
|
|
rpc LookupUsernameLink(LookupUsernameLinkRequest) returns (LookupUsernameLinkResponse) {}
|
||
|
|
|
||
|
|
// Gets the publicly-visible capabilities enabled on the account identified by
|
||
|
|
// the provided ACI.
|
||
|
|
rpc GetCapabilities(GetCapabilitiesAnonymousRequest) returns (GetCapabilitiesAnonymousResponse) {}
|
||
|
|
}
|
||
|
|
|
||
|
|
message GetAccountIdentityRequest {
|
||
|
|
}
|
||
|
|
|
||
|
|
message GetAccountIdentityResponse {
|
||
|
|
// The identifiers for the authenticated account.
|
||
|
|
common.AccountIdentifiers account_identifiers = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
message GetEntitlementsRequest {
|
||
|
|
}
|
||
|
|
|
||
|
|
message GetEntitlementsResponse {
|
||
|
|
message BadgeEntitlement {
|
||
|
|
// The id of the badge the account is entitled. Metadata to display for
|
||
|
|
// badges may be obtained by cross-referencing badge ids with
|
||
|
|
// RemoteConfiguration.GetBadges.
|
||
|
|
string badge_id = 1;
|
||
|
|
// When the badge expires, in number of seconds since epoch
|
||
|
|
uint64 expiration_epoch_seconds = 2;
|
||
|
|
// Whether the badge is currently configured to be visible
|
||
|
|
bool visible = 3;
|
||
|
|
}
|
||
|
|
|
||
|
|
message BackupEntitlement {
|
||
|
|
// The backup level of the account
|
||
|
|
uint64 level = 1;
|
||
|
|
// When the backup entitlement expires, in number of seconds since epoch
|
||
|
|
uint64 expiration_epoch_seconds = 2;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Active badges added via Donations.redeemReceipt
|
||
|
|
repeated BadgeEntitlement badges = 1;
|
||
|
|
|
||
|
|
// If present, the backup level set via Backups.redeemReceipt
|
||
|
|
BackupEntitlement backup = 2;
|
||
|
|
}
|
||
|
|
|
||
|
|
message DeleteAccountRequest {
|
||
|
|
}
|
||
|
|
|
||
|
|
message DeleteAccountResponse {
|
||
|
|
}
|
||
|
|
|
||
|
|
message SetRegistrationLockRequest {
|
||
|
|
// The new registration lock secret for the authenticated account.
|
||
|
|
bytes registration_lock = 1 [(require.exactlySize) = 32];
|
||
|
|
}
|
||
|
|
|
||
|
|
message SetRegistrationLockResponse {
|
||
|
|
}
|
||
|
|
|
||
|
|
message ClearRegistrationLockRequest {
|
||
|
|
}
|
||
|
|
|
||
|
|
message ClearRegistrationLockResponse {
|
||
|
|
}
|
||
|
|
|
||
|
|
message ReserveUsernameHashRequest {
|
||
|
|
// A prioritized list of username hashes to attempt to reserve.
|
||
|
|
repeated bytes username_hashes = 1 [(require.size) = {min: 1, max: 20}, (require.each) = {exactlySize: 32}];
|
||
|
|
}
|
||
|
|
|
||
|
|
message UsernameNotAvailable {}
|
||
|
|
|
||
|
|
message ReserveUsernameHashResponse {
|
||
|
|
oneof response {
|
||
|
|
// The first username hash that was available (and actually reserved).
|
||
|
|
bytes username_hash = 1;
|
||
|
|
|
||
|
|
// Indicates that, of all of the candidate hashes provided, none were
|
||
|
|
// available. Callers may generate a new set of hashes and and retry.
|
||
|
|
UsernameNotAvailable username_not_available = 2 [(tag.reason) = "username_not_available"];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
message ConfirmUsernameHashRequest {
|
||
|
|
// The username hash to claim for the authenticated account.
|
||
|
|
bytes username_hash = 1 [(require.exactlySize) = 32];
|
||
|
|
|
||
|
|
// A zero-knowledge proof that the given username hash was generated by the
|
||
|
|
// Signal username algorithm.
|
||
|
|
bytes zk_proof = 2 [(require.nonEmpty) = true];
|
||
|
|
|
||
|
|
// The ciphertext of the chosen username for use in public-facing contexts
|
||
|
|
// (e.g. links and QR codes).
|
||
|
|
bytes username_ciphertext = 3 [(require.size) = {min: 1, max: 128}];
|
||
|
|
}
|
||
|
|
|
||
|
|
message ConfirmUsernameHashResponse {
|
||
|
|
message ConfirmedUsernameHash {
|
||
|
|
reserved 1; // username_hash
|
||
|
|
|
||
|
|
// The server-generated username link handle for the newly-confirmed username.
|
||
|
|
bytes username_link_handle = 2;
|
||
|
|
}
|
||
|
|
|
||
|
|
oneof response {
|
||
|
|
// The details of the successfully confirmed username.
|
||
|
|
ConfirmedUsernameHash confirmed_username_hash = 1;
|
||
|
|
|
||
|
|
// The provided hash was not reserved for the account.
|
||
|
|
errors.FailedPrecondition reservation_not_found = 2 [(tag.reason) = "reservation_not_found"];
|
||
|
|
|
||
|
|
// The reservation has lapsed and the requested username has been claimed by
|
||
|
|
// another caller.
|
||
|
|
UsernameNotAvailable username_not_available = 3 [(tag.reason) = "username_not_available"];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
message DeleteUsernameHashRequest {
|
||
|
|
}
|
||
|
|
|
||
|
|
message DeleteUsernameHashResponse {
|
||
|
|
}
|
||
|
|
|
||
|
|
message SetUsernameLinkRequest {
|
||
|
|
// The username ciphertext for which to generate a new link handle.
|
||
|
|
bytes username_ciphertext = 1 [(require.size) = {min: 1, max: 128}];
|
||
|
|
|
||
|
|
// If true and the account already had an encrypted username stored, the
|
||
|
|
// existing link handle will be reused. Otherwise a new link handle will be
|
||
|
|
// created.
|
||
|
|
bool keep_link_handle = 2;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
message SetUsernameLinkResponse {
|
||
|
|
oneof response {
|
||
|
|
// A new link handle for the given username ciphertext.
|
||
|
|
bytes username_link_handle = 1;
|
||
|
|
|
||
|
|
// The authenticated account did not have a username set.
|
||
|
|
errors.FailedPrecondition no_username_set = 2 [(tag.reason) = "no_username_set"];
|
||
|
|
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
message DeleteUsernameLinkRequest {
|
||
|
|
}
|
||
|
|
|
||
|
|
message DeleteUsernameLinkResponse {
|
||
|
|
}
|
||
|
|
|
||
|
|
message ConfigureUnidentifiedAccessRequest {
|
||
|
|
oneof configuration {
|
||
|
|
// The key that other users must provide to interact with this account
|
||
|
|
// anonymously (i.e. to retrieve keys or profiles or to send messages) unless
|
||
|
|
// unrestricted unidentified access is permitted. Must be present if
|
||
|
|
// unrestricted unidentified access is not allowed.
|
||
|
|
bytes unidentified_access_key = 1 [(require.exactlySize) = 16];
|
||
|
|
|
||
|
|
// If set, any user may interact with this account anonymously without
|
||
|
|
// providing an unidentified access key. Otherwise, users must provide the
|
||
|
|
// given unidentified access key to interact with this account anonymously.
|
||
|
|
// Setting unrestricted unidentified access will clear any existing
|
||
|
|
// unidentified_access_key
|
||
|
|
google.protobuf.Empty allow_unrestricted_unidentified_access = 2;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
message ConfigureUnidentifiedAccessResponse {
|
||
|
|
}
|
||
|
|
|
||
|
|
message SetDiscoverableByPhoneNumberRequest {
|
||
|
|
// If true, the authenticated account may be discovered by phone number via
|
||
|
|
// the Contact Discovery Service (CDS). Otherwise, other users must discover
|
||
|
|
// this account by other means (i.e. by username).
|
||
|
|
bool discoverable_by_phone_number = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
message SetDiscoverableByPhoneNumberResponse {
|
||
|
|
}
|
||
|
|
|
||
|
|
message SetRegistrationRecoveryPasswordRequest {
|
||
|
|
// The new registration recovery password for the authenticated account.
|
||
|
|
bytes registration_recovery_password = 1 [(require.exactlySize) = 32];
|
||
|
|
}
|
||
|
|
|
||
|
|
message SetRegistrationRecoveryPasswordResponse {
|
||
|
|
}
|
||
|
|
|
||
|
|
message CheckAccountExistenceRequest {
|
||
|
|
// The service identifier of an account that may or may not exist.
|
||
|
|
common.ServiceIdentifier service_identifier = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
message CheckAccountExistenceResponse {
|
||
|
|
// True if an account exists with the given service identifier or false if no
|
||
|
|
// account was found.
|
||
|
|
bool account_exists = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
message LookupUsernameHashRequest {
|
||
|
|
// A 32-byte username hash for which to find an account.
|
||
|
|
bytes username_hash = 1 [(require.exactlySize) = 32];
|
||
|
|
}
|
||
|
|
|
||
|
|
message LookupUsernameHashResponse {
|
||
|
|
oneof response {
|
||
|
|
// The service identifier associated with the provided username hash.
|
||
|
|
common.ServiceIdentifier service_identifier = 1;
|
||
|
|
|
||
|
|
// No account was found for the provided username hash.
|
||
|
|
errors.NotFound not_found = 2 [(tag.reason) = "not_found"];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
message LookupUsernameLinkRequest {
|
||
|
|
// The link handle for which to find an encrypted username. Link handles are
|
||
|
|
// 16-byte representations of UUIDs.
|
||
|
|
bytes username_link_handle = 1 [(require.exactlySize) = 16];
|
||
|
|
}
|
||
|
|
|
||
|
|
message LookupUsernameLinkResponse {
|
||
|
|
oneof response {
|
||
|
|
// The ciphertext of the username identified by the provided link handle.
|
||
|
|
bytes username_ciphertext = 1;
|
||
|
|
|
||
|
|
|
||
|
|
// No username was found for the provided link handle.
|
||
|
|
errors.NotFound not_found = 2 [(tag.reason) = "not_found"];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
message SetZkCredentialKeyRequest {
|
||
|
|
// A serialized libsignal ZkCredentialPublicKey
|
||
|
|
bytes public_key = 1 [(require.exactlySize) = 33];
|
||
|
|
}
|
||
|
|
|
||
|
|
message SetZkCredentialKeyResponse {
|
||
|
|
// A random, non-zero, value that must be included in credential requests using the key.
|
||
|
|
//
|
||
|
|
// This value allows the server to ratchet the resulting binding identity,
|
||
|
|
// as reverting to the previous key will result in a new rotation ID.
|
||
|
|
uint64 rotation_id = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
message ChangeNumberRequest {
|
||
|
|
// A means of authenticating the change-number request for the new phone
|
||
|
|
// number. Exactly one must be provided.
|
||
|
|
oneof verification {
|
||
|
|
// A verified registration session ID (as returned by the registration
|
||
|
|
// service) for the new phone number.
|
||
|
|
bytes session_id = 1 [(require.nonEmpty) = true];
|
||
|
|
|
||
|
|
// A registration recovery password for the new phone number.
|
||
|
|
bytes recovery_password = 2 [(require.exactlySize) = 32];
|
||
|
|
}
|
||
|
|
|
||
|
|
// The new phone number for the authenticated account.
|
||
|
|
string number = 3 [(require.e164) = true];
|
||
|
|
|
||
|
|
// The registration lock secret for the new phone number, if the account
|
||
|
|
// associated with the new phone number has a registration lock configured.
|
||
|
|
bytes registration_lock = 4 [(require.exactlySize) = 0, (require.exactlySize) = 32];
|
||
|
|
|
||
|
|
// The new public identity key to use for the phone-number identity (PNI)
|
||
|
|
// associated with the new phone number.
|
||
|
|
bytes pni_identity_key = 5 [(require.nonEmpty) = true];
|
||
|
|
|
||
|
|
// Synchronization messages to send to companion devices to supply the private
|
||
|
|
// keys associated with the new identity key and their new pre-keys. Exactly
|
||
|
|
// one message must be supplied for each device other than the sending
|
||
|
|
// (primary) device. May be omitted if no companion devices are linked to the
|
||
|
|
// account.
|
||
|
|
messages.IndividualRecipientMessageBundle device_messages = 6;
|
||
|
|
|
||
|
|
// A new signed EC pre-key for each device on the account, including the
|
||
|
|
// sending device, keyed by device ID. Each must be accompanied by a valid
|
||
|
|
// signature from the identity key in this request.
|
||
|
|
map<uint32, common.EcSignedPreKey> device_pni_signed_pre_keys = 7;
|
||
|
|
|
||
|
|
// A new signed post-quantum last-resort pre-key for each device on the
|
||
|
|
// account, including the sending device, keyed by device ID. Each must be
|
||
|
|
// accompanied by a valid signature from the identity key in this request.
|
||
|
|
map<uint32, common.KemSignedPreKey> device_pni_pq_last_resort_pre_keys = 8;
|
||
|
|
|
||
|
|
// The new phone-number-identity registration ID for each device on the
|
||
|
|
// account, including the sending device, keyed by device ID.
|
||
|
|
map<uint32, uint32> pni_registration_ids = 9;
|
||
|
|
}
|
||
|
|
|
||
|
|
message ChangeNumberResponse {
|
||
|
|
oneof response {
|
||
|
|
// The identifiers of the account after the successful
|
||
|
|
// number change.
|
||
|
|
common.AccountIdentifiers account_identifiers = 1;
|
||
|
|
|
||
|
|
// Mismatched number of devices or device ids in 'devices to notify' list
|
||
|
|
messages.MismatchedDevices mismatched_devices = 2 [(tag.reason) = "mismatched_devices"];
|
||
|
|
|
||
|
|
// The account associated with the new phone number has a registration lock,
|
||
|
|
// and the provided registration lock secret was missing or incorrect.
|
||
|
|
RegistrationLockFailure registration_lock_failure = 3 [(tag.reason) = "registration_lock_failure"];
|
||
|
|
|
||
|
|
// Mismatched registration ids in 'devices to notify' list
|
||
|
|
StaleDevices stale_devices = 4 [(tag.reason) = "stale_devices"];
|
||
|
|
|
||
|
|
// One or more device messages was too large
|
||
|
|
errors.FailedPrecondition message_too_large = 5 [(tag.reason) = "message_too_large"];
|
||
|
|
|
||
|
|
// The registration session is unverified
|
||
|
|
errors.FailedPrecondition unverified_registration_session = 6 [(tag.reason) = "unverified_registration_session"];
|
||
|
|
|
||
|
|
// The number does not match the registration session, or the registration session is invalid
|
||
|
|
errors.FailedPrecondition invalid_registration_session = 7 [(tag.reason) = "invalid_registration_session"];
|
||
|
|
|
||
|
|
errors.FailedPrecondition recovery_password_verification_failed = 8 [(tag.reason) = "recovery_password_verification_failed"];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Information about the current Registration lock and SVR credentials. With a correct PIN, the credentials can
|
||
|
|
// be used to recover the secret used to derive the registration lock password.
|
||
|
|
message RegistrationLockFailure {
|
||
|
|
// Time remaining in milliseconds before the existing registration lock expires
|
||
|
|
uint64 time_remaining_millis = 1;
|
||
|
|
|
||
|
|
// Credentials that can be used with SVR2
|
||
|
|
ExternalServiceCredentials svr2_credentials = 2;
|
||
|
|
}
|
||
|
|
|
||
|
|
// A username/password pair for authenticating with an external service.
|
||
|
|
message ExternalServiceCredentials {
|
||
|
|
// A username that can be presented to authenticate with the external service.
|
||
|
|
string username = 1;
|
||
|
|
|
||
|
|
// A password that can be presented to authenticate with the external service.
|
||
|
|
string password = 2;
|
||
|
|
}
|
||
|
|
|
||
|
|
// A list of devices that are linked to the account but presented a stale
|
||
|
|
// registration ID (indicating the device has likely been replaced by another
|
||
|
|
// device).
|
||
|
|
message StaleDevices {
|
||
|
|
// The IDs of devices that are no longer active.
|
||
|
|
repeated uint32 stale_devices = 1 [(require.each) = {range: {max: 0x7f}}];
|
||
|
|
}
|
||
|
|
|
||
|
|
message GetAccountDataReportRequest {
|
||
|
|
}
|
||
|
|
|
||
|
|
message GetAccountDataReportResponse {
|
||
|
|
// The JSON representation of the data report
|
||
|
|
string json = 3;
|
||
|
|
// A plaintext representation of the data report
|
||
|
|
string text = 4;
|
||
|
|
}
|
||
|
|
|
||
|
|
message GetCapabilitiesRequest {
|
||
|
|
}
|
||
|
|
|
||
|
|
message Capabilities {
|
||
|
|
// A list of capabilities enabled on the account.
|
||
|
|
repeated common.DeviceCapability capabilities = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
message GetCapabilitiesResponse {
|
||
|
|
// A list of capabilities enabled on the account.
|
||
|
|
Capabilities capabilities = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
message GetCapabilitiesAnonymousRequest {
|
||
|
|
// The ACI of the account for which to get capabilities.
|
||
|
|
common.ServiceIdentifier account_identifier = 1 [(require.present) = true, (require.identityType) = IDENTITY_TYPE_ACI];
|
||
|
|
|
||
|
|
oneof authentication {
|
||
|
|
// The unidentified access key for the targeted account.
|
||
|
|
bytes unidentified_access_key = 2 [(require.exactlySize) = 16];
|
||
|
|
|
||
|
|
// A group send endorsement token for the targeted account.
|
||
|
|
bytes group_send_token = 3 [(require.nonEmpty) = true];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
message GetCapabilitiesAnonymousResponse {
|
||
|
|
oneof response {
|
||
|
|
// A list of capabilities enabled on the account.
|
||
|
|
Capabilities capabilities = 1;
|
||
|
|
errors.NotFound not_found = 2 [(tag.reason) = "not_found"];
|
||
|
|
errors.FailedUnidentifiedAuthorization failed_unidentified_authorization = 3 [(tag.reason) = "failed_unidentified_authorization"];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
message TotpParameters {
|
||
|
|
// The HMAC algorithm (e.g. "HmacSHA256") used by the TOTP generator
|
||
|
|
string algorithm = 1;
|
||
|
|
|
||
|
|
// The length of one-time passwords (in decimal digits) produced and expected
|
||
|
|
// by the TOTP generator
|
||
|
|
uint32 password_length = 2;
|
||
|
|
|
||
|
|
// The time step (in seconds) used by the TOTP generator
|
||
|
|
uint32 time_step_seconds = 3;
|
||
|
|
}
|
||
|
|
|
||
|
|
message GenerateTotpKeyRequest {
|
||
|
|
}
|
||
|
|
|
||
|
|
message GenerateTotpKeyResponse {
|
||
|
|
message KeyGenerated {
|
||
|
|
// The raw TOTP key
|
||
|
|
bytes key = 1;
|
||
|
|
|
||
|
|
// The TOTP parameters associated with the generated key
|
||
|
|
TotpParameters totp_parameters = 2;
|
||
|
|
}
|
||
|
|
|
||
|
|
oneof response {
|
||
|
|
// A new, pending TOTP key has been generated and added to the authenticated
|
||
|
|
// account
|
||
|
|
KeyGenerated key_generated = 1;
|
||
|
|
|
||
|
|
// The authenticated account already has too many TOTP keys, and the caller
|
||
|
|
// must remove one before adding more
|
||
|
|
errors.FailedPrecondition too_many_totp_keys = 2 [(tag.reason) = "too_many_totp_keys"];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
message ConfirmTotpKeyRequest {
|
||
|
|
// A one-time password derived from the current pending TOTP key
|
||
|
|
uint32 one_time_password = 1;
|
||
|
|
|
||
|
|
// The ciphertext of user-provided metadata (presumably including a
|
||
|
|
// human-readable name and creation timestamp) to be attached to the
|
||
|
|
// newly-confirmed key
|
||
|
|
bytes metadata_ciphertext = 2 [(require.exactlySize) = 160];
|
||
|
|
}
|
||
|
|
|
||
|
|
message ConfirmTotpKeyResponse {
|
||
|
|
message KeyConfirmed {
|
||
|
|
// The account-specific identifier for the newly-confirmed TOTP key
|
||
|
|
uint32 key_id = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
oneof response {
|
||
|
|
// The provided one-time password was accepted and the pending TOTP key was
|
||
|
|
// stored with the provided name ciphertext
|
||
|
|
KeyConfirmed key_confirmed = 1;
|
||
|
|
|
||
|
|
// The provided one-time password was not valid for any reason (including
|
||
|
|
// incorrect passwords, misaligned clocks, or missing account records)
|
||
|
|
errors.FailedPrecondition one_time_password_not_verified = 2 [(tag.reason) = "one_time_password_not_verified"];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
message ListTotpKeysRequest {}
|
||
|
|
|
||
|
|
message ListTotpKeysResponse {
|
||
|
|
message TotpKeyMetadata {
|
||
|
|
// The user-provided ciphertext for metadata associated with this TOTP key
|
||
|
|
bytes metadata_ciphertext = 1;
|
||
|
|
|
||
|
|
// The TOTP parameters associated with this key
|
||
|
|
TotpParameters totp_parameters = 2;
|
||
|
|
}
|
||
|
|
|
||
|
|
map<int32, TotpKeyMetadata> keys = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
message SetTotpKeyMetadataRequest {
|
||
|
|
// The account-specific identifier of the TOTP key to modify
|
||
|
|
uint32 key_id = 1;
|
||
|
|
|
||
|
|
// The ciphertext of the new user-provided metadata to be attached to the
|
||
|
|
// identified key
|
||
|
|
bytes metadata_ciphertext = 2 [(require.exactlySize) = 160];
|
||
|
|
}
|
||
|
|
|
||
|
|
message SetTotpKeyMetadataResponse {
|
||
|
|
message MetadataUpdated {
|
||
|
|
}
|
||
|
|
|
||
|
|
oneof response {
|
||
|
|
// New metadata was stored for the identified TOTP key
|
||
|
|
MetadataUpdated metadata_updated = 1;
|
||
|
|
|
||
|
|
// No TOTP was found with the given ID
|
||
|
|
errors.NotFound key_not_found = 2 [(tag.reason) = "key_not_found"];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
message RemoveTotpKeyRequest {
|
||
|
|
// The account-specific identifier of the TOTP key to remove
|
||
|
|
uint32 key_id = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
message RemoveTotpKeyResponse {
|
||
|
|
}
|