Encrypted messaging app
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
4.0 KiB

  1. import 'dart:convert';
  2. import 'package:Envelope/components/select_message_ttl.dart';
  3. import 'package:flutter_dotenv/flutter_dotenv.dart';
  4. import 'package:pointycastle/impl.dart';
  5. import 'package:shared_preferences/shared_preferences.dart';
  6. import '/utils/encryption/aes_helper.dart';
  7. import '/utils/encryption/crypto_utils.dart';
  8. // TODO: Replace this with the prod url when server is deployed
  9. String defaultServerUrl = dotenv.env['SERVER_URL'] ?? 'http://192.168.1.5:8080';
  10. class MyProfile {
  11. String id;
  12. String username;
  13. String? friendId;
  14. RSAPrivateKey? privateKey;
  15. RSAPublicKey? publicKey;
  16. DateTime? loggedInAt;
  17. String messageExpiryDefault = 'no_expiry';
  18. MyProfile({
  19. required this.id,
  20. required this.username,
  21. this.friendId,
  22. this.privateKey,
  23. this.publicKey,
  24. this.loggedInAt,
  25. required this.messageExpiryDefault,
  26. });
  27. factory MyProfile._fromJson(Map<String, dynamic> json) {
  28. DateTime loggedInAt = DateTime.now();
  29. if (json.containsKey('logged_in_at')) {
  30. loggedInAt = DateTime.parse(json['logged_in_at']);
  31. }
  32. RSAPrivateKey privateKey = CryptoUtils.rsaPrivateKeyFromPem(json['asymmetric_private_key']);
  33. RSAPublicKey publicKey = CryptoUtils.rsaPublicKeyFromPem(json['asymmetric_public_key']);
  34. return MyProfile(
  35. id: json['user_id'],
  36. username: json['username'],
  37. privateKey: privateKey,
  38. publicKey: publicKey,
  39. loggedInAt: loggedInAt,
  40. messageExpiryDefault: json['message_expiry_default']
  41. );
  42. }
  43. @override
  44. String toString() {
  45. return '''
  46. user_id: $id
  47. username: $username
  48. logged_in_at: $loggedInAt
  49. public_key: $publicKey
  50. private_key: $privateKey
  51. ''';
  52. }
  53. String toJson() {
  54. return jsonEncode(<String, dynamic>{
  55. 'user_id': id,
  56. 'username': username,
  57. 'asymmetric_private_key': privateKey != null ?
  58. CryptoUtils.encodeRSAPrivateKeyToPem(privateKey!) :
  59. null,
  60. 'asymmetric_public_key': publicKey != null ?
  61. CryptoUtils.encodeRSAPublicKeyToPem(publicKey!) :
  62. null,
  63. 'logged_in_at': loggedInAt?.toIso8601String(),
  64. 'message_expiry_default': messageExpiryDefault,
  65. });
  66. }
  67. static Future<MyProfile> login(Map<String, dynamic> json, String password) async {
  68. json['asymmetric_private_key'] = AesHelper.aesDecrypt(
  69. password,
  70. base64.decode(json['asymmetric_private_key'])
  71. );
  72. MyProfile profile = MyProfile._fromJson(json);
  73. final preferences = await SharedPreferences.getInstance();
  74. preferences.setString('profile', profile.toJson());
  75. return profile;
  76. }
  77. static Future<void> logout() async {
  78. final preferences = await SharedPreferences.getInstance();
  79. preferences.remove('profile');
  80. }
  81. static Future<MyProfile> getProfile() async {
  82. final preferences = await SharedPreferences.getInstance();
  83. String? profileJson = preferences.getString('profile');
  84. if (profileJson == null) {
  85. throw Exception('No profile');
  86. }
  87. return MyProfile._fromJson(json.decode(profileJson));
  88. }
  89. static Future<bool> isLoggedIn() async {
  90. MyProfile profile = await MyProfile.getProfile();
  91. if (profile.loggedInAt == null) {
  92. return false;
  93. }
  94. return profile.loggedInAt!.add(const Duration(hours: 12)).isAfter(
  95. (DateTime.now())
  96. );
  97. }
  98. static Future<RSAPrivateKey> getPrivateKey() async {
  99. MyProfile profile = await MyProfile.getProfile();
  100. if (profile.privateKey == null) {
  101. throw Exception('Could not get privateKey');
  102. }
  103. return profile.privateKey!;
  104. }
  105. static setServerUrl(String url) async {
  106. final preferences = await SharedPreferences.getInstance();
  107. preferences.setString('server_url', url);
  108. }
  109. static Future<Uri> getServerUrl(String path) async {
  110. final preferences = await SharedPreferences.getInstance();
  111. String? baseUrl = preferences.getString('server_url');
  112. if (baseUrl == null) {
  113. setServerUrl(defaultServerUrl);
  114. return Uri.parse('$defaultServerUrl$path');
  115. }
  116. return Uri.parse('$baseUrl$path');
  117. }
  118. }