licensify 1.6.0 copy "licensify: ^1.6.0" to clipboard
licensify: ^1.6.0 copied to clipboard

A lightweight yet powerful license management solution for Flutter and Dart applications with cryptographically secure signatures

Licensify #

Advanced licensing solution for Flutter/Dart applications with robust protection and flexible options.

Features #

  • 🔒 RSA Verification: Secure cryptographic signatures
  • 🕒 Expiration Dates: Automatic expiration verification
  • 🔄 Custom License Types: Standard and custom license types
  • 📋 Flexible Features: Add custom parameters and metadata
  • 💾 Storage Independence: Bring your own storage solution
  • 📲 Cross-Platform: Works on all platforms including web (WASM)
  • 🔍 Schema Validation: Validate license feature structure with customizable schemas

Installation #

dependencies:
  licensify: ^1.6.0
copied to clipboard

Quick Start #

Generate License Keys #

// Generate RSA keys (do this once, store private key securely!)
final keys = RsaKeyGenerator.generateKeyPairAsPem(bitLength: 2048);
copied to clipboard

Create & Distribute Licenses #

// Generate a license for a customer
final generator = GenerateLicenseUseCase(privateKey: yourPrivateKey);
final license = generator.generateLicense(
  appId: 'com.your.app',
  expirationDate: DateTime.now().add(const Duration(days: 365)),
  type: LicenseType.pro,  // Or custom: LicenseType('enterprise')
  features: {'maxUsers': 10, 'modules': ['reporting', 'export']},
  // Optional device binding
  metadata: {'deviceHash': 'unique-device-identifier'},
);

// Export license to bytes for distribution
final licenseBytes = generator.licenseToBytes(license);
copied to clipboard

Verify Licenses in Your App #

// Setup (do once at app startup)
// Use your own storage mechanism or use built-in InMemoryLicenseStorage for testing
final storage = InMemoryLicenseStorage();
final repository = LicenseRepository(storage: storage);
final validator = LicenseValidator(publicKey: yourPublicKey); 
final licenseChecker = CheckLicenseUseCase(
  repository: repository,
  validator: validator,
);

// Check license
final status = await licenseChecker.checkCurrentLicense();
if (status.isActive) {
  final license = (status as ActiveLicenseStatus).license;
  // Enable features based on license type and features
  if (license.type == LicenseType.pro || license.type.name == 'enterprise') {
    enableProFeatures();
  }
} else {
  // Handle invalid/expired/missing license
}
copied to clipboard

Storage Options #

The Licensify package follows the repository pattern and allows you to implement your own storage solution. Simply implement the ILicenseStorage interface to provide your own mechanism.

In-Memory Storage (For Testing) #

final storage = InMemoryLicenseStorage();
copied to clipboard

Implement Your Own Storage #

// Implement ILicenseStorage to create your own storage mechanism
class MyCustomStorage implements ILicenseStorage {
  @override
  Future<bool> deleteLicenseData() async {
    // Your implementation
  }

  @override
  Future<bool> hasLicense() async {
    // Your implementation
  }

  @override
  Future<Uint8List?> loadLicenseData() async {
    // Your implementation
  }

  @override
  Future<bool> saveLicenseData(Uint8List data) async {
    // Your implementation
  }
}
copied to clipboard

Schema Validation #

Define and validate expected structure for license features and metadata:

// Define a schema for enterprise licenses
final enterpriseSchema = LicenseSchema(
  // Feature fields schema
  featureSchema: {
    'maxUsers': SchemaField(
      type: FieldType.integer,
      required: true,
      validators: [NumberValidator(minimum: 1, maximum: 1000)],
    ),
    'modules': SchemaField(
      type: FieldType.array,
      required: true,
      validators: [ArrayValidator(minItems: 1)],
    ),
  },
  // Metadata fields schema
  metadataSchema: {
    'clientName': SchemaField(
      type: FieldType.string,
      required: true,
    ),
    'deviceHash': SchemaField(type: FieldType.string),
  },
  // Don't allow unknown feature fields
  allowUnknownFeatures: false,
);

// Validate a license against the schema
final validationResult = validator.validateSchema(license, enterpriseSchema);
if (validationResult.isValid) {
  print('License schema valid!');
} else {
  print('Schema validation failed: ${validationResult.errors}');
}

// Validate everything at once (signature, expiration, schema)
final isValid = validator.validateLicenseWithSchema(license, enterpriseSchema);
copied to clipboard

Custom License Types #

// Define custom license types beyond standard ones
final enterpriseType = LicenseType('enterprise');
final educationType = LicenseType('education');

// Standard types are predefined
final trial = LicenseType.trial;
final standard = LicenseType.standard;
final pro = LicenseType.pro;
copied to clipboard

License Format #

Licenses include:

  • Unique ID and app ID
  • Creation and expiration dates
  • License type (standard or custom)
  • Custom features and metadata
  • RSA signature for verification

Full JSON structure:

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "appId": "com.example.myapp",
  "createdAt": "2024-07-25T14:30:00Z",
  "expirationDate": "2025-07-25T14:30:00Z",
  "type": "enterprise",
  "features": {
    "maxUsers": 50,
    "modules": ["analytics", "reporting"]
  },
  "metadata": {
    "clientName": "Example Corp",
    "deviceHash": "device-unique-identifier"
  },
  "signature": "Base64EncodedSignature..."
}
copied to clipboard

Security Notes #

  • Store private keys securely, never in your app
  • Public key is safe to embed in your application
  • Consider using code obfuscation in release builds
  • For high-security needs, add server-side verification

Complete Example #

See example/rsa_license_demo.dart for a complete implementation.

License #

SPDX-License-Identifier: LGPL-3.0-or-later
copied to clipboard

Created by Karim "nogipx" Mamatkazin

4
likes
0
points
415
downloads

Publisher

verified publisherdart.nogipx.dev

Weekly Downloads

2024.09.16 - 2025.03.31

A lightweight yet powerful license management solution for Flutter and Dart applications with cryptographically secure signatures

Repository (GitHub)
View/report issues

Topics

#license #security #validation #cryptography #web

Documentation

Documentation

License

unknown (license)

Dependencies

basic_utils, pointycastle, uuid

More

Packages that depend on licensify