Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F33310436
D11570.1768808005.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
25 KB
Referenced Files
None
Subscribers
None
D11570.1768808005.diff
View Options
diff --git a/services/commtest/tests/identity_device_list_tests.rs b/services/commtest/tests/identity_device_list_tests.rs
--- a/services/commtest/tests/identity_device_list_tests.rs
+++ b/services/commtest/tests/identity_device_list_tests.rs
@@ -1,3 +1,4 @@
+use std::collections::{HashMap, HashSet};
use std::str::FromStr;
use commtest::identity::device::{
@@ -7,7 +8,9 @@
use commtest::service_addr;
use grpc_clients::identity::authenticated::ChainedInterceptedAuthClient;
use grpc_clients::identity::get_auth_client;
-use grpc_clients::identity::protos::auth::UpdateDeviceListRequest;
+use grpc_clients::identity::protos::auth::{
+ PeersDeviceListsRequest, UpdateDeviceListRequest,
+};
use grpc_clients::identity::protos::authenticated::GetDeviceListRequest;
use grpc_clients::identity::DeviceType;
use serde::Deserialize;
@@ -223,6 +226,65 @@
assert_eq!(device_lists_response, expected_device_list);
}
+#[tokio::test]
+async fn test_device_list_multifetch() {
+ // Create viewer (user that only auths request)
+ let viewer = register_user_device(None, None).await;
+ let mut auth_client = get_auth_client(
+ &service_addr::IDENTITY_GRPC.to_string(),
+ viewer.user_id.clone(),
+ viewer.device_id,
+ viewer.access_token,
+ PLACEHOLDER_CODE_VERSION,
+ DEVICE_TYPE.to_string(),
+ )
+ .await
+ .expect("Couldn't connect to identity service");
+
+ // Register users and prepare expected device lists
+ let mut expected_device_lists = HashMap::new();
+ for _ in 0..5 {
+ let user = register_user_device(None, None).await;
+ expected_device_lists.insert(user.user_id, vec![user.device_id]);
+ }
+
+ // Fetch device lists from server
+ let user_ids: Vec<_> = expected_device_lists.keys().cloned().collect();
+ let request = PeersDeviceListsRequest { user_ids };
+ let response_device_lists = auth_client
+ .get_device_lists_for_users(request)
+ .await
+ .expect("GetDeviceListsForUser RPC failed")
+ .into_inner()
+ .users_device_lists;
+
+ // verify if response has the same user IDs as request
+ let expected_user_ids: HashSet<String> =
+ expected_device_lists.keys().cloned().collect();
+ let response_user_ids: HashSet<String> =
+ response_device_lists.keys().cloned().collect();
+ let difference: HashSet<_> = expected_user_ids
+ .symmetric_difference(&response_user_ids)
+ .collect();
+ assert!(difference.is_empty(), "User IDs differ: {:?}", difference);
+
+ // verify device list for each user
+ for (user_id, expected_devices) in expected_device_lists {
+ let response_payload = response_device_lists.get(&user_id).unwrap();
+
+ let returned_devices = SignedDeviceList::from_str(response_payload)
+ .expect("failed to deserialize signed device list")
+ .into_raw()
+ .devices;
+
+ assert_eq!(
+ returned_devices, expected_devices,
+ "Device list differs for user: {}, Expected {:?}, but got {:?}",
+ user_id, expected_devices, returned_devices
+ );
+ }
+}
+
// See GetDeviceListResponse in identity_authenticated.proto
// for details on the response format.
#[derive(Deserialize)]
diff --git a/services/identity/src/grpc_services/authenticated.rs b/services/identity/src/grpc_services/authenticated.rs
--- a/services/identity/src/grpc_services/authenticated.rs
+++ b/services/identity/src/grpc_services/authenticated.rs
@@ -24,7 +24,10 @@
UpdateUserPasswordStartRequest, UpdateUserPasswordStartResponse,
UploadOneTimeKeysRequest,
};
-use super::protos::auth::{UserIdentityRequest, UserIdentityResponse};
+use super::protos::auth::{
+ PeersDeviceListsRequest, PeersDeviceListsResponse, UserIdentityRequest,
+ UserIdentityResponse,
+};
use super::protos::unauth::Empty;
#[derive(derive_more::Constructor)]
@@ -364,18 +367,62 @@
let stringified_updates = device_list_updates
.iter()
- .map(serde_json::to_string)
- .collect::<Result<Vec<_>, _>>()
- .map_err(|err| {
- error!("Failed to serialize device list updates: {}", err);
- tonic::Status::failed_precondition("unexpected error")
- })?;
+ .map(SignedDeviceList::as_json_string)
+ .collect::<Result<Vec<_>, _>>()?;
Ok(Response::new(GetDeviceListResponse {
device_list_updates: stringified_updates,
}))
}
+ async fn get_device_lists_for_users(
+ &self,
+ request: tonic::Request<PeersDeviceListsRequest>,
+ ) -> Result<tonic::Response<PeersDeviceListsResponse>, tonic::Status> {
+ let PeersDeviceListsRequest { user_ids } = request.into_inner();
+
+ // do all fetches concurrently
+ let mut fetch_tasks = tokio::task::JoinSet::new();
+ let mut device_lists = HashMap::with_capacity(user_ids.len());
+ for user_id in user_ids {
+ let db_client = self.db_client.clone();
+ fetch_tasks.spawn(async move {
+ let result = db_client.get_current_device_list(&user_id).await;
+ (user_id, result)
+ });
+ }
+
+ while let Some(task_result) = fetch_tasks.join_next().await {
+ match task_result {
+ Ok((user_id, Ok(Some(device_list_row)))) => {
+ let raw_list = RawDeviceList::from(device_list_row);
+ let signed_list = SignedDeviceList::try_from_raw(raw_list)?;
+ let serialized_list = signed_list.as_json_string()?;
+ device_lists.insert(user_id, serialized_list);
+ }
+ Ok((user_id, Ok(None))) => {
+ warn!(user_id, "User has no device list, skipping!");
+ }
+ Ok((user_id, Err(err))) => {
+ error!(user_id, "Failed fetching device list: {err}");
+ // abort fetching other users
+ fetch_tasks.abort_all();
+ return Err(handle_db_error(err));
+ }
+ Err(join_error) => {
+ error!("Failed to join device list task: {join_error}");
+ fetch_tasks.abort_all();
+ return Err(Status::aborted("unexpected error"));
+ }
+ }
+ }
+
+ let response = PeersDeviceListsResponse {
+ users_device_lists: device_lists,
+ };
+ Ok(Response::new(response))
+ }
+
async fn update_device_list(
&self,
request: tonic::Request<UpdateDeviceListRequest>,
@@ -513,6 +560,14 @@
tonic::Status::invalid_argument("invalid device list payload")
})
}
+
+ /// Serializes the signed device list to a JSON string
+ fn as_json_string(&self) -> Result<String, tonic::Status> {
+ serde_json::to_string(self).map_err(|err| {
+ error!("Failed to serialize device list updates: {}", err);
+ tonic::Status::failed_precondition("unexpected error")
+ })
+ }
}
impl TryFrom<UpdateDeviceListRequest> for SignedDeviceList {
diff --git a/shared/protos/identity_auth.proto b/shared/protos/identity_auth.proto
--- a/shared/protos/identity_auth.proto
+++ b/shared/protos/identity_auth.proto
@@ -58,6 +58,9 @@
// Returns device list history
rpc GetDeviceListForUser(GetDeviceListRequest) returns
(GetDeviceListResponse) {}
+ // Returns current device list for a set of users
+ rpc GetDeviceListsForUsers (PeersDeviceListsRequest) returns
+ (PeersDeviceListsResponse) {}
rpc UpdateDeviceList(UpdateDeviceListRequest) returns
(identity.unauth.Empty) {}
@@ -198,6 +201,19 @@
repeated string device_list_updates = 1;
}
+// GetDeviceListsForUsers
+
+message PeersDeviceListsRequest {
+ repeated string user_ids = 1;
+}
+
+message PeersDeviceListsResponse {
+ // keys are user_id
+ // values are JSON-stringified device list payloads
+ // (see GetDeviceListResponse message for payload structure)
+ map<string, string> users_device_lists = 1;
+}
+
// UpdateDeviceListForUser
message UpdateDeviceListRequest {
diff --git a/web/protobufs/identity-auth-client.cjs b/web/protobufs/identity-auth-client.cjs
--- a/web/protobufs/identity-auth-client.cjs
+++ b/web/protobufs/identity-auth-client.cjs
@@ -688,6 +688,67 @@
};
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ * !proto.identity.auth.PeersDeviceListsRequest,
+ * !proto.identity.auth.PeersDeviceListsResponse>}
+ */
+const methodDescriptor_IdentityClientService_GetDeviceListsForUsers = new grpc.web.MethodDescriptor(
+ '/identity.auth.IdentityClientService/GetDeviceListsForUsers',
+ grpc.web.MethodType.UNARY,
+ proto.identity.auth.PeersDeviceListsRequest,
+ proto.identity.auth.PeersDeviceListsResponse,
+ /**
+ * @param {!proto.identity.auth.PeersDeviceListsRequest} request
+ * @return {!Uint8Array}
+ */
+ function(request) {
+ return request.serializeBinary();
+ },
+ proto.identity.auth.PeersDeviceListsResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.identity.auth.PeersDeviceListsRequest} request The
+ * request proto
+ * @param {?Object<string, string>} metadata User defined
+ * call metadata
+ * @param {function(?grpc.web.RpcError, ?proto.identity.auth.PeersDeviceListsResponse)}
+ * callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.identity.auth.PeersDeviceListsResponse>|undefined}
+ * The XHR Node Readable Stream
+ */
+proto.identity.auth.IdentityClientServiceClient.prototype.getDeviceListsForUsers =
+ function(request, metadata, callback) {
+ return this.client_.rpcCall(this.hostname_ +
+ '/identity.auth.IdentityClientService/GetDeviceListsForUsers',
+ request,
+ metadata || {},
+ methodDescriptor_IdentityClientService_GetDeviceListsForUsers,
+ callback);
+};
+
+
+/**
+ * @param {!proto.identity.auth.PeersDeviceListsRequest} request The
+ * request proto
+ * @param {?Object<string, string>=} metadata User defined
+ * call metadata
+ * @return {!Promise<!proto.identity.auth.PeersDeviceListsResponse>}
+ * Promise that resolves to the response
+ */
+proto.identity.auth.IdentityClientServicePromiseClient.prototype.getDeviceListsForUsers =
+ function(request, metadata) {
+ return this.client_.unaryCall(this.hostname_ +
+ '/identity.auth.IdentityClientService/GetDeviceListsForUsers',
+ request,
+ metadata || {},
+ methodDescriptor_IdentityClientService_GetDeviceListsForUsers);
+};
+
+
/**
* @const
* @type {!grpc.web.MethodDescriptor<
diff --git a/web/protobufs/identity-auth-client.cjs.flow b/web/protobufs/identity-auth-client.cjs.flow
--- a/web/protobufs/identity-auth-client.cjs.flow
+++ b/web/protobufs/identity-auth-client.cjs.flow
@@ -81,6 +81,13 @@
response: identityAuthStructs.GetDeviceListResponse) => void
): grpcWeb.ClientReadableStream<identityAuthStructs.GetDeviceListResponse>;
+ getDeviceListsForUsers(
+ request: identityAuthStructs.PeersDeviceListsRequest,
+ metadata: grpcWeb.Metadata | void,
+ callback: (err: grpcWeb.RpcError,
+ response: identityAuthStructs.PeersDeviceListsResponse) => void
+ ): grpcWeb.ClientReadableStream<identityAuthStructs.PeersDeviceListsResponse>;
+
updateDeviceList(
request: identityAuthStructs.UpdateDeviceListRequest,
metadata: grpcWeb.Metadata | void,
@@ -165,6 +172,11 @@
metadata?: grpcWeb.Metadata
): Promise<identityAuthStructs.GetDeviceListResponse>;
+ getDeviceListsForUsers(
+ request: identityAuthStructs.PeersDeviceListsRequest,
+ metadata?: grpcWeb.Metadata
+ ): Promise<identityAuthStructs.PeersDeviceListsResponse>;
+
updateDeviceList(
request: identityAuthStructs.UpdateDeviceListRequest,
metadata?: grpcWeb.Metadata
diff --git a/web/protobufs/identity-auth-structs.cjs b/web/protobufs/identity-auth-structs.cjs
--- a/web/protobufs/identity-auth-structs.cjs
+++ b/web/protobufs/identity-auth-structs.cjs
@@ -36,6 +36,8 @@
goog.exportSymbol('proto.identity.auth.OutboundKeyInfo', null, global);
goog.exportSymbol('proto.identity.auth.OutboundKeysForUserRequest', null, global);
goog.exportSymbol('proto.identity.auth.OutboundKeysForUserResponse', null, global);
+goog.exportSymbol('proto.identity.auth.PeersDeviceListsRequest', null, global);
+goog.exportSymbol('proto.identity.auth.PeersDeviceListsResponse', null, global);
goog.exportSymbol('proto.identity.auth.RefreshUserPrekeysRequest', null, global);
goog.exportSymbol('proto.identity.auth.UpdateDeviceListRequest', null, global);
goog.exportSymbol('proto.identity.auth.UpdateUserPasswordFinishRequest', null, global);
@@ -380,6 +382,48 @@
*/
proto.identity.auth.GetDeviceListResponse.displayName = 'proto.identity.auth.GetDeviceListResponse';
}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.identity.auth.PeersDeviceListsRequest = function(opt_data) {
+ jspb.Message.initialize(this, opt_data, 0, -1, proto.identity.auth.PeersDeviceListsRequest.repeatedFields_, null);
+};
+goog.inherits(proto.identity.auth.PeersDeviceListsRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+ /**
+ * @public
+ * @override
+ */
+ proto.identity.auth.PeersDeviceListsRequest.displayName = 'proto.identity.auth.PeersDeviceListsRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.identity.auth.PeersDeviceListsResponse = function(opt_data) {
+ jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.identity.auth.PeersDeviceListsResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+ /**
+ * @public
+ * @override
+ */
+ proto.identity.auth.PeersDeviceListsResponse.displayName = 'proto.identity.auth.PeersDeviceListsResponse';
+}
/**
* Generated by JsPbCodeGenerator.
* @param {Array=} opt_data Optional initial data array, typically from a
@@ -3533,6 +3577,296 @@
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.identity.auth.PeersDeviceListsRequest.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ * net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ * JSPB instance for transitional soy proto support:
+ * http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.identity.auth.PeersDeviceListsRequest.prototype.toObject = function(opt_includeInstance) {
+ return proto.identity.auth.PeersDeviceListsRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ * the JSPB instance for transitional soy proto support:
+ * http://goto/soy-param-migration
+ * @param {!proto.identity.auth.PeersDeviceListsRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.identity.auth.PeersDeviceListsRequest.toObject = function(includeInstance, msg) {
+ var f, obj = {
+ userIdsList: (f = jspb.Message.getRepeatedField(msg, 1)) == null ? undefined : f
+ };
+
+ if (includeInstance) {
+ obj.$jspbMessageInstance = msg;
+ }
+ return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.identity.auth.PeersDeviceListsRequest}
+ */
+proto.identity.auth.PeersDeviceListsRequest.deserializeBinary = function(bytes) {
+ var reader = new jspb.BinaryReader(bytes);
+ var msg = new proto.identity.auth.PeersDeviceListsRequest;
+ return proto.identity.auth.PeersDeviceListsRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.identity.auth.PeersDeviceListsRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.identity.auth.PeersDeviceListsRequest}
+ */
+proto.identity.auth.PeersDeviceListsRequest.deserializeBinaryFromReader = function(msg, reader) {
+ while (reader.nextField()) {
+ if (reader.isEndGroup()) {
+ break;
+ }
+ var field = reader.getFieldNumber();
+ switch (field) {
+ case 1:
+ var value = /** @type {string} */ (reader.readString());
+ msg.addUserIds(value);
+ break;
+ default:
+ reader.skipField();
+ break;
+ }
+ }
+ return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.identity.auth.PeersDeviceListsRequest.prototype.serializeBinary = function() {
+ var writer = new jspb.BinaryWriter();
+ proto.identity.auth.PeersDeviceListsRequest.serializeBinaryToWriter(this, writer);
+ return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.identity.auth.PeersDeviceListsRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.identity.auth.PeersDeviceListsRequest.serializeBinaryToWriter = function(message, writer) {
+ var f = undefined;
+ f = message.getUserIdsList();
+ if (f.length > 0) {
+ writer.writeRepeatedString(
+ 1,
+ f
+ );
+ }
+};
+
+
+/**
+ * repeated string user_ids = 1;
+ * @return {!Array<string>}
+ */
+proto.identity.auth.PeersDeviceListsRequest.prototype.getUserIdsList = function() {
+ return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 1));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.identity.auth.PeersDeviceListsRequest} returns this
+ */
+proto.identity.auth.PeersDeviceListsRequest.prototype.setUserIdsList = function(value) {
+ return jspb.Message.setField(this, 1, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.identity.auth.PeersDeviceListsRequest} returns this
+ */
+proto.identity.auth.PeersDeviceListsRequest.prototype.addUserIds = function(value, opt_index) {
+ return jspb.Message.addToRepeatedField(this, 1, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.identity.auth.PeersDeviceListsRequest} returns this
+ */
+proto.identity.auth.PeersDeviceListsRequest.prototype.clearUserIdsList = function() {
+ return this.setUserIdsList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ * net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ * JSPB instance for transitional soy proto support:
+ * http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.identity.auth.PeersDeviceListsResponse.prototype.toObject = function(opt_includeInstance) {
+ return proto.identity.auth.PeersDeviceListsResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ * the JSPB instance for transitional soy proto support:
+ * http://goto/soy-param-migration
+ * @param {!proto.identity.auth.PeersDeviceListsResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.identity.auth.PeersDeviceListsResponse.toObject = function(includeInstance, msg) {
+ var f, obj = {
+ usersDeviceListsMap: (f = msg.getUsersDeviceListsMap()) ? f.toObject(includeInstance, undefined) : []
+ };
+
+ if (includeInstance) {
+ obj.$jspbMessageInstance = msg;
+ }
+ return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.identity.auth.PeersDeviceListsResponse}
+ */
+proto.identity.auth.PeersDeviceListsResponse.deserializeBinary = function(bytes) {
+ var reader = new jspb.BinaryReader(bytes);
+ var msg = new proto.identity.auth.PeersDeviceListsResponse;
+ return proto.identity.auth.PeersDeviceListsResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.identity.auth.PeersDeviceListsResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.identity.auth.PeersDeviceListsResponse}
+ */
+proto.identity.auth.PeersDeviceListsResponse.deserializeBinaryFromReader = function(msg, reader) {
+ while (reader.nextField()) {
+ if (reader.isEndGroup()) {
+ break;
+ }
+ var field = reader.getFieldNumber();
+ switch (field) {
+ case 1:
+ var value = msg.getUsersDeviceListsMap();
+ reader.readMessage(value, function(message, reader) {
+ jspb.Map.deserializeBinary(message, reader, jspb.BinaryReader.prototype.readString, jspb.BinaryReader.prototype.readString, null, "", "");
+ });
+ break;
+ default:
+ reader.skipField();
+ break;
+ }
+ }
+ return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.identity.auth.PeersDeviceListsResponse.prototype.serializeBinary = function() {
+ var writer = new jspb.BinaryWriter();
+ proto.identity.auth.PeersDeviceListsResponse.serializeBinaryToWriter(this, writer);
+ return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.identity.auth.PeersDeviceListsResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.identity.auth.PeersDeviceListsResponse.serializeBinaryToWriter = function(message, writer) {
+ var f = undefined;
+ f = message.getUsersDeviceListsMap(true);
+ if (f && f.getLength() > 0) {
+ f.serializeBinary(1, writer, jspb.BinaryWriter.prototype.writeString, jspb.BinaryWriter.prototype.writeString);
+ }
+};
+
+
+/**
+ * map<string, string> users_device_lists = 1;
+ * @param {boolean=} opt_noLazyCreate Do not create the map if
+ * empty, instead returning `undefined`
+ * @return {!jspb.Map<string,string>}
+ */
+proto.identity.auth.PeersDeviceListsResponse.prototype.getUsersDeviceListsMap = function(opt_noLazyCreate) {
+ return /** @type {!jspb.Map<string,string>} */ (
+ jspb.Message.getMapField(this, 1, opt_noLazyCreate,
+ null));
+};
+
+
+/**
+ * Clears values from the map. The map will be non-null.
+ * @return {!proto.identity.auth.PeersDeviceListsResponse} returns this
+ */
+proto.identity.auth.PeersDeviceListsResponse.prototype.clearUsersDeviceListsMap = function() {
+ this.getUsersDeviceListsMap().clear();
+ return this;
+};
+
+
+
if (jspb.Message.GENERATE_TO_OBJECT) {
diff --git a/web/protobufs/identity-auth-structs.cjs.flow b/web/protobufs/identity-auth-structs.cjs.flow
--- a/web/protobufs/identity-auth-structs.cjs.flow
+++ b/web/protobufs/identity-auth-structs.cjs.flow
@@ -379,6 +379,40 @@
deviceListUpdatesList: Array<string>,
}
+declare export class PeersDeviceListsRequest extends Message {
+ getUserIdsList(): Array<string>;
+ setUserIdsList(value: Array<string>): PeersDeviceListsRequest;
+ clearUserIdsList(): PeersDeviceListsRequest;
+ addUserIds(value: string, index?: number): PeersDeviceListsRequest;
+
+ serializeBinary(): Uint8Array;
+ toObject(includeInstance?: boolean): PeersDeviceListsRequestObject;
+ static toObject(includeInstance: boolean, msg: PeersDeviceListsRequest): PeersDeviceListsRequestObject;
+ static serializeBinaryToWriter(message: PeersDeviceListsRequest, writer: BinaryWriter): void;
+ static deserializeBinary(bytes: Uint8Array): PeersDeviceListsRequest;
+ static deserializeBinaryFromReader(message: PeersDeviceListsRequest, reader: BinaryReader): PeersDeviceListsRequest;
+}
+
+export type PeersDeviceListsRequestObject = {
+ userIdsList: Array<string>,
+}
+
+declare export class PeersDeviceListsResponse extends Message {
+ getUsersDeviceListsMap(): ProtoMap<string, string>;
+ clearUsersDeviceListsMap(): PeersDeviceListsResponse;
+
+ serializeBinary(): Uint8Array;
+ toObject(includeInstance?: boolean): PeersDeviceListsResponseObject;
+ static toObject(includeInstance: boolean, msg: PeersDeviceListsResponse): PeersDeviceListsResponseObject;
+ static serializeBinaryToWriter(message: PeersDeviceListsResponse, writer: BinaryWriter): void;
+ static deserializeBinary(bytes: Uint8Array): PeersDeviceListsResponse;
+ static deserializeBinaryFromReader(message: PeersDeviceListsResponse, reader: BinaryReader): PeersDeviceListsResponse;
+}
+
+export type PeersDeviceListsResponseObject = {
+ usersDeviceListsMap: Array<[string, string]>,
+}
+
declare export class UpdateDeviceListRequest extends Message {
getNewDeviceList(): string;
setNewDeviceList(value: string): UpdateDeviceListRequest;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Jan 19, 7:33 AM (17 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5955182
Default Alt Text
D11570.1768808005.diff (25 KB)
Attached To
Mode
D11570: [protos][identity] Add RPC for fetching multiple device lists
Attached
Detach File
Event Timeline
Log In to Comment