1 module vibeauth.authenticators.oauth.RefreshTokenGrantAccess;
2 
3 import vibeauth.authenticators.oauth.IGrantAccess;
4 import vibeauth.authenticators.oauth.AuthData;
5 import vibeauth.collections.usercollection;
6 import vibeauth.data.user;
7 
8 import std.datetime;
9 import std.array;
10 import std.algorithm;
11 
12 import vibe.data.json;
13 
14 
15 /// Grant user access based on a refresh token
16 final class RefreshTokenGrantAccess : IGrantAccess {
17   private {
18     AuthData data;
19     UserCollection collection;
20     User user;
21   }
22 
23   /// setter for the authentication data
24   void authData(AuthData authData) {
25     this.data = authData;
26     cacheData;
27   }
28 
29   /// setter for the user collection
30   void userCollection(UserCollection userCollection) {
31     this.collection = userCollection;
32     cacheData;
33   }
34 
35   private void cacheData() {
36     if(collection is null || data.refreshToken == "") {
37       return;
38     }
39 
40     user = collection.byToken(data.refreshToken);
41     data.scopes = user.getScopes(data.refreshToken).filter!(a => a != "refresh").array;
42   }
43 
44   /// Validate the refresh token
45   bool isValid() {
46     if(data.refreshToken == "") {
47       return false;
48     }
49 
50     return user.isValidToken(data.refreshToken, "refresh");
51   }
52 
53   /// Get the token Json response object
54   Json get() {
55     auto response = Json.emptyObject;
56 
57     if(!isValid) {
58       response["error"] = "Invalid `refresh_token`";
59       return response;
60     }
61 
62     auto username = user.email();
63 
64     auto accessToken = collection.createToken(username, Clock.currTime + 3601.seconds, data.scopes, "Bearer");
65 
66     response["access_token"] = accessToken.name;
67     response["expires_in"] = (accessToken.expire - Clock.currTime).total!"seconds";
68     response["token_type"] = accessToken.type;
69 
70     return response;
71   }
72 }