aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar vnugent <public@vaughnnugent.com>2024-03-21 14:33:21 -0400
committerLibravatar vnugent <public@vaughnnugent.com>2024-03-21 14:33:21 -0400
commitf8aea6453ddb2d56c1ce2ecb6a9e67d1af523c2e (patch)
treeb62d6086e93b8da32a1b5caa2c0981a1c1ed2518
parentcc29bed99dc9e151315cce75e50d55dca306b532 (diff)
feat: Add optional svg base64 icons for social OAuth2 connections
-rw-r--r--lib/vnlib.browser/src/social/index.ts13
-rw-r--r--plugins/VNLib.Plugins.Essentials.Accounts/README.md2
-rw-r--r--plugins/VNLib.Plugins.Essentials.Accounts/src/AccountsEntryPoint.cs2
-rw-r--r--plugins/VNLib.Plugins.Essentials.Accounts/src/SecurityProvider/AccountSecProvider.cs2
-rw-r--r--plugins/VNLib.Plugins.Essentials.Auth.Social/src/PortalsEndpoint.cs37
-rw-r--r--plugins/VNLib.Plugins.Essentials.Auth.Social/src/SocialOAuthPortal.cs3
-rw-r--r--plugins/providers/VNLib.Plugins.Essentials.Auth.Auth0/src/Auth0Portal.cs7
-rw-r--r--plugins/providers/VNLib.Plugins.Essentials.Auth.Discord/src/DiscordPortal.cs7
-rw-r--r--plugins/providers/VNLib.Plugins.Essentials.Auth.Github/src/GithubPortal.cs7
9 files changed, 61 insertions, 19 deletions
diff --git a/lib/vnlib.browser/src/social/index.ts b/lib/vnlib.browser/src/social/index.ts
index dac3cc9..7d80687 100644
--- a/lib/vnlib.browser/src/social/index.ts
+++ b/lib/vnlib.browser/src/social/index.ts
@@ -55,6 +55,7 @@ export interface SocialOAuthPortal {
readonly id: string;
readonly login: string;
readonly logout?: string;
+ readonly icon?: string;
}
/**
@@ -67,6 +68,10 @@ export interface OAuthMethod {
*/
readonly id: string;
/**
+ * Optional bas64encoded icon image url for the method
+ */
+ readonly icon?: string;
+ /**
* Determines if the current flow is active for this method
*/
isActiveLogin(): boolean
@@ -90,6 +95,10 @@ export interface SocialOauthMethod {
*/
readonly id: string
/**
+ * Optional bas64encoded icon image url for the method
+ */
+ readonly icon?: string
+ /**
* The endpoint to submit the authentication request to
*/
loginUrl(): string
@@ -214,7 +223,8 @@ export const fromSocialConnections = <T extends SocialOauthMethod>(methods: T[],
return map(methods, method => {
return{
id: method.id,
-
+ icon: method.icon,
+
async beginLoginFlow() {
//Prepare the login claim`
const claim = await prepareLogin()
@@ -314,6 +324,7 @@ export const fromSocialPortals = (portals: SocialOAuthPortal[]): SocialOauthMeth
return map(portals, p => {
return {
id: p.id,
+ icon: p.icon,
loginUrl : () => p.login,
//Get the logout data from the server
getLogoutData: () => ({ url: p.logout!, args: {}}),
diff --git a/plugins/VNLib.Plugins.Essentials.Accounts/README.md b/plugins/VNLib.Plugins.Essentials.Accounts/README.md
index 13f2dad..3caedb2 100644
--- a/plugins/VNLib.Plugins.Essentials.Accounts/README.md
+++ b/plugins/VNLib.Plugins.Essentials.Accounts/README.md
@@ -2,7 +2,7 @@
*An Essentials web plugin that provides endpoints for authenticating, registering, resetting, local user accounts including multi-factor authentication using TOTP (for now).*
### Dependency notice
-This library uses some external dependencies: VaultSharp, Serilog, libargon2, and FluentValidation.
+This library uses some external dependencies: Serilog, libargon2, and FluentValidation.
## Builds
Debug build w/ symbols & xml docs, release builds, NuGet packages, and individually packaged source code are available on my website (link below).
diff --git a/plugins/VNLib.Plugins.Essentials.Accounts/src/AccountsEntryPoint.cs b/plugins/VNLib.Plugins.Essentials.Accounts/src/AccountsEntryPoint.cs
index 318f3ce..219239e 100644
--- a/plugins/VNLib.Plugins.Essentials.Accounts/src/AccountsEntryPoint.cs
+++ b/plugins/VNLib.Plugins.Essentials.Accounts/src/AccountsEntryPoint.cs
@@ -92,7 +92,7 @@ namespace VNLib.Plugins.Essentials.Accounts
this.ExportService<IAccountSecurityProvider>(securityProvider);
//Also add the middleware array
- this.ExportService(new IHttpMiddleware[] { securityProvider });
+ this.ExportService<IHttpMiddleware[]>([ securityProvider ]);
Log.Information("Configuring the account security provider service");
}
diff --git a/plugins/VNLib.Plugins.Essentials.Accounts/src/SecurityProvider/AccountSecProvider.cs b/plugins/VNLib.Plugins.Essentials.Accounts/src/SecurityProvider/AccountSecProvider.cs
index 8770930..3088ada 100644
--- a/plugins/VNLib.Plugins.Essentials.Accounts/src/SecurityProvider/AccountSecProvider.cs
+++ b/plugins/VNLib.Plugins.Essentials.Accounts/src/SecurityProvider/AccountSecProvider.cs
@@ -637,7 +637,7 @@ namespace VNLib.Plugins.Essentials.Accounts.SecurityProvider
string base32SigningKey = VnEncoding.ToBase32String(signingKey, false);
//Zero signing key now were done using it
- MemoryUtil.InitializeBlock(signingKey.AsSpan());
+ MemoryUtil.InitializeBlock(signingKey);
//Compile the jwt for the cookie value
string jwtValue = jwt.Compile();
diff --git a/plugins/VNLib.Plugins.Essentials.Auth.Social/src/PortalsEndpoint.cs b/plugins/VNLib.Plugins.Essentials.Auth.Social/src/PortalsEndpoint.cs
index 4e5f867..177988f 100644
--- a/plugins/VNLib.Plugins.Essentials.Auth.Social/src/PortalsEndpoint.cs
+++ b/plugins/VNLib.Plugins.Essentials.Auth.Social/src/PortalsEndpoint.cs
@@ -23,44 +23,63 @@
*/
using System;
+using System.Net;
using System.Linq;
+using System.Text.Json;
using System.Collections.Generic;
+using VNLib.Utils.IO;
+using VNLib.Net.Http;
using VNLib.Plugins.Essentials.Endpoints;
using VNLib.Plugins.Extensions.Loading;
-
namespace VNLib.Plugins.Essentials.Auth.Social
{
[ConfigurationName("portals")]
- internal sealed class PortalsEndpoint : UnprotectedWebEndpoint
+ internal sealed class PortalsEndpoint : UnprotectedWebEndpoint, IDisposable
{
- private PortalDefJson[] _portals;
+ private readonly VnMemoryStream _portals;
public PortalsEndpoint(PluginBase plugin, IConfigScope config)
{
string path = config.GetRequiredProperty("path", p => p.GetString()!);
InitPathAndLog(path, plugin.Log);
- //Empty array by default
- _portals = [];
+ _portals = new VnMemoryStream();
}
public void SetPortals(IEnumerable<SocialOAuthPortal> portals)
{
//Convert to json
- _portals = portals.Select(p => new PortalDefJson
+ PortalDefJson[] jsn = portals.Select(p => new PortalDefJson
{
id = p.PortalId,
login = p.LoginEndpoint.Path,
logout = p.LogoutEndpoint?.Path,
+ icon = p.Base64Icon
}).ToArray();
+
+ //Serialize portals array to memory stream
+ JsonSerializer.Serialize(_portals, jsn);
+
+ //Set memory stream to readonly so shallow copy can be returned
+ _ = VnMemoryStream.CreateReadonly(_portals);
}
protected override VfReturnType Get(HttpEntity entity)
{
- //return portals array as json
- return VirtualOkJson(entity, _portals);
+ //return portals array, pre-serialized
+ return VirtualClose(
+ entity,
+ HttpStatusCode.OK,
+ ContentType.Json,
+ _portals!.GetReadonlyShallowCopy()
+ );
+ }
+
+ void IDisposable.Dispose()
+ {
+ _portals?.Dispose();
}
private sealed class PortalDefJson
@@ -70,6 +89,8 @@ namespace VNLib.Plugins.Essentials.Auth.Social
public string? login { get; set; }
public string? logout { get; set; }
+
+ public string? icon { get; set; }
}
}
} \ No newline at end of file
diff --git a/plugins/VNLib.Plugins.Essentials.Auth.Social/src/SocialOAuthPortal.cs b/plugins/VNLib.Plugins.Essentials.Auth.Social/src/SocialOAuthPortal.cs
index 3fe6ddf..db5ed6e 100644
--- a/plugins/VNLib.Plugins.Essentials.Auth.Social/src/SocialOAuthPortal.cs
+++ b/plugins/VNLib.Plugins.Essentials.Auth.Social/src/SocialOAuthPortal.cs
@@ -30,5 +30,6 @@ namespace VNLib.Plugins.Essentials.Auth.Social
/// <param name="PortalId"> The unique identifier for the portal </param>
/// <param name="LoginEndpoint"> Required login endpoint to advertise to the client </param>
/// <param name="LogoutEndpoint"> Optional logout endpoint to advertise to the client </param>
- public record SocialOAuthPortal(string PortalId, IEndpoint LoginEndpoint, IEndpoint? LogoutEndpoint);
+ /// <param name="Base64Icon">Optional base64 image icon src for the client to load and display</param>
+ public record SocialOAuthPortal(string PortalId, IEndpoint LoginEndpoint, IEndpoint? LogoutEndpoint, string? Base64Icon);
} \ No newline at end of file
diff --git a/plugins/providers/VNLib.Plugins.Essentials.Auth.Auth0/src/Auth0Portal.cs b/plugins/providers/VNLib.Plugins.Essentials.Auth.Auth0/src/Auth0Portal.cs
index 2fcc477..a698806 100644
--- a/plugins/providers/VNLib.Plugins.Essentials.Auth.Auth0/src/Auth0Portal.cs
+++ b/plugins/providers/VNLib.Plugins.Essentials.Auth.Auth0/src/Auth0Portal.cs
@@ -33,7 +33,7 @@ namespace VNLib.Plugins.Essentials.Auth.Auth0
[ServiceExport]
[ConfigurationName(ConfigKey)]
- public sealed class Auth0Portal(PluginBase plugin) : IOAuthProvider
+ public sealed class Auth0Portal(PluginBase plugin, IConfigScope config) : IOAuthProvider
{
internal const string ConfigKey = "auth0";
@@ -43,12 +43,15 @@ namespace VNLib.Plugins.Essentials.Auth.Auth0
///<inheritdoc/>
public SocialOAuthPortal[] GetPortals()
{
+ string? base64IconData = config.GetValueOrDefault("icon", p => p.GetString()!, null);
+
//Return the Auth0 portal
return [
new SocialOAuthPortal(
ConfigKey,
_loginEndpoint,
- _logoutEndpoint
+ _logoutEndpoint,
+ base64IconData
)
];
diff --git a/plugins/providers/VNLib.Plugins.Essentials.Auth.Discord/src/DiscordPortal.cs b/plugins/providers/VNLib.Plugins.Essentials.Auth.Discord/src/DiscordPortal.cs
index ed3940f..01bfe8d 100644
--- a/plugins/providers/VNLib.Plugins.Essentials.Auth.Discord/src/DiscordPortal.cs
+++ b/plugins/providers/VNLib.Plugins.Essentials.Auth.Discord/src/DiscordPortal.cs
@@ -35,7 +35,7 @@ namespace VNLib.Plugins.Essentials.Auth.Discord
[ServiceExport]
[ConfigurationName(ConfigKey)]
- public sealed class DiscordPortal(PluginBase plugin) : IOAuthProvider
+ public sealed class DiscordPortal(PluginBase plugin, IConfigScope config) : IOAuthProvider
{
internal const string ConfigKey = "discord";
@@ -44,12 +44,15 @@ namespace VNLib.Plugins.Essentials.Auth.Discord
///<inheritdoc/>
public SocialOAuthPortal[] GetPortals()
{
+ string? base64IconData = config.GetValueOrDefault("icon", p => p.GetString()!, null);
+
//Return the Discord portal
return [
new SocialOAuthPortal(
ConfigKey,
_loginEndpoint,
- null
+ null,
+ base64IconData
)
];
diff --git a/plugins/providers/VNLib.Plugins.Essentials.Auth.Github/src/GithubPortal.cs b/plugins/providers/VNLib.Plugins.Essentials.Auth.Github/src/GithubPortal.cs
index 946531d..c438bfe 100644
--- a/plugins/providers/VNLib.Plugins.Essentials.Auth.Github/src/GithubPortal.cs
+++ b/plugins/providers/VNLib.Plugins.Essentials.Auth.Github/src/GithubPortal.cs
@@ -33,7 +33,7 @@ namespace VNLib.Plugins.Essentials.Auth.Github
[ServiceExport]
[ConfigurationName(ConfigKey)]
- public sealed class GithubPortal(PluginBase plugin) : IOAuthProvider
+ public sealed class GithubPortal(PluginBase plugin, IConfigScope config) : IOAuthProvider
{
internal const string ConfigKey = "github";
@@ -42,12 +42,15 @@ namespace VNLib.Plugins.Essentials.Auth.Github
///<inheritdoc/>
public SocialOAuthPortal[] GetPortals()
{
+ string? base64IconData = config.GetValueOrDefault("icon", p => p.GetString()!, null);
+
//Return the github portal
return [
new SocialOAuthPortal(
ConfigKey,
_loginEndpoint,
- null
+ null,
+ base64IconData
)
];