about summary refs log tree commit diff
path: root/MatrixUtils.Web/Classes/RMUStorageWrapper.cs
blob: 45028ba08774c033bd8d550160562eb6f76be91a (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
135
136
137
138
using LibMatrix;
using LibMatrix.Homeservers;
using LibMatrix.Services;
using Microsoft.AspNetCore.Components;

namespace MatrixUtils.Web.Classes;

public class RMUStorageWrapper(ILogger<RMUStorageWrapper> logger, TieredStorageService storageService, HomeserverProviderService homeserverProviderService, NavigationManager navigationManager) {
    public async Task<List<UserAuth>?> GetAllTokens() {
        logger.LogTrace("Getting all tokens.");
        return await storageService.DataStorageProvider.LoadObjectAsync<List<UserAuth>>("rmu.tokens") ??
               new List<UserAuth>();
    }

    public async Task<UserAuth?> GetCurrentToken() {
        logger.LogTrace("Getting current token.");
        var currentToken = await storageService.DataStorageProvider.LoadObjectAsync<UserAuth>("rmu.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(UserAuth UserAuth) {
        logger.LogTrace("Adding token.");
        var tokens = await GetAllTokens() ?? new List<UserAuth>();

        tokens.Add(UserAuth);
        await storageService.DataStorageProvider.SaveObjectAsync("rmu.tokens", tokens);
    }

    private async Task<AuthenticatedHomeserverGeneric?> GetCurrentSession() {
        logger.LogTrace("Getting current session.");
        var token = await GetCurrentToken();
        if (token == null) {
            return null;
        }

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

    public async Task<AuthenticatedHomeserverGeneric?> GetSession(UserAuth userAuth) {
        logger.LogTrace("Getting session.");
        return await homeserverProviderService.GetAuthenticatedWithToken(userAuth.Homeserver, userAuth.AccessToken, userAuth.Proxy);
    }

    public async Task<AuthenticatedHomeserverGeneric?> GetCurrentSessionOrNavigate() {
        logger.LogTrace("Getting current session or navigating.");
        AuthenticatedHomeserverGeneric? 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();
                logger.LogWarning("Encountered invalid token for {user} on {homeserver}", token.UserId, token.Homeserver);
                navigationManager.NavigateTo("/InvalidSession?ctx=" + token.AccessToken);
                return null;
            }

            throw;
        }

        if (session is null) {
            logger.LogInformation("No session found. Navigating to login.");
            navigationManager.NavigateTo("/Login");
        }

        return session;
    }

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

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

    public async Task RemoveToken(UserAuth auth) {
        logger.LogTrace("Removing token.");
        var tokens = await GetAllTokens();
        if (tokens == null) {
            return;
        }

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

    public async Task SetCurrentToken(UserAuth? auth) {
        logger.LogTrace("Setting current token.");
        await storageService.DataStorageProvider.SaveObjectAsync("rmu.token", auth);
    }

    public async Task MigrateFromMRU() {
        logger.LogInformation("Migrating from MRU token namespace!");
        var dsp = storageService.DataStorageProvider!;
        if(await dsp.ObjectExistsAsync("token")) {
            var oldToken = await dsp.LoadObjectAsync<UserAuth>("token");
            if (oldToken != null) {
                await dsp.SaveObjectAsync("rmu.token", oldToken);
                await dsp.DeleteObjectAsync("tokens");
            }
        }
        
        if(await dsp.ObjectExistsAsync("tokens")) {
            var oldTokens = await dsp.LoadObjectAsync<List<UserAuth>>("tokens");
            if (oldTokens != null) {
                await dsp.SaveObjectAsync("rmu.tokens", oldTokens);
                await dsp.DeleteObjectAsync("tokens");
            }
        }
        
        if(await dsp.ObjectExistsAsync("mru.tokens")) {
            var oldTokens = await dsp.LoadObjectAsync<List<UserAuth>>("mru.tokens");
            if (oldTokens != null) {
                await dsp.SaveObjectAsync("rmu.tokens", oldTokens);
                await dsp.DeleteObjectAsync("mru.tokens");
            }
        }
    }
}