Convex.Client.Extensions.Clerk 3.0.0-alpha

This is a prerelease version of Convex.Client.Extensions.Clerk.
The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet add package Convex.Client.Extensions.Clerk --version 3.0.0-alpha
                    
NuGet\Install-Package Convex.Client.Extensions.Clerk -Version 3.0.0-alpha
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Convex.Client.Extensions.Clerk" Version="3.0.0-alpha" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Convex.Client.Extensions.Clerk" Version="3.0.0-alpha" />
                    
Directory.Packages.props
<PackageReference Include="Convex.Client.Extensions.Clerk" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Convex.Client.Extensions.Clerk --version 3.0.0-alpha
                    
#r "nuget: Convex.Client.Extensions.Clerk, 3.0.0-alpha"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Convex.Client.Extensions.Clerk@3.0.0-alpha
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Convex.Client.Extensions.Clerk&version=3.0.0-alpha&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Convex.Client.Extensions.Clerk&version=3.0.0-alpha&prerelease
                    
Install as a Cake Tool

Convex.Client.Extensions.Clerk

Clerk authentication integration for the Convex .NET Client.

Overview

This package provides seamless Clerk authentication integration for Convex .NET clients, similar to the JavaScript SDK's convex/react-clerk package. It includes dependency injection support, token providers, and helper methods for easy integration.

Installation

dotnet add package Convex.Client.Extensions.Clerk

Requirements

  • .NET 8.0 or .NET 9.0
  • Convex .NET Client (Convex.Client)
  • Clerk account with Convex integration configured
  • Clerk JWT template named "convex" configured in your Clerk dashboard

Quick Start

Basic Usage with Dependency Injection

using Convex.Client.Extensions.Clerk;
using Convex.Client.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

// Register Convex with Clerk authentication
builder.Services.AddConvexWithClerk(
    clerkOptions => {
        clerkOptions.PublishableKey = "pk_test_..."; // For client-side
        // OR
        clerkOptions.SecretKey = "sk_test_..."; // For server-side
        clerkOptions.TokenTemplate = "convex";
    },
    convexOptions => {
        convexOptions.DeploymentUrl = "https://your-app.convex.cloud";
    }
);

var app = builder.Build();

Using Configuration Files

Add configuration to appsettings.json:

{
  "Clerk": {
    "PublishableKey": "pk_test_...",
    "SecretKey": "sk_test_...",
    "TokenTemplate": "convex",
    "EnableTokenCaching": true,
    "TokenCacheExpiration": "00:05:00"
  },
  "Convex": {
    "DeploymentUrl": "https://your-app.convex.cloud"
  }
}

Then register services:

builder.Services.AddConvexWithClerk(
    builder.Configuration.GetSection("Clerk"),
    builder.Configuration.GetSection("Convex")
);

Manual Configuration

If you prefer to configure the client manually:

using Convex.Client.Extensions.Clerk;

// Create Clerk token provider
var clerkOptions = new ClerkOptions
{
    PublishableKey = "pk_test_...",
    TokenTemplate = "convex"
};

// Implement IClerkTokenService based on your Clerk SDK
var clerkTokenService = new MyClerkTokenService(clerkOptions);
var tokenProvider = new ClerkAuthTokenProvider(clerkTokenService, clerkOptions);

// Configure Convex client
var client = new ConvexClient("https://your-app.convex.cloud");
await client.UseClerkAuthAsync(tokenProvider);

Features

Token Provider

The ClerkAuthTokenProvider implements IAuthTokenProvider and handles:

  • Automatic token retrieval from Clerk
  • Token caching to reduce API calls
  • Token expiration and refresh
  • Error handling and logging

Dependency Injection Support

Extension methods for easy integration:

  • AddConvexWithClerk() - Full integration with both Clerk and Convex
  • AddClerkAuthTokenProvider() - Just the token provider

Helper Methods

Convenience extensions for IConvexClient:

  • UseClerkAuthAsync() - Configure client with Clerk authentication

Configuration Options

ClerkOptions

Property Type Default Description
PublishableKey string? null Clerk publishable key (client-side)
SecretKey string? null Clerk secret key (server-side)
TokenTemplate string "convex" JWT template name
EnableTokenCaching bool true Enable token caching
TokenCacheExpiration TimeSpan 5 minutes Token cache expiration
CustomTokenRetriever Func<CancellationToken, Task<string?>>? null Custom token retrieval function

Implementing IClerkTokenService

Since Clerk doesn't have an official .NET SDK, you need to implement IClerkTokenService based on your Clerk integration approach:

Option 1: Using CustomTokenRetriever

var clerkOptions = new ClerkOptions
{
    CustomTokenRetriever = async (ct) =>
    {
        // Use your Clerk SDK or API client here
        var token = await GetTokenFromClerkAsync("convex", ct);
        return token;
    }
};

Option 2: Custom IClerkTokenService Implementation

public class MyClerkTokenService : IClerkTokenService
{
    private readonly MyClerkClient _clerkClient;

