OneTimeLink.Core 1.0.0

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 OneTimeLink.Core --version 1.0.0
                    
NuGet\Install-Package OneTimeLink.Core -Version 1.0.0
                    
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="OneTimeLink.Core" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="OneTimeLink.Core" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="OneTimeLink.Core" />
                    
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 OneTimeLink.Core --version 1.0.0
                    
#r "nuget: OneTimeLink.Core, 1.0.0"
                    
#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 OneTimeLink.Core@1.0.0
                    
#: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=OneTimeLink.Core&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=OneTimeLink.Core&version=1.0.0
                    
Install as a Cake Tool

Build Tests NuGet

A robust, lightweight .NET library for creating and validating one-time use links. Perfect for password reset emails, email verification, secure invitations, and more.

Features

  • ๐Ÿ”’ Secure token generation
  • โฑ๏ธ Configurable expiration times
  • ๐Ÿšซ Automatic protection against reuse
  • ๐Ÿงน Easy cleanup of expired tokens
  • ๐Ÿ”Œ Database agnostic with Entity Framework Core support
  • ๐Ÿงฉ Simple integration with dependency injection

Installation

Core Package

dotnet add package OneTimeLink.Core

Entity Framework Core Integration

dotnet add package OneTimeLink.EntityFrameworkCore

Quick Start

Setup with Entity Framework Core

// In Program.cs or Startup.cs
services.AddLinkWithEfCore<LinkDbContext>(
    options => {
        options.DefaultExpiration = TimeSpan.FromHours(24);
    },
    dbOptions => dbOptions.UseMySql(
        connectionString,
        ServerVersion.AutoDetect(connectionString)
    )
);
public class PasswordResetController : ControllerBase
{
    private readonly ILinkService _linkService;
    
    public PasswordResetController(ILinkService linkService)
    {
        _linkService = linkService;
    }
    
    [HttpPost]
    public async Task<IActionResult> RequestReset(string email)
    {
        var user = await _userService.FindByEmailAsync(email);
        if (user == null) return Ok(); // Don't reveal if email exists
        
        var baseUrl = $"{Request.Scheme}://{Request.Host}";
        var resetLink = await _linkService.GenerateLinkAsync(baseUrl, user.Id, "password-reset");
        
        await _emailService.SendPasswordResetEmailAsync(email, resetLink);
        
        return Ok();
    }
    
    [HttpGet("reset/{token}")]
    public async Task<IActionResult> ValidateResetToken(string token)
    {
        var link = await _linkService.ValidateAndUseLinkAsync(token);
        if (link == null)
        {
            return BadRequest("Invalid or expired reset link");
        }
        
        // Token is valid and has been marked as used
        return View(new ResetPasswordViewModel { UserId = link.UserId, Token = token });
    }
}

Database Setup

Using your own DbContext

public class ApplicationDbContext : DbContext, ILinkDbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
    
    public DbSet<Link> Links { get; set; }
    
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        
        modelBuilder.Entity<Link>(entity =>
        {
            entity.HasKey(e => e.Id);
            entity.HasIndex(e => e.Token).IsUnique();
            // Other configurations...
        });
    }
}

Running Database Migrations

dotnet ef migrations add AddLinkTable
dotnet ef database update

Advanced Configuration

Custom Token Length

services.AddLinkWithEfCore<LinkDbContext>(
    options => {
        options.DefaultExpiration = TimeSpan.FromDays(7);
        options.TokenLength = 64; // Longer tokens for higher security
    },
    dbOptions => dbOptions.UseSqlServer(connectionString)
);
var resetLink = await _linkService.GenerateLinkAsync(
    "https://myapp.com/custom-reset-page", 
    user.Id, 
    "password-reset",
    TimeSpan.FromHours(2) // Custom expiration
);

Scheduled Cleanup

// Use a background service or scheduled job to clean up expired links
public class LinkCleanupService : BackgroundService
{
    private readonly IServiceProvider _services;
    
    public LinkCleanupService(IServiceProvider services)
    {
        _services = services;
    }
    
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            using (var scope = _services.CreateScope())
            {
                var linkService = scope.ServiceProvider.GetRequiredService<ILinkService>();
                await linkService.CleanupExpiredLinksAsync();
            }
            
            // Run once per day
            await Task.Delay(TimeSpan.FromDays(1), stoppingToken);
        }
    }
}

License

This project is licensed under the MIT License - see the LICENSE file for details.

Product Compatible and additional computed target framework versions.
.NET 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