Просмотр исходного кода

[rust]: extra user-infro from flowy-user

appflowy 3 лет назад
Родитель
Сommit
65cdeec1dc
57 измененных файлов с 4699 добавлено и 414 удалено
  1. 489 0
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/auth.pb.dart
  2. 7 0
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/auth.pbenum.dart
  3. 84 0
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/auth.pbjson.dart
  4. 9 0
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/auth.pbserver.dart
  5. 11 0
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/errors.pb.dart
  6. 54 0
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/errors.pbenum.dart
  7. 35 0
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/errors.pbjson.dart
  8. 9 0
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/errors.pbserver.dart
  9. 4 0
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/protobuf.dart
  10. 403 0
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/user_profile.pb.dart
  11. 7 0
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/user_profile.pbenum.dart
  12. 69 0
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/user_profile.pbjson.dart
  13. 9 0
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/user_profile.pbserver.dart
  14. 4 8
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/errors.pb.dart
  15. 0 47
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/errors.pbenum.dart
  16. 2 27
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/errors.pbjson.dart
  17. 1 1
      backend/Cargo.toml
  18. 1 1
      backend/src/service/trash/router.rs
  19. 2 2
      backend/src/service/user/auth.rs
  20. 4 14
      backend/src/service/user/router.rs
  21. 1 1
      backend/tests/api/auth.rs
  22. 1 0
      rust-lib/Cargo.toml
  23. 10 10
      rust-lib/flowy-derive/src/derive_cache/derive_cache.rs
  24. 1 1
      rust-lib/flowy-document/src/services/doc/revision/persistence.rs
  25. 12 12
      rust-lib/flowy-sdk/src/deps_resolve/document_deps.rs
  26. 26 0
      rust-lib/flowy-user-infra/Cargo.toml
  27. 3 0
      rust-lib/flowy-user-infra/Flowy.toml
  28. 11 9
      rust-lib/flowy-user-infra/src/entities/auth.rs
  29. 0 1
      rust-lib/flowy-user-infra/src/entities/mod.rs
  30. 11 23
      rust-lib/flowy-user-infra/src/entities/user_profile.rs
  31. 61 0
      rust-lib/flowy-user-infra/src/errors.rs
  32. 5 0
      rust-lib/flowy-user-infra/src/lib.rs
  33. 0 0
      rust-lib/flowy-user-infra/src/parser/mod.rs
  34. 0 0
      rust-lib/flowy-user-infra/src/parser/user_email.rs
  35. 4 2
      rust-lib/flowy-user-infra/src/parser/user_id.rs
  36. 0 0
      rust-lib/flowy-user-infra/src/parser/user_name.rs
  37. 0 0
      rust-lib/flowy-user-infra/src/parser/user_password.rs
  38. 0 0
      rust-lib/flowy-user-infra/src/parser/user_workspace.rs
  39. 4 0
      rust-lib/flowy-user-infra/src/protobuf/mod.rs
  40. 1661 0
      rust-lib/flowy-user-infra/src/protobuf/model/auth.rs
  41. 175 0
      rust-lib/flowy-user-infra/src/protobuf/model/errors.rs
  42. 10 0
      rust-lib/flowy-user-infra/src/protobuf/model/mod.rs
  43. 1351 0
      rust-lib/flowy-user-infra/src/protobuf/model/user_profile.rs
  44. 34 0
      rust-lib/flowy-user-infra/src/protobuf/proto/auth.proto
  45. 20 0
      rust-lib/flowy-user-infra/src/protobuf/proto/errors.proto
  46. 23 0
      rust-lib/flowy-user-infra/src/protobuf/proto/user_profile.proto
  47. 0 0
      rust-lib/flowy-user-infra/src/user_default.rs
  48. 1 8
      rust-lib/flowy-user/Cargo.toml
  49. 17 63
      rust-lib/flowy-user/src/errors.rs
  50. 2 1
      rust-lib/flowy-user/src/lib.rs
  51. 26 156
      rust-lib/flowy-user/src/protobuf/model/errors.rs
  52. 1 19
      rust-lib/flowy-user/src/protobuf/proto/errors.proto
  53. 2 1
      rust-lib/flowy-user/src/services/server/server_api.rs
  54. 4 4
      rust-lib/flowy-user/src/services/user/user_session.rs
  55. 12 0
      rust-lib/flowy-user/src/sql_tables/user.rs
  56. 5 2
      rust-lib/flowy-user/tests/event/auth_test.rs
  57. 1 1
      rust-lib/flowy-user/tests/event/user_profile_test.rs

+ 489 - 0
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/auth.pb.dart

