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.

111 lines
3.1 KiB

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