about summary refs log tree commit diff
path: root/MatrixRoomUtils.Desktop/MRUStorageWrapper.cs
blob: 5444f2481d5f5eae3bcffb383f71ea12cb0460be (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
using LibMatrix;
using LibMatrix.Responses;
using LibMatrix.Services;

namespace MatrixRoomUtils.Desktop;

public class MRUStorageWrapper {
    private readonly TieredStorageService _storageService;
    private readonly HomeserverProviderService _homeserverProviderService;

    public MRUStorageWrapper(
        TieredStorageService storageService,
        HomeserverProviderService homeserverProviderService
    ) {
        _storageService = storageService;
        _homeserverProviderService = homeserverProviderService;
    }

    public async Task<List<LoginResponse>?> GetAllTokens() {
        if(!await _storageService.DataStorageProvider.ObjectExistsAsync("mru.tokens")) {
            return null;
        }
        return await _storageService.DataStorageProvider.LoadObjectAsync<List<LoginResponse>>("mru.tokens") ??
               new List<LoginResponse>();
    }

    public async Task<LoginResponse?> GetCurrentToken() {
        if(!await _storageService.DataStorageProvider.ObjectExistsAsync("token")) {
            return null;
        }
        var currentToken = await _storageService.DataStorageProvider.LoadObjectAsync<LoginResponse>("token");
        var allTokens = await GetAllTokens();
        if (allTokens is null or { Count: 0 }) {
            await SetCurrentToken(null);
            return null;
        }

        if (currentToken is null) {
            await SetCurrentToken(currentToken = allTokens[0]);
        }

        if (!allTokens.Any(x => x.AccessToken == currentToken.AccessToken)) {
            await SetCurrentToken(currentToken = allTokens[0]);
        }

        return currentToken;
    }

    public async Task AddToken(LoginResponse loginResponse) {
        var tokens = await GetAllTokens();
        if (tokens == null) {
            tokens = new List<LoginResponse>();
        }

        tokens.Add(loginResponse);
        await _storageService.DataStorageProvider.SaveObjectAsync("mru.tokens", tokens);
        if(await GetCurrentToken() is null)
            await SetCurrentToken(loginResponse);
    }

    private async Task<AuthenticatedHomeServer?> GetCurrentSession() {
        var token = await GetCurrentToken();
        if (token == null) {
            return null;
        }

        return await _homeserverProviderService.GetAuthenticatedWithToken(token.Homeserver, token.AccessToken);
    }

    public async Task<AuthenticatedHomeServer?> GetCurrentSessionOrPrompt() {
        AuthenticatedHomeServer? session = null;

        try {
            //catch if the token is invalid
            session = await GetCurrentSession();
        }
        catch (MatrixException e) {
            if (e.ErrorCode == "M_UNKNOWN_TOKEN") {
                var token = await GetCurrentToken();
                // _navigationManager.NavigateTo("/InvalidSession?ctx=" + token.AccessToken);
                return null;
            }

            throw;
        }

        if (session is null) {
            // _navigationManager.NavigateTo("/Login");
            var wnd = new LoginWindow(this);
            wnd.ShowDialog(MainWindow.Instance);
            while (wnd.IsVisible) await Task.Delay(100);
            session = await GetCurrentSession();
        }

        return session;
    }

    public class Settings {
        public DeveloperSettings DeveloperSettings { get; set; } = new();
    }

    public class DeveloperSettings {
        public bool EnableLogViewers { get; set; } = false;
        public bool EnableConsoleLogging { get; set; } = true;
        public bool EnablePortableDevtools { get; set; } = false;
    }

    public async Task RemoveToken(LoginResponse auth) {
        var tokens = await GetAllTokens();
        if (tokens == null) {
            return;
        }

        tokens.RemoveAll(x => x.AccessToken == auth.AccessToken);
        await _storageService.DataStorageProvider.SaveObjectAsync("mru.tokens", tokens);
    }

    public async Task SetCurrentToken(LoginResponse? auth) {
        _storageService.DataStorageProvider.SaveObjectAsync("token", auth);
    }

    public async Task<LoginResponse?> Login(string homeserver, string username, string password) {
        try {
            return await _homeserverProviderService.Login(homeserver, username, password);
        }
        catch (MatrixException e) {
            if (e.ErrorCode == "M_FORBIDDEN") {
                return null;
            }

            throw;
        }
    }
}