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.

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