diff --git a/VoidCat/Model/User/UserAuthToken.cs b/VoidCat/Model/User/UserAuthToken.cs
index 774b29f..775a3dc 100644
--- a/VoidCat/Model/User/UserAuthToken.cs
+++ b/VoidCat/Model/User/UserAuthToken.cs
@@ -20,4 +20,6 @@ public sealed class UserAuthToken
public string RefreshToken { get; init; }
public string Scope { get; init; }
+
+ public string IdToken { get; init; }
}
\ No newline at end of file
diff --git a/VoidCat/Services/Users/Auth/GenericOAuth2Service.cs b/VoidCat/Services/Users/Auth/GenericOAuth2Service.cs
index 46dc0ac..eb41ebd 100644
--- a/VoidCat/Services/Users/Auth/GenericOAuth2Service.cs
+++ b/VoidCat/Services/Users/Auth/GenericOAuth2Service.cs
@@ -61,7 +61,7 @@ public abstract class GenericOAuth2Service : IOAuthProvider
{"response_type", "code"},
{"client_id", Details.ClientId!},
{"scope", string.Join(" ", Scopes)},
- {"prompt", "none"},
+ {"prompt", Prompt},
{"redirect_uri", new Uri(_uri, $"/auth/{Id}/token").ToString()}
};
@@ -79,6 +79,11 @@ public abstract class GenericOAuth2Service : IOAuthProvider
{"redirect_uri", new Uri(_uri, $"/auth/{Id}/token").ToString()}
};
+ ///
+ /// Prompt type for authorization
+ ///
+ protected virtual string Prompt => "none";
+
///
/// Authorize url for this service
///
@@ -114,20 +119,29 @@ public abstract class GenericOAuth2Service : IOAuthProvider
Expires = DateTime.UtcNow.AddSeconds(dto.ExpiresIn),
TokenType = dto.TokenType,
RefreshToken = dto.RefreshToken,
- Scope = dto.Scope
+ Scope = dto.Scope,
+ IdToken = dto.IdToken
};
}
protected class OAuthAccessToken
{
- [JsonProperty("access_token")] public string AccessToken { get; init; }
+ [JsonProperty("access_token")]
+ public string AccessToken { get; init; }
- [JsonProperty("expires_in")] public int ExpiresIn { get; init; }
+ [JsonProperty("expires_in")]
+ public int ExpiresIn { get; init; }
- [JsonProperty("token_type")] public string TokenType { get; init; }
+ [JsonProperty("token_type")]
+ public string TokenType { get; init; }
- [JsonProperty("refresh_token")] public string RefreshToken { get; init; }
+ [JsonProperty("refresh_token")]
+ public string RefreshToken { get; init; }
- [JsonProperty("scope")] public string Scope { get; init; }
+ [JsonProperty("scope")]
+ public string Scope { get; init; }
+
+ [JsonProperty("id_token")]
+ public string IdToken { get; init; }
}
}
\ No newline at end of file
diff --git a/VoidCat/Services/Users/Auth/GoogleOAuthProvider.cs b/VoidCat/Services/Users/Auth/GoogleOAuthProvider.cs
index 8e23dfc..d4b7ff6 100644
--- a/VoidCat/Services/Users/Auth/GoogleOAuthProvider.cs
+++ b/VoidCat/Services/Users/Auth/GoogleOAuthProvider.cs
@@ -20,18 +20,28 @@ public class GoogleOAuthProvider : GenericOAuth2Service
///
public override ValueTask GetUserDetails(UserAuthToken token)
{
- var jwt = JwtPayload.Base64UrlDeserialize(token.AccessToken);
+ var jwt = new JwtSecurityToken(token.IdToken);
+
+ string? GetPayloadValue(string key)
+ => jwt.Payload.TryGetValue(key, out var v)
+ ? v as string
+ : default;
+
return ValueTask.FromResult(new InternalUser()
{
Id = Guid.NewGuid(),
Created = DateTimeOffset.UtcNow,
LastLogin = DateTimeOffset.UtcNow,
AuthType = AuthType.OAuth2,
- Email = jwt.Jti,
- DisplayName = jwt.Acr
+ Email = GetPayloadValue("email") ?? throw new InvalidOperationException("Failed to get email from Google JWT"),
+ DisplayName = GetPayloadValue("name"),
+ Avatar = GetPayloadValue("picture")
})!;
}
+ ///
+ protected override string Prompt => "select_account";
+
///
protected override Uri AuthorizeEndpoint => new("https://accounts.google.com/o/oauth2/v2/auth");
@@ -44,8 +54,4 @@ public class GoogleOAuthProvider : GenericOAuth2Service
///
protected override string[] Scopes => new[]
{"https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"};
-}
-
-public sealed class GoogleUserAccount
-{
}
\ No newline at end of file