@@ -0,0 +1,489 @@
+///
+//  Generated code. Do not modify.
+//  source: auth.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
+
+import 'dart:core' as $core;
+
+import 'package:protobuf/protobuf.dart' as $pb;
+
+class SignInRequest extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SignInRequest', createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'email')
+    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'password')
+    ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
+    ..hasRequiredFields = false
+  ;
+
+  SignInRequest._() : super();
+  factory SignInRequest({
+    $core.String? email,
+    $core.String? password,
+    $core.String? name,
+  }) {
+    final _result = create();
+    if (email != null) {
+      _result.email = email;
+    }
+    if (password != null) {
+      _result.password = password;
+    }
+    if (name != null) {
+      _result.name = name;
+    }
+    return _result;
+  }
+  factory SignInRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory SignInRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  SignInRequest clone() => SignInRequest()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  SignInRequest copyWith(void Function(SignInRequest) updates) => super.copyWith((message) => updates(message as SignInRequest)) as SignInRequest; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static SignInRequest create() => SignInRequest._();
+  SignInRequest createEmptyInstance() => create();
+  static $pb.PbList<SignInRequest> createRepeated() => $pb.PbList<SignInRequest>();
+  @$core.pragma('dart2js:noInline')
+  static SignInRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<SignInRequest>(create);
+  static SignInRequest? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.String get email => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set email($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasEmail() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearEmail() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get password => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set password($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasPassword() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearPassword() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.String get name => $_getSZ(2);
+  @$pb.TagNumber(3)
+  set name($core.String v) { $_setString(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasName() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearName() => clearField(3);
+}
+
+class SignInParams extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SignInParams', createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'email')
+    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'password')
+    ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
+    ..hasRequiredFields = false
+  ;
+
+  SignInParams._() : super();
+  factory SignInParams({
+    $core.String? email,
+    $core.String? password,
+    $core.String? name,
+  }) {
+    final _result = create();
+    if (email != null) {
+      _result.email = email;
+    }
+    if (password != null) {
+      _result.password = password;
+    }
+    if (name != null) {
+      _result.name = name;
+    }
+    return _result;
+  }
+  factory SignInParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory SignInParams.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  SignInParams clone() => SignInParams()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  SignInParams copyWith(void Function(SignInParams) updates) => super.copyWith((message) => updates(message as SignInParams)) as SignInParams; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static SignInParams create() => SignInParams._();
+  SignInParams createEmptyInstance() => create();
+  static $pb.PbList<SignInParams> createRepeated() => $pb.PbList<SignInParams>();
+  @$core.pragma('dart2js:noInline')
+  static SignInParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<SignInParams>(create);
+  static SignInParams? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.String get email => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set email($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasEmail() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearEmail() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get password => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set password($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasPassword() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearPassword() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.String get name => $_getSZ(2);
+  @$pb.TagNumber(3)
+  set name($core.String v) { $_setString(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasName() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearName() => clearField(3);
+}
+
+class SignInResponse extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SignInResponse', createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'userId')
+    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
+    ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'email')
+    ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'token')
+    ..hasRequiredFields = false
+  ;
+
+  SignInResponse._() : super();
+  factory SignInResponse({
+    $core.String? userId,
+    $core.String? name,
+    $core.String? email,
+    $core.String? token,
+  }) {
+    final _result = create();
+    if (userId != null) {
+      _result.userId = userId;
+    }
+    if (name != null) {
+      _result.name = name;
+    }
+    if (email != null) {
+      _result.email = email;
+    }
+    if (token != null) {
+      _result.token = token;
+    }
+    return _result;
+  }
+  factory SignInResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory SignInResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  SignInResponse clone() => SignInResponse()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  SignInResponse copyWith(void Function(SignInResponse) updates) => super.copyWith((message) => updates(message as SignInResponse)) as SignInResponse; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static SignInResponse create() => SignInResponse._();
+  SignInResponse createEmptyInstance() => create();
+  static $pb.PbList<SignInResponse> createRepeated() => $pb.PbList<SignInResponse>();
+  @$core.pragma('dart2js:noInline')
+  static SignInResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<SignInResponse>(create);
+  static SignInResponse? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.String get userId => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set userId($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasUserId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearUserId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get name => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set name($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasName() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearName() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.String get email => $_getSZ(2);
+  @$pb.TagNumber(3)
+  set email($core.String v) { $_setString(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasEmail() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearEmail() => clearField(3);
+
+  @$pb.TagNumber(4)
+  $core.String get token => $_getSZ(3);
+  @$pb.TagNumber(4)
+  set token($core.String v) { $_setString(3, v); }
+  @$pb.TagNumber(4)
+  $core.bool hasToken() => $_has(3);
+  @$pb.TagNumber(4)
+  void clearToken() => clearField(4);
+}
+
+class SignUpRequest extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SignUpRequest', createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'email')
+    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
+    ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'password')
+    ..hasRequiredFields = false
+  ;
+
+  SignUpRequest._() : super();
+  factory SignUpRequest({
+    $core.String? email,
+    $core.String? name,
+    $core.String? password,
+  }) {
+    final _result = create();
+    if (email != null) {
+      _result.email = email;
+    }
+    if (name != null) {
+      _result.name = name;
+    }
+    if (password != null) {
+      _result.password = password;
+    }
+    return _result;
+  }
+  factory SignUpRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory SignUpRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  SignUpRequest clone() => SignUpRequest()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  SignUpRequest copyWith(void Function(SignUpRequest) updates) => super.copyWith((message) => updates(message as SignUpRequest)) as SignUpRequest; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static SignUpRequest create() => SignUpRequest._();
+  SignUpRequest createEmptyInstance() => create();
+  static $pb.PbList<SignUpRequest> createRepeated() => $pb.PbList<SignUpRequest>();
+  @$core.pragma('dart2js:noInline')
+  static SignUpRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<SignUpRequest>(create);
+  static SignUpRequest? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.String get email => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set email($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasEmail() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearEmail() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get name => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set name($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasName() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearName() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.String get password => $_getSZ(2);
+  @$pb.TagNumber(3)
+  set password($core.String v) { $_setString(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasPassword() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearPassword() => clearField(3);
+}
+
+class SignUpParams extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SignUpParams', createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'email')
+    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
+    ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'password')
+    ..hasRequiredFields = false
+  ;
+
+  SignUpParams._() : super();
+  factory SignUpParams({
+    $core.String? email,
+    $core.String? name,
+    $core.String? password,
+  }) {
+    final _result = create();
+    if (email != null) {
+      _result.email = email;
+    }
+    if (name != null) {
+      _result.name = name;
+    }
+    if (password != null) {
+      _result.password = password;
+    }
+    return _result;
+  }
+  factory SignUpParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory SignUpParams.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  SignUpParams clone() => SignUpParams()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  SignUpParams copyWith(void Function(SignUpParams) updates) => super.copyWith((message) => updates(message as SignUpParams)) as SignUpParams; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static SignUpParams create() => SignUpParams._();
+  SignUpParams createEmptyInstance() => create();
+  static $pb.PbList<SignUpParams> createRepeated() => $pb.PbList<SignUpParams>();
+  @$core.pragma('dart2js:noInline')
+  static SignUpParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<SignUpParams>(create);
+  static SignUpParams? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.String get email => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set email($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasEmail() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearEmail() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get name => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set name($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasName() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearName() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.String get password => $_getSZ(2);
+  @$pb.TagNumber(3)
+  set password($core.String v) { $_setString(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasPassword() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearPassword() => clearField(3);
+}
+
+class SignUpResponse extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SignUpResponse', createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'userId')
+    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
+    ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'email')
+    ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'token')
+    ..hasRequiredFields = false
+  ;
+
+  SignUpResponse._() : super();
+  factory SignUpResponse({
+    $core.String? userId,
+    $core.String? name,
+    $core.String? email,
+    $core.String? token,
+  }) {
+    final _result = create();
+    if (userId != null) {
+      _result.userId = userId;
+    }
+    if (name != null) {
+      _result.name = name;
+    }
+    if (email != null) {
+      _result.email = email;
+    }
+    if (token != null) {
+      _result.token = token;
+    }
+    return _result;
+  }
+  factory SignUpResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory SignUpResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  SignUpResponse clone() => SignUpResponse()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  SignUpResponse copyWith(void Function(SignUpResponse) updates) => super.copyWith((message) => updates(message as SignUpResponse)) as SignUpResponse; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static SignUpResponse create() => SignUpResponse._();
+  SignUpResponse createEmptyInstance() => create();
+  static $pb.PbList<SignUpResponse> createRepeated() => $pb.PbList<SignUpResponse>();
+  @$core.pragma('dart2js:noInline')
+  static SignUpResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<SignUpResponse>(create);
+  static SignUpResponse? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.String get userId => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set userId($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasUserId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearUserId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get name => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set name($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasName() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearName() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.String get email => $_getSZ(2);
+  @$pb.TagNumber(3)
+  set email($core.String v) { $_setString(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasEmail() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearEmail() => clearField(3);
+
+  @$pb.TagNumber(4)
+  $core.String get token => $_getSZ(3);
+  @$pb.TagNumber(4)
+  set token($core.String v) { $_setString(3, v); }
+  @$pb.TagNumber(4)
+  $core.bool hasToken() => $_has(3);
+  @$pb.TagNumber(4)
+  void clearToken() => clearField(4);
+}
+

+ 7 - 0
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/auth.pbenum.dart

@@ -0,0 +1,7 @@
+///
+//  Generated code. Do not modify.
+//  source: auth.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
+

+ 84 - 0
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/auth.pbjson.dart

@@ -0,0 +1,84 @@
+///
+//  Generated code. Do not modify.
+//  source: auth.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
+
+import 'dart:core' as $core;
+import 'dart:convert' as $convert;
+import 'dart:typed_data' as $typed_data;
+@$core.Deprecated('Use signInRequestDescriptor instead')
+const SignInRequest$json = const {
+  '1': 'SignInRequest',
+  '2': const [
+    const {'1': 'email', '3': 1, '4': 1, '5': 9, '10': 'email'},
+    const {'1': 'password', '3': 2, '4': 1, '5': 9, '10': 'password'},
+    const {'1': 'name', '3': 3, '4': 1, '5': 9, '10': 'name'},
+  ],
+};
+
+/// Descriptor for `SignInRequest`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List signInRequestDescriptor = $convert.base64Decode('Cg1TaWduSW5SZXF1ZXN0EhQKBWVtYWlsGAEgASgJUgVlbWFpbBIaCghwYXNzd29yZBgCIAEoCVIIcGFzc3dvcmQSEgoEbmFtZRgDIAEoCVIEbmFtZQ==');
+@$core.Deprecated('Use signInParamsDescriptor instead')
+const SignInParams$json = const {
+  '1': 'SignInParams',
+  '2': const [
+    const {'1': 'email', '3': 1, '4': 1, '5': 9, '10': 'email'},
+    const {'1': 'password', '3': 2, '4': 1, '5': 9, '10': 'password'},
+    const {'1': 'name', '3': 3, '4': 1, '5': 9, '10': 'name'},
+  ],
+};
+
+/// Descriptor for `SignInParams`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List signInParamsDescriptor = $convert.base64Decode('CgxTaWduSW5QYXJhbXMSFAoFZW1haWwYASABKAlSBWVtYWlsEhoKCHBhc3N3b3JkGAIgASgJUghwYXNzd29yZBISCgRuYW1lGAMgASgJUgRuYW1l');
+@$core.Deprecated('Use signInResponseDescriptor instead')
+const SignInResponse$json = const {
+  '1': 'SignInResponse',
+  '2': const [
+    const {'1': 'user_id', '3': 1, '4': 1, '5': 9, '10': 'userId'},
+    const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'},
+    const {'1': 'email', '3': 3, '4': 1, '5': 9, '10': 'email'},
+    const {'1': 'token', '3': 4, '4': 1, '5': 9, '10': 'token'},
+  ],
+};
+
+/// Descriptor for `SignInResponse`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List signInResponseDescriptor = $convert.base64Decode('Cg5TaWduSW5SZXNwb25zZRIXCgd1c2VyX2lkGAEgASgJUgZ1c2VySWQSEgoEbmFtZRgCIAEoCVIEbmFtZRIUCgVlbWFpbBgDIAEoCVIFZW1haWwSFAoFdG9rZW4YBCABKAlSBXRva2Vu');
+@$core.Deprecated('Use signUpRequestDescriptor instead')
+const SignUpRequest$json = const {
+  '1': 'SignUpRequest',
+  '2': const [
+    const {'1': 'email', '3': 1, '4': 1, '5': 9, '10': 'email'},
+    const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'},
+    const {'1': 'password', '3': 3, '4': 1, '5': 9, '10': 'password'},
+  ],
+};
+
+/// Descriptor for `SignUpRequest`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List signUpRequestDescriptor = $convert.base64Decode('Cg1TaWduVXBSZXF1ZXN0EhQKBWVtYWlsGAEgASgJUgVlbWFpbBISCgRuYW1lGAIgASgJUgRuYW1lEhoKCHBhc3N3b3JkGAMgASgJUghwYXNzd29yZA==');
+@$core.Deprecated('Use signUpParamsDescriptor instead')
+const SignUpParams$json = const {
+  '1': 'SignUpParams',
+  '2': const [
+    const {'1': 'email', '3': 1, '4': 1, '5': 9, '10': 'email'},
+    const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'},
+    const {'1': 'password', '3': 3, '4': 1, '5': 9, '10': 'password'},
+  ],
+};
+
+/// Descriptor for `SignUpParams`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List signUpParamsDescriptor = $convert.base64Decode('CgxTaWduVXBQYXJhbXMSFAoFZW1haWwYASABKAlSBWVtYWlsEhIKBG5hbWUYAiABKAlSBG5hbWUSGgoIcGFzc3dvcmQYAyABKAlSCHBhc3N3b3Jk');
+@$core.Deprecated('Use signUpResponseDescriptor instead')
+const SignUpResponse$json = const {
+  '1': 'SignUpResponse',
+  '2': const [
+    const {'1': 'user_id', '3': 1, '4': 1, '5': 9, '10': 'userId'},
+    const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'},
+    const {'1': 'email', '3': 3, '4': 1, '5': 9, '10': 'email'},
+    const {'1': 'token', '3': 4, '4': 1, '5': 9, '10': 'token'},
+  ],
+};
+
+/// Descriptor for `SignUpResponse`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List signUpResponseDescriptor = $convert.base64Decode('Cg5TaWduVXBSZXNwb25zZRIXCgd1c2VyX2lkGAEgASgJUgZ1c2VySWQSEgoEbmFtZRgCIAEoCVIEbmFtZRIUCgVlbWFpbBgDIAEoCVIFZW1haWwSFAoFdG9rZW4YBCABKAlSBXRva2Vu');

+ 9 - 0
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/auth.pbserver.dart

@@ -0,0 +1,9 @@
+///
+//  Generated code. Do not modify.
+//  source: auth.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
+
+export 'auth.pb.dart';
+

+ 11 - 0
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/errors.pb.dart

@@ -0,0 +1,11 @@
+///
+//  Generated code. Do not modify.
+//  source: errors.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
+
+import 'dart:core' as $core;
+
+export 'errors.pbenum.dart';
+

+ 54 - 0
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/errors.pbenum.dart

@@ -0,0 +1,54 @@
+///
+//  Generated code. Do not modify.
+//  source: errors.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
+
+// ignore_for_file: UNDEFINED_SHOWN_NAME
+import 'dart:core' as $core;
+import 'package:protobuf/protobuf.dart' as $pb;
+
+class ErrorCode extends $pb.ProtobufEnum {
+  static const ErrorCode EmailIsEmpty = ErrorCode._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EmailIsEmpty');
+  static const ErrorCode EmailFormatInvalid = ErrorCode._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EmailFormatInvalid');
+  static const ErrorCode EmailAlreadyExists = ErrorCode._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EmailAlreadyExists');
+  static const ErrorCode PasswordIsEmpty = ErrorCode._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PasswordIsEmpty');
+  static const ErrorCode PasswordTooLong = ErrorCode._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PasswordTooLong');
+  static const ErrorCode PasswordContainsForbidCharacters = ErrorCode._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PasswordContainsForbidCharacters');
+  static const ErrorCode PasswordFormatInvalid = ErrorCode._(13, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PasswordFormatInvalid');
+  static const ErrorCode PasswordNotMatch = ErrorCode._(14, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PasswordNotMatch');
+  static const ErrorCode UserNameTooLong = ErrorCode._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNameTooLong');
+  static const ErrorCode UserNameContainForbiddenCharacters = ErrorCode._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNameContainForbiddenCharacters');
+  static const ErrorCode UserNameIsEmpty = ErrorCode._(22, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNameIsEmpty');
+  static const ErrorCode UserIdInvalid = ErrorCode._(23, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserIdInvalid');
+  static const ErrorCode UserUnauthorized = ErrorCode._(24, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserUnauthorized');
+  static const ErrorCode UserNotExist = ErrorCode._(25, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNotExist');
+  static const ErrorCode ServerError = ErrorCode._(99, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ServerError');
+  static const ErrorCode InternalError = ErrorCode._(100, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InternalError');
+
+  static const $core.List<ErrorCode> values = <ErrorCode> [
+    EmailIsEmpty,
+    EmailFormatInvalid,
+    EmailAlreadyExists,
+    PasswordIsEmpty,
+    PasswordTooLong,
+    PasswordContainsForbidCharacters,
+    PasswordFormatInvalid,
+    PasswordNotMatch,
+    UserNameTooLong,
+    UserNameContainForbiddenCharacters,
+    UserNameIsEmpty,
+    UserIdInvalid,
+    UserUnauthorized,
+    UserNotExist,
+    ServerError,
+    InternalError,
+  ];
+
+  static final $core.Map<$core.int, ErrorCode> _byValue = $pb.ProtobufEnum.initByValue(values);
+  static ErrorCode? valueOf($core.int value) => _byValue[value];
+
+  const ErrorCode._($core.int v, $core.String n) : super(v, n);
+}
+

+ 35 - 0
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/errors.pbjson.dart

@@ -0,0 +1,35 @@
+///
+//  Generated code. Do not modify.
+//  source: errors.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
+
+import 'dart:core' as $core;
+import 'dart:convert' as $convert;
+import 'dart:typed_data' as $typed_data;
+@$core.Deprecated('Use errorCodeDescriptor instead')
+const ErrorCode$json = const {
+  '1': 'ErrorCode',
+  '2': const [
+    const {'1': 'EmailIsEmpty', '2': 0},
+    const {'1': 'EmailFormatInvalid', '2': 1},
+    const {'1': 'EmailAlreadyExists', '2': 2},
+    const {'1': 'PasswordIsEmpty', '2': 10},
+    const {'1': 'PasswordTooLong', '2': 11},
+    const {'1': 'PasswordContainsForbidCharacters', '2': 12},
+    const {'1': 'PasswordFormatInvalid', '2': 13},
+    const {'1': 'PasswordNotMatch', '2': 14},
+    const {'1': 'UserNameTooLong', '2': 20},
+    const {'1': 'UserNameContainForbiddenCharacters', '2': 21},
+    const {'1': 'UserNameIsEmpty', '2': 22},
+    const {'1': 'UserIdInvalid', '2': 23},
+    const {'1': 'UserUnauthorized', '2': 24},
+    const {'1': 'UserNotExist', '2': 25},
+    const {'1': 'ServerError', '2': 99},
+    const {'1': 'InternalError', '2': 100},
+  ],
+};
+
+/// Descriptor for `ErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`.
+final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSEAoMRW1haWxJc0VtcHR5EAASFgoSRW1haWxGb3JtYXRJbnZhbGlkEAESFgoSRW1haWxBbHJlYWR5RXhpc3RzEAISEwoPUGFzc3dvcmRJc0VtcHR5EAoSEwoPUGFzc3dvcmRUb29Mb25nEAsSJAogUGFzc3dvcmRDb250YWluc0ZvcmJpZENoYXJhY3RlcnMQDBIZChVQYXNzd29yZEZvcm1hdEludmFsaWQQDRIUChBQYXNzd29yZE5vdE1hdGNoEA4SEwoPVXNlck5hbWVUb29Mb25nEBQSJgoiVXNlck5hbWVDb250YWluRm9yYmlkZGVuQ2hhcmFjdGVycxAVEhMKD1VzZXJOYW1lSXNFbXB0eRAWEhEKDVVzZXJJZEludmFsaWQQFxIUChBVc2VyVW5hdXRob3JpemVkEBgSEAoMVXNlck5vdEV4aXN0EBkSDwoLU2VydmVyRXJyb3IQYxIRCg1JbnRlcm5hbEVycm9yEGQ=');

+ 9 - 0
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/errors.pbserver.dart

@@ -0,0 +1,9 @@
+///
+//  Generated code. Do not modify.
+//  source: errors.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
+
+export 'errors.pb.dart';
+

+ 4 - 0
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/protobuf.dart

@@ -0,0 +1,4 @@
+// Auto-generated, do not edit 
+export './errors.pb.dart';
+export './user_profile.pb.dart';
+export './auth.pb.dart';

+ 403 - 0
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/user_profile.pb.dart

@@ -0,0 +1,403 @@
+///
+//  Generated code. Do not modify.
+//  source: user_profile.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
+
+import 'dart:core' as $core;
+
+import 'package:protobuf/protobuf.dart' as $pb;
+
+class UserToken extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'UserToken', createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'token')
+    ..hasRequiredFields = false
+  ;
+
+  UserToken._() : super();
+  factory UserToken({
+    $core.String? token,
+  }) {
+    final _result = create();
+    if (token != null) {
+      _result.token = token;
+    }
+    return _result;
+  }
+  factory UserToken.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory UserToken.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  UserToken clone() => UserToken()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  UserToken copyWith(void Function(UserToken) updates) => super.copyWith((message) => updates(message as UserToken)) as UserToken; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static UserToken create() => UserToken._();
+  UserToken createEmptyInstance() => create();
+  static $pb.PbList<UserToken> createRepeated() => $pb.PbList<UserToken>();
+  @$core.pragma('dart2js:noInline')
+  static UserToken getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<UserToken>(create);
+  static UserToken? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.String get token => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set token($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasToken() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearToken() => clearField(1);
+}
+
+class UserProfile extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'UserProfile', createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
+    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'email')
+    ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
+    ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'token')
+    ..hasRequiredFields = false
+  ;
+
+  UserProfile._() : super();
+  factory UserProfile({
+    $core.String? id,
+    $core.String? email,
+    $core.String? name,
+    $core.String? token,
+  }) {
+    final _result = create();
+    if (id != null) {
+      _result.id = id;
+    }
+    if (email != null) {
+      _result.email = email;
+    }
+    if (name != null) {
+      _result.name = name;
+    }
+    if (token != null) {
+      _result.token = token;
+    }
+    return _result;
+  }
+  factory UserProfile.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory UserProfile.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  UserProfile clone() => UserProfile()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  UserProfile copyWith(void Function(UserProfile) updates) => super.copyWith((message) => updates(message as UserProfile)) as UserProfile; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static UserProfile create() => UserProfile._();
+  UserProfile createEmptyInstance() => create();
+  static $pb.PbList<UserProfile> createRepeated() => $pb.PbList<UserProfile>();
+  @$core.pragma('dart2js:noInline')
+  static UserProfile getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<UserProfile>(create);
+  static UserProfile? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.String get id => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set id($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get email => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set email($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasEmail() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearEmail() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.String get name => $_getSZ(2);
+  @$pb.TagNumber(3)
+  set name($core.String v) { $_setString(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasName() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearName() => clearField(3);
+
+  @$pb.TagNumber(4)
+  $core.String get token => $_getSZ(3);
+  @$pb.TagNumber(4)
+  set token($core.String v) { $_setString(3, v); }
+  @$pb.TagNumber(4)
+  $core.bool hasToken() => $_has(3);
+  @$pb.TagNumber(4)
+  void clearToken() => clearField(4);
+}
+
+enum UpdateUserRequest_OneOfName {
+  name, 
+  notSet
+}
+
+enum UpdateUserRequest_OneOfEmail {
+  email, 
+  notSet
+}
+
+enum UpdateUserRequest_OneOfPassword {
+  password, 
+  notSet
+}
+
+class UpdateUserRequest extends $pb.GeneratedMessage {
+  static const $core.Map<$core.int, UpdateUserRequest_OneOfName> _UpdateUserRequest_OneOfNameByTag = {
+    2 : UpdateUserRequest_OneOfName.name,
+    0 : UpdateUserRequest_OneOfName.notSet
+  };
+  static const $core.Map<$core.int, UpdateUserRequest_OneOfEmail> _UpdateUserRequest_OneOfEmailByTag = {
+    3 : UpdateUserRequest_OneOfEmail.email,
+    0 : UpdateUserRequest_OneOfEmail.notSet
+  };
+  static const $core.Map<$core.int, UpdateUserRequest_OneOfPassword> _UpdateUserRequest_OneOfPasswordByTag = {
+    4 : UpdateUserRequest_OneOfPassword.password,
+    0 : UpdateUserRequest_OneOfPassword.notSet
+  };
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'UpdateUserRequest', createEmptyInstance: create)
+    ..oo(0, [2])
+    ..oo(1, [3])
+    ..oo(2, [4])
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
+    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
+    ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'email')
+    ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'password')
+    ..hasRequiredFields = false
+  ;
+
+  UpdateUserRequest._() : super();
+  factory UpdateUserRequest({
+    $core.String? id,
+    $core.String? name,
+    $core.String? email,
+    $core.String? password,
+  }) {
+    final _result = create();
+    if (id != null) {
+      _result.id = id;
+    }
+    if (name != null) {
+      _result.name = name;
+    }
+    if (email != null) {
+      _result.email = email;
+    }
+    if (password != null) {
+      _result.password = password;
+    }
+    return _result;
+  }
+  factory UpdateUserRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory UpdateUserRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  UpdateUserRequest clone() => UpdateUserRequest()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  UpdateUserRequest copyWith(void Function(UpdateUserRequest) updates) => super.copyWith((message) => updates(message as UpdateUserRequest)) as UpdateUserRequest; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static UpdateUserRequest create() => UpdateUserRequest._();
+  UpdateUserRequest createEmptyInstance() => create();
+  static $pb.PbList<UpdateUserRequest> createRepeated() => $pb.PbList<UpdateUserRequest>();
+  @$core.pragma('dart2js:noInline')
+  static UpdateUserRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<UpdateUserRequest>(create);
+  static UpdateUserRequest? _defaultInstance;
+
+  UpdateUserRequest_OneOfName whichOneOfName() => _UpdateUserRequest_OneOfNameByTag[$_whichOneof(0)]!;
+  void clearOneOfName() => clearField($_whichOneof(0));
+
+  UpdateUserRequest_OneOfEmail whichOneOfEmail() => _UpdateUserRequest_OneOfEmailByTag[$_whichOneof(1)]!;
+  void clearOneOfEmail() => clearField($_whichOneof(1));
+
+  UpdateUserRequest_OneOfPassword whichOneOfPassword() => _UpdateUserRequest_OneOfPasswordByTag[$_whichOneof(2)]!;
+  void clearOneOfPassword() => clearField($_whichOneof(2));
+
+  @$pb.TagNumber(1)
+  $core.String get id => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set id($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get name => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set name($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasName() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearName() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.String get email => $_getSZ(2);
+  @$pb.TagNumber(3)
+  set email($core.String v) { $_setString(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasEmail() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearEmail() => clearField(3);
+
+  @$pb.TagNumber(4)
+  $core.String get password => $_getSZ(3);
+  @$pb.TagNumber(4)
+  set password($core.String v) { $_setString(3, v); }
+  @$pb.TagNumber(4)
+  $core.bool hasPassword() => $_has(3);
+  @$pb.TagNumber(4)
+  void clearPassword() => clearField(4);
+}
+
+enum UpdateUserParams_OneOfName {
+  name, 
+  notSet
+}
+
+enum UpdateUserParams_OneOfEmail {
+  email, 
+  notSet
+}
+
+enum UpdateUserParams_OneOfPassword {
+  password, 
+  notSet
+}
+
+class UpdateUserParams extends $pb.GeneratedMessage {
+  static const $core.Map<$core.int, UpdateUserParams_OneOfName> _UpdateUserParams_OneOfNameByTag = {
+    2 : UpdateUserParams_OneOfName.name,
+    0 : UpdateUserParams_OneOfName.notSet
+  };
+  static const $core.Map<$core.int, UpdateUserParams_OneOfEmail> _UpdateUserParams_OneOfEmailByTag = {
+    3 : UpdateUserParams_OneOfEmail.email,
+    0 : UpdateUserParams_OneOfEmail.notSet
+  };
+  static const $core.Map<$core.int, UpdateUserParams_OneOfPassword> _UpdateUserParams_OneOfPasswordByTag = {
+    4 : UpdateUserParams_OneOfPassword.password,
+    0 : UpdateUserParams_OneOfPassword.notSet
+  };
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'UpdateUserParams', createEmptyInstance: create)
+    ..oo(0, [2])
+    ..oo(1, [3])
+    ..oo(2, [4])
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
+    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
+    ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'email')
+    ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'password')
+    ..hasRequiredFields = false
+  ;
+
+  UpdateUserParams._() : super();
+  factory UpdateUserParams({
+    $core.String? id,
+    $core.String? name,
+    $core.String? email,
+    $core.String? password,
+  }) {
+    final _result = create();
+    if (id != null) {
+      _result.id = id;
+    }
+    if (name != null) {
+      _result.name = name;
+    }
+    if (email != null) {
+      _result.email = email;
+    }
+    if (password != null) {
+      _result.password = password;
+    }
+    return _result;
+  }
+  factory UpdateUserParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory UpdateUserParams.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  UpdateUserParams clone() => UpdateUserParams()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  UpdateUserParams copyWith(void Function(UpdateUserParams) updates) => super.copyWith((message) => updates(message as UpdateUserParams)) as UpdateUserParams; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static UpdateUserParams create() => UpdateUserParams._();
+  UpdateUserParams createEmptyInstance() => create();
+  static $pb.PbList<UpdateUserParams> createRepeated() => $pb.PbList<UpdateUserParams>();
+  @$core.pragma('dart2js:noInline')
+  static UpdateUserParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<UpdateUserParams>(create);
+  static UpdateUserParams? _defaultInstance;
+
+  UpdateUserParams_OneOfName whichOneOfName() => _UpdateUserParams_OneOfNameByTag[$_whichOneof(0)]!;
+  void clearOneOfName() => clearField($_whichOneof(0));
+
+  UpdateUserParams_OneOfEmail whichOneOfEmail() => _UpdateUserParams_OneOfEmailByTag[$_whichOneof(1)]!;
+  void clearOneOfEmail() => clearField($_whichOneof(1));
+
+  UpdateUserParams_OneOfPassword whichOneOfPassword() => _UpdateUserParams_OneOfPasswordByTag[$_whichOneof(2)]!;
+  void clearOneOfPassword() => clearField($_whichOneof(2));
+
+  @$pb.TagNumber(1)
+  $core.String get id => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set id($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get name => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set name($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasName() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearName() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.String get email => $_getSZ(2);
+  @$pb.TagNumber(3)
+  set email($core.String v) { $_setString(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasEmail() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearEmail() => clearField(3);
+
+  @$pb.TagNumber(4)
+  $core.String get password => $_getSZ(3);
+  @$pb.TagNumber(4)
+  set password($core.String v) { $_setString(3, v); }
+  @$pb.TagNumber(4)
+  $core.bool hasPassword() => $_has(3);
+  @$pb.TagNumber(4)
+  void clearPassword() => clearField(4);
+}
+

+ 7 - 0
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/user_profile.pbenum.dart

@@ -0,0 +1,7 @@
+///
+//  Generated code. Do not modify.
+//  source: user_profile.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
+

+ 69 - 0
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/user_profile.pbjson.dart

@@ -0,0 +1,69 @@
+///
+//  Generated code. Do not modify.
+//  source: user_profile.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
+
+import 'dart:core' as $core;
+import 'dart:convert' as $convert;
+import 'dart:typed_data' as $typed_data;
+@$core.Deprecated('Use userTokenDescriptor instead')
+const UserToken$json = const {
+  '1': 'UserToken',
+  '2': const [
+    const {'1': 'token', '3': 1, '4': 1, '5': 9, '10': 'token'},
+  ],
+};
+
+/// Descriptor for `UserToken`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List userTokenDescriptor = $convert.base64Decode('CglVc2VyVG9rZW4SFAoFdG9rZW4YASABKAlSBXRva2Vu');
+@$core.Deprecated('Use userProfileDescriptor instead')
+const UserProfile$json = const {
+  '1': 'UserProfile',
+  '2': const [
+    const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
+    const {'1': 'email', '3': 2, '4': 1, '5': 9, '10': 'email'},
+    const {'1': 'name', '3': 3, '4': 1, '5': 9, '10': 'name'},
+    const {'1': 'token', '3': 4, '4': 1, '5': 9, '10': 'token'},
+  ],
+};
+
+/// Descriptor for `UserProfile`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List userProfileDescriptor = $convert.base64Decode('CgtVc2VyUHJvZmlsZRIOCgJpZBgBIAEoCVICaWQSFAoFZW1haWwYAiABKAlSBWVtYWlsEhIKBG5hbWUYAyABKAlSBG5hbWUSFAoFdG9rZW4YBCABKAlSBXRva2Vu');
+@$core.Deprecated('Use updateUserRequestDescriptor instead')
+const UpdateUserRequest$json = const {
+  '1': 'UpdateUserRequest',
+  '2': const [
+    const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
+    const {'1': 'name', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'name'},
+    const {'1': 'email', '3': 3, '4': 1, '5': 9, '9': 1, '10': 'email'},
+    const {'1': 'password', '3': 4, '4': 1, '5': 9, '9': 2, '10': 'password'},
+  ],
+  '8': const [
+    const {'1': 'one_of_name'},
+    const {'1': 'one_of_email'},
+    const {'1': 'one_of_password'},
+  ],
+};
+
+/// Descriptor for `UpdateUserRequest`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List updateUserRequestDescriptor = $convert.base64Decode('ChFVcGRhdGVVc2VyUmVxdWVzdBIOCgJpZBgBIAEoCVICaWQSFAoEbmFtZRgCIAEoCUgAUgRuYW1lEhYKBWVtYWlsGAMgASgJSAFSBWVtYWlsEhwKCHBhc3N3b3JkGAQgASgJSAJSCHBhc3N3b3JkQg0KC29uZV9vZl9uYW1lQg4KDG9uZV9vZl9lbWFpbEIRCg9vbmVfb2ZfcGFzc3dvcmQ=');
+@$core.Deprecated('Use updateUserParamsDescriptor instead')
+const UpdateUserParams$json = const {
+  '1': 'UpdateUserParams',
+  '2': const [
+    const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
+    const {'1': 'name', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'name'},
+    const {'1': 'email', '3': 3, '4': 1, '5': 9, '9': 1, '10': 'email'},
+    const {'1': 'password', '3': 4, '4': 1, '5': 9, '9': 2, '10': 'password'},
+  ],
+  '8': const [
+    const {'1': 'one_of_name'},
+    const {'1': 'one_of_email'},
+    const {'1': 'one_of_password'},
+  ],
+};
+
+/// Descriptor for `UpdateUserParams`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List updateUserParamsDescriptor = $convert.base64Decode('ChBVcGRhdGVVc2VyUGFyYW1zEg4KAmlkGAEgASgJUgJpZBIUCgRuYW1lGAIgASgJSABSBG5hbWUSFgoFZW1haWwYAyABKAlIAVIFZW1haWwSHAoIcGFzc3dvcmQYBCABKAlIAlIIcGFzc3dvcmRCDQoLb25lX29mX25hbWVCDgoMb25lX29mX2VtYWlsQhEKD29uZV9vZl9wYXNzd29yZA==');

+ 9 - 0
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user-infra/user_profile.pbserver.dart

@@ -0,0 +1,9 @@
+///
+//  Generated code. Do not modify.
+//  source: user_profile.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
+
+export 'user_profile.pb.dart';
+

+ 4 - 8
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/errors.pb.dart

@@ -9,20 +9,16 @@ import 'dart:core' as $core;
 
 import 'package:protobuf/protobuf.dart' as $pb;
 
-import 'errors.pbenum.dart';
-
-export 'errors.pbenum.dart';
-
 class UserError extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'UserError', createEmptyInstance: create)
-    ..e<ErrorCode>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'code', $pb.PbFieldType.OE, defaultOrMaker: ErrorCode.EmailIsEmpty, valueOf: ErrorCode.valueOf, enumValues: ErrorCode.values)
+    ..a<$core.int>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'code', $pb.PbFieldType.O3)
     ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'msg')
     ..hasRequiredFields = false
   ;
 
   UserError._() : super();
   factory UserError({
-    ErrorCode? code,
+    $core.int? code,
     $core.String? msg,
   }) {
     final _result = create();
@@ -56,9 +52,9 @@ class UserError extends $pb.GeneratedMessage {
   static UserError? _defaultInstance;
 
   @$pb.TagNumber(1)
-  ErrorCode get code => $_getN(0);
+  $core.int get code => $_getIZ(0);
   @$pb.TagNumber(1)
-  set code(ErrorCode v) { setField(1, v); }
+  set code($core.int v) { $_setSignedInt32(0, v); }
   @$pb.TagNumber(1)
   $core.bool hasCode() => $_has(0);
   @$pb.TagNumber(1)

+ 0 - 47
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/errors.pbenum.dart

@@ -5,50 +5,3 @@
 // @dart = 2.12
 // ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
 
-// ignore_for_file: UNDEFINED_SHOWN_NAME
-import 'dart:core' as $core;
-import 'package:protobuf/protobuf.dart' as $pb;
-
-class ErrorCode extends $pb.ProtobufEnum {
-  static const ErrorCode EmailIsEmpty = ErrorCode._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EmailIsEmpty');
-  static const ErrorCode EmailFormatInvalid = ErrorCode._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EmailFormatInvalid');
-  static const ErrorCode EmailAlreadyExists = ErrorCode._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EmailAlreadyExists');
-  static const ErrorCode PasswordIsEmpty = ErrorCode._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PasswordIsEmpty');
-  static const ErrorCode PasswordTooLong = ErrorCode._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PasswordTooLong');
-  static const ErrorCode PasswordContainsForbidCharacters = ErrorCode._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PasswordContainsForbidCharacters');
-  static const ErrorCode PasswordFormatInvalid = ErrorCode._(13, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PasswordFormatInvalid');
-  static const ErrorCode PasswordNotMatch = ErrorCode._(14, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PasswordNotMatch');
-  static const ErrorCode UserNameTooLong = ErrorCode._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNameTooLong');
-  static const ErrorCode UserNameContainForbiddenCharacters = ErrorCode._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNameContainForbiddenCharacters');
-  static const ErrorCode UserNameIsEmpty = ErrorCode._(22, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNameIsEmpty');
-  static const ErrorCode UserIdInvalid = ErrorCode._(23, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserIdInvalid');
-  static const ErrorCode UserUnauthorized = ErrorCode._(24, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserUnauthorized');
-  static const ErrorCode UserNotExist = ErrorCode._(25, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNotExist');
-  static const ErrorCode ServerOffline = ErrorCode._(26, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ServerOffline');
-  static const ErrorCode InternalError = ErrorCode._(100, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InternalError');
-
-  static const $core.List<ErrorCode> values = <ErrorCode> [
-    EmailIsEmpty,
-    EmailFormatInvalid,
-    EmailAlreadyExists,
-    PasswordIsEmpty,
-    PasswordTooLong,
-    PasswordContainsForbidCharacters,
-    PasswordFormatInvalid,
-    PasswordNotMatch,
-    UserNameTooLong,
-    UserNameContainForbiddenCharacters,
-    UserNameIsEmpty,
-    UserIdInvalid,
-    UserUnauthorized,
-    UserNotExist,
-    ServerOffline,
-    InternalError,
-  ];
-
-  static final $core.Map<$core.int, ErrorCode> _byValue = $pb.ProtobufEnum.initByValue(values);
-  static ErrorCode? valueOf($core.int value) => _byValue[value];
-
-  const ErrorCode._($core.int v, $core.String n) : super(v, n);
-}
-

+ 2 - 27
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/errors.pbjson.dart

@@ -8,39 +8,14 @@
 import 'dart:core' as $core;
 import 'dart:convert' as $convert;
 import 'dart:typed_data' as $typed_data;
-@$core.Deprecated('Use errorCodeDescriptor instead')
-const ErrorCode$json = const {
-  '1': 'ErrorCode',
-  '2': const [
-    const {'1': 'EmailIsEmpty', '2': 0},
-    const {'1': 'EmailFormatInvalid', '2': 1},
-    const {'1': 'EmailAlreadyExists', '2': 2},
-    const {'1': 'PasswordIsEmpty', '2': 10},
-    const {'1': 'PasswordTooLong', '2': 11},
-    const {'1': 'PasswordContainsForbidCharacters', '2': 12},
-    const {'1': 'PasswordFormatInvalid', '2': 13},
-    const {'1': 'PasswordNotMatch', '2': 14},
-    const {'1': 'UserNameTooLong', '2': 20},
-    const {'1': 'UserNameContainForbiddenCharacters', '2': 21},
-    const {'1': 'UserNameIsEmpty', '2': 22},
-    const {'1': 'UserIdInvalid', '2': 23},
-    const {'1': 'UserUnauthorized', '2': 24},
-    const {'1': 'UserNotExist', '2': 25},
-    const {'1': 'ServerOffline', '2': 26},
-    const {'1': 'InternalError', '2': 100},
-  ],
-};
-
-/// Descriptor for `ErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`.
-final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSEAoMRW1haWxJc0VtcHR5EAASFgoSRW1haWxGb3JtYXRJbnZhbGlkEAESFgoSRW1haWxBbHJlYWR5RXhpc3RzEAISEwoPUGFzc3dvcmRJc0VtcHR5EAoSEwoPUGFzc3dvcmRUb29Mb25nEAsSJAogUGFzc3dvcmRDb250YWluc0ZvcmJpZENoYXJhY3RlcnMQDBIZChVQYXNzd29yZEZvcm1hdEludmFsaWQQDRIUChBQYXNzd29yZE5vdE1hdGNoEA4SEwoPVXNlck5hbWVUb29Mb25nEBQSJgoiVXNlck5hbWVDb250YWluRm9yYmlkZGVuQ2hhcmFjdGVycxAVEhMKD1VzZXJOYW1lSXNFbXB0eRAWEhEKDVVzZXJJZEludmFsaWQQFxIUChBVc2VyVW5hdXRob3JpemVkEBgSEAoMVXNlck5vdEV4aXN0EBkSEQoNU2VydmVyT2ZmbGluZRAaEhEKDUludGVybmFsRXJyb3IQZA==');
 @$core.Deprecated('Use userErrorDescriptor instead')
 const UserError$json = const {
   '1': 'UserError',
   '2': const [
-    const {'1': 'code', '3': 1, '4': 1, '5': 14, '6': '.ErrorCode', '10': 'code'},
+    const {'1': 'code', '3': 1, '4': 1, '5': 5, '10': 'code'},
     const {'1': 'msg', '3': 2, '4': 1, '5': 9, '10': 'msg'},
   ],
 };
 
 /// Descriptor for `UserError`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List userErrorDescriptor = $convert.base64Decode('CglVc2VyRXJyb3ISHgoEY29kZRgBIAEoDjIKLkVycm9yQ29kZVIEY29kZRIQCgNtc2cYAiABKAlSA21zZw==');
+final $typed_data.Uint8List userErrorDescriptor = $convert.base64Decode('CglVc2VyRXJyb3ISEgoEY29kZRgBIAEoBVIEY29kZRIQCgNtc2cYAiABKAlSA21zZw==');

+ 1 - 1
backend/Cargo.toml

@@ -60,7 +60,7 @@ pin-project = "1.0.0"
 byteorder = {version = "1.3.4"}
 async-stream = "0.3.2"
 
-flowy-user = { path = "../rust-lib/flowy-user" }
+flowy-user-infra = { path = "../rust-lib/flowy-user-infra" }
 flowy-workspace = { path = "../rust-lib/flowy-workspace", default-features = false, features = ["backend_service"]}
 flowy-document = { path = "../rust-lib/flowy-document" }
 flowy-ws = { path = "../rust-lib/flowy-ws" }

+ 1 - 1
backend/src/service/trash/router.rs

@@ -13,7 +13,7 @@ use flowy_net::{
     errors::{invalid_params, ServerError},
     response::FlowyResponse,
 };
-use flowy_workspace::{backend_service::TrashType, entities::trash::parser::TrashId, protobuf::TrashIdentifiers};
+use flowy_workspace::{entities::trash::parser::TrashId, protobuf::TrashIdentifiers};
 use sqlx::PgPool;
 use uuid::Uuid;
 

+ 2 - 2
backend/src/service/user/auth.rs

@@ -6,8 +6,8 @@ use flowy_net::{
     errors::{invalid_params, ErrorCode, ServerError},
     response::FlowyResponse,
 };
-use flowy_user::{
-    entities::parser::{UserEmail, UserName, UserPassword},
+use flowy_user_infra::{
+    parser::{UserEmail, UserName, UserPassword},
     protobuf::{SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserParams, UserProfile},
 };
 

+ 4 - 14
backend/src/service/user/router.rs

@@ -7,7 +7,7 @@ use actix_web::{
 use sqlx::PgPool;
 
 use flowy_net::{errors::ServerError, response::FlowyResponse};
-use flowy_user::protobuf::{SignInParams, SignUpParams, UpdateUserParams};
+use flowy_user_infra::protobuf::{SignInParams, SignUpParams, UpdateUserParams};
 
 use crate::{
     entities::token::Token,
@@ -17,11 +17,7 @@ use crate::{
     },
 };
 
-pub async fn sign_in_handler(
-    payload: Payload,
-    id: Identity,
-    pool: Data<PgPool>,
-) -> Result<HttpResponse, ServerError> {
+pub async fn sign_in_handler(payload: Payload, id: Identity, pool: Data<PgPool>) -> Result<HttpResponse, ServerError> {
     let params: SignInParams = parse_from_payload(payload).await?;
     let data = sign_in(pool.get_ref(), params).await?;
     id.remember(data.token.clone());
@@ -29,10 +25,7 @@ pub async fn sign_in_handler(
     Ok(response.into())
 }
 
-pub async fn sign_out_handler(
-    logged_user: LoggedUser,
-    id: Identity,
-) -> Result<HttpResponse, ServerError> {
+pub async fn sign_out_handler(logged_user: LoggedUser, id: Identity) -> Result<HttpResponse, ServerError> {
     id.forget();
 
     let response = sign_out(logged_user).await?;
@@ -58,10 +51,7 @@ pub async fn set_user_profile_handler(
     Ok(response.into())
 }
 
-pub async fn register_handler(
-    payload: Payload,
-    pool: Data<PgPool>,
-) -> Result<HttpResponse, ServerError> {
+pub async fn register_handler(payload: Payload, pool: Data<PgPool>) -> Result<HttpResponse, ServerError> {
     let params: SignUpParams = parse_from_payload(payload).await?;
     let resp = register_user(pool.get_ref(), params).await?;
 

+ 1 - 1
backend/tests/api/auth.rs

@@ -77,7 +77,7 @@ async fn user_update_password() {
     match server.sign_in(sign_in_params).await {
         Ok(_) => {},
         Err(e) => {
-            assert_eq!(e.code, flowy_user::errors::ErrorCode::PasswordNotMatch);
+            assert_eq!(e.code, flowy_user::errors::ErrorCode::PasswordNotMatch.value());
         },
     }
 }

+ 1 - 0
rust-lib/Cargo.toml

@@ -5,6 +5,7 @@ members = [
   "dart-ffi",
   "flowy-log",
   "flowy-user",
+  "flowy-user-infra",
   "flowy-ast",
   "flowy-derive",
   "flowy-test",

+ 10 - 10
rust-lib/flowy-derive/src/derive_cache/derive_cache.rs

@@ -52,6 +52,16 @@ pub fn category_from_str(type_str: &str) -> TypeCategory {
         | "WorkspaceError"
         | "WsError"
         | "WsMessage"
+        | "SignInRequest"
+        | "SignInParams"
+        | "SignInResponse"
+        | "SignUpRequest"
+        | "SignUpParams"
+        | "SignUpResponse"
+        | "UserToken"
+        | "UserProfile"
+        | "UpdateUserRequest"
+        | "UpdateUserParams"
         | "CreateDocParams"
         | "Doc"
         | "UpdateDocParams"
@@ -66,16 +76,6 @@ pub fn category_from_str(type_str: &str) -> TypeCategory {
         | "FFIRequest"
         | "FFIResponse"
         | "SubscribeObject"
-        | "SignInRequest"
-        | "SignInParams"
-        | "SignInResponse"
-        | "SignUpRequest"
-        | "SignUpParams"
-        | "SignUpResponse"
-        | "UserToken"
-        | "UserProfile"
-        | "UpdateUserRequest"
-        | "UpdateUserParams"
         | "UserError"
         => TypeCategory::Protobuf,
         "TrashType"

+ 1 - 1
rust-lib/flowy-document/src/services/doc/revision/persistence.rs

@@ -8,7 +8,7 @@ use async_stream::stream;
 use dashmap::DashMap;
 use flowy_database::ConnectionPool;
 use flowy_infra::future::ResultFuture;
-use flowy_ot::core::{Delta, Operation, OperationTransformable};
+use flowy_ot::core::{Delta, OperationTransformable};
 use futures::stream::StreamExt;
 use std::{collections::VecDeque, sync::Arc, time::Duration};
 use tokio::{

+ 12 - 12
rust-lib/flowy-sdk/src/deps_resolve/document_deps.rs

@@ -9,6 +9,7 @@ use flowy_document::{entities::ws::WsDocumentData, errors::internal_error, servi
 use flowy_user::{errors::ErrorCode, services::user::UserSession};
 use flowy_ws::{WsMessage, WsMessageHandler, WsModule};
 
+use flowy_user::errors::UserError;
 use std::{path::Path, sync::Arc};
 
 pub struct DocumentDepsResolver {
@@ -39,6 +40,15 @@ struct DocumentUserImpl {
     user: Arc<UserSession>,
 }
 
+impl DocumentUserImpl {}
+
+fn map_user_error(error: UserError) -> DocError {
+    match ErrorCode::from_i32(error.code) {
+        ErrorCode::InternalError => DocError::internal().context(error.msg),
+        _ => DocError::internal().context(error),
+    }
+}
+
 impl DocumentUser for DocumentUserImpl {
     fn user_dir(&self) -> Result<String, DocError> {
         let dir = self.user.user_dir().map_err(|e| DocError::unauthorized().context(e))?;
@@ -50,19 +60,9 @@ impl DocumentUser for DocumentUserImpl {
         Ok(doc_dir)
     }
 
-    fn user_id(&self) -> Result<String, DocError> {
-        self.user.user_id().map_err(|e| match e.code {
-            ErrorCode::InternalError => DocError::internal().context(e.msg),
-            _ => DocError::internal().context(e),
-        })
-    }
+    fn user_id(&self) -> Result<String, DocError> { self.user.user_id().map_err(map_user_error) }
 
-    fn token(&self) -> Result<String, DocError> {
-        self.user.token().map_err(|e| match e.code {
-            ErrorCode::InternalError => DocError::internal().context(e.msg),
-            _ => DocError::internal().context(e),
-        })
-    }
+    fn token(&self) -> Result<String, DocError> { self.user.token().map_err(map_user_error) }
 }
 
 struct WsSenderImpl {

+ 26 - 0
rust-lib/flowy-user-infra/Cargo.toml

@@ -0,0 +1,26 @@
+[package]
+name = "flowy-user-infra"
+version = "0.1.0"
+edition = "2018"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+flowy-derive = { path = "../flowy-derive" }
+protobuf = {version = "2.18.0"}
+bytes = "1.0"
+unicode-segmentation = "1.7.1"
+derive_more = {version = "0.99", features = ["display"]}
+validator = "0.12.0"
+log = "0.4.14"
+fancy-regex = "0.5.0"
+lazy_static = "1.4"
+
+
+[dev-dependencies]
+quickcheck = "0.9.2"
+quickcheck_macros = "0.9.1"
+fake = "~2.3.0"
+claim = "0.4.0"
+futures = "0.3.15"
+serial_test = "0.5.1"

+ 3 - 0
rust-lib/flowy-user-infra/Flowy.toml

@@ -0,0 +1,3 @@
+
+proto_crates = ["src/entities", "src/errors.rs"]
+event_files = []

+ 11 - 9
rust-lib/flowy-user/src/entities/auth.rs → rust-lib/flowy-user-infra/src/entities/auth.rs

@@ -1,7 +1,9 @@
-use crate::{entities::parser::*, errors::*};
-use flowy_derive::ProtoBuf;
 use std::convert::TryInto;
 
+use flowy_derive::ProtoBuf;
+
+use crate::{errors::*, parser::*};
+
 #[derive(ProtoBuf, Default)]
 pub struct SignInRequest {
     #[pb(index = 1)]
@@ -42,11 +44,11 @@ pub struct SignInResponse {
 }
 
 impl TryInto<SignInParams> for SignInRequest {
-    type Error = UserError;
+    type Error = ErrorCode;
 
     fn try_into(self) -> Result<SignInParams, Self::Error> {
-        let email = UserEmail::parse(self.email).map_err(|e| UserError::code(e))?;
-        let password = UserPassword::parse(self.password).map_err(|e| UserError::code(e))?;
+        let email = UserEmail::parse(self.email)?;
+        let password = UserPassword::parse(self.password)?;
 
         Ok(SignInParams {
             email: email.0,
@@ -68,12 +70,12 @@ pub struct SignUpRequest {
     pub password: String,
 }
 impl TryInto<SignUpParams> for SignUpRequest {
-    type Error = UserError;
+    type Error = ErrorCode;
 
     fn try_into(self) -> Result<SignUpParams, Self::Error> {
-        let email = UserEmail::parse(self.email).map_err(|e| UserError::code(e))?;
-        let password = UserPassword::parse(self.password).map_err(|e| UserError::code(e))?;
-        let name = UserName::parse(self.name).map_err(|e| UserError::code(e))?;
+        let email = UserEmail::parse(self.email)?;
+        let password = UserPassword::parse(self.password)?;
+        let name = UserName::parse(self.name)?;
 
         Ok(SignUpParams {
             email: email.0,

+ 0 - 1
rust-lib/flowy-user/src/entities/mod.rs → rust-lib/flowy-user-infra/src/entities/mod.rs

@@ -1,6 +1,5 @@
 pub use auth::*;
 pub use user_profile::*;
-pub mod parser;
 
 pub mod auth;
 mod user_profile;

+ 11 - 23
rust-lib/flowy-user/src/entities/user_profile.rs → rust-lib/flowy-user-infra/src/entities/user_profile.rs

@@ -1,4 +1,10 @@
 use flowy_derive::ProtoBuf;
+use std::convert::TryInto;
+
+use crate::{
+    errors::ErrorCode,
+    parser::{UserEmail, UserId, UserName, UserPassword},
+};
 
 #[derive(Default, ProtoBuf)]
 pub struct UserToken {
@@ -21,24 +27,6 @@ pub struct UserProfile {
     pub token: String,
 }
 
-use crate::{
-    entities::parser::{UserEmail, UserId, UserName, UserPassword},
-    errors::UserError,
-    sql_tables::UserTable,
-};
-use std::convert::TryInto;
-
-impl std::convert::From<UserTable> for UserProfile {
-    fn from(user: UserTable) -> Self {
-        UserProfile {
-            id: user.id,
-            email: user.email,
-            name: user.name,
-            token: user.token,
-        }
-    }
-}
-
 #[derive(ProtoBuf, Default)]
 pub struct UpdateUserRequest {
     #[pb(index = 1)]
@@ -119,24 +107,24 @@ impl UpdateUserParams {
 }
 
 impl TryInto<UpdateUserParams> for UpdateUserRequest {
-    type Error = UserError;
+    type Error = ErrorCode;
 
     fn try_into(self) -> Result<UpdateUserParams, Self::Error> {
-        let id = UserId::parse(self.id).map_err(|e| UserError::user_id().context(e))?.0;
+        let id = UserId::parse(self.id)?.0;
 
         let name = match self.name {
             None => None,
-            Some(name) => Some(UserName::parse(name).map_err(|e| UserError::code(e))?.0),
+            Some(name) => Some(UserName::parse(name)?.0),
         };
 
         let email = match self.email {
             None => None,
-            Some(email) => Some(UserEmail::parse(email).map_err(|e| UserError::code(e))?.0),
+            Some(email) => Some(UserEmail::parse(email)?.0),
         };
 
         let password = match self.password {
             None => None,
-            Some(password) => Some(UserPassword::parse(password).map_err(|e| UserError::code(e))?.0),
+            Some(password) => Some(UserPassword::parse(password)?.0),
         };
 
         Ok(UpdateUserParams {

+ 61 - 0
rust-lib/flowy-user-infra/src/errors.rs

@@ -0,0 +1,61 @@
+use crate::protobuf::ErrorCode as ProtoBufErrorCode;
+use derive_more::Display;
+use flowy_derive::ProtoBuf_Enum;
+use protobuf::ProtobufEnum;
+use std::convert::{TryFrom, TryInto};
+
+#[derive(Debug, Clone, ProtoBuf_Enum, Display, PartialEq, Eq)]
+pub enum ErrorCode {
+    #[display(fmt = "Email can not be empty or whitespace")]
+    EmailIsEmpty       = 0,
+    #[display(fmt = "Email format is not valid")]
+    EmailFormatInvalid = 1,
+    #[display(fmt = "Email already exists")]
+    EmailAlreadyExists = 2,
+    #[display(fmt = "Password can not be empty or whitespace")]
+    PasswordIsEmpty    = 10,
+    #[display(fmt = "Password format too long")]
+    PasswordTooLong    = 11,
+    #[display(fmt = "Password contains forbidden characters.")]
+    PasswordContainsForbidCharacters = 12,
+    #[display(fmt = "Password should contain a minimum of 6 characters with 1 special 1 letter and 1 numeric")]
+    PasswordFormatInvalid = 13,
+    #[display(fmt = "Password not match")]
+    PasswordNotMatch   = 14,
+    #[display(fmt = "User name is too long")]
+    UserNameTooLong    = 20,
+    #[display(fmt = "User name contain forbidden characters")]
+    UserNameContainForbiddenCharacters = 21,
+    #[display(fmt = "User name can not be empty or whitespace")]
+    UserNameIsEmpty    = 22,
+    #[display(fmt = "user id is empty or whitespace")]
+    UserIdInvalid      = 23,
+    #[display(fmt = "User token is invalid")]
+    UserUnauthorized   = 24,
+    #[display(fmt = "User not exist")]
+    UserNotExist       = 25,
+
+    #[display(fmt = "Server error")]
+    ServerError        = 99,
+
+    #[display(fmt = "Internal error")]
+    InternalError      = 100,
+}
+
+impl ErrorCode {
+    pub fn value(&self) -> i32 {
+        let code: ProtoBufErrorCode = self.clone().try_into().unwrap();
+        code.value()
+    }
+
+    pub fn from_i32(value: i32) -> Self {
+        match ProtoBufErrorCode::from_i32(value) {
+            None => ErrorCode::InternalError,
+            Some(code) => ErrorCode::try_from(&code).unwrap(),
+        }
+    }
+}
+
+impl std::default::Default for ErrorCode {
+    fn default() -> Self { ErrorCode::InternalError }
+}

+ 5 - 0
rust-lib/flowy-user-infra/src/lib.rs

@@ -0,0 +1,5 @@
+pub mod entities;
+pub mod errors;
+pub mod parser;
+pub mod protobuf;
+pub mod user_default;

+ 0 - 0
rust-lib/flowy-user/src/entities/parser/mod.rs → rust-lib/flowy-user-infra/src/parser/mod.rs


+ 0 - 0
rust-lib/flowy-user/src/entities/parser/user_email.rs → rust-lib/flowy-user-infra/src/parser/user_email.rs


+ 4 - 2
rust-lib/flowy-user/src/entities/parser/user_id.rs → rust-lib/flowy-user-infra/src/parser/user_id.rs

@@ -1,11 +1,13 @@
+use crate::errors::ErrorCode;
+
 #[derive(Debug)]
 pub struct UserId(pub String);
 
 impl UserId {
-    pub fn parse(s: String) -> Result<UserId, String> {
+    pub fn parse(s: String) -> Result<UserId, ErrorCode> {
         let is_empty_or_whitespace = s.trim().is_empty();
         if is_empty_or_whitespace {
-            return Err(format!("user id is empty or whitespace"));
+            return Err(ErrorCode::UserIdInvalid);
         }
         Ok(Self(s))
     }

+ 0 - 0
rust-lib/flowy-user/src/entities/parser/user_name.rs → rust-lib/flowy-user-infra/src/parser/user_name.rs


+ 0 - 0
rust-lib/flowy-user/src/entities/parser/user_password.rs → rust-lib/flowy-user-infra/src/parser/user_password.rs


+ 0 - 0
rust-lib/flowy-user/src/entities/parser/user_workspace.rs → rust-lib/flowy-user-infra/src/parser/user_workspace.rs


+ 4 - 0
rust-lib/flowy-user-infra/src/protobuf/mod.rs

@@ -0,0 +1,4 @@
+
+mod model;
+pub use model::*;
+        

+ 1661 - 0
rust-lib/flowy-user-infra/src/protobuf/model/auth.rs

@@ -0,0 +1,1661 @@
+// This file is generated by rust-protobuf 2.22.1. Do not edit
+// @generated
+
+// https://github.com/rust-lang/rust-clippy/issues/702
+#![allow(unknown_lints)]
+#![allow(clippy::all)]
+
+#![allow(unused_attributes)]
+#![cfg_attr(rustfmt, rustfmt::skip)]
+
+#![allow(box_pointers)]
+#![allow(dead_code)]
+#![allow(missing_docs)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+#![allow(non_upper_case_globals)]
+#![allow(trivial_casts)]
+#![allow(unused_imports)]
+#![allow(unused_results)]
+//! Generated file from `auth.proto`
+
+/// Generated files are compatible only with the same version
+/// of protobuf runtime.
+// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_22_1;
+
+#[derive(PartialEq,Clone,Default)]
+pub struct SignInRequest {
+    // message fields
+    pub email: ::std::string::String,
+    pub password: ::std::string::String,
+    pub name: ::std::string::String,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a SignInRequest {
+    fn default() -> &'a SignInRequest {
+        <SignInRequest as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl SignInRequest {
+    pub fn new() -> SignInRequest {
+        ::std::default::Default::default()
+    }
+
+    // string email = 1;
+
+
+    pub fn get_email(&self) -> &str {
+        &self.email
+    }
+    pub fn clear_email(&mut self) {
+        self.email.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_email(&mut self, v: ::std::string::String) {
+        self.email = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_email(&mut self) -> &mut ::std::string::String {
+        &mut self.email
+    }
+
+    // Take field
+    pub fn take_email(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.email, ::std::string::String::new())
+    }
+
+    // string password = 2;
+
+
+    pub fn get_password(&self) -> &str {
+        &self.password
+    }
+    pub fn clear_password(&mut self) {
+        self.password.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_password(&mut self, v: ::std::string::String) {
+        self.password = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_password(&mut self) -> &mut ::std::string::String {
+        &mut self.password
+    }
+
+    // Take field
+    pub fn take_password(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.password, ::std::string::String::new())
+    }
+
+    // string name = 3;
+
+
+    pub fn get_name(&self) -> &str {
+        &self.name
+    }
+    pub fn clear_name(&mut self) {
+        self.name.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_name(&mut self, v: ::std::string::String) {
+        self.name = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_name(&mut self) -> &mut ::std::string::String {
+        &mut self.name
+    }
+
+    // Take field
+    pub fn take_name(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.name, ::std::string::String::new())
+    }
+}
+
+impl ::protobuf::Message for SignInRequest {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.email)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.password)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if !self.email.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.email);
+        }
+        if !self.password.is_empty() {
+            my_size += ::protobuf::rt::string_size(2, &self.password);
+        }
+        if !self.name.is_empty() {
+            my_size += ::protobuf::rt::string_size(3, &self.name);
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        if !self.email.is_empty() {
+            os.write_string(1, &self.email)?;
+        }
+        if !self.password.is_empty() {
+            os.write_string(2, &self.password)?;
+        }
+        if !self.name.is_empty() {
+            os.write_string(3, &self.name)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &dyn (::std::any::Any) {
+        self as &dyn (::std::any::Any)
+    }
+    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
+        self as &mut dyn (::std::any::Any)
+    }
+    fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> SignInRequest {
+        SignInRequest::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
+        descriptor.get(|| {
+            let mut fields = ::std::vec::Vec::new();
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "email",
+                |m: &SignInRequest| { &m.email },
+                |m: &mut SignInRequest| { &mut m.email },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "password",
+                |m: &SignInRequest| { &m.password },
+                |m: &mut SignInRequest| { &mut m.password },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "name",
+                |m: &SignInRequest| { &m.name },
+                |m: &mut SignInRequest| { &mut m.name },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<SignInRequest>(
+                "SignInRequest",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static SignInRequest {
+        static instance: ::protobuf::rt::LazyV2<SignInRequest> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(SignInRequest::new)
+    }
+}
+
+impl ::protobuf::Clear for SignInRequest {
+    fn clear(&mut self) {
+        self.email.clear();
+        self.password.clear();
+        self.name.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for SignInRequest {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for SignInRequest {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct SignInParams {
+    // message fields
+    pub email: ::std::string::String,
+    pub password: ::std::string::String,
+    pub name: ::std::string::String,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a SignInParams {
+    fn default() -> &'a SignInParams {
+        <SignInParams as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl SignInParams {
+    pub fn new() -> SignInParams {
+        ::std::default::Default::default()
+    }
+
+    // string email = 1;
+
+
+    pub fn get_email(&self) -> &str {
+        &self.email
+    }
+    pub fn clear_email(&mut self) {
+        self.email.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_email(&mut self, v: ::std::string::String) {
+        self.email = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_email(&mut self) -> &mut ::std::string::String {
+        &mut self.email
+    }
+
+    // Take field
+    pub fn take_email(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.email, ::std::string::String::new())
+    }
+
+    // string password = 2;
+
+
+    pub fn get_password(&self) -> &str {
+        &self.password
+    }
+    pub fn clear_password(&mut self) {
+        self.password.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_password(&mut self, v: ::std::string::String) {
+        self.password = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_password(&mut self) -> &mut ::std::string::String {
+        &mut self.password
+    }
+
+    // Take field
+    pub fn take_password(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.password, ::std::string::String::new())
+    }
+
+    // string name = 3;
+
+
+    pub fn get_name(&self) -> &str {
+        &self.name
+    }
+    pub fn clear_name(&mut self) {
+        self.name.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_name(&mut self, v: ::std::string::String) {
+        self.name = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_name(&mut self) -> &mut ::std::string::String {
+        &mut self.name
+    }
+
+    // Take field
+    pub fn take_name(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.name, ::std::string::String::new())
+    }
+}
+
+impl ::protobuf::Message for SignInParams {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.email)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.password)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if !self.email.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.email);
+        }
+        if !self.password.is_empty() {
+            my_size += ::protobuf::rt::string_size(2, &self.password);
+        }
+        if !self.name.is_empty() {
+            my_size += ::protobuf::rt::string_size(3, &self.name);
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        if !self.email.is_empty() {
+            os.write_string(1, &self.email)?;
+        }
+        if !self.password.is_empty() {
+            os.write_string(2, &self.password)?;
+        }
+        if !self.name.is_empty() {
+            os.write_string(3, &self.name)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &dyn (::std::any::Any) {
+        self as &dyn (::std::any::Any)
+    }
+    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
+        self as &mut dyn (::std::any::Any)
+    }
+    fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> SignInParams {
+        SignInParams::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
+        descriptor.get(|| {
+            let mut fields = ::std::vec::Vec::new();
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "email",
+                |m: &SignInParams| { &m.email },
+                |m: &mut SignInParams| { &mut m.email },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "password",
+                |m: &SignInParams| { &m.password },
+                |m: &mut SignInParams| { &mut m.password },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "name",
+                |m: &SignInParams| { &m.name },
+                |m: &mut SignInParams| { &mut m.name },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<SignInParams>(
+                "SignInParams",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static SignInParams {
+        static instance: ::protobuf::rt::LazyV2<SignInParams> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(SignInParams::new)
+    }
+}
+
+impl ::protobuf::Clear for SignInParams {
+    fn clear(&mut self) {
+        self.email.clear();
+        self.password.clear();
+        self.name.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for SignInParams {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for SignInParams {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct SignInResponse {
+    // message fields
+    pub user_id: ::std::string::String,
+    pub name: ::std::string::String,
+    pub email: ::std::string::String,
+    pub token: ::std::string::String,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a SignInResponse {
+    fn default() -> &'a SignInResponse {
+        <SignInResponse as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl SignInResponse {
+    pub fn new() -> SignInResponse {
+        ::std::default::Default::default()
+    }
+
+    // string user_id = 1;
+
+
+    pub fn get_user_id(&self) -> &str {
+        &self.user_id
+    }
+    pub fn clear_user_id(&mut self) {
+        self.user_id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_user_id(&mut self, v: ::std::string::String) {
+        self.user_id = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_user_id(&mut self) -> &mut ::std::string::String {
+        &mut self.user_id
+    }
+
+    // Take field
+    pub fn take_user_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.user_id, ::std::string::String::new())
+    }
+
+    // string name = 2;
+
+
+    pub fn get_name(&self) -> &str {
+        &self.name
+    }
+    pub fn clear_name(&mut self) {
+        self.name.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_name(&mut self, v: ::std::string::String) {
+        self.name = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_name(&mut self) -> &mut ::std::string::String {
+        &mut self.name
+    }
+
+    // Take field
+    pub fn take_name(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.name, ::std::string::String::new())
+    }
+
+    // string email = 3;
+
+
+    pub fn get_email(&self) -> &str {
+        &self.email
+    }
+    pub fn clear_email(&mut self) {
+        self.email.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_email(&mut self, v: ::std::string::String) {
+        self.email = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_email(&mut self) -> &mut ::std::string::String {
+        &mut self.email
+    }
+
+    // Take field
+    pub fn take_email(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.email, ::std::string::String::new())
+    }
+
+    // string token = 4;
+
+
+    pub fn get_token(&self) -> &str {
+        &self.token
+    }
+    pub fn clear_token(&mut self) {
+        self.token.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_token(&mut self, v: ::std::string::String) {
+        self.token = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_token(&mut self) -> &mut ::std::string::String {
+        &mut self.token
+    }
+
+    // Take field
+    pub fn take_token(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.token, ::std::string::String::new())
+    }
+}
+
+impl ::protobuf::Message for SignInResponse {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.user_id)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.email)?;
+                },
+                4 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.token)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if !self.user_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.user_id);
+        }
+        if !self.name.is_empty() {
+            my_size += ::protobuf::rt::string_size(2, &self.name);
+        }
+        if !self.email.is_empty() {
+            my_size += ::protobuf::rt::string_size(3, &self.email);
+        }
+        if !self.token.is_empty() {
+            my_size += ::protobuf::rt::string_size(4, &self.token);
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        if !self.user_id.is_empty() {
+            os.write_string(1, &self.user_id)?;
+        }
+        if !self.name.is_empty() {
+            os.write_string(2, &self.name)?;
+        }
+        if !self.email.is_empty() {
+            os.write_string(3, &self.email)?;
+        }
+        if !self.token.is_empty() {
+            os.write_string(4, &self.token)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &dyn (::std::any::Any) {
+        self as &dyn (::std::any::Any)
+    }
+    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
+        self as &mut dyn (::std::any::Any)
+    }
+    fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> SignInResponse {
+        SignInResponse::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
+        descriptor.get(|| {
+            let mut fields = ::std::vec::Vec::new();
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "user_id",
+                |m: &SignInResponse| { &m.user_id },
+                |m: &mut SignInResponse| { &mut m.user_id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "name",
+                |m: &SignInResponse| { &m.name },
+                |m: &mut SignInResponse| { &mut m.name },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "email",
+                |m: &SignInResponse| { &m.email },
+                |m: &mut SignInResponse| { &mut m.email },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "token",
+                |m: &SignInResponse| { &m.token },
+                |m: &mut SignInResponse| { &mut m.token },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<SignInResponse>(
+                "SignInResponse",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static SignInResponse {
+        static instance: ::protobuf::rt::LazyV2<SignInResponse> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(SignInResponse::new)
+    }
+}
+
+impl ::protobuf::Clear for SignInResponse {
+    fn clear(&mut self) {
+        self.user_id.clear();
+        self.name.clear();
+        self.email.clear();
+        self.token.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for SignInResponse {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for SignInResponse {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct SignUpRequest {
+    // message fields
+    pub email: ::std::string::String,
+    pub name: ::std::string::String,
+    pub password: ::std::string::String,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a SignUpRequest {
+    fn default() -> &'a SignUpRequest {
+        <SignUpRequest as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl SignUpRequest {
+    pub fn new() -> SignUpRequest {
+        ::std::default::Default::default()
+    }
+
+    // string email = 1;
+
+
+    pub fn get_email(&self) -> &str {
+        &self.email
+    }
+    pub fn clear_email(&mut self) {
+        self.email.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_email(&mut self, v: ::std::string::String) {
+        self.email = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_email(&mut self) -> &mut ::std::string::String {
+        &mut self.email
+    }
+
+    // Take field
+    pub fn take_email(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.email, ::std::string::String::new())
+    }
+
+    // string name = 2;
+
+
+    pub fn get_name(&self) -> &str {
+        &self.name
+    }
+    pub fn clear_name(&mut self) {
+        self.name.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_name(&mut self, v: ::std::string::String) {
+        self.name = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_name(&mut self) -> &mut ::std::string::String {
+        &mut self.name
+    }
+
+    // Take field
+    pub fn take_name(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.name, ::std::string::String::new())
+    }
+
+    // string password = 3;
+
+
+    pub fn get_password(&self) -> &str {
+        &self.password
+    }
+    pub fn clear_password(&mut self) {
+        self.password.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_password(&mut self, v: ::std::string::String) {
+        self.password = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_password(&mut self) -> &mut ::std::string::String {
+        &mut self.password
+    }
+
+    // Take field
+    pub fn take_password(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.password, ::std::string::String::new())
+    }
+}
+
+impl ::protobuf::Message for SignUpRequest {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.email)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.password)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if !self.email.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.email);
+        }
+        if !self.name.is_empty() {
+            my_size += ::protobuf::rt::string_size(2, &self.name);
+        }
+        if !self.password.is_empty() {
+            my_size += ::protobuf::rt::string_size(3, &self.password);
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        if !self.email.is_empty() {
+            os.write_string(1, &self.email)?;
+        }
+        if !self.name.is_empty() {
+            os.write_string(2, &self.name)?;
+        }
+        if !self.password.is_empty() {
+            os.write_string(3, &self.password)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &dyn (::std::any::Any) {
+        self as &dyn (::std::any::Any)
+    }
+    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
+        self as &mut dyn (::std::any::Any)
+    }
+    fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> SignUpRequest {
+        SignUpRequest::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
+        descriptor.get(|| {
+            let mut fields = ::std::vec::Vec::new();
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "email",
+                |m: &SignUpRequest| { &m.email },
+                |m: &mut SignUpRequest| { &mut m.email },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "name",
+                |m: &SignUpRequest| { &m.name },
+                |m: &mut SignUpRequest| { &mut m.name },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "password",
+                |m: &SignUpRequest| { &m.password },
+                |m: &mut SignUpRequest| { &mut m.password },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<SignUpRequest>(
+                "SignUpRequest",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static SignUpRequest {
+        static instance: ::protobuf::rt::LazyV2<SignUpRequest> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(SignUpRequest::new)
+    }
+}
+
+impl ::protobuf::Clear for SignUpRequest {
+    fn clear(&mut self) {
+        self.email.clear();
+        self.name.clear();
+        self.password.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for SignUpRequest {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for SignUpRequest {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct SignUpParams {
+    // message fields
+    pub email: ::std::string::String,
+    pub name: ::std::string::String,
+    pub password: ::std::string::String,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a SignUpParams {
+    fn default() -> &'a SignUpParams {
+        <SignUpParams as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl SignUpParams {
+    pub fn new() -> SignUpParams {
+        ::std::default::Default::default()
+    }
+
+    // string email = 1;
+
+
+    pub fn get_email(&self) -> &str {
+        &self.email
+    }
+    pub fn clear_email(&mut self) {
+        self.email.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_email(&mut self, v: ::std::string::String) {
+        self.email = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_email(&mut self) -> &mut ::std::string::String {
+        &mut self.email
+    }
+
+    // Take field
+    pub fn take_email(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.email, ::std::string::String::new())
+    }
+
+    // string name = 2;
+
+
+    pub fn get_name(&self) -> &str {
+        &self.name
+    }
+    pub fn clear_name(&mut self) {
+        self.name.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_name(&mut self, v: ::std::string::String) {
+        self.name = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_name(&mut self) -> &mut ::std::string::String {
+        &mut self.name
+    }
+
+    // Take field
+    pub fn take_name(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.name, ::std::string::String::new())
+    }
+
+    // string password = 3;
+
+
+    pub fn get_password(&self) -> &str {
+        &self.password
+    }
+    pub fn clear_password(&mut self) {
+        self.password.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_password(&mut self, v: ::std::string::String) {
+        self.password = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_password(&mut self) -> &mut ::std::string::String {
+        &mut self.password
+    }
+
+    // Take field
+    pub fn take_password(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.password, ::std::string::String::new())
+    }
+}
+
+impl ::protobuf::Message for SignUpParams {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.email)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.password)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if !self.email.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.email);
+        }
+        if !self.name.is_empty() {
+            my_size += ::protobuf::rt::string_size(2, &self.name);
+        }
+        if !self.password.is_empty() {
+            my_size += ::protobuf::rt::string_size(3, &self.password);
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        if !self.email.is_empty() {
+            os.write_string(1, &self.email)?;
+        }
+        if !self.name.is_empty() {
+            os.write_string(2, &self.name)?;
+        }
+        if !self.password.is_empty() {
+            os.write_string(3, &self.password)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &dyn (::std::any::Any) {
+        self as &dyn (::std::any::Any)
+    }
+    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
+        self as &mut dyn (::std::any::Any)
+    }
+    fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> SignUpParams {
+        SignUpParams::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
+        descriptor.get(|| {
+            let mut fields = ::std::vec::Vec::new();
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "email",
+                |m: &SignUpParams| { &m.email },
+                |m: &mut SignUpParams| { &mut m.email },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "name",
+                |m: &SignUpParams| { &m.name },
+                |m: &mut SignUpParams| { &mut m.name },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "password",
+                |m: &SignUpParams| { &m.password },
+                |m: &mut SignUpParams| { &mut m.password },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<SignUpParams>(
+                "SignUpParams",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static SignUpParams {
+        static instance: ::protobuf::rt::LazyV2<SignUpParams> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(SignUpParams::new)
+    }
+}
+
+impl ::protobuf::Clear for SignUpParams {
+    fn clear(&mut self) {
+        self.email.clear();
+        self.name.clear();
+        self.password.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for SignUpParams {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for SignUpParams {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct SignUpResponse {
+    // message fields
+    pub user_id: ::std::string::String,
+    pub name: ::std::string::String,
+    pub email: ::std::string::String,
+    pub token: ::std::string::String,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a SignUpResponse {
+    fn default() -> &'a SignUpResponse {
+        <SignUpResponse as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl SignUpResponse {
+    pub fn new() -> SignUpResponse {
+        ::std::default::Default::default()
+    }
+
+    // string user_id = 1;
+
+
+    pub fn get_user_id(&self) -> &str {
+        &self.user_id
+    }
+    pub fn clear_user_id(&mut self) {
+        self.user_id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_user_id(&mut self, v: ::std::string::String) {
+        self.user_id = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_user_id(&mut self) -> &mut ::std::string::String {
+        &mut self.user_id
+    }
+
+    // Take field
+    pub fn take_user_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.user_id, ::std::string::String::new())
+    }
+
+    // string name = 2;
+
+
+    pub fn get_name(&self) -> &str {
+        &self.name
+    }
+    pub fn clear_name(&mut self) {
+        self.name.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_name(&mut self, v: ::std::string::String) {
+        self.name = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_name(&mut self) -> &mut ::std::string::String {
+        &mut self.name
+    }
+
+    // Take field
+    pub fn take_name(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.name, ::std::string::String::new())
+    }
+
+    // string email = 3;
+
+
+    pub fn get_email(&self) -> &str {
+        &self.email
+    }
+    pub fn clear_email(&mut self) {
+        self.email.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_email(&mut self, v: ::std::string::String) {
+        self.email = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_email(&mut self) -> &mut ::std::string::String {
+        &mut self.email
+    }
+
+    // Take field
+    pub fn take_email(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.email, ::std::string::String::new())
+    }
+
+    // string token = 4;
+
+
+    pub fn get_token(&self) -> &str {
+        &self.token
+    }
+    pub fn clear_token(&mut self) {
+        self.token.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_token(&mut self, v: ::std::string::String) {
+        self.token = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_token(&mut self) -> &mut ::std::string::String {
+        &mut self.token
+    }
+
+    // Take field
+    pub fn take_token(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.token, ::std::string::String::new())
+    }
+}
+
+impl ::protobuf::Message for SignUpResponse {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.user_id)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.email)?;
+                },
+                4 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.token)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if !self.user_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.user_id);
+        }
+        if !self.name.is_empty() {
+            my_size += ::protobuf::rt::string_size(2, &self.name);
+        }
+        if !self.email.is_empty() {
+            my_size += ::protobuf::rt::string_size(3, &self.email);
+        }
+        if !self.token.is_empty() {
+            my_size += ::protobuf::rt::string_size(4, &self.token);
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        if !self.user_id.is_empty() {
+            os.write_string(1, &self.user_id)?;
+        }
+        if !self.name.is_empty() {
+            os.write_string(2, &self.name)?;
+        }
+        if !self.email.is_empty() {
+            os.write_string(3, &self.email)?;
+        }
+        if !self.token.is_empty() {
+            os.write_string(4, &self.token)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &dyn (::std::any::Any) {
+        self as &dyn (::std::any::Any)
+    }
+    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
+        self as &mut dyn (::std::any::Any)
+    }
+    fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> SignUpResponse {
+        SignUpResponse::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
+        descriptor.get(|| {
+            let mut fields = ::std::vec::Vec::new();
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "user_id",
+                |m: &SignUpResponse| { &m.user_id },
+                |m: &mut SignUpResponse| { &mut m.user_id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "name",
+                |m: &SignUpResponse| { &m.name },
+                |m: &mut SignUpResponse| { &mut m.name },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "email",
+                |m: &SignUpResponse| { &m.email },
+                |m: &mut SignUpResponse| { &mut m.email },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "token",
+                |m: &SignUpResponse| { &m.token },
+                |m: &mut SignUpResponse| { &mut m.token },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<SignUpResponse>(
+                "SignUpResponse",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static SignUpResponse {
+        static instance: ::protobuf::rt::LazyV2<SignUpResponse> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(SignUpResponse::new)
+    }
+}
+
+impl ::protobuf::Clear for SignUpResponse {
+    fn clear(&mut self) {
+        self.user_id.clear();
+        self.name.clear();
+        self.email.clear();
+        self.token.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for SignUpResponse {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for SignUpResponse {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+static file_descriptor_proto_data: &'static [u8] = b"\
+    \n\nauth.proto\"U\n\rSignInRequest\x12\x14\n\x05email\x18\x01\x20\x01(\t\
+    R\x05email\x12\x1a\n\x08password\x18\x02\x20\x01(\tR\x08password\x12\x12\
+    \n\x04name\x18\x03\x20\x01(\tR\x04name\"T\n\x0cSignInParams\x12\x14\n\
+    \x05email\x18\x01\x20\x01(\tR\x05email\x12\x1a\n\x08password\x18\x02\x20\
+    \x01(\tR\x08password\x12\x12\n\x04name\x18\x03\x20\x01(\tR\x04name\"i\n\
+    \x0eSignInResponse\x12\x17\n\x07user_id\x18\x01\x20\x01(\tR\x06userId\
+    \x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x14\n\x05email\x18\
+    \x03\x20\x01(\tR\x05email\x12\x14\n\x05token\x18\x04\x20\x01(\tR\x05toke\
+    n\"U\n\rSignUpRequest\x12\x14\n\x05email\x18\x01\x20\x01(\tR\x05email\
+    \x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x1a\n\x08password\x18\
+    \x03\x20\x01(\tR\x08password\"T\n\x0cSignUpParams\x12\x14\n\x05email\x18\
+    \x01\x20\x01(\tR\x05email\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\
+    \x12\x1a\n\x08password\x18\x03\x20\x01(\tR\x08password\"i\n\x0eSignUpRes\
+    ponse\x12\x17\n\x07user_id\x18\x01\x20\x01(\tR\x06userId\x12\x12\n\x04na\
+    me\x18\x02\x20\x01(\tR\x04name\x12\x14\n\x05email\x18\x03\x20\x01(\tR\
+    \x05email\x12\x14\n\x05token\x18\x04\x20\x01(\tR\x05tokenJ\xee\t\n\x06\
+    \x12\x04\0\0!\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\
+    \x04\x02\0\x06\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x15\n\x0b\n\x04\
+    \x04\0\x02\0\x12\x03\x03\x04\x15\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x03\
+    \x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\x0b\x10\n\x0c\n\x05\x04\0\
+    \x02\0\x03\x12\x03\x03\x13\x14\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\
+    \x18\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x04\x04\n\n\x0c\n\x05\x04\0\
+    \x02\x01\x01\x12\x03\x04\x0b\x13\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\
+    \x04\x16\x17\n\x0b\n\x04\x04\0\x02\x02\x12\x03\x05\x04\x14\n\x0c\n\x05\
+    \x04\0\x02\x02\x05\x12\x03\x05\x04\n\n\x0c\n\x05\x04\0\x02\x02\x01\x12\
+    \x03\x05\x0b\x0f\n\x0c\n\x05\x04\0\x02\x02\x03\x12\x03\x05\x12\x13\n\n\n\
+    \x02\x04\x01\x12\x04\x07\0\x0b\x01\n\n\n\x03\x04\x01\x01\x12\x03\x07\x08\
+    \x14\n\x0b\n\x04\x04\x01\x02\0\x12\x03\x08\x04\x15\n\x0c\n\x05\x04\x01\
+    \x02\0\x05\x12\x03\x08\x04\n\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\x08\
+    \x0b\x10\n\x0c\n\x05\x04\x01\x02\0\x03\x12\x03\x08\x13\x14\n\x0b\n\x04\
+    \x04\x01\x02\x01\x12\x03\t\x04\x18\n\x0c\n\x05\x04\x01\x02\x01\x05\x12\
+    \x03\t\x04\n\n\x0c\n\x05\x04\x01\x02\x01\x01\x12\x03\t\x0b\x13\n\x0c\n\
+    \x05\x04\x01\x02\x01\x03\x12\x03\t\x16\x17\n\x0b\n\x04\x04\x01\x02\x02\
+    \x12\x03\n\x04\x14\n\x0c\n\x05\x04\x01\x02\x02\x05\x12\x03\n\x04\n\n\x0c\
+    \n\x05\x04\x01\x02\x02\x01\x12\x03\n\x0b\x0f\n\x0c\n\x05\x04\x01\x02\x02\
+    \x03\x12\x03\n\x12\x13\n\n\n\x02\x04\x02\x12\x04\x0c\0\x11\x01\n\n\n\x03\
+    \x04\x02\x01\x12\x03\x0c\x08\x16\n\x0b\n\x04\x04\x02\x02\0\x12\x03\r\x04\
+    \x17\n\x0c\n\x05\x04\x02\x02\0\x05\x12\x03\r\x04\n\n\x0c\n\x05\x04\x02\
+    \x02\0\x01\x12\x03\r\x0b\x12\n\x0c\n\x05\x04\x02\x02\0\x03\x12\x03\r\x15\
+    \x16\n\x0b\n\x04\x04\x02\x02\x01\x12\x03\x0e\x04\x14\n\x0c\n\x05\x04\x02\
+    \x02\x01\x05\x12\x03\x0e\x04\n\n\x0c\n\x05\x04\x02\x02\x01\x01\x12\x03\
+    \x0e\x0b\x0f\n\x0c\n\x05\x04\x02\x02\x01\x03\x12\x03\x0e\x12\x13\n\x0b\n\
+    \x04\x04\x02\x02\x02\x12\x03\x0f\x04\x15\n\x0c\n\x05\x04\x02\x02\x02\x05\
+    \x12\x03\x0f\x04\n\n\x0c\n\x05\x04\x02\x02\x02\x01\x12\x03\x0f\x0b\x10\n\
+    \x0c\n\x05\x04\x02\x02\x02\x03\x12\x03\x0f\x13\x14\n\x0b\n\x04\x04\x02\
+    \x02\x03\x12\x03\x10\x04\x15\n\x0c\n\x05\x04\x02\x02\x03\x05\x12\x03\x10\
+    \x04\n\n\x0c\n\x05\x04\x02\x02\x03\x01\x12\x03\x10\x0b\x10\n\x0c\n\x05\
+    \x04\x02\x02\x03\x03\x12\x03\x10\x13\x14\n\n\n\x02\x04\x03\x12\x04\x12\0\
+    \x16\x01\n\n\n\x03\x04\x03\x01\x12\x03\x12\x08\x15\n\x0b\n\x04\x04\x03\
+    \x02\0\x12\x03\x13\x04\x15\n\x0c\n\x05\x04\x03\x02\0\x05\x12\x03\x13\x04\
+    \n\n\x0c\n\x05\x04\x03\x02\0\x01\x12\x03\x13\x0b\x10\n\x0c\n\x05\x04\x03\
+    \x02\0\x03\x12\x03\x13\x13\x14\n\x0b\n\x04\x04\x03\x02\x01\x12\x03\x14\
+    \x04\x14\n\x0c\n\x05\x04\x03\x02\x01\x05\x12\x03\x14\x04\n\n\x0c\n\x05\
+    \x04\x03\x02\x01\x01\x12\x03\x14\x0b\x0f\n\x0c\n\x05\x04\x03\x02\x01\x03\
+    \x12\x03\x14\x12\x13\n\x0b\n\x04\x04\x03\x02\x02\x12\x03\x15\x04\x18\n\
+    \x0c\n\x05\x04\x03\x02\x02\x05\x12\x03\x15\x04\n\n\x0c\n\x05\x04\x03\x02\
+    \x02\x01\x12\x03\x15\x0b\x13\n\x0c\n\x05\x04\x03\x02\x02\x03\x12\x03\x15\
+    \x16\x17\n\n\n\x02\x04\x04\x12\x04\x17\0\x1b\x01\n\n\n\x03\x04\x04\x01\
+    \x12\x03\x17\x08\x14\n\x0b\n\x04\x04\x04\x02\0\x12\x03\x18\x04\x15\n\x0c\
+    \n\x05\x04\x04\x02\0\x05\x12\x03\x18\x04\n\n\x0c\n\x05\x04\x04\x02\0\x01\
+    \x12\x03\x18\x0b\x10\n\x0c\n\x05\x04\x04\x02\0\x03\x12\x03\x18\x13\x14\n\
+    \x0b\n\x04\x04\x04\x02\x01\x12\x03\x19\x04\x14\n\x0c\n\x05\x04\x04\x02\
+    \x01\x05\x12\x03\x19\x04\n\n\x0c\n\x05\x04\x04\x02\x01\x01\x12\x03\x19\
+    \x0b\x0f\n\x0c\n\x05\x04\x04\x02\x01\x03\x12\x03\x19\x12\x13\n\x0b\n\x04\
+    \x04\x04\x02\x02\x12\x03\x1a\x04\x18\n\x0c\n\x05\x04\x04\x02\x02\x05\x12\
+    \x03\x1a\x04\n\n\x0c\n\x05\x04\x04\x02\x02\x01\x12\x03\x1a\x0b\x13\n\x0c\
+    \n\x05\x04\x04\x02\x02\x03\x12\x03\x1a\x16\x17\n\n\n\x02\x04\x05\x12\x04\
+    \x1c\0!\x01\n\n\n\x03\x04\x05\x01\x12\x03\x1c\x08\x16\n\x0b\n\x04\x04\
+    \x05\x02\0\x12\x03\x1d\x04\x17\n\x0c\n\x05\x04\x05\x02\0\x05\x12\x03\x1d\
+    \x04\n\n\x0c\n\x05\x04\x05\x02\0\x01\x12\x03\x1d\x0b\x12\n\x0c\n\x05\x04\
+    \x05\x02\0\x03\x12\x03\x1d\x15\x16\n\x0b\n\x04\x04\x05\x02\x01\x12\x03\
+    \x1e\x04\x14\n\x0c\n\x05\x04\x05\x02\x01\x05\x12\x03\x1e\x04\n\n\x0c\n\
+    \x05\x04\x05\x02\x01\x01\x12\x03\x1e\x0b\x0f\n\x0c\n\x05\x04\x05\x02\x01\
+    \x03\x12\x03\x1e\x12\x13\n\x0b\n\x04\x04\x05\x02\x02\x12\x03\x1f\x04\x15\
+    \n\x0c\n\x05\x04\x05\x02\x02\x05\x12\x03\x1f\x04\n\n\x0c\n\x05\x04\x05\
+    \x02\x02\x01\x12\x03\x1f\x0b\x10\n\x0c\n\x05\x04\x05\x02\x02\x03\x12\x03\
+    \x1f\x13\x14\n\x0b\n\x04\x04\x05\x02\x03\x12\x03\x20\x04\x15\n\x0c\n\x05\
+    \x04\x05\x02\x03\x05\x12\x03\x20\x04\n\n\x0c\n\x05\x04\x05\x02\x03\x01\
+    \x12\x03\x20\x0b\x10\n\x0c\n\x05\x04\x05\x02\x03\x03\x12\x03\x20\x13\x14\
+    b\x06proto3\
+";
+
+static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
+
+fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
+    ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap()
+}
+
+pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
+    file_descriptor_proto_lazy.get(|| {
+        parse_descriptor_proto()
+    })
+}

+ 175 - 0
rust-lib/flowy-user-infra/src/protobuf/model/errors.rs

@@ -0,0 +1,175 @@
+// This file is generated by rust-protobuf 2.22.1. Do not edit
+// @generated
+
+// https://github.com/rust-lang/rust-clippy/issues/702
+#![allow(unknown_lints)]
+#![allow(clippy::all)]
+
+#![allow(unused_attributes)]
+#![cfg_attr(rustfmt, rustfmt::skip)]
+
+#![allow(box_pointers)]
+#![allow(dead_code)]
+#![allow(missing_docs)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+#![allow(non_upper_case_globals)]
+#![allow(trivial_casts)]
+#![allow(unused_imports)]
+#![allow(unused_results)]
+//! Generated file from `errors.proto`
+
+/// Generated files are compatible only with the same version
+/// of protobuf runtime.
+// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_22_1;
+
+#[derive(Clone,PartialEq,Eq,Debug,Hash)]
+pub enum ErrorCode {
+    EmailIsEmpty = 0,
+    EmailFormatInvalid = 1,
+    EmailAlreadyExists = 2,
+    PasswordIsEmpty = 10,
+    PasswordTooLong = 11,
+    PasswordContainsForbidCharacters = 12,
+    PasswordFormatInvalid = 13,
+    PasswordNotMatch = 14,
+    UserNameTooLong = 20,
+    UserNameContainForbiddenCharacters = 21,
+    UserNameIsEmpty = 22,
+    UserIdInvalid = 23,
+    UserUnauthorized = 24,
+    UserNotExist = 25,
+    ServerError = 99,
+    InternalError = 100,
+}
+
+impl ::protobuf::ProtobufEnum for ErrorCode {
+    fn value(&self) -> i32 {
+        *self as i32
+    }
+
+    fn from_i32(value: i32) -> ::std::option::Option<ErrorCode> {
+        match value {
+            0 => ::std::option::Option::Some(ErrorCode::EmailIsEmpty),
+            1 => ::std::option::Option::Some(ErrorCode::EmailFormatInvalid),
+            2 => ::std::option::Option::Some(ErrorCode::EmailAlreadyExists),
+            10 => ::std::option::Option::Some(ErrorCode::PasswordIsEmpty),
+            11 => ::std::option::Option::Some(ErrorCode::PasswordTooLong),
+            12 => ::std::option::Option::Some(ErrorCode::PasswordContainsForbidCharacters),
+            13 => ::std::option::Option::Some(ErrorCode::PasswordFormatInvalid),
+            14 => ::std::option::Option::Some(ErrorCode::PasswordNotMatch),
+            20 => ::std::option::Option::Some(ErrorCode::UserNameTooLong),
+            21 => ::std::option::Option::Some(ErrorCode::UserNameContainForbiddenCharacters),
+            22 => ::std::option::Option::Some(ErrorCode::UserNameIsEmpty),
+            23 => ::std::option::Option::Some(ErrorCode::UserIdInvalid),
+            24 => ::std::option::Option::Some(ErrorCode::UserUnauthorized),
+            25 => ::std::option::Option::Some(ErrorCode::UserNotExist),
+            99 => ::std::option::Option::Some(ErrorCode::ServerError),
+            100 => ::std::option::Option::Some(ErrorCode::InternalError),
+            _ => ::std::option::Option::None
+        }
+    }
+
+    fn values() -> &'static [Self] {
+        static values: &'static [ErrorCode] = &[
+            ErrorCode::EmailIsEmpty,
+            ErrorCode::EmailFormatInvalid,
+            ErrorCode::EmailAlreadyExists,
+            ErrorCode::PasswordIsEmpty,
+            ErrorCode::PasswordTooLong,
+            ErrorCode::PasswordContainsForbidCharacters,
+            ErrorCode::PasswordFormatInvalid,
+            ErrorCode::PasswordNotMatch,
+            ErrorCode::UserNameTooLong,
+            ErrorCode::UserNameContainForbiddenCharacters,
+            ErrorCode::UserNameIsEmpty,
+            ErrorCode::UserIdInvalid,
+            ErrorCode::UserUnauthorized,
+            ErrorCode::UserNotExist,
+            ErrorCode::ServerError,
+            ErrorCode::InternalError,
+        ];
+        values
+    }
+
+    fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor {
+        static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT;
+        descriptor.get(|| {
+            ::protobuf::reflect::EnumDescriptor::new_pb_name::<ErrorCode>("ErrorCode", file_descriptor_proto())
+        })
+    }
+}
+
+impl ::std::marker::Copy for ErrorCode {
+}
+
+impl ::std::default::Default for ErrorCode {
+    fn default() -> Self {
+        ErrorCode::EmailIsEmpty
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ErrorCode {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self))
+    }
+}
+
+static file_descriptor_proto_data: &'static [u8] = b"\
+    \n\x0cerrors.proto*\xff\x02\n\tErrorCode\x12\x10\n\x0cEmailIsEmpty\x10\0\
+    \x12\x16\n\x12EmailFormatInvalid\x10\x01\x12\x16\n\x12EmailAlreadyExists\
+    \x10\x02\x12\x13\n\x0fPasswordIsEmpty\x10\n\x12\x13\n\x0fPasswordTooLong\
+    \x10\x0b\x12$\n\x20PasswordContainsForbidCharacters\x10\x0c\x12\x19\n\
+    \x15PasswordFormatInvalid\x10\r\x12\x14\n\x10PasswordNotMatch\x10\x0e\
+    \x12\x13\n\x0fUserNameTooLong\x10\x14\x12&\n\"UserNameContainForbiddenCh\
+    aracters\x10\x15\x12\x13\n\x0fUserNameIsEmpty\x10\x16\x12\x11\n\rUserIdI\
+    nvalid\x10\x17\x12\x14\n\x10UserUnauthorized\x10\x18\x12\x10\n\x0cUserNo\
+    tExist\x10\x19\x12\x0f\n\x0bServerError\x10c\x12\x11\n\rInternalError\
+    \x10dJ\xba\x05\n\x06\x12\x04\0\0\x13\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\
+    \n\n\n\x02\x05\0\x12\x04\x02\0\x13\x01\n\n\n\x03\x05\0\x01\x12\x03\x02\
+    \x05\x0e\n\x0b\n\x04\x05\0\x02\0\x12\x03\x03\x04\x15\n\x0c\n\x05\x05\0\
+    \x02\0\x01\x12\x03\x03\x04\x10\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x03\
+    \x13\x14\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x04\x04\x1b\n\x0c\n\x05\x05\0\
+    \x02\x01\x01\x12\x03\x04\x04\x16\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\
+    \x04\x19\x1a\n\x0b\n\x04\x05\0\x02\x02\x12\x03\x05\x04\x1b\n\x0c\n\x05\
+    \x05\0\x02\x02\x01\x12\x03\x05\x04\x16\n\x0c\n\x05\x05\0\x02\x02\x02\x12\
+    \x03\x05\x19\x1a\n\x0b\n\x04\x05\0\x02\x03\x12\x03\x06\x04\x19\n\x0c\n\
+    \x05\x05\0\x02\x03\x01\x12\x03\x06\x04\x13\n\x0c\n\x05\x05\0\x02\x03\x02\
+    \x12\x03\x06\x16\x18\n\x0b\n\x04\x05\0\x02\x04\x12\x03\x07\x04\x19\n\x0c\
+    \n\x05\x05\0\x02\x04\x01\x12\x03\x07\x04\x13\n\x0c\n\x05\x05\0\x02\x04\
+    \x02\x12\x03\x07\x16\x18\n\x0b\n\x04\x05\0\x02\x05\x12\x03\x08\x04*\n\
+    \x0c\n\x05\x05\0\x02\x05\x01\x12\x03\x08\x04$\n\x0c\n\x05\x05\0\x02\x05\
+    \x02\x12\x03\x08')\n\x0b\n\x04\x05\0\x02\x06\x12\x03\t\x04\x1f\n\x0c\n\
+    \x05\x05\0\x02\x06\x01\x12\x03\t\x04\x19\n\x0c\n\x05\x05\0\x02\x06\x02\
+    \x12\x03\t\x1c\x1e\n\x0b\n\x04\x05\0\x02\x07\x12\x03\n\x04\x1a\n\x0c\n\
+    \x05\x05\0\x02\x07\x01\x12\x03\n\x04\x14\n\x0c\n\x05\x05\0\x02\x07\x02\
+    \x12\x03\n\x17\x19\n\x0b\n\x04\x05\0\x02\x08\x12\x03\x0b\x04\x19\n\x0c\n\
+    \x05\x05\0\x02\x08\x01\x12\x03\x0b\x04\x13\n\x0c\n\x05\x05\0\x02\x08\x02\
+    \x12\x03\x0b\x16\x18\n\x0b\n\x04\x05\0\x02\t\x12\x03\x0c\x04,\n\x0c\n\
+    \x05\x05\0\x02\t\x01\x12\x03\x0c\x04&\n\x0c\n\x05\x05\0\x02\t\x02\x12\
+    \x03\x0c)+\n\x0b\n\x04\x05\0\x02\n\x12\x03\r\x04\x19\n\x0c\n\x05\x05\0\
+    \x02\n\x01\x12\x03\r\x04\x13\n\x0c\n\x05\x05\0\x02\n\x02\x12\x03\r\x16\
+    \x18\n\x0b\n\x04\x05\0\x02\x0b\x12\x03\x0e\x04\x17\n\x0c\n\x05\x05\0\x02\
+    \x0b\x01\x12\x03\x0e\x04\x11\n\x0c\n\x05\x05\0\x02\x0b\x02\x12\x03\x0e\
+    \x14\x16\n\x0b\n\x04\x05\0\x02\x0c\x12\x03\x0f\x04\x1a\n\x0c\n\x05\x05\0\
+    \x02\x0c\x01\x12\x03\x0f\x04\x14\n\x0c\n\x05\x05\0\x02\x0c\x02\x12\x03\
+    \x0f\x17\x19\n\x0b\n\x04\x05\0\x02\r\x12\x03\x10\x04\x16\n\x0c\n\x05\x05\
+    \0\x02\r\x01\x12\x03\x10\x04\x10\n\x0c\n\x05\x05\0\x02\r\x02\x12\x03\x10\
+    \x13\x15\n\x0b\n\x04\x05\0\x02\x0e\x12\x03\x11\x04\x15\n\x0c\n\x05\x05\0\
+    \x02\x0e\x01\x12\x03\x11\x04\x0f\n\x0c\n\x05\x05\0\x02\x0e\x02\x12\x03\
+    \x11\x12\x14\n\x0b\n\x04\x05\0\x02\x0f\x12\x03\x12\x04\x18\n\x0c\n\x05\
+    \x05\0\x02\x0f\x01\x12\x03\x12\x04\x11\n\x0c\n\x05\x05\0\x02\x0f\x02\x12\
+    \x03\x12\x14\x17b\x06proto3\
+";
+
+static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
+
+fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
+    ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap()
+}
+
+pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
+    file_descriptor_proto_lazy.get(|| {
+        parse_descriptor_proto()
+    })
+}

+ 10 - 0
rust-lib/flowy-user-infra/src/protobuf/model/mod.rs

@@ -0,0 +1,10 @@
+// Auto-generated, do not edit 
+
+mod errors; 
+pub use errors::*; 
+
+mod user_profile; 
+pub use user_profile::*; 
+
+mod auth; 
+pub use auth::*; 

+ 1351 - 0
rust-lib/flowy-user-infra/src/protobuf/model/user_profile.rs

@@ -0,0 +1,1351 @@
+// This file is generated by rust-protobuf 2.22.1. Do not edit
+// @generated
+
+// https://github.com/rust-lang/rust-clippy/issues/702
+#![allow(unknown_lints)]
+#![allow(clippy::all)]
+
+#![allow(unused_attributes)]
+#![cfg_attr(rustfmt, rustfmt::skip)]
+
+#![allow(box_pointers)]
+#![allow(dead_code)]
+#![allow(missing_docs)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+#![allow(non_upper_case_globals)]
+#![allow(trivial_casts)]
+#![allow(unused_imports)]
+#![allow(unused_results)]
+//! Generated file from `user_profile.proto`
+
+/// Generated files are compatible only with the same version
+/// of protobuf runtime.
+// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_22_1;
+
+#[derive(PartialEq,Clone,Default)]
+pub struct UserToken {
+    // message fields
+    pub token: ::std::string::String,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a UserToken {
+    fn default() -> &'a UserToken {
+        <UserToken as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl UserToken {
+    pub fn new() -> UserToken {
+        ::std::default::Default::default()
+    }
+
+    // string token = 1;
+
+
+    pub fn get_token(&self) -> &str {
+        &self.token
+    }
+    pub fn clear_token(&mut self) {
+        self.token.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_token(&mut self, v: ::std::string::String) {
+        self.token = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_token(&mut self) -> &mut ::std::string::String {
+        &mut self.token
+    }
+
+    // Take field
+    pub fn take_token(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.token, ::std::string::String::new())
+    }
+}
+
+impl ::protobuf::Message for UserToken {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.token)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if !self.token.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.token);
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        if !self.token.is_empty() {
+            os.write_string(1, &self.token)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &dyn (::std::any::Any) {
+        self as &dyn (::std::any::Any)
+    }
+    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
+        self as &mut dyn (::std::any::Any)
+    }
+    fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> UserToken {
+        UserToken::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
+        descriptor.get(|| {
+            let mut fields = ::std::vec::Vec::new();
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "token",
+                |m: &UserToken| { &m.token },
+                |m: &mut UserToken| { &mut m.token },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<UserToken>(
+                "UserToken",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static UserToken {
+        static instance: ::protobuf::rt::LazyV2<UserToken> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(UserToken::new)
+    }
+}
+
+impl ::protobuf::Clear for UserToken {
+    fn clear(&mut self) {
+        self.token.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for UserToken {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for UserToken {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct UserProfile {
+    // message fields
+    pub id: ::std::string::String,
+    pub email: ::std::string::String,
+    pub name: ::std::string::String,
+    pub token: ::std::string::String,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a UserProfile {
+    fn default() -> &'a UserProfile {
+        <UserProfile as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl UserProfile {
+    pub fn new() -> UserProfile {
+        ::std::default::Default::default()
+    }
+
+    // string id = 1;
+
+
+    pub fn get_id(&self) -> &str {
+        &self.id
+    }
+    pub fn clear_id(&mut self) {
+        self.id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_id(&mut self, v: ::std::string::String) {
+        self.id = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_id(&mut self) -> &mut ::std::string::String {
+        &mut self.id
+    }
+
+    // Take field
+    pub fn take_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.id, ::std::string::String::new())
+    }
+
+    // string email = 2;
+
+
+    pub fn get_email(&self) -> &str {
+        &self.email
+    }
+    pub fn clear_email(&mut self) {
+        self.email.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_email(&mut self, v: ::std::string::String) {
+        self.email = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_email(&mut self) -> &mut ::std::string::String {
+        &mut self.email
+    }
+
+    // Take field
+    pub fn take_email(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.email, ::std::string::String::new())
+    }
+
+    // string name = 3;
+
+
+    pub fn get_name(&self) -> &str {
+        &self.name
+    }
+    pub fn clear_name(&mut self) {
+        self.name.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_name(&mut self, v: ::std::string::String) {
+        self.name = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_name(&mut self) -> &mut ::std::string::String {
+        &mut self.name
+    }
+
+    // Take field
+    pub fn take_name(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.name, ::std::string::String::new())
+    }
+
+    // string token = 4;
+
+
+    pub fn get_token(&self) -> &str {
+        &self.token
+    }
+    pub fn clear_token(&mut self) {
+        self.token.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_token(&mut self, v: ::std::string::String) {
+        self.token = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_token(&mut self) -> &mut ::std::string::String {
+        &mut self.token
+    }
+
+    // Take field
+    pub fn take_token(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.token, ::std::string::String::new())
+    }
+}
+
+impl ::protobuf::Message for UserProfile {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.email)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?;
+                },
+                4 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.token)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if !self.id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.id);
+        }
+        if !self.email.is_empty() {
+            my_size += ::protobuf::rt::string_size(2, &self.email);
+        }
+        if !self.name.is_empty() {
+            my_size += ::protobuf::rt::string_size(3, &self.name);
+        }
+        if !self.token.is_empty() {
+            my_size += ::protobuf::rt::string_size(4, &self.token);
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        if !self.id.is_empty() {
+            os.write_string(1, &self.id)?;
+        }
+        if !self.email.is_empty() {
+            os.write_string(2, &self.email)?;
+        }
+        if !self.name.is_empty() {
+            os.write_string(3, &self.name)?;
+        }
+        if !self.token.is_empty() {
+            os.write_string(4, &self.token)?;
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &dyn (::std::any::Any) {
+        self as &dyn (::std::any::Any)
+    }
+    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
+        self as &mut dyn (::std::any::Any)
+    }
+    fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> UserProfile {
+        UserProfile::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
+        descriptor.get(|| {
+            let mut fields = ::std::vec::Vec::new();
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "id",
+                |m: &UserProfile| { &m.id },
+                |m: &mut UserProfile| { &mut m.id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "email",
+                |m: &UserProfile| { &m.email },
+                |m: &mut UserProfile| { &mut m.email },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "name",
+                |m: &UserProfile| { &m.name },
+                |m: &mut UserProfile| { &mut m.name },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "token",
+                |m: &UserProfile| { &m.token },
+                |m: &mut UserProfile| { &mut m.token },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<UserProfile>(
+                "UserProfile",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static UserProfile {
+        static instance: ::protobuf::rt::LazyV2<UserProfile> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(UserProfile::new)
+    }
+}
+
+impl ::protobuf::Clear for UserProfile {
+    fn clear(&mut self) {
+        self.id.clear();
+        self.email.clear();
+        self.name.clear();
+        self.token.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for UserProfile {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for UserProfile {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct UpdateUserRequest {
+    // message fields
+    pub id: ::std::string::String,
+    // message oneof groups
+    pub one_of_name: ::std::option::Option<UpdateUserRequest_oneof_one_of_name>,
+    pub one_of_email: ::std::option::Option<UpdateUserRequest_oneof_one_of_email>,
+    pub one_of_password: ::std::option::Option<UpdateUserRequest_oneof_one_of_password>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a UpdateUserRequest {
+    fn default() -> &'a UpdateUserRequest {
+        <UpdateUserRequest as ::protobuf::Message>::default_instance()
+    }
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum UpdateUserRequest_oneof_one_of_name {
+    name(::std::string::String),
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum UpdateUserRequest_oneof_one_of_email {
+    email(::std::string::String),
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum UpdateUserRequest_oneof_one_of_password {
+    password(::std::string::String),
+}
+
+impl UpdateUserRequest {
+    pub fn new() -> UpdateUserRequest {
+        ::std::default::Default::default()
+    }
+
+    // string id = 1;
+
+
+    pub fn get_id(&self) -> &str {
+        &self.id
+    }
+    pub fn clear_id(&mut self) {
+        self.id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_id(&mut self, v: ::std::string::String) {
+        self.id = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_id(&mut self) -> &mut ::std::string::String {
+        &mut self.id
+    }
+
+    // Take field
+    pub fn take_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.id, ::std::string::String::new())
+    }
+
+    // string name = 2;
+
+
+    pub fn get_name(&self) -> &str {
+        match self.one_of_name {
+            ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_name::name(ref v)) => v,
+            _ => "",
+        }
+    }
+    pub fn clear_name(&mut self) {
+        self.one_of_name = ::std::option::Option::None;
+    }
+
+    pub fn has_name(&self) -> bool {
+        match self.one_of_name {
+            ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_name::name(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_name(&mut self, v: ::std::string::String) {
+        self.one_of_name = ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_name::name(v))
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_name(&mut self) -> &mut ::std::string::String {
+        if let ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_name::name(_)) = self.one_of_name {
+        } else {
+            self.one_of_name = ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_name::name(::std::string::String::new()));
+        }
+        match self.one_of_name {
+            ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_name::name(ref mut v)) => v,
+            _ => panic!(),
+        }
+    }
+
+    // Take field
+    pub fn take_name(&mut self) -> ::std::string::String {
+        if self.has_name() {
+            match self.one_of_name.take() {
+                ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_name::name(v)) => v,
+                _ => panic!(),
+            }
+        } else {
+            ::std::string::String::new()
+        }
+    }
+
+    // string email = 3;
+
+
+    pub fn get_email(&self) -> &str {
+        match self.one_of_email {
+            ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_email::email(ref v)) => v,
+            _ => "",
+        }
+    }
+    pub fn clear_email(&mut self) {
+        self.one_of_email = ::std::option::Option::None;
+    }
+
+    pub fn has_email(&self) -> bool {
+        match self.one_of_email {
+            ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_email::email(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_email(&mut self, v: ::std::string::String) {
+        self.one_of_email = ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_email::email(v))
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_email(&mut self) -> &mut ::std::string::String {
+        if let ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_email::email(_)) = self.one_of_email {
+        } else {
+            self.one_of_email = ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_email::email(::std::string::String::new()));
+        }
+        match self.one_of_email {
+            ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_email::email(ref mut v)) => v,
+            _ => panic!(),
+        }
+    }
+
+    // Take field
+    pub fn take_email(&mut self) -> ::std::string::String {
+        if self.has_email() {
+            match self.one_of_email.take() {
+                ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_email::email(v)) => v,
+                _ => panic!(),
+            }
+        } else {
+            ::std::string::String::new()
+        }
+    }
+
+    // string password = 4;
+
+
+    pub fn get_password(&self) -> &str {
+        match self.one_of_password {
+            ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_password::password(ref v)) => v,
+            _ => "",
+        }
+    }
+    pub fn clear_password(&mut self) {
+        self.one_of_password = ::std::option::Option::None;
+    }
+
+    pub fn has_password(&self) -> bool {
+        match self.one_of_password {
+            ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_password::password(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_password(&mut self, v: ::std::string::String) {
+        self.one_of_password = ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_password::password(v))
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_password(&mut self) -> &mut ::std::string::String {
+        if let ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_password::password(_)) = self.one_of_password {
+        } else {
+            self.one_of_password = ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_password::password(::std::string::String::new()));
+        }
+        match self.one_of_password {
+            ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_password::password(ref mut v)) => v,
+            _ => panic!(),
+        }
+    }
+
+    // Take field
+    pub fn take_password(&mut self) -> ::std::string::String {
+        if self.has_password() {
+            match self.one_of_password.take() {
+                ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_password::password(v)) => v,
+                _ => panic!(),
+            }
+        } else {
+            ::std::string::String::new()
+        }
+    }
+}
+
+impl ::protobuf::Message for UpdateUserRequest {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?;
+                },
+                2 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_name = ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_name::name(is.read_string()?));
+                },
+                3 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_email = ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_email::email(is.read_string()?));
+                },
+                4 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_password = ::std::option::Option::Some(UpdateUserRequest_oneof_one_of_password::password(is.read_string()?));
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if !self.id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.id);
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_name {
+            match v {
+                &UpdateUserRequest_oneof_one_of_name::name(ref v) => {
+                    my_size += ::protobuf::rt::string_size(2, &v);
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_email {
+            match v {
+                &UpdateUserRequest_oneof_one_of_email::email(ref v) => {
+                    my_size += ::protobuf::rt::string_size(3, &v);
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_password {
+            match v {
+                &UpdateUserRequest_oneof_one_of_password::password(ref v) => {
+                    my_size += ::protobuf::rt::string_size(4, &v);
+                },
+            };
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        if !self.id.is_empty() {
+            os.write_string(1, &self.id)?;
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_name {
+            match v {
+                &UpdateUserRequest_oneof_one_of_name::name(ref v) => {
+                    os.write_string(2, v)?;
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_email {
+            match v {
+                &UpdateUserRequest_oneof_one_of_email::email(ref v) => {
+                    os.write_string(3, v)?;
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_password {
+            match v {
+                &UpdateUserRequest_oneof_one_of_password::password(ref v) => {
+                    os.write_string(4, v)?;
+                },
+            };
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &dyn (::std::any::Any) {
+        self as &dyn (::std::any::Any)
+    }
+    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
+        self as &mut dyn (::std::any::Any)
+    }
+    fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> UpdateUserRequest {
+        UpdateUserRequest::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
+        descriptor.get(|| {
+            let mut fields = ::std::vec::Vec::new();
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "id",
+                |m: &UpdateUserRequest| { &m.id },
+                |m: &mut UpdateUserRequest| { &mut m.id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>(
+                "name",
+                UpdateUserRequest::has_name,
+                UpdateUserRequest::get_name,
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>(
+                "email",
+                UpdateUserRequest::has_email,
+                UpdateUserRequest::get_email,
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>(
+                "password",
+                UpdateUserRequest::has_password,
+                UpdateUserRequest::get_password,
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<UpdateUserRequest>(
+                "UpdateUserRequest",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static UpdateUserRequest {
+        static instance: ::protobuf::rt::LazyV2<UpdateUserRequest> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(UpdateUserRequest::new)
+    }
+}
+
+impl ::protobuf::Clear for UpdateUserRequest {
+    fn clear(&mut self) {
+        self.id.clear();
+        self.one_of_name = ::std::option::Option::None;
+        self.one_of_email = ::std::option::Option::None;
+        self.one_of_password = ::std::option::Option::None;
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for UpdateUserRequest {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for UpdateUserRequest {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct UpdateUserParams {
+    // message fields
+    pub id: ::std::string::String,
+    // message oneof groups
+    pub one_of_name: ::std::option::Option<UpdateUserParams_oneof_one_of_name>,
+    pub one_of_email: ::std::option::Option<UpdateUserParams_oneof_one_of_email>,
+    pub one_of_password: ::std::option::Option<UpdateUserParams_oneof_one_of_password>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a UpdateUserParams {
+    fn default() -> &'a UpdateUserParams {
+        <UpdateUserParams as ::protobuf::Message>::default_instance()
+    }
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum UpdateUserParams_oneof_one_of_name {
+    name(::std::string::String),
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum UpdateUserParams_oneof_one_of_email {
+    email(::std::string::String),
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum UpdateUserParams_oneof_one_of_password {
+    password(::std::string::String),
+}
+
+impl UpdateUserParams {
+    pub fn new() -> UpdateUserParams {
+        ::std::default::Default::default()
+    }
+
+    // string id = 1;
+
+
+    pub fn get_id(&self) -> &str {
+        &self.id
+    }
+    pub fn clear_id(&mut self) {
+        self.id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_id(&mut self, v: ::std::string::String) {
+        self.id = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_id(&mut self) -> &mut ::std::string::String {
+        &mut self.id
+    }
+
+    // Take field
+    pub fn take_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.id, ::std::string::String::new())
+    }
+
+    // string name = 2;
+
+
+    pub fn get_name(&self) -> &str {
+        match self.one_of_name {
+            ::std::option::Option::Some(UpdateUserParams_oneof_one_of_name::name(ref v)) => v,
+            _ => "",
+        }
+    }
+    pub fn clear_name(&mut self) {
+        self.one_of_name = ::std::option::Option::None;
+    }
+
+    pub fn has_name(&self) -> bool {
+        match self.one_of_name {
+            ::std::option::Option::Some(UpdateUserParams_oneof_one_of_name::name(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_name(&mut self, v: ::std::string::String) {
+        self.one_of_name = ::std::option::Option::Some(UpdateUserParams_oneof_one_of_name::name(v))
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_name(&mut self) -> &mut ::std::string::String {
+        if let ::std::option::Option::Some(UpdateUserParams_oneof_one_of_name::name(_)) = self.one_of_name {
+        } else {
+            self.one_of_name = ::std::option::Option::Some(UpdateUserParams_oneof_one_of_name::name(::std::string::String::new()));
+        }
+        match self.one_of_name {
+            ::std::option::Option::Some(UpdateUserParams_oneof_one_of_name::name(ref mut v)) => v,
+            _ => panic!(),
+        }
+    }
+
+    // Take field
+    pub fn take_name(&mut self) -> ::std::string::String {
+        if self.has_name() {
+            match self.one_of_name.take() {
+                ::std::option::Option::Some(UpdateUserParams_oneof_one_of_name::name(v)) => v,
+                _ => panic!(),
+            }
+        } else {
+            ::std::string::String::new()
+        }
+    }
+
+    // string email = 3;
+
+
+    pub fn get_email(&self) -> &str {
+        match self.one_of_email {
+            ::std::option::Option::Some(UpdateUserParams_oneof_one_of_email::email(ref v)) => v,
+            _ => "",
+        }
+    }
+    pub fn clear_email(&mut self) {
+        self.one_of_email = ::std::option::Option::None;
+    }
+
+    pub fn has_email(&self) -> bool {
+        match self.one_of_email {
+            ::std::option::Option::Some(UpdateUserParams_oneof_one_of_email::email(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_email(&mut self, v: ::std::string::String) {
+        self.one_of_email = ::std::option::Option::Some(UpdateUserParams_oneof_one_of_email::email(v))
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_email(&mut self) -> &mut ::std::string::String {
+        if let ::std::option::Option::Some(UpdateUserParams_oneof_one_of_email::email(_)) = self.one_of_email {
+        } else {
+            self.one_of_email = ::std::option::Option::Some(UpdateUserParams_oneof_one_of_email::email(::std::string::String::new()));
+        }
+        match self.one_of_email {
+            ::std::option::Option::Some(UpdateUserParams_oneof_one_of_email::email(ref mut v)) => v,
+            _ => panic!(),
+        }
+    }
+
+    // Take field
+    pub fn take_email(&mut self) -> ::std::string::String {
+        if self.has_email() {
+            match self.one_of_email.take() {
+                ::std::option::Option::Some(UpdateUserParams_oneof_one_of_email::email(v)) => v,
+                _ => panic!(),
+            }
+        } else {
+            ::std::string::String::new()
+        }
+    }
+
+    // string password = 4;
+
+
+    pub fn get_password(&self) -> &str {
+        match self.one_of_password {
+            ::std::option::Option::Some(UpdateUserParams_oneof_one_of_password::password(ref v)) => v,
+            _ => "",
+        }
+    }
+    pub fn clear_password(&mut self) {
+        self.one_of_password = ::std::option::Option::None;
+    }
+
+    pub fn has_password(&self) -> bool {
+        match self.one_of_password {
+            ::std::option::Option::Some(UpdateUserParams_oneof_one_of_password::password(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_password(&mut self, v: ::std::string::String) {
+        self.one_of_password = ::std::option::Option::Some(UpdateUserParams_oneof_one_of_password::password(v))
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_password(&mut self) -> &mut ::std::string::String {
+        if let ::std::option::Option::Some(UpdateUserParams_oneof_one_of_password::password(_)) = self.one_of_password {
+        } else {
+            self.one_of_password = ::std::option::Option::Some(UpdateUserParams_oneof_one_of_password::password(::std::string::String::new()));
+        }
+        match self.one_of_password {
+            ::std::option::Option::Some(UpdateUserParams_oneof_one_of_password::password(ref mut v)) => v,
+            _ => panic!(),
+        }
+    }
+
+    // Take field
+    pub fn take_password(&mut self) -> ::std::string::String {
+        if self.has_password() {
+            match self.one_of_password.take() {
+                ::std::option::Option::Some(UpdateUserParams_oneof_one_of_password::password(v)) => v,
+                _ => panic!(),
+            }
+        } else {
+            ::std::string::String::new()
+        }
+    }
+}
+
+impl ::protobuf::Message for UpdateUserParams {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?;
+                },
+                2 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_name = ::std::option::Option::Some(UpdateUserParams_oneof_one_of_name::name(is.read_string()?));
+                },
+                3 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_email = ::std::option::Option::Some(UpdateUserParams_oneof_one_of_email::email(is.read_string()?));
+                },
+                4 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_password = ::std::option::Option::Some(UpdateUserParams_oneof_one_of_password::password(is.read_string()?));
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if !self.id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.id);
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_name {
+            match v {
+                &UpdateUserParams_oneof_one_of_name::name(ref v) => {
+                    my_size += ::protobuf::rt::string_size(2, &v);
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_email {
+            match v {
+                &UpdateUserParams_oneof_one_of_email::email(ref v) => {
+                    my_size += ::protobuf::rt::string_size(3, &v);
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_password {
+            match v {
+                &UpdateUserParams_oneof_one_of_password::password(ref v) => {
+                    my_size += ::protobuf::rt::string_size(4, &v);
+                },
+            };
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        if !self.id.is_empty() {
+            os.write_string(1, &self.id)?;
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_name {
+            match v {
+                &UpdateUserParams_oneof_one_of_name::name(ref v) => {
+                    os.write_string(2, v)?;
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_email {
+            match v {
+                &UpdateUserParams_oneof_one_of_email::email(ref v) => {
+                    os.write_string(3, v)?;
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_password {
+            match v {
+                &UpdateUserParams_oneof_one_of_password::password(ref v) => {
+                    os.write_string(4, v)?;
+                },
+            };
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &dyn (::std::any::Any) {
+        self as &dyn (::std::any::Any)
+    }
+    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
+        self as &mut dyn (::std::any::Any)
+    }
+    fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> UpdateUserParams {
+        UpdateUserParams::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
+        descriptor.get(|| {
+            let mut fields = ::std::vec::Vec::new();
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "id",
+                |m: &UpdateUserParams| { &m.id },
+                |m: &mut UpdateUserParams| { &mut m.id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>(
+                "name",
+                UpdateUserParams::has_name,
+                UpdateUserParams::get_name,
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>(
+                "email",
+                UpdateUserParams::has_email,
+                UpdateUserParams::get_email,
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>(
+                "password",
+                UpdateUserParams::has_password,
+                UpdateUserParams::get_password,
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<UpdateUserParams>(
+                "UpdateUserParams",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static UpdateUserParams {
+        static instance: ::protobuf::rt::LazyV2<UpdateUserParams> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(UpdateUserParams::new)
+    }
+}
+
+impl ::protobuf::Clear for UpdateUserParams {
+    fn clear(&mut self) {
+        self.id.clear();
+        self.one_of_name = ::std::option::Option::None;
+        self.one_of_email = ::std::option::Option::None;
+        self.one_of_password = ::std::option::Option::None;
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for UpdateUserParams {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for UpdateUserParams {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+static file_descriptor_proto_data: &'static [u8] = b"\
+    \n\x12user_profile.proto\"!\n\tUserToken\x12\x14\n\x05token\x18\x01\x20\
+    \x01(\tR\x05token\"]\n\x0bUserProfile\x12\x0e\n\x02id\x18\x01\x20\x01(\t\
+    R\x02id\x12\x14\n\x05email\x18\x02\x20\x01(\tR\x05email\x12\x12\n\x04nam\
+    e\x18\x03\x20\x01(\tR\x04name\x12\x14\n\x05token\x18\x04\x20\x01(\tR\x05\
+    token\"\xa1\x01\n\x11UpdateUserRequest\x12\x0e\n\x02id\x18\x01\x20\x01(\
+    \tR\x02id\x12\x14\n\x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x16\n\x05\
+    email\x18\x03\x20\x01(\tH\x01R\x05email\x12\x1c\n\x08password\x18\x04\
+    \x20\x01(\tH\x02R\x08passwordB\r\n\x0bone_of_nameB\x0e\n\x0cone_of_email\
+    B\x11\n\x0fone_of_password\"\xa0\x01\n\x10UpdateUserParams\x12\x0e\n\x02\
+    id\x18\x01\x20\x01(\tR\x02id\x12\x14\n\x04name\x18\x02\x20\x01(\tH\0R\
+    \x04name\x12\x16\n\x05email\x18\x03\x20\x01(\tH\x01R\x05email\x12\x1c\n\
+    \x08password\x18\x04\x20\x01(\tH\x02R\x08passwordB\r\n\x0bone_of_nameB\
+    \x0e\n\x0cone_of_emailB\x11\n\x0fone_of_passwordJ\xdf\x07\n\x06\x12\x04\
+    \0\0\x16\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\
+    \0\x04\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x11\n\x0b\n\x04\x04\0\x02\
+    \0\x12\x03\x03\x04\x15\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x03\x04\n\n\
+    \x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\x0b\x10\n\x0c\n\x05\x04\0\x02\0\
+    \x03\x12\x03\x03\x13\x14\n\n\n\x02\x04\x01\x12\x04\x05\0\n\x01\n\n\n\x03\
+    \x04\x01\x01\x12\x03\x05\x08\x13\n\x0b\n\x04\x04\x01\x02\0\x12\x03\x06\
+    \x04\x12\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\x06\x04\n\n\x0c\n\x05\x04\
+    \x01\x02\0\x01\x12\x03\x06\x0b\r\n\x0c\n\x05\x04\x01\x02\0\x03\x12\x03\
+    \x06\x10\x11\n\x0b\n\x04\x04\x01\x02\x01\x12\x03\x07\x04\x15\n\x0c\n\x05\
+    \x04\x01\x02\x01\x05\x12\x03\x07\x04\n\n\x0c\n\x05\x04\x01\x02\x01\x01\
+    \x12\x03\x07\x0b\x10\n\x0c\n\x05\x04\x01\x02\x01\x03\x12\x03\x07\x13\x14\
+    \n\x0b\n\x04\x04\x01\x02\x02\x12\x03\x08\x04\x14\n\x0c\n\x05\x04\x01\x02\
+    \x02\x05\x12\x03\x08\x04\n\n\x0c\n\x05\x04\x01\x02\x02\x01\x12\x03\x08\
+    \x0b\x0f\n\x0c\n\x05\x04\x01\x02\x02\x03\x12\x03\x08\x12\x13\n\x0b\n\x04\
+    \x04\x01\x02\x03\x12\x03\t\x04\x15\n\x0c\n\x05\x04\x01\x02\x03\x05\x12\
+    \x03\t\x04\n\n\x0c\n\x05\x04\x01\x02\x03\x01\x12\x03\t\x0b\x10\n\x0c\n\
+    \x05\x04\x01\x02\x03\x03\x12\x03\t\x13\x14\n\n\n\x02\x04\x02\x12\x04\x0b\
+    \0\x10\x01\n\n\n\x03\x04\x02\x01\x12\x03\x0b\x08\x19\n\x0b\n\x04\x04\x02\
+    \x02\0\x12\x03\x0c\x04\x12\n\x0c\n\x05\x04\x02\x02\0\x05\x12\x03\x0c\x04\
+    \n\n\x0c\n\x05\x04\x02\x02\0\x01\x12\x03\x0c\x0b\r\n\x0c\n\x05\x04\x02\
+    \x02\0\x03\x12\x03\x0c\x10\x11\n\x0b\n\x04\x04\x02\x08\0\x12\x03\r\x04*\
+    \n\x0c\n\x05\x04\x02\x08\0\x01\x12\x03\r\n\x15\n\x0b\n\x04\x04\x02\x02\
+    \x01\x12\x03\r\x18(\n\x0c\n\x05\x04\x02\x02\x01\x05\x12\x03\r\x18\x1e\n\
+    \x0c\n\x05\x04\x02\x02\x01\x01\x12\x03\r\x1f#\n\x0c\n\x05\x04\x02\x02\
+    \x01\x03\x12\x03\r&'\n\x0b\n\x04\x04\x02\x08\x01\x12\x03\x0e\x04,\n\x0c\
+    \n\x05\x04\x02\x08\x01\x01\x12\x03\x0e\n\x16\n\x0b\n\x04\x04\x02\x02\x02\
+    \x12\x03\x0e\x19*\n\x0c\n\x05\x04\x02\x02\x02\x05\x12\x03\x0e\x19\x1f\n\
+    \x0c\n\x05\x04\x02\x02\x02\x01\x12\x03\x0e\x20%\n\x0c\n\x05\x04\x02\x02\
+    \x02\x03\x12\x03\x0e()\n\x0b\n\x04\x04\x02\x08\x02\x12\x03\x0f\x042\n\
+    \x0c\n\x05\x04\x02\x08\x02\x01\x12\x03\x0f\n\x19\n\x0b\n\x04\x04\x02\x02\
+    \x03\x12\x03\x0f\x1c0\n\x0c\n\x05\x04\x02\x02\x03\x05\x12\x03\x0f\x1c\"\
+    \n\x0c\n\x05\x04\x02\x02\x03\x01\x12\x03\x0f#+\n\x0c\n\x05\x04\x02\x02\
+    \x03\x03\x12\x03\x0f./\n\n\n\x02\x04\x03\x12\x04\x11\0\x16\x01\n\n\n\x03\
+    \x04\x03\x01\x12\x03\x11\x08\x18\n\x0b\n\x04\x04\x03\x02\0\x12\x03\x12\
+    \x04\x12\n\x0c\n\x05\x04\x03\x02\0\x05\x12\x03\x12\x04\n\n\x0c\n\x05\x04\
+    \x03\x02\0\x01\x12\x03\x12\x0b\r\n\x0c\n\x05\x04\x03\x02\0\x03\x12\x03\
+    \x12\x10\x11\n\x0b\n\x04\x04\x03\x08\0\x12\x03\x13\x04*\n\x0c\n\x05\x04\
+    \x03\x08\0\x01\x12\x03\x13\n\x15\n\x0b\n\x04\x04\x03\x02\x01\x12\x03\x13\
+    \x18(\n\x0c\n\x05\x04\x03\x02\x01\x05\x12\x03\x13\x18\x1e\n\x0c\n\x05\
+    \x04\x03\x02\x01\x01\x12\x03\x13\x1f#\n\x0c\n\x05\x04\x03\x02\x01\x03\
+    \x12\x03\x13&'\n\x0b\n\x04\x04\x03\x08\x01\x12\x03\x14\x04,\n\x0c\n\x05\
+    \x04\x03\x08\x01\x01\x12\x03\x14\n\x16\n\x0b\n\x04\x04\x03\x02\x02\x12\
+    \x03\x14\x19*\n\x0c\n\x05\x04\x03\x02\x02\x05\x12\x03\x14\x19\x1f\n\x0c\
+    \n\x05\x04\x03\x02\x02\x01\x12\x03\x14\x20%\n\x0c\n\x05\x04\x03\x02\x02\
+    \x03\x12\x03\x14()\n\x0b\n\x04\x04\x03\x08\x02\x12\x03\x15\x042\n\x0c\n\
+    \x05\x04\x03\x08\x02\x01\x12\x03\x15\n\x19\n\x0b\n\x04\x04\x03\x02\x03\
+    \x12\x03\x15\x1c0\n\x0c\n\x05\x04\x03\x02\x03\x05\x12\x03\x15\x1c\"\n\
+    \x0c\n\x05\x04\x03\x02\x03\x01\x12\x03\x15#+\n\x0c\n\x05\x04\x03\x02\x03\
+    \x03\x12\x03\x15./b\x06proto3\
+";
+
+static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
+
+fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
+    ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap()
+}
+
+pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
+    file_descriptor_proto_lazy.get(|| {
+        parse_descriptor_proto()
+    })
+}

+ 34 - 0
rust-lib/flowy-user-infra/src/protobuf/proto/auth.proto

@@ -0,0 +1,34 @@
+syntax = "proto3";
+
+message SignInRequest {
+    string email = 1;
+    string password = 2;
+    string name = 3;
+}
+message SignInParams {
+    string email = 1;
+    string password = 2;
+    string name = 3;
+}
+message SignInResponse {
+    string user_id = 1;
+    string name = 2;
+    string email = 3;
+    string token = 4;
+}
+message SignUpRequest {
+    string email = 1;
+    string name = 2;
+    string password = 3;
+}
+message SignUpParams {
+    string email = 1;
+    string name = 2;
+    string password = 3;
+}
+message SignUpResponse {
+    string user_id = 1;
+    string name = 2;
+    string email = 3;
+    string token = 4;
+}

+ 20 - 0
rust-lib/flowy-user-infra/src/protobuf/proto/errors.proto

@@ -0,0 +1,20 @@
+syntax = "proto3";
+
+enum ErrorCode {
+    EmailIsEmpty = 0;
+    EmailFormatInvalid = 1;
+    EmailAlreadyExists = 2;
+    PasswordIsEmpty = 10;
+    PasswordTooLong = 11;
+    PasswordContainsForbidCharacters = 12;
+    PasswordFormatInvalid = 13;
+    PasswordNotMatch = 14;
+    UserNameTooLong = 20;
+    UserNameContainForbiddenCharacters = 21;
+    UserNameIsEmpty = 22;
+    UserIdInvalid = 23;
+    UserUnauthorized = 24;
+    UserNotExist = 25;
+    ServerError = 99;
+    InternalError = 100;
+}

+ 23 - 0
rust-lib/flowy-user-infra/src/protobuf/proto/user_profile.proto

@@ -0,0 +1,23 @@
+syntax = "proto3";
+
+message UserToken {
+    string token = 1;
+}
+message UserProfile {
+    string id = 1;
+    string email = 2;
+    string name = 3;
+    string token = 4;
+}
+message UpdateUserRequest {
+    string id = 1;
+    oneof one_of_name { string name = 2; };
+    oneof one_of_email { string email = 3; };
+    oneof one_of_password { string password = 4; };
+}
+message UpdateUserParams {
+    string id = 1;
+    oneof one_of_name { string name = 2; };
+    oneof one_of_email { string email = 3; };
+    oneof one_of_password { string password = 4; };
+}

+ 0 - 0
rust-lib/flowy-user-infra/src/user_default.rs


+ 1 - 8
rust-lib/flowy-user/Cargo.toml

@@ -6,6 +6,7 @@ edition = "2018"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
+flowy-user-infra = { path = "../flowy-user-infra" }
 derive_more = {version = "0.99", features = ["display"]}
 flowy-dispatch = { path = "../flowy-dispatch" }
 flowy-derive = { path = "../flowy-derive" }
@@ -20,13 +21,9 @@ tracing = { version = "0.1", features = ["log"] }
 bytes = "1.0"
 serde = { version = "1.0", features = ["derive"] }
 serde_json = {version = "1.0"}
-validator = "0.12.0"
-rand = { version = "0.8", features=["std_rng"] }
-unicode-segmentation = "1.7.1"
 log = "0.4.14"
 protobuf = {version = "2.18.0"}
 lazy_static = "1.4.0"
-fancy-regex = "0.5.0"
 diesel = {version = "1.4.7", features = ["sqlite"]}
 diesel_derives = {version = "1.4.1", features = ["sqlite"]}
 thread_local = "1.1.3"
@@ -41,10 +38,6 @@ futures-core = { version = "0.3", default-features = false }
 r2d2 = "0.8.9"
 
 [dev-dependencies]
-quickcheck = "0.9.2"
-quickcheck_macros = "0.9.1"
-fake = "~2.3.0"
-claim = "0.4.0"
 flowy-test = { path = "../flowy-test" }
 futures = "0.3.15"
 serial_test = "0.5.1"

+ 17 - 63
rust-lib/flowy-user/src/errors.rs

@@ -1,13 +1,14 @@
 use bytes::Bytes;
-use derive_more::Display;
-use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
+
+use flowy_derive::ProtoBuf;
 use flowy_dispatch::prelude::{EventResponse, ResponseBuilder};
+pub use flowy_user_infra::errors::ErrorCode;
 use std::{convert::TryInto, fmt, fmt::Debug};
 
 #[derive(Debug, Default, Clone, ProtoBuf)]
 pub struct UserError {
     #[pb(index = 1)]
-    pub code: ErrorCode,
+    pub code: i32,
 
     #[pb(index = 2)]
     pub msg: String,
@@ -18,32 +19,20 @@ impl std::fmt::Display for UserError {
 }
 
 macro_rules! static_user_error {
-    ($name:ident, $status:expr) => {
+    ($name:ident, $code:expr) => {
         #[allow(non_snake_case, missing_docs)]
-        pub fn $name() -> UserError {
-            UserError {
-                code: $status,
-                msg: format!("{}", $status),
-            }
-        }
+        pub fn $name() -> UserError { $code.into() }
     };
 }
 
 impl UserError {
     pub(crate) fn new(code: ErrorCode, msg: &str) -> Self {
         Self {
-            code,
+            code: code.value(),
             msg: msg.to_owned(),
         }
     }
 
-    pub(crate) fn code(code: ErrorCode) -> Self {
-        Self {
-            msg: format!("{}", &code),
-            code,
-        }
-    }
-
     pub fn context<T: Debug>(mut self, error: T) -> Self {
         self.msg = format!("{:?}", error);
         self
@@ -66,50 +55,13 @@ impl UserError {
     static_user_error!(internal, ErrorCode::InternalError);
 }
 
-#[derive(Debug, Clone, ProtoBuf_Enum, Display, PartialEq, Eq)]
-pub enum ErrorCode {
-    #[display(fmt = "Email can not be empty or whitespace")]
-    EmailIsEmpty       = 0,
-    #[display(fmt = "Email format is not valid")]
-    EmailFormatInvalid = 1,
-    #[display(fmt = "Email already exists")]
-    EmailAlreadyExists = 2,
-    #[display(fmt = "Password can not be empty or whitespace")]
-    PasswordIsEmpty    = 10,
-    #[display(fmt = "Password format too long")]
-    PasswordTooLong    = 11,
-    #[display(fmt = "Password contains forbidden characters.")]
-    PasswordContainsForbidCharacters = 12,
-    #[display(fmt = "Password should contain a minimum of 6 characters with 1 special 1 letter and 1 numeric")]
-    PasswordFormatInvalid = 13,
-    #[display(fmt = "Password not match")]
-    PasswordNotMatch   = 14,
-    #[display(fmt = "User name is too long")]
-    UserNameTooLong    = 20,
-    #[display(fmt = "User name contain forbidden characters")]
-    UserNameContainForbiddenCharacters = 21,
-    #[display(fmt = "User name can not be empty or whitespace")]
-    UserNameIsEmpty    = 22,
-    #[display(fmt = "User id is invalid")]
-    UserIdInvalid      = 23,
-    #[display(fmt = "User token is invalid")]
-    UserUnauthorized   = 24,
-    #[display(fmt = "User not exist")]
-    UserNotExist       = 25,
-
-    #[display(fmt = "Server is offline, try again later")]
-    ServerOffline       = 26,
-
-    #[display(fmt = "Internal error")]
-    InternalError      = 100,
-}
-
-impl std::convert::Into<UserError> for ErrorCode {
-    fn into(self) -> UserError { UserError::new(self, "") }
-}
-
-impl std::default::Default for ErrorCode {
-    fn default() -> Self { ErrorCode::InternalError }
+impl std::convert::From<ErrorCode> for UserError {
+    fn from(code: ErrorCode) -> Self {
+        UserError {
+            code: code.value(),
+            msg: format!("{}", code),
+        }
+    }
 }
 
 impl std::convert::From<flowy_database::Error> for UserError {
@@ -153,7 +105,9 @@ fn server_error_to_user_error(error: flowy_net::errors::ServerError) -> (ErrorCo
         ServerErrorCode::UserUnauthorized => ErrorCode::UserUnauthorized,
         ServerErrorCode::PasswordNotMatch => ErrorCode::PasswordNotMatch,
         ServerErrorCode::RecordNotFound => ErrorCode::UserNotExist,
-        ServerErrorCode::ConnectRefused | ServerErrorCode::ConnectTimeout | ServerErrorCode::ConnectClose => ErrorCode::ServerOffline,
+        ServerErrorCode::ConnectRefused | ServerErrorCode::ConnectTimeout | ServerErrorCode::ConnectClose => {
+            ErrorCode::ServerError
+        },
         _ => ErrorCode::InternalError,
     };
 

+ 2 - 1
rust-lib/flowy-user/src/lib.rs

@@ -1,8 +1,9 @@
 mod handlers;
 mod sql_tables;
 
-pub mod entities;
+pub use flowy_user_infra::entities;
 pub mod errors;
+
 pub mod event;
 pub mod module;
 mod notify;

+ 26 - 156
rust-lib/flowy-user/src/protobuf/model/errors.rs

@@ -26,7 +26,7 @@
 #[derive(PartialEq,Clone,Default)]
 pub struct UserError {
     // message fields
-    pub code: ErrorCode,
+    pub code: i32,
     pub msg: ::std::string::String,
     // special fields
     pub unknown_fields: ::protobuf::UnknownFields,
@@ -44,18 +44,18 @@ impl UserError {
         ::std::default::Default::default()
     }
 
-    // .ErrorCode code = 1;
+    // int32 code = 1;
 
 
-    pub fn get_code(&self) -> ErrorCode {
+    pub fn get_code(&self) -> i32 {
         self.code
     }
     pub fn clear_code(&mut self) {
-        self.code = ErrorCode::EmailIsEmpty;
+        self.code = 0;
     }
 
     // Param is passed by value, moved
-    pub fn set_code(&mut self, v: ErrorCode) {
+    pub fn set_code(&mut self, v: i32) {
         self.code = v;
     }
 
@@ -96,7 +96,11 @@ impl ::protobuf::Message for UserError {
             let (field_number, wire_type) = is.read_tag_unpack()?;
             match field_number {
                 1 => {
-                    ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.code, 1, &mut self.unknown_fields)?
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int32()?;
+                    self.code = tmp;
                 },
                 2 => {
                     ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.msg)?;
@@ -113,8 +117,8 @@ impl ::protobuf::Message for UserError {
     #[allow(unused_variables)]
     fn compute_size(&self) -> u32 {
         let mut my_size = 0;
-        if self.code != ErrorCode::EmailIsEmpty {
-            my_size += ::protobuf::rt::enum_size(1, self.code);
+        if self.code != 0 {
+            my_size += ::protobuf::rt::value_size(1, self.code, ::protobuf::wire_format::WireTypeVarint);
         }
         if !self.msg.is_empty() {
             my_size += ::protobuf::rt::string_size(2, &self.msg);
@@ -125,8 +129,8 @@ impl ::protobuf::Message for UserError {
     }
 
     fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
-        if self.code != ErrorCode::EmailIsEmpty {
-            os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.code))?;
+        if self.code != 0 {
+            os.write_int32(1, self.code)?;
         }
         if !self.msg.is_empty() {
             os.write_string(2, &self.msg)?;
@@ -169,7 +173,7 @@ impl ::protobuf::Message for UserError {
         static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
         descriptor.get(|| {
             let mut fields = ::std::vec::Vec::new();
-            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<ErrorCode>>(
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
                 "code",
                 |m: &UserError| { &m.code },
                 |m: &mut UserError| { &mut m.code },
@@ -195,7 +199,7 @@ impl ::protobuf::Message for UserError {
 
 impl ::protobuf::Clear for UserError {
     fn clear(&mut self) {
-        self.code = ErrorCode::EmailIsEmpty;
+        self.code = 0;
         self.msg.clear();
         self.unknown_fields.clear();
     }
@@ -213,151 +217,17 @@ impl ::protobuf::reflect::ProtobufValue for UserError {
     }
 }
 
-#[derive(Clone,PartialEq,Eq,Debug,Hash)]
-pub enum ErrorCode {
-    EmailIsEmpty = 0,
-    EmailFormatInvalid = 1,
-    EmailAlreadyExists = 2,
-    PasswordIsEmpty = 10,
-    PasswordTooLong = 11,
-    PasswordContainsForbidCharacters = 12,
-    PasswordFormatInvalid = 13,
-    PasswordNotMatch = 14,
-    UserNameTooLong = 20,
-    UserNameContainForbiddenCharacters = 21,
-    UserNameIsEmpty = 22,
-    UserIdInvalid = 23,
-    UserUnauthorized = 24,
-    UserNotExist = 25,
-    ServerOffline = 26,
-    InternalError = 100,
-}
-
-impl ::protobuf::ProtobufEnum for ErrorCode {
-    fn value(&self) -> i32 {
-        *self as i32
-    }
-
-    fn from_i32(value: i32) -> ::std::option::Option<ErrorCode> {
-        match value {
-            0 => ::std::option::Option::Some(ErrorCode::EmailIsEmpty),
-            1 => ::std::option::Option::Some(ErrorCode::EmailFormatInvalid),
-            2 => ::std::option::Option::Some(ErrorCode::EmailAlreadyExists),
-            10 => ::std::option::Option::Some(ErrorCode::PasswordIsEmpty),
-            11 => ::std::option::Option::Some(ErrorCode::PasswordTooLong),
-            12 => ::std::option::Option::Some(ErrorCode::PasswordContainsForbidCharacters),
-            13 => ::std::option::Option::Some(ErrorCode::PasswordFormatInvalid),
-            14 => ::std::option::Option::Some(ErrorCode::PasswordNotMatch),
-            20 => ::std::option::Option::Some(ErrorCode::UserNameTooLong),
-            21 => ::std::option::Option::Some(ErrorCode::UserNameContainForbiddenCharacters),
-            22 => ::std::option::Option::Some(ErrorCode::UserNameIsEmpty),
-            23 => ::std::option::Option::Some(ErrorCode::UserIdInvalid),
-            24 => ::std::option::Option::Some(ErrorCode::UserUnauthorized),
-            25 => ::std::option::Option::Some(ErrorCode::UserNotExist),
-            26 => ::std::option::Option::Some(ErrorCode::ServerOffline),
-            100 => ::std::option::Option::Some(ErrorCode::InternalError),
-            _ => ::std::option::Option::None
-        }
-    }
-
-    fn values() -> &'static [Self] {
-        static values: &'static [ErrorCode] = &[
-            ErrorCode::EmailIsEmpty,
-            ErrorCode::EmailFormatInvalid,
-            ErrorCode::EmailAlreadyExists,
-            ErrorCode::PasswordIsEmpty,
-            ErrorCode::PasswordTooLong,
-            ErrorCode::PasswordContainsForbidCharacters,
-            ErrorCode::PasswordFormatInvalid,
-            ErrorCode::PasswordNotMatch,
-            ErrorCode::UserNameTooLong,
-            ErrorCode::UserNameContainForbiddenCharacters,
-            ErrorCode::UserNameIsEmpty,
-            ErrorCode::UserIdInvalid,
-            ErrorCode::UserUnauthorized,
-            ErrorCode::UserNotExist,
-            ErrorCode::ServerOffline,
-            ErrorCode::InternalError,
-        ];
-        values
-    }
-
-    fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor {
-        static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT;
-        descriptor.get(|| {
-            ::protobuf::reflect::EnumDescriptor::new_pb_name::<ErrorCode>("ErrorCode", file_descriptor_proto())
-        })
-    }
-}
-
-impl ::std::marker::Copy for ErrorCode {
-}
-
-impl ::std::default::Default for ErrorCode {
-    fn default() -> Self {
-        ErrorCode::EmailIsEmpty
-    }
-}
-
-impl ::protobuf::reflect::ProtobufValue for ErrorCode {
-    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
-        ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self))
-    }
-}
-
 static file_descriptor_proto_data: &'static [u8] = b"\
-    \n\x0cerrors.proto\"=\n\tUserError\x12\x1e\n\x04code\x18\x01\x20\x01(\
-    \x0e2\n.ErrorCodeR\x04code\x12\x10\n\x03msg\x18\x02\x20\x01(\tR\x03msg*\
-    \x81\x03\n\tErrorCode\x12\x10\n\x0cEmailIsEmpty\x10\0\x12\x16\n\x12Email\
-    FormatInvalid\x10\x01\x12\x16\n\x12EmailAlreadyExists\x10\x02\x12\x13\n\
-    \x0fPasswordIsEmpty\x10\n\x12\x13\n\x0fPasswordTooLong\x10\x0b\x12$\n\
-    \x20PasswordContainsForbidCharacters\x10\x0c\x12\x19\n\x15PasswordFormat\
-    Invalid\x10\r\x12\x14\n\x10PasswordNotMatch\x10\x0e\x12\x13\n\x0fUserNam\
-    eTooLong\x10\x14\x12&\n\"UserNameContainForbiddenCharacters\x10\x15\x12\
-    \x13\n\x0fUserNameIsEmpty\x10\x16\x12\x11\n\rUserIdInvalid\x10\x17\x12\
-    \x14\n\x10UserUnauthorized\x10\x18\x12\x10\n\x0cUserNotExist\x10\x19\x12\
-    \x11\n\rServerOffline\x10\x1a\x12\x11\n\rInternalError\x10dJ\xc0\x06\n\
-    \x06\x12\x04\0\0\x17\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\
-    \x12\x04\x02\0\x05\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x11\n\x0b\n\
-    \x04\x04\0\x02\0\x12\x03\x03\x04\x17\n\x0c\n\x05\x04\0\x02\0\x06\x12\x03\
-    \x03\x04\r\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\x0e\x12\n\x0c\n\x05\
-    \x04\0\x02\0\x03\x12\x03\x03\x15\x16\n\x0b\n\x04\x04\0\x02\x01\x12\x03\
-    \x04\x04\x13\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x04\x04\n\n\x0c\n\x05\
-    \x04\0\x02\x01\x01\x12\x03\x04\x0b\x0e\n\x0c\n\x05\x04\0\x02\x01\x03\x12\
-    \x03\x04\x11\x12\n\n\n\x02\x05\0\x12\x04\x06\0\x17\x01\n\n\n\x03\x05\0\
-    \x01\x12\x03\x06\x05\x0e\n\x0b\n\x04\x05\0\x02\0\x12\x03\x07\x04\x15\n\
-    \x0c\n\x05\x05\0\x02\0\x01\x12\x03\x07\x04\x10\n\x0c\n\x05\x05\0\x02\0\
-    \x02\x12\x03\x07\x13\x14\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x08\x04\x1b\n\
-    \x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x08\x04\x16\n\x0c\n\x05\x05\0\x02\
-    \x01\x02\x12\x03\x08\x19\x1a\n\x0b\n\x04\x05\0\x02\x02\x12\x03\t\x04\x1b\
-    \n\x0c\n\x05\x05\0\x02\x02\x01\x12\x03\t\x04\x16\n\x0c\n\x05\x05\0\x02\
-    \x02\x02\x12\x03\t\x19\x1a\n\x0b\n\x04\x05\0\x02\x03\x12\x03\n\x04\x19\n\
-    \x0c\n\x05\x05\0\x02\x03\x01\x12\x03\n\x04\x13\n\x0c\n\x05\x05\0\x02\x03\
-    \x02\x12\x03\n\x16\x18\n\x0b\n\x04\x05\0\x02\x04\x12\x03\x0b\x04\x19\n\
-    \x0c\n\x05\x05\0\x02\x04\x01\x12\x03\x0b\x04\x13\n\x0c\n\x05\x05\0\x02\
-    \x04\x02\x12\x03\x0b\x16\x18\n\x0b\n\x04\x05\0\x02\x05\x12\x03\x0c\x04*\
-    \n\x0c\n\x05\x05\0\x02\x05\x01\x12\x03\x0c\x04$\n\x0c\n\x05\x05\0\x02\
-    \x05\x02\x12\x03\x0c')\n\x0b\n\x04\x05\0\x02\x06\x12\x03\r\x04\x1f\n\x0c\
-    \n\x05\x05\0\x02\x06\x01\x12\x03\r\x04\x19\n\x0c\n\x05\x05\0\x02\x06\x02\
-    \x12\x03\r\x1c\x1e\n\x0b\n\x04\x05\0\x02\x07\x12\x03\x0e\x04\x1a\n\x0c\n\
-    \x05\x05\0\x02\x07\x01\x12\x03\x0e\x04\x14\n\x0c\n\x05\x05\0\x02\x07\x02\
-    \x12\x03\x0e\x17\x19\n\x0b\n\x04\x05\0\x02\x08\x12\x03\x0f\x04\x19\n\x0c\
-    \n\x05\x05\0\x02\x08\x01\x12\x03\x0f\x04\x13\n\x0c\n\x05\x05\0\x02\x08\
-    \x02\x12\x03\x0f\x16\x18\n\x0b\n\x04\x05\0\x02\t\x12\x03\x10\x04,\n\x0c\
-    \n\x05\x05\0\x02\t\x01\x12\x03\x10\x04&\n\x0c\n\x05\x05\0\x02\t\x02\x12\
-    \x03\x10)+\n\x0b\n\x04\x05\0\x02\n\x12\x03\x11\x04\x19\n\x0c\n\x05\x05\0\
-    \x02\n\x01\x12\x03\x11\x04\x13\n\x0c\n\x05\x05\0\x02\n\x02\x12\x03\x11\
-    \x16\x18\n\x0b\n\x04\x05\0\x02\x0b\x12\x03\x12\x04\x17\n\x0c\n\x05\x05\0\
-    \x02\x0b\x01\x12\x03\x12\x04\x11\n\x0c\n\x05\x05\0\x02\x0b\x02\x12\x03\
-    \x12\x14\x16\n\x0b\n\x04\x05\0\x02\x0c\x12\x03\x13\x04\x1a\n\x0c\n\x05\
-    \x05\0\x02\x0c\x01\x12\x03\x13\x04\x14\n\x0c\n\x05\x05\0\x02\x0c\x02\x12\
-    \x03\x13\x17\x19\n\x0b\n\x04\x05\0\x02\r\x12\x03\x14\x04\x16\n\x0c\n\x05\
-    \x05\0\x02\r\x01\x12\x03\x14\x04\x10\n\x0c\n\x05\x05\0\x02\r\x02\x12\x03\
-    \x14\x13\x15\n\x0b\n\x04\x05\0\x02\x0e\x12\x03\x15\x04\x17\n\x0c\n\x05\
-    \x05\0\x02\x0e\x01\x12\x03\x15\x04\x11\n\x0c\n\x05\x05\0\x02\x0e\x02\x12\
-    \x03\x15\x14\x16\n\x0b\n\x04\x05\0\x02\x0f\x12\x03\x16\x04\x18\n\x0c\n\
-    \x05\x05\0\x02\x0f\x01\x12\x03\x16\x04\x11\n\x0c\n\x05\x05\0\x02\x0f\x02\
-    \x12\x03\x16\x14\x17b\x06proto3\
+    \n\x0cerrors.proto\"1\n\tUserError\x12\x12\n\x04code\x18\x01\x20\x01(\
+    \x05R\x04code\x12\x10\n\x03msg\x18\x02\x20\x01(\tR\x03msgJ\x98\x01\n\x06\
+    \x12\x04\0\0\x05\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\
+    \x04\x02\0\x05\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x11\n\x0b\n\x04\
+    \x04\0\x02\0\x12\x03\x03\x04\x13\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x03\
+    \x04\t\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\n\x0e\n\x0c\n\x05\x04\0\
+    \x02\0\x03\x12\x03\x03\x11\x12\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\
+    \x13\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x04\x04\n\n\x0c\n\x05\x04\0\
+    \x02\x01\x01\x12\x03\x04\x0b\x0e\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\
+    \x04\x11\x12b\x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

+ 1 - 19
rust-lib/flowy-user/src/protobuf/proto/errors.proto

@@ -1,24 +1,6 @@
 syntax = "proto3";
 
 message UserError {
-    ErrorCode code = 1;
+    int32 code = 1;
     string msg = 2;
 }
-enum ErrorCode {
-    EmailIsEmpty = 0;
-    EmailFormatInvalid = 1;
-    EmailAlreadyExists = 2;
-    PasswordIsEmpty = 10;
-    PasswordTooLong = 11;
-    PasswordContainsForbidCharacters = 12;
-    PasswordFormatInvalid = 13;
-    PasswordNotMatch = 14;
-    UserNameTooLong = 20;
-    UserNameContainForbiddenCharacters = 21;
-    UserNameIsEmpty = 22;
-    UserIdInvalid = 23;
-    UserUnauthorized = 24;
-    UserNotExist = 25;
-    ServerOffline = 26;
-    InternalError = 100;
-}

+ 2 - 1
rust-lib/flowy-user/src/services/server/server_api.rs

@@ -52,8 +52,9 @@ impl UserServerAPI for UserServer {
     fn ws_addr(&self) -> String { self.config.ws_addr() }
 }
 
-use crate::{errors::ErrorCode, notify::*};
+use crate::notify::*;
 use flowy_net::response::FlowyResponse;
+use flowy_user_infra::errors::ErrorCode;
 use lazy_static::lazy_static;
 use std::sync::Arc;
 lazy_static! {

+ 4 - 4
rust-lib/flowy-user/src/services/user/user_session.rs

@@ -95,7 +95,7 @@ impl UserSession {
             let session = Session::new(&resp.user_id, &resp.token, &resp.email);
             let _ = self.set_session(Some(session))?;
             let user_table = self.save_user(resp.into()).await?;
-            let user_profile = UserProfile::from(user_table);
+            let user_profile: UserProfile = user_table.into();
             (self.status_callback)(SessionStatus::Login {
                 token: user_profile.token.clone(),
             });
@@ -112,7 +112,7 @@ impl UserSession {
             let session = Session::new(&resp.user_id, &resp.token, &resp.email);
             let _ = self.set_session(Some(session))?;
             let user_table = self.save_user(resp.into()).await?;
-            let user_profile = UserProfile::from(user_table);
+            let user_profile: UserProfile = user_table.into();
             (self.status_callback)(SessionStatus::Login {
                 token: user_profile.token.clone(),
             });
@@ -160,7 +160,7 @@ impl UserSession {
             .first::<UserTable>(&*(self.db_connection()?))?;
 
         let _ = self.read_user_profile_on_server(&token)?;
-        Ok(UserProfile::from(user))
+        Ok(user.into())
     }
 
     pub async fn user_profile(&self) -> Result<UserProfile, UserError> {
@@ -170,7 +170,7 @@ impl UserSession {
             .first::<UserTable>(&*(self.db_connection()?))?;
 
         let _ = self.read_user_profile_on_server(&token)?;
-        Ok(UserProfile::from(user))
+        Ok(user.into())
     }
 
     pub fn user_dir(&self) -> Result<String, UserError> {

+ 12 - 0
rust-lib/flowy-user/src/sql_tables/user.rs

@@ -1,5 +1,6 @@
 use crate::entities::{SignInResponse, SignUpResponse, UpdateUserParams};
 use flowy_database::schema::user_table;
+use flowy_user_infra::entities::UserProfile;
 
 #[derive(Clone, Default, Queryable, Identifiable, Insertable)]
 #[table_name = "user_table"]
@@ -36,6 +37,17 @@ impl std::convert::From<SignInResponse> for UserTable {
     fn from(resp: SignInResponse) -> Self { UserTable::new(resp.user_id, resp.name, resp.email, resp.token) }
 }
 
+impl std::convert::Into<UserProfile> for UserTable {
+    fn into(self) -> UserProfile {
+        UserProfile {
+            id: self.id,
+            email: self.email,
+            name: self.name,
+            token: self.token,
+        }
+    }
+}
+
 #[derive(AsChangeset, Identifiable, Default, Debug)]
 #[table_name = "user_table"]
 pub struct UserTableChangeset {

+ 5 - 2
rust-lib/flowy-user/tests/event/auth_test.rs

@@ -20,7 +20,7 @@ async fn sign_up_with_invalid_email() {
                 .await
                 .error()
                 .code,
-            ErrorCode::EmailFormatInvalid
+            ErrorCode::EmailFormatInvalid.value()
         );
     }
 }
@@ -52,6 +52,7 @@ async fn sign_in_success() {
     let request = SignInRequest {
         email: sign_up_context.user_profile.email.clone(),
         password: sign_up_context.password.clone(),
+        name: "".to_string(),
     };
 
     let response = UserTest::new(test.sdk())
@@ -70,6 +71,7 @@ async fn sign_in_with_invalid_email() {
         let request = SignInRequest {
             email: email.to_string(),
             password: login_password(),
+            name: "".to_string(),
         };
 
         assert_eq!(
@@ -80,7 +82,7 @@ async fn sign_in_with_invalid_email() {
                 .await
                 .error()
                 .code,
-            ErrorCode::EmailFormatInvalid
+            ErrorCode::EmailFormatInvalid.value()
         );
     }
 }
@@ -93,6 +95,7 @@ async fn sign_in_with_invalid_password() {
         let request = SignInRequest {
             email: random_email(),
             password,
+            name: "".to_string(),
         };
 
         UserTest::new(test.sdk)

+ 1 - 1
rust-lib/flowy-user/tests/event/user_profile_test.rs

@@ -91,7 +91,7 @@ async fn user_update_with_invalid_email() {
                 .sync_send()
                 .error()
                 .code,
-            ErrorCode::EmailFormatInvalid
+            ErrorCode::EmailFormatInvalid.value()
         );
     }
 }