feat(release): prepare 1.1.0 candidate

This commit is contained in:
Yun Chan 2026-08-29 18:33:45 +09:00
parent 5a34f66981
commit 5205dcdfa9
736 changed files with 115667 additions and 12203 deletions

View file

@ -23,6 +23,23 @@ import { verifySignedLicenseKey, createDefaultTrialPayload } from '@d3ro/core/ut
const logger = getLogger('license')
function resolveLicenseVerificationConfig(): {
publicKeyPem: string | undefined
allowDevelopmentKeys: boolean
environment: string | undefined
} {
const environment = process.env.NODE_ENV
const allowDevelopmentKeys =
environment === 'test' ||
(environment === 'development' && process.env.D3RO_ALLOW_LEGACY_DEV_LICENSES === 'true')
const configuredPublicKey = process.env.D3RO_LICENSE_PUBLIC_KEY?.trim()
return {
publicKeyPem: configuredPublicKey?.replace(/\\n/g, '\n'),
allowDevelopmentKeys,
environment,
}
}
// ── 머신 ID 생성 ─────────────────────────────────────────
function generateMachineId(): string {
const raw = `${os.hostname()}-${os.cpus()[0]?.model ?? 'unknown'}-${os.platform()}-${os.arch()}`
@ -108,9 +125,6 @@ const TIER_ORDER: Record<LicenseTier, number> = {
/** 오프라인 유예 기간: 30일 */
const OFFLINE_GRACE_PERIOD_MS = 30 * 24 * 60 * 60 * 1000
/** 온라인 재검증 주기: 30일 */
const REVERIFY_INTERVAL_MS = 30 * 24 * 60 * 60 * 1000
function tierAtLeast(current: LicenseTier, required: LicenseTier): boolean {
return TIER_ORDER[current] >= TIER_ORDER[required]
}
@ -174,8 +188,6 @@ class LicenseService extends EventEmitter {
const storedTrialExpiresAt = this._readStoredField<number>('licenseTrialExpiresAt')
const storedExpiresAt = this._readStoredField<number>('licenseExpiresAt')
const storedCustomerEmail = this._readStoredField<string>('licenseCustomerEmail')
const trialEverStarted = this._readStoredField<boolean>('licenseTrialEverStarted')
const now = Date.now()
if (storedTier && storedTier !== 'free') {
@ -410,9 +422,9 @@ class LicenseService extends EventEmitter {
}
/**
* (Ed25519 + ).
* D3RO-LIC-xxx (Ed25519 ) D3RO-PRO-xxx ( )
* Payple/Stripe CloudSync
* (Ed25519 ).
* D3RO_LICENSE_PUBLIC_KEY가 , fixture는 test
* opt-in한 development .
*/
async activate(key: string): Promise<ActivateLicenseResult> {
const trimmedKey = key.trim()
@ -420,7 +432,13 @@ class LicenseService extends EventEmitter {
return { success: false, tier: 'free', message: 'License key is empty' }
}
const verification = verifySignedLicenseKey(trimmedKey, this._info.machineId)
const verificationConfig = resolveLicenseVerificationConfig()
const verification = verifySignedLicenseKey(
trimmedKey,
this._info.machineId,
verificationConfig.publicKeyPem,
verificationConfig,
)
if (!verification.valid) {
return { success: false, tier: 'free', message: verification.message }
}