    public MyClerkTokenService(MyClerkClient clerkClient)
    {
        _clerkClient = clerkClient;
    }

    public bool IsAuthenticated => _clerkClient.IsSignedIn;
    public bool IsLoading => !_clerkClient.IsLoaded;

    public async Task<string?> GetTokenAsync(
        string template = "convex",
        bool skipCache = false,
        CancellationToken cancellationToken = default)
    {
        return await _clerkClient.GetTokenAsync(template, skipCache, cancellationToken);
    }
}

// Register your implementation
builder.Services.AddScoped<IClerkTokenService, MyClerkTokenService>();
builder.Services.AddClerkAuthTokenProvider();

Platform-Specific Guides

ASP.NET Core

using Convex.Client.Extensions.Clerk;
using Convex.Client.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddConvexWithClerk(
    clerkOptions => {
        // Configure Clerk
        clerkOptions.SecretKey = builder.Configuration["Clerk:SecretKey"];
    },
    convexOptions => {
        // Configure Convex
        convexOptions.DeploymentUrl = builder.Configuration["Convex:DeploymentUrl"];
    }
);

var app = builder.Build();

// Use Convex client in your services
app.MapGet("/api/data", async (IConvexClient client) =>
{
    var result = await client.Query<List<MyData>>("data:list").ExecuteAsync();
    return Results.Ok(result);
});

app.Run();

Blazor Server

using Convex.Client.Extensions.Clerk;
using Convex.Client.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();

builder.Services.AddConvexWithClerk(
    clerkOptions => {
        clerkOptions.PublishableKey = builder.Configuration["Clerk:PublishableKey"];
    },
    convexOptions => {
        convexOptions.DeploymentUrl = builder.Configuration["Convex:DeploymentUrl"];
    }
);

var app = builder.Build();

Blazor WebAssembly

For Blazor WASM, you'll need to implement token retrieval from the browser:

// In your Blazor component or service
public class ClerkTokenService : IClerkTokenService
{
    private readonly IJSRuntime _jsRuntime;

    public ClerkTokenService(IJSRuntime jsRuntime)
    {
        _jsRuntime = jsRuntime;
    }

    public bool IsAuthenticated { get; private set; }
    public bool IsLoading { get; private set; }

    public async Task<string?> GetTokenAsync(
        string template = "convex",
        bool skipCache = false,
        CancellationToken cancellationToken = default)
    {
        // Call JavaScript Clerk SDK
        return await _jsRuntime.InvokeAsync<string>(
            "clerk.getToken",
            cancellationToken,
            template,
            skipCache);
    }
}

Console Applications

using Convex.Client.Extensions.Clerk;

var clerkOptions = new ClerkOptions
{
    SecretKey = Environment.GetEnvironmentVariable("CLERK_SECRET_KEY"),
    TokenTemplate = "convex"
};

var clerkTokenService = new MyClerkTokenService(clerkOptions);
var tokenProvider = new ClerkAuthTokenProvider(clerkTokenService, clerkOptions);

var client = new ConvexClient("https://your-app.convex.cloud");
await client.UseClerkAuthAsync(tokenProvider);

// Use the client
var result = await client.Query<List<Data>>("data:list").ExecuteAsync();

Token Caching

Token caching is enabled by default to reduce Clerk API calls. Tokens are cached for 5 minutes by default.

To disable caching:

clerkOptions.EnableTokenCaching = false;

To customize cache expiration:

clerkOptions.TokenCacheExpiration = TimeSpan.FromMinutes(10);

To clear the cache manually:

var tokenProvider = serviceProvider.GetRequiredService<ClerkAuthTokenProvider>();
tokenProvider.ClearCache();

Error Handling

The token provider handles errors gracefully:

  • Returns null if user is not authenticated
  • Returns null if authentication is still loading
  • Throws exceptions for actual errors (network failures, etc.)

Monitor authentication state:

client.AuthenticationSlice.AuthenticationStateChanged += (sender, args) =>
{
    Console.WriteLine($"Auth state: {args.State}");
    if (args.ErrorMessage != null)
    {
        Console.WriteLine($"Error: {args.ErrorMessage}");
    }
};

Troubleshooting

Token Template Not Found

Ensure you've created a JWT template named "convex" in your Clerk dashboard:

  1. Go to Clerk Dashboard → JWT Templates
  2. Create a new template named "convex"
  3. Configure it according to Convex requirements

Authentication Not Working

  1. Verify Clerk keys are correct
  2. Check that TokenTemplate matches your Clerk template name
  3. Ensure IClerkTokenService is properly implemented
  4. Check logs for authentication errors

Token Caching Issues

If tokens seem stale:

  1. Disable caching temporarily: EnableTokenCaching = false
  2. Clear cache manually: tokenProvider.ClearCache()
  3. Adjust TokenCacheExpiration if needed

Examples

See the examples directory for complete working examples.

License

MIT License - see LICENSE for details.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated

Initial release (0.0.1) of Clerk authentication integration for Convex .NET SDK. Includes OAuth 2.0 Authorization Code Flow with PKCE. See CHANGELOG.md for full details.