{"_id":"@ben0918/offline-license-manager","_rev":"9-4aacd1e73ff97f10b487de95292bf051","name":"@ben0918/offline-license-manager","dist-tags":{"latest":"1.7.2"},"versions":{"1.0.0":{"name":"@ben0918/offline-license-manager","version":"1.0.0","keywords":["license","offline","ed25519","cli"],"license":"MIT","_id":"@ben0918/offline-license-manager@1.0.0","maintainers":[{"name":"ben0918","email":"renyu0520@gmail.com"}],"homepage":"https://github.com/Yu-Ren-NEU/Offline-License-Manager#readme","bugs":{"url":"https://github.com/Yu-Ren-NEU/Offline-License-Manager/issues"},"bin":{"offline-license":"dist/src/cli.js"},"dist":{"shasum":"ddae07c05708f075ee6d4533b440e77b3b2e3f9c","tarball":"https://registry.npmjs.org/@ben0918/offline-license-manager/-/offline-license-manager-1.0.0.tgz","fileCount":30,"integrity":"sha512-/GxuRY8n9NbvkTi5CPaNBmKKFtcjH5joaDN+5oAJMKkFKPjtxSNmnQXTQ2AKpX5284N608oEfljh5MIlD3qePg==","signatures":[{"sig":"MEUCIQCbTKNQ7++EsdGiysqMFwqlw+RcLUaW8Ti8EMdLRyoOGgIgFOlYRZqM6KKgLAt6cgHLFciIPKFyapWFwFd82hSzjm8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":57744},"main":"dist/src/index.js","type":"module","types":"dist/src/index.d.ts","engines":{"node":">=20"},"gitHead":"042f3c2770c0df12df87352391dfe184fefe5130","scripts":{"lint":"tsc -p tsconfig.json --noEmit","test":"npm run build && node --test dist/test/*.test.js","build":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json"},"_npmUser":{"name":"ben0918","email":"renyu0520@gmail.com"},"repository":{"url":"git+https://github.com/Yu-Ren-NEU/Offline-License-Manager.git","type":"git"},"_npmVersion":"11.19.0","description":"Zero-server Ed25519 license issuing and verification toolkit","directories":{},"_nodeVersion":"26.7.0","dependencies":{"argon2":"^0.44.0","commander":"^14.0.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.2","@types/node":"^24.3.0"},"_npmOperationalInternal":{"tmp":"tmp/offline-license-manager_1.0.0_1788006238679_0.3215612498050553","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@ben0918/offline-license-manager","version":"1.1.0","keywords":["license","offline","ed25519","cli"],"license":"MIT","_id":"@ben0918/offline-license-manager@1.1.0","maintainers":[{"name":"ben0918","email":"renyu0520@gmail.com"}],"homepage":"https://github.com/Yu-Ren-NEU/Offline-License-Manager#readme","bugs":{"url":"https://github.com/Yu-Ren-NEU/Offline-License-Manager/issues"},"bin":{"offline-license":"dist/src/cli.js"},"dist":{"shasum":"a0cae3fb6a7a2511f889445304f06c4c1c94404f","tarball":"https://registry.npmjs.org/@ben0918/offline-license-manager/-/offline-license-manager-1.1.0.tgz","fileCount":34,"integrity":"sha512-4S/MmFeyA9iLOuZO23Xw3tRMPTu65VSUHWGVBXlow/TC7mRRDTSGoGlA3F+eqcnZQxBgw36w2tq7SfDsgNhJQA==","signatures":[{"sig":"MEQCIEGW9GWW5JLOoQswFQF18I9LT2i4xcol7F/1jmqj6pEAAiBryvW80MzG/NuGpbb3Votlh//2le8R94KPMFG/RYwisg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":79287},"main":"dist/src/index.js","type":"module","types":"dist/src/index.d.ts","engines":{"node":">=20"},"gitHead":"0c189ebef6f86a449f3c87d6c78f38df4f9cc997","scripts":{"lint":"tsc -p tsconfig.json --noEmit","test":"npm run build && node --test dist/test/*.test.js","build":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json"},"_npmUser":{"name":"ben0918","email":"renyu0520@gmail.com"},"repository":{"url":"git+https://github.com/Yu-Ren-NEU/Offline-License-Manager.git","type":"git"},"_npmVersion":"11.19.0","description":"Zero-server Ed25519 license issuing and verification toolkit","directories":{},"_nodeVersion":"26.7.0","dependencies":{"argon2":"^0.44.0","commander":"^14.0.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.2","@types/node":"^24.3.0"},"_npmOperationalInternal":{"tmp":"tmp/offline-license-manager_1.1.0_1788007023289_0.9974130239602994","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@ben0918/offline-license-manager","version":"1.2.0","keywords":["license","offline","ed25519","cli"],"license":"MIT","_id":"@ben0918/offline-license-manager@1.2.0","maintainers":[{"name":"ben0918","email":"renyu0520@gmail.com"}],"homepage":"https://github.com/Yu-Ren-NEU/Offline-License-Manager#readme","bugs":{"url":"https://github.com/Yu-Ren-NEU/Offline-License-Manager/issues"},"bin":{"offline-license":"dist/src/cli.js"},"dist":{"shasum":"84d173c325254b0d37351610d6b4f823f9f9d719","tarball":"https://registry.npmjs.org/@ben0918/offline-license-manager/-/offline-license-manager-1.2.0.tgz","fileCount":34,"integrity":"sha512-XFcXhGWqwnp3U8EwjzvLUL7jWyo2f/7gPgaLH4IqLDpqogd/j4OK+cQvAQpzB6yFODZmqs4+KxPx/1QlCAVhHQ==","signatures":[{"sig":"MEUCICrq+ZXOMeq0KWa9ibpZbdyEKc17YC3PhQVOnrF+RmxSAiEAp3kym64/SzNcqiinz+PXHYvOtBOiTkVOh01SPQo8a40=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":91231},"main":"dist/src/index.js","type":"module","types":"dist/src/index.d.ts","engines":{"node":">=20"},"gitHead":"b26e049b220e430f80d91a90042a2c5523c489e9","scripts":{"lint":"tsc -p tsconfig.json --noEmit","test":"npm run build && node --test dist/test/*.test.js","build":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json"},"_npmUser":{"name":"ben0918","email":"renyu0520@gmail.com"},"repository":{"url":"git+https://github.com/Yu-Ren-NEU/Offline-License-Manager.git","type":"git"},"_npmVersion":"11.19.0","description":"Zero-server Ed25519 license issuing and verification toolkit","directories":{},"_nodeVersion":"26.7.0","dependencies":{"argon2":"^0.44.0","commander":"^14.0.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.2","@types/node":"^24.3.0"},"_npmOperationalInternal":{"tmp":"tmp/offline-license-manager_1.2.0_1788019717958_0.15229401833306855","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@ben0918/offline-license-manager","version":"1.3.0","keywords":["license","offline","ed25519","cli"],"license":"MIT","_id":"@ben0918/offline-license-manager@1.3.0","maintainers":[{"name":"ben0918","email":"renyu0520@gmail.com"}],"homepage":"https://github.com/Yu-Ren-NEU/Offline-License-Manager#readme","bugs":{"url":"https://github.com/Yu-Ren-NEU/Offline-License-Manager/issues"},"bin":{"offline-license":"dist/src/cli.js"},"dist":{"shasum":"647df33c5ecb3083aae7663455312195aad5fe7b","tarball":"https://registry.npmjs.org/@ben0918/offline-license-manager/-/offline-license-manager-1.3.0.tgz","fileCount":34,"integrity":"sha512-AToYDIFchClncbg0S2XzN+F/x8tcRbUFVrbau0L6KTCmXTfBE+JN87adtqN6pS1wstNkJjeO46lTtyuzIIK70Q==","signatures":[{"sig":"MEUCIQCnEdde0wyXSezH+b8JJSu1VFLbCmlWGIQGAX1rgkEx4QIgbGvRttzJNr2f8sc2mMzAiKHfTcx+4jqXf6dXsjdMDwc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":98737},"main":"dist/src/index.js","type":"module","types":"dist/src/index.d.ts","engines":{"node":">=20"},"gitHead":"b9220053e541b7fd5c2dfcec8a862241d7fcd6c2","scripts":{"lint":"tsc -p tsconfig.json --noEmit","test":"npm run build && node --test dist/test/*.test.js","build":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json"},"_npmUser":{"name":"ben0918","email":"renyu0520@gmail.com"},"repository":{"url":"git+https://github.com/Yu-Ren-NEU/Offline-License-Manager.git","type":"git"},"_npmVersion":"11.19.0","description":"Zero-server Ed25519 license issuing and verification toolkit","directories":{},"_nodeVersion":"26.7.0","dependencies":{"argon2":"^0.44.0","commander":"^14.0.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.2","@types/node":"^24.3.0"},"_npmOperationalInternal":{"tmp":"tmp/offline-license-manager_1.3.0_1788020572291_0.8632687785235895","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"@ben0918/offline-license-manager","version":"1.4.0","keywords":["license","offline","ed25519","cli"],"license":"MIT","_id":"@ben0918/offline-license-manager@1.4.0","maintainers":[{"name":"ben0918","email":"renyu0520@gmail.com"}],"homepage":"https://github.com/Yu-Ren-NEU/Offline-License-Manager#readme","bugs":{"url":"https://github.com/Yu-Ren-NEU/Offline-License-Manager/issues"},"bin":{"offline-license":"dist/src/cli.js"},"dist":{"shasum":"e8259aea48db250af607cb5676016fb2aa44d429","tarball":"https://registry.npmjs.org/@ben0918/offline-license-manager/-/offline-license-manager-1.4.0.tgz","fileCount":34,"integrity":"sha512-x4ygIH1XxQK0xFZdEyhVy4ZPSEOWXRdFhpWxcy03n16Nf203v9P7rhN+GQvmNG5gatx/pfH6y17IthHzT5oTeQ==","signatures":[{"sig":"MEYCIQC88/1hx/2SYYL/DBnmYs21sG7amwU/tbD/kUR0WkBcqgIhAKz456SHWZV6kqgnCgPClpf19kMgNCOJWWo7YgZEuXiq","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":107461},"main":"dist/src/index.js","type":"module","types":"dist/src/index.d.ts","engines":{"node":">=20"},"gitHead":"3a257eb8ce8fa1858d31989fd5b101c73f13ae6d","scripts":{"lint":"tsc -p tsconfig.json --noEmit","test":"npm run build && node --test dist/test/*.test.js","build":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json"},"_npmUser":{"name":"ben0918","email":"renyu0520@gmail.com"},"repository":{"url":"git+https://github.com/Yu-Ren-NEU/Offline-License-Manager.git","type":"git"},"_npmVersion":"11.19.0","description":"Zero-server Ed25519 license issuing and verification toolkit","directories":{},"_nodeVersion":"26.7.0","dependencies":{"argon2":"^0.44.0","commander":"^14.0.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.2","@types/node":"^24.3.0"},"_npmOperationalInternal":{"tmp":"tmp/offline-license-manager_1.4.0_1788021623784_0.3767195895016415","host":"s3://npm-registry-packages-npm-production"}},"1.6.0":{"name":"@ben0918/offline-license-manager","version":"1.6.0","keywords":["license","offline","ed25519","cli"],"license":"MIT","_id":"@ben0918/offline-license-manager@1.6.0","maintainers":[{"name":"ben0918","email":"renyu0520@gmail.com"}],"homepage":"https://github.com/Yu-Ren-NEU/Offline-License-Manager#readme","bugs":{"url":"https://github.com/Yu-Ren-NEU/Offline-License-Manager/issues"},"bin":{"offline-license":"dist/src/cli.js"},"dist":{"shasum":"99d0f1cee973cdd1694fda3d0feb980d4aa67558","tarball":"https://registry.npmjs.org/@ben0918/offline-license-manager/-/offline-license-manager-1.6.0.tgz","fileCount":34,"integrity":"sha512-WdLYurc+fhF+adrwnFFO7AJnYOQuWPYwYdQJvfMln6Fvz1o3AoVqswxUWb0Q4PRKce69JJrWBuE5qzyDh6T/MA==","signatures":[{"sig":"MEUCIGnjusk6S5m+JCzv824ZpvRlqRjT6Q7Gn8qr2zV6CCn9AiEAttIHzgWPq1xErZNErX+Zlg0oqV/r/jb9ijg2E+7Hk2I=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":118394},"main":"dist/src/index.js","type":"module","types":"dist/src/index.d.ts","engines":{"node":">=20"},"gitHead":"054eabcdc14a8424c1b521de884d3b7c6726f68b","scripts":{"lint":"tsc -p tsconfig.json --noEmit","test":"npm run build && node --test dist/test/*.test.js","build":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json"},"_npmUser":{"name":"ben0918","email":"renyu0520@gmail.com"},"repository":{"url":"git+https://github.com/Yu-Ren-NEU/Offline-License-Manager.git","type":"git"},"_npmVersion":"11.19.0","description":"Zero-server Ed25519 license issuing and verification toolkit","directories":{},"_nodeVersion":"26.7.0","dependencies":{"argon2":"^0.44.0","commander":"^14.0.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.2","@types/node":"^24.3.0"},"_npmOperationalInternal":{"tmp":"tmp/offline-license-manager_1.6.0_1788066708721_0.8415295123712612","host":"s3://npm-registry-packages-npm-production"}},"1.7.0":{"name":"@ben0918/offline-license-manager","version":"1.7.0","keywords":["license","offline","ed25519","cli"],"license":"MIT","_id":"@ben0918/offline-license-manager@1.7.0","maintainers":[{"name":"ben0918","email":"renyu0520@gmail.com"}],"homepage":"https://github.com/Yu-Ren-NEU/Offline-License-Manager#readme","bugs":{"url":"https://github.com/Yu-Ren-NEU/Offline-License-Manager/issues"},"bin":{"offline-license":"dist/src/cli.js"},"dist":{"shasum":"425331f0bcb949a07fbc22ac9f3e5cce74e66650","tarball":"https://registry.npmjs.org/@ben0918/offline-license-manager/-/offline-license-manager-1.7.0.tgz","fileCount":6,"integrity":"sha512-PyUhwwrkqRHCWp8HpIgGQs0CdJUIUVu19iab1dEPNde3KWr1OUS1QnAfF1HVAVlBNUiOR0tcX3FSAR6C1RzmCA==","signatures":[{"sig":"MEUCIQCiwWBDyYpXL+kSpQHGuusqc+U8pMip7tnAncAsWyWHTAIgBhUkf8dpbirO9M5uMz/qorBJ9HlVubH3KVg3FLe0d8M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ben0918%2foffline-license-manager@1.7.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":31416},"main":"dist/src/index.js","type":"module","types":"dist/src/index.d.ts","engines":{"node":">=20"},"gitHead":"2de2d0163c47911a55320ad7f2a82fc954191c47","scripts":{"lint":"tsc -p tsconfig.json --noEmit","test":"npm run build && node --test dist/test/*.test.js","build":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3aed3b7b-16ea-4697-8c6a-4345555bf570"}},"repository":{"url":"git+https://github.com/Yu-Ren-NEU/Offline-License-Manager.git","type":"git"},"_npmVersion":"11.17.0","description":"Zero-server Ed25519 license issuing and verification toolkit","directories":{},"_nodeVersion":"24.19.0","dependencies":{"argon2":"^0.44.0","commander":"^14.0.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.2","@types/node":"^24.3.0"},"_npmOperationalInternal":{"tmp":"tmp/offline-license-manager_1.7.0_1788070857280_0.3680519096562893","host":"s3://npm-registry-packages-npm-production"}},"1.7.1":{"name":"@ben0918/offline-license-manager","version":"1.7.1","keywords":["license","offline","ed25519","cli"],"license":"MIT","_id":"@ben0918/offline-license-manager@1.7.1","maintainers":[{"name":"ben0918","email":"renyu0520@gmail.com"}],"homepage":"https://github.com/Yu-Ren-NEU/Offline-License-Manager#readme","bugs":{"url":"https://github.com/Yu-Ren-NEU/Offline-License-Manager/issues"},"bin":{"offline-license":"dist/src/cli.js"},"dist":{"shasum":"fe0deed625d15b1ea0aae1b76a745b22ffff2925","tarball":"https://registry.npmjs.org/@ben0918/offline-license-manager/-/offline-license-manager-1.7.1.tgz","fileCount":34,"integrity":"sha512-J5VAN7WPAIR5+q6ZZMmBA4BVtXZjjQrSV8UrEwNB5C1a0EZnypkburF2DaB6C93MIwv1zJ3LuBGBDVnQAApRLA==","signatures":[{"sig":"MEQCIBlsawDmUEXU3Qd6BXQwrgfnbyoc4tfpJMepBgjmEqIMAiA0f3eHQjg0DDG71HArkVao5QnDNvF8Aa8YRsGWiboh/g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ben0918%2foffline-license-manager@1.7.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":124764},"main":"dist/src/index.js","type":"module","types":"dist/src/index.d.ts","engines":{"node":">=20"},"gitHead":"21208025930432a4620655eebf030719328b6b8f","scripts":{"lint":"tsc -p tsconfig.json --noEmit","test":"npm run build && node --test dist/test/*.test.js","build":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json","prepack":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3aed3b7b-16ea-4697-8c6a-4345555bf570"}},"repository":{"url":"git+https://github.com/Yu-Ren-NEU/Offline-License-Manager.git","type":"git"},"_npmVersion":"11.17.0","description":"Zero-server Ed25519 license issuing and verification toolkit","directories":{},"_nodeVersion":"24.19.0","dependencies":{"argon2":"^0.44.0","commander":"^14.0.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.2","@types/node":"^24.3.0"},"_npmOperationalInternal":{"tmp":"tmp/offline-license-manager_1.7.1_1788184849337_0.07045495011236835","host":"s3://npm-registry-packages-npm-production"}},"1.7.2":{"name":"@ben0918/offline-license-manager","version":"1.7.2","description":"Zero-server Ed25519 license issuing and verification toolkit","type":"module","main":"dist/src/index.js","types":"dist/src/index.d.ts","bin":{"offline-license":"dist/src/cli.js"},"scripts":{"build":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json","prepack":"npm run build","test":"npm run build && node --test dist/test/*.test.js","lint":"tsc -p tsconfig.json --noEmit"},"engines":{"node":">=20"},"dependencies":{"argon2":"^0.44.0","commander":"^14.0.0"},"devDependencies":{"@types/node":"^24.3.0","typescript":"^5.9.2"},"keywords":["license","offline","ed25519","cli"],"repository":{"type":"git","url":"git+https://github.com/Yu-Ren-NEU/Offline-License-Manager.git"},"bugs":{"url":"https://github.com/Yu-Ren-NEU/Offline-License-Manager/issues"},"homepage":"https://github.com/Yu-Ren-NEU/Offline-License-Manager#readme","license":"MIT","gitHead":"ea4d776a041b677339d48008a6cf68109e69cf5b","_id":"@ben0918/offline-license-manager@1.7.2","_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-wwoM6cT7S/pCyiIDTIXGUYVT1qoNCWyPYtaEvhlkdS9HDhqjjflEJPabpGLsyDzbzRHReMJCQnJLWo32reEXqA==","shasum":"dc6ddedc6cbee0abc5da058762113f42fc2210b9","tarball":"https://registry.npmjs.org/@ben0918/offline-license-manager/-/offline-license-manager-1.7.2.tgz","fileCount":34,"unpackedSize":124924,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ben0918%2foffline-license-manager@1.7.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIB6Dhzjn/iis7KZTfon7msG2f0WiczvwLiqbWAdws/JnAiEA01Sg12XoQ5E6IE36vBv7bwIs35bq9xo8U+6ZyXtiGgQ="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3aed3b7b-16ea-4697-8c6a-4345555bf570"}},"directories":{},"maintainers":[{"name":"ben0918","email":"renyu0520@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/offline-license-manager_1.7.2_1788184987454_0.7606481846872062"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-29T12:23:58.379Z","modified":"2026-08-31T14:03:08.290Z","1.0.0":"2026-08-29T12:23:58.805Z","1.1.0":"2026-08-29T12:37:03.436Z","1.2.0":"2026-08-29T16:08:38.090Z","1.3.0":"2026-08-29T16:22:52.420Z","1.4.0":"2026-08-29T16:40:23.913Z","1.6.0":"2026-08-30T05:11:48.877Z","1.7.0":"2026-08-30T06:20:57.416Z","1.7.1":"2026-08-31T14:00:49.477Z","1.7.2":"2026-08-31T14:03:07.605Z"},"bugs":{"url":"https://github.com/Yu-Ren-NEU/Offline-License-Manager/issues"},"license":"MIT","homepage":"https://github.com/Yu-Ren-NEU/Offline-License-Manager#readme","keywords":["license","offline","ed25519","cli"],"repository":{"type":"git","url":"git+https://github.com/Yu-Ren-NEU/Offline-License-Manager.git"},"description":"Zero-server Ed25519 license issuing and verification toolkit","maintainers":[{"name":"ben0918","email":"renyu0520@gmail.com"}],"readme":"# Offline License Manager\n\nA zero-server license toolkit for desktop, mobile, Mini Program, and other offline-first apps. It issues compact licenses signed with Ed25519 and verifies them locally with public keys embedded in the app.\n\n## What is included\n\n- Core license envelope and strict payload validation\n- Ed25519 key generation, signing, and verification\n- Password-encrypted private-key storage using Argon2id and AES-256-GCM\n- SDK client with `valid`, `plan`, and `hasFeature()`\n- CLI for key generation, issuing, and verification\n- Local-only graphical manager for setup, unlock, issue history, backup, and restore\n- Multiple public keys selected by `kid` for safe key rotation\n- Optional per-App device binding, selected when the App is created\n\nThere is no server, account system, telemetry, remote revocation, version entity, semver range, or payload encryption.\n\n## Local Manager UI\n\nInstall once:\n\n```bash\nnpm install -g @ben0918/offline-license-manager\n```\n\nStart the multi-App manager bound only to this Mac:\n\n```bash\noffline-license manager\n```\n\nThe browser opens automatically at a tokenized `127.0.0.1` URL. The home screen lists Apps and provides **Create App** and **Restore from backup**. Creating an App generates an Ed25519 key pair and an internal `kid` automatically; the password is used by Argon2id and AES-256-GCM to encrypt the private key, not as key-generation input. The UI never writes the plaintext key to disk and keeps the decrypted key only in process memory until locked or closed. Existing Apps move between machines through complete encrypted backups rather than pasted private keys.\n\nManager data defaults to:\n\n```text\n~/Library/Application Support/Offline License Manager/apps/<appId>/\n```\n\nThe UI creates every license record before reporting issuance success. Records can be searched by customer, features, note, or a pasted bound license/device request, and filtered by multiple plans. Device binding is an App-level creation switch: bound Apps require a device request code for every issuance, while unbound Apps produce portable licenses.\n\nEvery App starts with Major Version 1. The full-width Major Versions module releases versions sequentially (1, 2, 3, ...) after confirmation and lets the issuer select any released version. Existing versions cannot be deleted, so licenses for an older App release remain available. For device-bound Apps, pasting a device request automatically selects the exact Major Version declared by that request. Major-version state is included in complete backups.\n\nApp creation, Major Version release, and every successful issue automatically create a complete encrypted `.olmbackup`. Automatic destinations retain only the latest 10 snapshots. If iCloud Drive exists, the default external destination is `iCloud Drive/Offline License Manager/<appId>/Backups`; otherwise the UI asks for a folder. **Export to another location** creates an independent offline copy and is never automatically deleted. A new machine can restore the App configuration, encrypted key, public key, Major Versions, and complete record ledger directly from one backup.\n\n### Key rotation\n\n`kid` is retained in the protocol but hidden from ordinary App creation. The Manager generates it automatically. Rotation is deliberately two-stage:\n\n1. Generate a pending key.\n2. Copy the full public-key set into the business App and release that App update.\n3. Confirm activation in the Manager.\n\nOnly after confirmation do newly issued licenses use the new key. Retired keys remain in the keyring, public-key export, and encrypted backups so old licenses continue to verify.\n\n## Install and test\n\n```bash\nnpm install\nnpm test\n```\n\n## Automated npm publishing\n\nPushes to `main` run `.github/workflows/publish.yml`. The workflow tests the package and publishes only when the version in `package.json` does not already exist on npm. Publishing uses npm Trusted Publishing with GitHub OIDC, so the repository does not store a long-lived npm token. Configure the npm package trusted publisher for repository `Yu-Ren-NEU/Offline-License-Manager` and workflow filename `publish.yml`.\n\n## CLI quick start\n\n```bash\nnpm run build\n\nnode dist/src/cli.js keygen \\\n  --kid 2026-01 \\\n  --private .local/lemon.olmkey \\\n  --public .local/lemon.public.json \\\n  --password 'replace-with-a-long-password'\n\nnode dist/src/cli.js issue \\\n  --key .local/lemon.olmkey \\\n  --password 'replace-with-a-long-password' \\\n  --app app_lemon_note \\\n  --major 1 \\\n  --records .local/licenses.json \\\n  --plan pro \\\n  --features excel-export,unlimited-roster\n```\n\nThe password option is convenient for local testing but can appear in shell history. A local manager UI should collect it through a password field; production CLI integration should provide a secret-input wrapper.\n\n## SDK\n\n```ts\nimport { createLicenseClient } from '@ben0918/offline-license-manager'\n\nconst license = createLicenseClient({\n  appId: 'app_lemon_note',\n  majorVersion: 1,\n  deviceId: currentDeviceId, // omit for an App created without device binding\n  publicKeys: {\n    '2026-01': `-----BEGIN PUBLIC KEY-----\\n...\\n-----END PUBLIC KEY-----\\n`\n  }\n})\n\nconst result = license.verify(userSuppliedCode)\nif (result.valid && result.plan === 'pro') enablePro()\nif (result.valid && result.hasFeature('excel-export')) enableExport()\n```\n\nThe SDK checks the signature, `kid`, `appId`, exact `majorVersion`, optional device binding, and optional expiry. Business code decides what plans and features mean.\n\nFor WeChat Mini Programs, vendor `miniprogram/index.js` and provide a TweetNaCl-compatible implementation plus raw public keys from the generated public-key record. This adapter has no Node.js dependency.\n\n## Backup and recovery\n\nCreate a complete encrypted backup containing the encrypted signing key, public-key record, and all issued-license records:\n\n```bash\noffline-license backup-export --app app_lemon_note \\\n  --key .local/lemon.olmkey \\\n  --public .local/lemon.public.json \\\n  --records .local/licenses.json \\\n  --output /Volumes/OfflineBackup/lemon.olmbackup \\\n  --password 'a-separate-backup-password'\n\noffline-license backup-icloud --app app_lemon_note \\\n  --backup /Volumes/OfflineBackup/lemon.olmbackup\n\noffline-license backup-restore \\\n  --app app_lemon_note \\\n  --backup /path/to/lemon.olmbackup \\\n  --destination .local \\\n  --password 'a-separate-backup-password'\n```\n\nThe whole `.olmbackup` is protected by Argon2id and AES-256-GCM. Keep at least one iCloud copy and one manual offline copy on separate storage; iCloud must never be the only backup. Restore is fully local and requires no server.\n\n## Design contract\n\nSee [License_Manager_Plan.md](License_Manager_Plan.md). The current SDK uses Node's crypto API. Apps without Node compatibility can implement the same `OLM1` wire format with any conforming Ed25519 library.\n\n## Security\n\nNever commit `.olmkey` files, plaintext private keys, real licenses, passwords, or customer records. The public key is intentionally safe to embed in an app. Offline licensing cannot revoke a license in real time and cannot stop a determined attacker from patching an app binary.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}