Xeku.Sharing 0.0.0.7

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

Xeku.Sharing

A secure Magic Link module for sharing XAF business objects with external users without requiring authentication. Enables time-limited, PIN-protected, and access-tracked external sharing.

繁體中文文檔

Features

  • Magic Links: Generate secure, high-entropy tokens for external sharing
  • Security First: Stores only SHA256 hashes, never plaintext tokens
  • Flexible Access Control:
    • Time-based expiration
    • Optional PIN protection
    • Maximum access count limits
    • Manual activation/deactivation toggle
  • Audit Trail: Complete access logging with IP addresses, user agents, and success/failure tracking
  • IShareable Interface: Mark any business object as shareable
  • UI Integration: Built-in "Share Externally" action in detail views
  • Anonymous Access: Shared links work without authentication

Architecture

graph TB
    classDef ui fill:#e1f5ff,stroke:#01579b
    classDef service fill:#fff4e1,stroke:#ff6f00
    classDef entity fill:#e8f5e9,stroke:#2e7d32
    classDef external fill:#f3e5f5,stroke:#7b1fa2

    subgraph "Presentation Layer"
        Controller[ShareLinkController]:::ui
        UI[DetailView Action]:::ui
    end

    subgraph "Service Layer"
        SharingService[SharingService]:::service
        TokenGen[Token Generator]:::service
        HashFunc[SHA256 Hashing]:::service
    end

    subgraph "Data Layer"
        SharedLink[SharedLink]:::entity
        AccessLog[SharedLinkAccessLog]:::entity
        IShareable[IShareable Interface]:::entity
    end

    subgraph "External"
        AnonymousUser[Anonymous User]:::external
        WebAPI[Sharing WebAPI]:::external
    end

    UI --> Controller
    Controller --> SharingService
    SharingService --> TokenGen
    SharingService --> HashFunc
    SharingService --> SharedLink
    SharedLink --> AccessLog
    AnonymousUser --> WebAPI
    WebAPI --> SharingService

Installation

1. Add NuGet Package

dotnet add package Xeku.Sharing

2. Register Module

In your application module constructor:

RequiredModuleTypes.Add(typeof(Xeku.Sharing.SharingModule));

3. Configure Base URL

In appsettings.json, configure the base URL for generating full share links:

{
  "Sharing": {
    "BaseUrl": "https://yourapp.com"
  }
}

4. Mark Business Objects as Shareable

Implement the IShareable interface on business objects you want to share externally:

using Xeku.Sharing.Interfaces;

public class Invoice : BaseObject, IShareable
{
    // Your business object properties
}

Usage

  1. Open the detail view of a business object that implements IShareable
  2. Click the "Share Externally" action button
  3. Configure sharing settings:
    • Expiration Date: When the link will expire (optional)
    • Access PIN: Additional security code (optional)
    • Max Access Count: Limit number of accesses (optional)
  4. Click "Generate Link" to create the magic link
  5. Copy the generated URL and share it with external users
using Xeku.Sharing.Services;
using Xeku.Sharing.BusinessObjects;

// Generate a secure token
string plaintextToken = SharingService.GenerateToken();
string tokenHash = SharingService.ComputeHash(plaintextToken);

// Create a SharedLink record
using IObjectSpace os = objectSpaceFactory.CreateObjectSpace(typeof(SharedLink));
SharedLink link = os.CreateObject<SharedLink>();
link.TokenHash = tokenHash;
link.TargetType = "MyApp.BusinessObjects.Invoice"; // Full type name
link.TargetKey = invoice.Oid.ToString(); // Primary key as string
link.ExpirationDate = DateTime.UtcNow.AddDays(7); // Expires in 7 days
link.AccessPin = "1234"; // Optional PIN
link.MaxAccessCount = 10; // Optional limit
link.CreatedBy = (Guid)SecuritySystem.CurrentUserId;

os.CommitChanges();

// Build the full URL
string shareUrl = $"https://yourapp.com/share/{plaintextToken}";

Validating and Retrieving Shared Objects

using Xeku.Sharing.Services;

var sharingService = new SharingService();
var metadata = new AccessMetadata(ipAddress, userAgent);

using IObjectSpace os = objectSpaceFactory.CreateNonSecuredObjectSpace(typeof(SharedLink));

SharingResult result = sharingService.GetSharedObject(os, plaintextToken, pin, metadata);

if (result.IsValid)
{
    // Success - result.TargetObject contains the shared business object
    var invoice = result.TargetObject as Invoice;
    // Display or process the invoice
}
else
{
    // Error - result.ErrorMessage contains the reason
    Console.WriteLine($"Access denied: {result.ErrorMessage}");
}

Business Objects

Stores encrypted information for external sharing links.

Key Properties:

  • TokenHash (string): SHA256 hash of the plaintext token
  • TargetType (string): Full type name of the shared business object
  • TargetKey (string): Primary key (Oid) of the shared object
  • ExpirationDate (DateTime?): When the link expires
  • AccessPin (string?): Optional PIN for additional security
  • IsActive (bool): Manual enable/disable toggle
  • MaxAccessCount (int?): Maximum number of accesses allowed
  • AccessCount (int): Current number of successful accesses
  • IsValid (bool): Computed property checking all validation rules

