snapshot of https://github.com/tldraw/tldraw.git (main, 2026-09-23; blobs > 131072B omitted)
Some checks failed
Deploy analytics worker / Deploy analytics worker to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
i18n upload strings / Upload latest strings (push) Failing after 1s
Deploy bemo / Deploy bemo to ${{ (github.ref == 'refs/heads/bemo-production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
Deploy grafana resources / ${{ github.event_name == 'push' && 'Deploy grafana resources' || 'Validate grafana resources (dry run)' }} (push) Failing after 0s
End to end tests (dotcom) / Check for relevant changes (push) Failing after 0s
End to end tests (examples) / Check for relevant changes (push) Failing after 0s
End to end tests (mermaid readability) / Check for relevant changes (push) Failing after 1s
End to end tests (perf) / Check for relevant changes (push) Failing after 0s
Publish editor extensions / Publish editor extensions (push) Failing after 1s
Publish SDK packages / Remove the publish-packages label (push) Has been skipped
Checks / Tests & checks (push) Has been cancelled
Checks / Build all projects (push) Has been cancelled
Deploy templates / Deploy templates (push) Has been cancelled
End to end tests (dotcom) / End to end tests (dotcom) (push) Has been cancelled
End to end tests (mermaid readability) / End to end tests (mermaid readability) (push) Has been cancelled
End to end tests (perf) / End to end tests (perf) (push) Has been cancelled
Deploy .com / Deploy dotcom to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Has been cancelled
End to end tests (examples) / End to end tests (examples) (push) Has been cancelled
Publish SDK packages / Publish SDK packages (push) Has been cancelled
Publish SDK packages / Tell user released version (push) Has been cancelled
Publish SDK packages / Publishes code templates to separate repositories (push) Has been cancelled
Publish SDK packages / Deploys the template demos with the new SDK version (push) Has been cancelled

This commit is contained in:
upstream-mirror
2026-09-23 16:12:52 +05:00
commit a774ac673a
4541 changed files with 770499 additions and 0 deletions

View File

@@ -0,0 +1,257 @@
#!/usr/bin/env npx tsx
/**
* Test License Key Generator
*
* This script generates various license keys for manual testing of the LicenseManager.
* Uses the existing test utilities from LicenseManager.test.ts
*/
import crypto from 'crypto'
import { FLAGS } from '../../packages/editor/src/lib/license/LicenseManager'
import { str2ab } from '../../packages/editor/src/lib/utils/licensing'
// Utility function copied from LicenseManager.test.ts to avoid import issues
function ab2str(buf: ArrayBuffer) {
return String.fromCharCode.apply(null, Array.from(new Uint8Array(buf)))
}
// Utility functions copied from LicenseManager.test.ts (not exported)
async function generateLicenseKey(
message: string,
keyPair: { publicKey: string; privateKey: string }
) {
const enc = new TextEncoder()
const encodedMsg = enc.encode(message)
const privateKey = await importPrivateKey(keyPair.privateKey)
const signedLicenseKeyBuffer = await crypto.subtle.sign(
{
name: 'ECDSA',
hash: { name: 'SHA-256' },
},
privateKey,
encodedMsg
)
const signature = btoa(ab2str(signedLicenseKeyBuffer))
const prefix = 'tldraw-'
const licenseKey = `${prefix}/${btoa(message)}.${signature}`
return licenseKey
}
function importPrivateKey(pemContents: string) {
const binaryDerString = atob(pemContents)
const binaryDer = str2ab(binaryDerString)
return crypto.subtle.importKey(
'pkcs8',
new Uint8Array(binaryDer),
{
name: 'ECDSA',
namedCurve: 'P-256',
},
true,
['sign']
)
}
async function exportCryptoKey(key: CryptoKey, isPublic = false) {
const exported = await crypto.subtle.exportKey(isPublic ? 'spki' : 'pkcs8', key)
return btoa(ab2str(exported))
}
// Generate a fresh key pair for each run
async function generateKeyPair() {
const keyPair = await crypto.subtle.generateKey(
{
name: 'ECDSA',
namedCurve: 'P-256',
},
true,
['sign', 'verify']
)
const publicKey = await exportCryptoKey(keyPair.publicKey, true /* isPublic */)
const privateKey = await exportCryptoKey(keyPair.privateKey)
return { publicKey, privateKey }
}
function createLicenseInfo(id: string, hosts: string[], flags: number, expiryDate: string) {
return JSON.stringify([id, hosts, flags, expiryDate])
}
function getDateOffset(days: number): string {
const date = new Date()
date.setDate(date.getDate() + days)
return date.toISOString().slice(0, 10)
}
async function main() {
console.log('🔑 Generating test license keys for LicenseManager testing...\n')
console.log('Generating fresh key pair for testing...')
const keyPair = await generateKeyPair()
console.log('Public Key:', keyPair.publicKey)
console.log('Private Key:', keyPair.privateKey)
console.log('')
const testCases = [
// === VALID LICENSES ===
{
name: 'Valid Annual License',
info: createLicenseInfo(
'test-annual-valid',
['localhost'],
FLAGS.ANNUAL_LICENSE,
getDateOffset(60) // 2 months future
),
},
{
name: 'Valid Perpetual License',
info: createLicenseInfo(
'test-perpetual-valid',
['localhost'],
FLAGS.PERPETUAL_LICENSE,
getDateOffset(365) // 1 year future
),
},
{
name: 'Valid Evaluation License',
info: createLicenseInfo(
'test-eval-valid',
['localhost'],
FLAGS.EVALUATION_LICENSE,
getDateOffset(14) // 2 weeks future
),
},
{
name: 'Valid Internal License',
info: createLicenseInfo(
'test-internal-valid',
['localhost'],
FLAGS.ANNUAL_LICENSE | FLAGS.INTERNAL_LICENSE,
getDateOffset(60) // 2 months future
),
},
{
name: 'License with Watermark Flag',
info: createLicenseInfo(
'test-watermark-only',
['localhost'],
FLAGS.WITH_WATERMARK,
getDateOffset(60) // 2 months future
),
},
// === FEATURE FLAGS ===
{
name: 'License with Commenting Feature',
info: createLicenseInfo(
'test-feat-commenting',
['localhost'],
FLAGS.ANNUAL_LICENSE | FLAGS.FEAT_COMMENTING,
getDateOffset(60) // 2 months future
),
},
{
name: 'License with Collaboration Feature (grants commenting)',
info: createLicenseInfo(
'test-feat-collaboration',
['localhost'],
FLAGS.ANNUAL_LICENSE | FLAGS.FEAT_COLLABORATION,
getDateOffset(60) // 2 months future
),
},
// === GRACE PERIOD TESTING ===
{
name: 'Annual License (expired 15 days - within grace period)',
info: createLicenseInfo(
'test-grace-15days',
['localhost'],
FLAGS.ANNUAL_LICENSE,
getDateOffset(-15) // 15 days past
),
},
{
name: 'Annual License (expired 45 days - beyond grace period)',
info: createLicenseInfo(
'test-annual-expired-45days',
['localhost'],
FLAGS.ANNUAL_LICENSE,
getDateOffset(-45) // 45 days past
),
},
// === EXPIRED INTERNAL LICENSES ===
{
name: 'Internal License (expired 15 days - within grace period)',
info: createLicenseInfo(
'test-internal-expired-15days',
['localhost'],
FLAGS.ANNUAL_LICENSE | FLAGS.INTERNAL_LICENSE,
getDateOffset(-15) // 15 days past
),
},
{
name: 'Internal License (expired 45 days - beyond grace period)',
info: createLicenseInfo(
'test-internal-expired-45days',
['localhost'],
FLAGS.ANNUAL_LICENSE | FLAGS.INTERNAL_LICENSE,
getDateOffset(-45) // 45 days past
),
},
// === EXPIRED EVALUATION LICENSES ===
{
name: 'Evaluation License (expired 1 day)',
info: createLicenseInfo(
'test-eval-expired-1day',
['localhost'],
FLAGS.EVALUATION_LICENSE,
getDateOffset(-1) // 1 day past
),
},
{
name: 'Evaluation License (expired 15 days)',
info: createLicenseInfo(
'test-eval-expired-15days',
['localhost'],
FLAGS.EVALUATION_LICENSE,
getDateOffset(-15) // 15 days past
),
},
]
console.log('🎫 Generated Test License Keys:\n')
for (const testCase of testCases) {
try {
const licenseKey = await generateLicenseKey(testCase.info, keyPair)
console.log(`## ${testCase.name}`)
console.log(`License Info: ${testCase.info}`)
console.log(`License Key: ${licenseKey}`)
console.log('')
} catch (error) {
console.error(`❌ Failed to generate license for ${testCase.name}:`, error)
}
}
console.log('📝 Usage Instructions:')
console.log('')
console.log('🚨 DO NOT COMMIT THESE KEYS TO THE REPOSITORY! 🚨')
console.log('These are temporary test keys - generate fresh ones for each session')
console.log('')
console.log('Option 1 - Update LicenseManager (development):')
console.log(` Replace publicKey in LicenseManager.ts with: "${keyPair.publicKey}"`)
console.log(' Then use: <Tldraw licenseKey="license-key-from-above" />')
console.log('')
console.log('Option 2 - Pass testPublicKey (automated testing):')
console.log(` new LicenseManager("license-key", "${keyPair.publicKey}", "production")`)
console.log('')
console.log('ℹ️ For production licenses: sales@tldraw.com')
}
main().catch(console.error)