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 @@ -559,6 +559,7 @@ let response = PeersDeviceListsResponse { users_device_lists: device_lists, + users_devices_platform_details: HashMap::new(), }; Ok(Response::new(response)) } 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 @@ -232,6 +232,20 @@ // GetDeviceListsForUsers +// platform details for single device +message PlatformDetails { + identity.unauth.DeviceType device_type = 1; + uint64 code_version = 2; + optional uint64 state_version = 3; + optional uint64 major_desktop_version = 4; +} + +// platform details for user's devices +message UserDevicesPlatformDetails { + // keys are device IDs + map devices_platform_details = 1; +} + message PeersDeviceListsRequest { repeated string user_ids = 1; } @@ -241,6 +255,9 @@ // values are JSON-stringified device list payloads // (see GetDeviceListResponse message for payload structure) map users_device_lists = 1; + + // keys are user IDs + map users_devices_platform_details = 2; } // UpdateDeviceListForUser 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 @@ -41,12 +41,14 @@ 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.PlatformDetails', 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); goog.exportSymbol('proto.identity.auth.UpdateUserPasswordStartRequest', null, global); goog.exportSymbol('proto.identity.auth.UpdateUserPasswordStartResponse', null, global); goog.exportSymbol('proto.identity.auth.UploadOneTimeKeysRequest', null, global); +goog.exportSymbol('proto.identity.auth.UserDevicesPlatformDetails', null, global); goog.exportSymbol('proto.identity.auth.UserIdentitiesRequest', null, global); goog.exportSymbol('proto.identity.auth.UserIdentitiesResponse', null, global); /** @@ -448,6 +450,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.PlatformDetails = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.identity.auth.PlatformDetails, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.identity.auth.PlatformDetails.displayName = 'proto.identity.auth.PlatformDetails'; +} +/** + * 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.UserDevicesPlatformDetails = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.identity.auth.UserDevicesPlatformDetails, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.identity.auth.UserDevicesPlatformDetails.displayName = 'proto.identity.auth.UserDevicesPlatformDetails'; +} /** * Generated by JsPbCodeGenerator. * @param {Array=} opt_data Optional initial data array, typically from a @@ -4213,6 +4257,396 @@ + + +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_, 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.PlatformDetails.prototype.toObject = function(opt_includeInstance) { + return proto.identity.auth.PlatformDetails.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.PlatformDetails} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.identity.auth.PlatformDetails.toObject = function(includeInstance, msg) { + var f, obj = { + deviceType: jspb.Message.getFieldWithDefault(msg, 1, 0), + codeVersion: jspb.Message.getFieldWithDefault(msg, 2, 0), + stateVersion: jspb.Message.getFieldWithDefault(msg, 3, 0), + majorDesktopVersion: jspb.Message.getFieldWithDefault(msg, 4, 0) + }; + + 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.PlatformDetails} + */ +proto.identity.auth.PlatformDetails.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.identity.auth.PlatformDetails; + return proto.identity.auth.PlatformDetails.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.identity.auth.PlatformDetails} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.identity.auth.PlatformDetails} + */ +proto.identity.auth.PlatformDetails.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {!proto.identity.unauth.DeviceType} */ (reader.readEnum()); + msg.setDeviceType(value); + break; + case 2: + var value = /** @type {number} */ (reader.readUint64()); + msg.setCodeVersion(value); + break; + case 3: + var value = /** @type {number} */ (reader.readUint64()); + msg.setStateVersion(value); + break; + case 4: + var value = /** @type {number} */ (reader.readUint64()); + msg.setMajorDesktopVersion(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.identity.auth.PlatformDetails.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.identity.auth.PlatformDetails.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.PlatformDetails} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.identity.auth.PlatformDetails.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getDeviceType(); + if (f !== 0.0) { + writer.writeEnum( + 1, + f + ); + } + f = message.getCodeVersion(); + if (f !== 0) { + writer.writeUint64( + 2, + f + ); + } + f = /** @type {number} */ (jspb.Message.getField(message, 3)); + if (f != null) { + writer.writeUint64( + 3, + f + ); + } + f = /** @type {number} */ (jspb.Message.getField(message, 4)); + if (f != null) { + writer.writeUint64( + 4, + f + ); + } +}; + + +/** + * optional identity.unauth.DeviceType device_type = 1; + * @return {!proto.identity.unauth.DeviceType} + */ +proto.identity.auth.PlatformDetails.prototype.getDeviceType = function() { + return /** @type {!proto.identity.unauth.DeviceType} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); +}; + + +/** + * @param {!proto.identity.unauth.DeviceType} value + * @return {!proto.identity.auth.PlatformDetails} returns this + */ +proto.identity.auth.PlatformDetails.prototype.setDeviceType = function(value) { + return jspb.Message.setProto3EnumField(this, 1, value); +}; + + +/** + * optional uint64 code_version = 2; + * @return {number} + */ +proto.identity.auth.PlatformDetails.prototype.getCodeVersion = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.identity.auth.PlatformDetails} returns this + */ +proto.identity.auth.PlatformDetails.prototype.setCodeVersion = function(value) { + return jspb.Message.setProto3IntField(this, 2, value); +}; + + +/** + * optional uint64 state_version = 3; + * @return {number} + */ +proto.identity.auth.PlatformDetails.prototype.getStateVersion = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.identity.auth.PlatformDetails} returns this + */ +proto.identity.auth.PlatformDetails.prototype.setStateVersion = function(value) { + return jspb.Message.setField(this, 3, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.identity.auth.PlatformDetails} returns this + */ +proto.identity.auth.PlatformDetails.prototype.clearStateVersion = function() { + return jspb.Message.setField(this, 3, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.identity.auth.PlatformDetails.prototype.hasStateVersion = function() { + return jspb.Message.getField(this, 3) != null; +}; + + +/** + * optional uint64 major_desktop_version = 4; + * @return {number} + */ +proto.identity.auth.PlatformDetails.prototype.getMajorDesktopVersion = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.identity.auth.PlatformDetails} returns this + */ +proto.identity.auth.PlatformDetails.prototype.setMajorDesktopVersion = function(value) { + return jspb.Message.setField(this, 4, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.identity.auth.PlatformDetails} returns this + */ +proto.identity.auth.PlatformDetails.prototype.clearMajorDesktopVersion = function() { + return jspb.Message.setField(this, 4, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.identity.auth.PlatformDetails.prototype.hasMajorDesktopVersion = function() { + return jspb.Message.getField(this, 4) != null; +}; + + + + + +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_, 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.UserDevicesPlatformDetails.prototype.toObject = function(opt_includeInstance) { + return proto.identity.auth.UserDevicesPlatformDetails.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.UserDevicesPlatformDetails} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.identity.auth.UserDevicesPlatformDetails.toObject = function(includeInstance, msg) { + var f, obj = { + devicesPlatformDetailsMap: (f = msg.getDevicesPlatformDetailsMap()) ? f.toObject(includeInstance, proto.identity.auth.PlatformDetails.toObject) : [] + }; + + 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.UserDevicesPlatformDetails} + */ +proto.identity.auth.UserDevicesPlatformDetails.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.identity.auth.UserDevicesPlatformDetails; + return proto.identity.auth.UserDevicesPlatformDetails.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.identity.auth.UserDevicesPlatformDetails} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.identity.auth.UserDevicesPlatformDetails} + */ +proto.identity.auth.UserDevicesPlatformDetails.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = msg.getDevicesPlatformDetailsMap(); + reader.readMessage(value, function(message, reader) { + jspb.Map.deserializeBinary(message, reader, jspb.BinaryReader.prototype.readString, jspb.BinaryReader.prototype.readMessage, proto.identity.auth.PlatformDetails.deserializeBinaryFromReader, "", new proto.identity.auth.PlatformDetails()); + }); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.identity.auth.UserDevicesPlatformDetails.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.identity.auth.UserDevicesPlatformDetails.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.UserDevicesPlatformDetails} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.identity.auth.UserDevicesPlatformDetails.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getDevicesPlatformDetailsMap(true); + if (f && f.getLength() > 0) { + f.serializeBinary(1, writer, jspb.BinaryWriter.prototype.writeString, jspb.BinaryWriter.prototype.writeMessage, proto.identity.auth.PlatformDetails.serializeBinaryToWriter); + } +}; + + +/** + * map devices_platform_details = 1; + * @param {boolean=} opt_noLazyCreate Do not create the map if + * empty, instead returning `undefined` + * @return {!jspb.Map} + */ +proto.identity.auth.UserDevicesPlatformDetails.prototype.getDevicesPlatformDetailsMap = function(opt_noLazyCreate) { + return /** @type {!jspb.Map} */ ( + jspb.Message.getMapField(this, 1, opt_noLazyCreate, + proto.identity.auth.PlatformDetails)); +}; + + +/** + * Clears values from the map. The map will be non-null. + * @return {!proto.identity.auth.UserDevicesPlatformDetails} returns this + */ +proto.identity.auth.UserDevicesPlatformDetails.prototype.clearDevicesPlatformDetailsMap = function() { + this.getDevicesPlatformDetailsMap().clear(); + return this; +}; + + + /** * List of repeated fields within this message type. * @private {!Array} @@ -4400,7 +4834,8 @@ */ proto.identity.auth.PeersDeviceListsResponse.toObject = function(includeInstance, msg) { var f, obj = { - usersDeviceListsMap: (f = msg.getUsersDeviceListsMap()) ? f.toObject(includeInstance, undefined) : [] + usersDeviceListsMap: (f = msg.getUsersDeviceListsMap()) ? f.toObject(includeInstance, undefined) : [], + usersDevicesPlatformDetailsMap: (f = msg.getUsersDevicesPlatformDetailsMap()) ? f.toObject(includeInstance, proto.identity.auth.UserDevicesPlatformDetails.toObject) : [] }; if (includeInstance) { @@ -4443,6 +4878,12 @@ jspb.Map.deserializeBinary(message, reader, jspb.BinaryReader.prototype.readString, jspb.BinaryReader.prototype.readString, null, "", ""); }); break; + case 2: + var value = msg.getUsersDevicesPlatformDetailsMap(); + reader.readMessage(value, function(message, reader) { + jspb.Map.deserializeBinary(message, reader, jspb.BinaryReader.prototype.readString, jspb.BinaryReader.prototype.readMessage, proto.identity.auth.UserDevicesPlatformDetails.deserializeBinaryFromReader, "", new proto.identity.auth.UserDevicesPlatformDetails()); + }); + break; default: reader.skipField(); break; @@ -4476,6 +4917,10 @@ if (f && f.getLength() > 0) { f.serializeBinary(1, writer, jspb.BinaryWriter.prototype.writeString, jspb.BinaryWriter.prototype.writeString); } + f = message.getUsersDevicesPlatformDetailsMap(true); + if (f && f.getLength() > 0) { + f.serializeBinary(2, writer, jspb.BinaryWriter.prototype.writeString, jspb.BinaryWriter.prototype.writeMessage, proto.identity.auth.UserDevicesPlatformDetails.serializeBinaryToWriter); + } }; @@ -4502,6 +4947,29 @@ }; +/** + * map users_devices_platform_details = 2; + * @param {boolean=} opt_noLazyCreate Do not create the map if + * empty, instead returning `undefined` + * @return {!jspb.Map} + */ +proto.identity.auth.PeersDeviceListsResponse.prototype.getUsersDevicesPlatformDetailsMap = function(opt_noLazyCreate) { + return /** @type {!jspb.Map} */ ( + jspb.Message.getMapField(this, 2, opt_noLazyCreate, + proto.identity.auth.UserDevicesPlatformDetails)); +}; + + +/** + * Clears values from the map. The map will be non-null. + * @return {!proto.identity.auth.PeersDeviceListsResponse} returns this + */ +proto.identity.auth.PeersDeviceListsResponse.prototype.clearUsersDevicesPlatformDetailsMap = function() { + this.getUsersDevicesPlatformDetailsMap().clear(); + return this; +}; + + 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 @@ -447,6 +447,54 @@ deviceListUpdatesList: Array, } +declare export class PlatformDetails extends Message { + getDeviceType(): identityStructs.DeviceType; + setDeviceType(value: identityStructs.DeviceType): PlatformDetails; + + getCodeVersion(): number; + setCodeVersion(value: number): PlatformDetails; + + getStateVersion(): number; + setStateVersion(value: number): PlatformDetails; + hasStateVersion(): boolean; + clearStateVersion(): PlatformDetails; + + getMajorDesktopVersion(): number; + setMajorDesktopVersion(value: number): PlatformDetails; + hasMajorDesktopVersion(): boolean; + clearMajorDesktopVersion(): PlatformDetails; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): PlatformDetailsObject; + static toObject(includeInstance: boolean, msg: PlatformDetails): PlatformDetailsObject; + static serializeBinaryToWriter(message: PlatformDetails, writer: BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): PlatformDetails; + static deserializeBinaryFromReader(message: PlatformDetails, reader: BinaryReader): PlatformDetails; +} + +export type PlatformDetailsObject = { + deviceType: identityStructs.DeviceType, + codeVersion: number, + stateVersion?: number, + majorDesktopVersion?: number, +} + +declare export class UserDevicesPlatformDetails extends Message { + getDevicesPlatformDetailsMap(): ProtoMap; + clearDevicesPlatformDetailsMap(): UserDevicesPlatformDetails; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): UserDevicesPlatformDetailsObject; + static toObject(includeInstance: boolean, msg: UserDevicesPlatformDetails): UserDevicesPlatformDetailsObject; + static serializeBinaryToWriter(message: UserDevicesPlatformDetails, writer: BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): UserDevicesPlatformDetails; + static deserializeBinaryFromReader(message: UserDevicesPlatformDetails, reader: BinaryReader): UserDevicesPlatformDetails; +} + +export type UserDevicesPlatformDetailsObject = { + devicesPlatformDetailsMap: Array<[string, PlatformDetailsObject]>, +} + declare export class PeersDeviceListsRequest extends Message { getUserIdsList(): Array; setUserIdsList(value: Array): PeersDeviceListsRequest; @@ -469,6 +517,9 @@ getUsersDeviceListsMap(): ProtoMap; clearUsersDeviceListsMap(): PeersDeviceListsResponse; + getUsersDevicesPlatformDetailsMap(): ProtoMap; + clearUsersDevicesPlatformDetailsMap(): PeersDeviceListsResponse; + serializeBinary(): Uint8Array; toObject(includeInstance?: boolean): PeersDeviceListsResponseObject; static toObject(includeInstance: boolean, msg: PeersDeviceListsResponse): PeersDeviceListsResponseObject; @@ -479,6 +530,7 @@ export type PeersDeviceListsResponseObject = { usersDeviceListsMap: Array<[string, string]>, + usersDevicesPlatformDetailsMap: Array<[string, UserDevicesPlatformDetailsObject]>, } declare export class UpdateDeviceListRequest extends Message {