SharedLinkAccessLog

Audit log for tracking all access attempts to shared links.

Key Properties:

  • SharedLink (SharedLink): Associated share link
  • AccessTime (DateTime): When the access occurred
  • IpAddress (string?): IP address of the visitor
  • UserAgent (string?): Browser information
  • IsSuccess (bool): Whether access was successful
  • ErrorMessage (string?): Error reason if access failed

ShareLinkParameters

Non-persistent object used in the UI for configuring share links.

Key Properties:

  • TargetType (string): Business object type to share
  • TargetKey (string): Object key/ID
  • ExpirationDate (DateTime?): Link expiration
  • AccessPin (string?): Optional PIN code
  • MaxAccessCount (int?): Access limit
  • GeneratedUrl (string?): Display the generated URL after creation

Interfaces

IShareable

Marker interface for business objects that can be shared externally.

public interface IShareable
{
}

ShareableAttribute

Attribute to mark specific properties as shareable (future enhancement).

[AttributeUsage(AttributeTargets.Property)]
public class ShareableAttribute : Attribute
{
}

Controllers

ShareLinkController

Provides the "Share Externally" action button in detail views for IShareable objects.

Features:

  • Popup window for configuring share settings
  • Real-time link generation
  • Two-step workflow: Generate → Copy → Close
  • Configuration validation and warnings

Services

SharingService

Core service for managing and validating external sharing links.

Methods:

Method Description
GenerateToken() Generate a secure 64-character hex token
ComputeHash(token) Compute SHA256 hash of a plaintext token
GetSharedObject(os, token, pin, metadata) Validate token and retrieve shared object

Security Considerations

Token Security

  • Tokens are 64-character hexadecimal strings (256 bits of entropy)
  • Only SHA256 hashes are stored in the database
  • Plaintext tokens are shown only once during generation

Validation Chain

  1. Link Existence: Token hash must exist in database
  2. Active Status: Link must be manually activated
  3. Expiration: Current time must be before expiration date
  4. Access Limit: Access count must be below maximum
  5. PIN Verification: PIN must match if configured

Access Control

  • Uses INonSecuredObjectSpaceFactory for data access
  • No XAF security checks on shared objects
  • Implement field-level control using [Shareable] attribute (future)

Error Messages

Error Meaning
"Link not found." Invalid or non-existent token
"Link has been disabled." IsActive is set to false
"Link has expired." Current time exceeds ExpirationDate
"Access limit reached." AccessCount >= MaxAccessCount
"Invalid PIN code." Provided PIN doesn't match
"Source type not found: {type}" Business object type no longer exists
"Shared data no longer exists." Target object was deleted

Configuration

appsettings.json

{
  "Sharing": {
    "BaseUrl": "https://yourapp.com"
  }
}

Required Services

This module requires IConfiguration to be available in the DI container for reading the base URL.

AI Agent Integration

Use Cases

AI agents can use the Sharing module to:

  • Generate Shareable Links: Create magic links for reports, invoices, or documents
  • Access Control: Set expiration times and access limits programmatically
  • Audit Analysis: Query access logs to understand sharing patterns
  • Link Management: Deactivate or update existing share links

API Integration Guide

See Xeku.Sharing.WebApi for REST API endpoints.

Best Practices

  1. Always Set Expiration: Don't create permanent links unless absolutely necessary
  2. Use PIN for Sensitive Data: Add PIN protection for confidential information
  3. Monitor Access Logs: Regularly review SharedLinkAccessLog for suspicious activity
  4. Deactivate After Use: Manually set IsActive = false when link is no longer needed
  5. Field-Level Security: Only share necessary properties (use [Shareable] attribute)

Troubleshooting

"Warning: Sharing:BaseUrl not configured"

Solution: Add Sharing:BaseUrl to your appsettings.json:

{
  "Sharing": {
    "BaseUrl": "https://yourapp.com"
  }
}

Share action button not visible

Possible causes:

  1. Business object doesn't implement IShareable interface
  2. You're in a ListView (action only appears in DetailView)
  3. Module not registered in application

Possible causes:

  1. Token was copied incorrectly (case-sensitive)
  2. Token was modified during transmission
  3. Link was deleted from database

Dependencies

This module requires:

  • DevExpress.ExpressApp - XAF framework
  • DevExpress.Persistent.BaseImpl - Base business objects
  • System.Security.Cryptography - SHA256 hashing

License

MIT

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 was computed.  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 (2)

Showing the top 2 NuGet packages that depend on Xeku.Sharing:

Package Downloads
Xeku.Sharing.WebApi

Web API endpoints for Xeku.Sharing, supporting anonymous data retrieval.

Xeku.Sharing.Blazor

Blazor components for Xeku.Sharing, including anonymous access pages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.0.0.7 132 1/28/2026