localssl-cli 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sumit Sheokand
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,25 +1,169 @@
1
- # localssl
1
+ # localssl-cli
2
2
 
3
- One-command local HTTPS for development teams.
3
+ One-command local HTTPS for local development.
4
4
 
5
5
  ## Install
6
6
 
7
+ ### One-time run
7
8
  ```bash
8
- npm i -D localssl
9
- npx localssl
9
+ npx localssl-cli
10
10
  ```
11
11
 
12
+ ### Project install (recommended)
13
+ ```bash
14
+ npm i -D localssl-cli
15
+ ```
16
+
17
+ ### Global install
18
+ ```bash
19
+ npm i -g localssl-cli
20
+ ```
21
+
22
+ > Binary names exposed: `localssl-cli` and `localssl`.
23
+
24
+ ---
25
+
26
+ ## Quick start
27
+
28
+ ```bash
29
+ npx localssl-cli
30
+ ```
31
+
32
+ This does:
33
+ 1. Installs/uses mkcert in `~/.localssl`
34
+ 2. Creates machine CA and trusts it in OS store
35
+ 3. Tries trust import for Firefox + Chrome/Edge NSS stores
36
+ 4. Generates project cert/key in `.localssl/`
37
+ 5. Configures supported framework HTTPS settings
38
+ 6. Updates `.gitignore` to avoid key commits
39
+ 7. Syncs team public cert metadata in `localssl.json`
40
+
41
+ Then run your app as usual (`npm run dev` / `npm start`).
42
+
43
+ ---
44
+
45
+ ## Auto-setup on install
46
+
47
+ `localssl-cli@0.1.3+` adds setup hooks at install time:
48
+
49
+ - Adds `predev: "localssl-cli use"` if `dev` exists
50
+ - Adds `prestart: "localssl-cli use"` if `start` exists
51
+ - If `predev`/`prestart` already exists, prepends `localssl-cli use && ...`
52
+ - Skips if already configured
53
+
54
+ Disable this behavior:
55
+ ```bash
56
+ LOCALSSL_SKIP_POSTINSTALL=1 npm i -D localssl-cli
57
+ ```
58
+
59
+ ---
60
+
12
61
  ## Commands
13
62
 
14
- - `localssl` / `localssl use` - initialize + create project cert + configure framework
15
- - `localssl init` - initialize machine CA and trust stores
16
- - `localssl status` - check expiry and team sync status
17
- - `localssl renew` - renew project cert
18
- - `localssl trust` - import team public CAs from `localssl.json`
19
- - `localssl qr` - serve CA certificate + print QR for phone install
20
- - `localssl ci` - ephemeral cert setup for CI (`CI=true`)
21
- - `localssl remove` - uninstall trust and local files
63
+ ### `localssl-cli` (default)
64
+ Runs project setup flow (`use`).
65
+
66
+ ### `localssl-cli init`
67
+ Machine bootstrap only:
68
+ - mkcert setup
69
+ - machine CA install
70
+ - trust stores (OS + Firefox + Chrome/Edge NSS)
71
+
72
+ ### `localssl-cli use [hosts...]`
73
+ Project setup only:
74
+ - detects hosts from `package.json` + `.env`/`.env.local`
75
+ - defaults: `localhost`, `127.0.0.1`, `::1`
76
+ - generates `.localssl/cert.pem` and `.localssl/key.pem`
77
+ - injects framework HTTPS config if supported
78
+
79
+ Examples:
80
+ ```bash
81
+ localssl-cli use
82
+ localssl-cli use myapp.local api.myapp.local
83
+ ```
22
84
 
23
- ## Team sharing
85
+ ### `localssl-cli use --open` or `localssl-cli --open`
86
+ Same as setup, then opens a guessed HTTPS URL in default browser.
24
87
 
25
- `localssl.json` is safe to commit. It stores only public CA certificates.
88
+ ### `localssl-cli trust`
89
+ Imports teammate public CAs from `localssl.json` into local trust stores.
90
+
91
+ ### `localssl-cli status`
92
+ Shows:
93
+ - machine CA validity
94
+ - project cert validity
95
+ - detected framework
96
+ - hosts/team summary
97
+ - warning when cert expires in <=30 days
98
+
99
+ ### `localssl-cli renew`
100
+ Regenerates project cert/key (keeps machine CA).
101
+
102
+ ### `localssl-cli qr`
103
+ Starts temporary HTTP server to download CA cert and prints QR code for mobile install.
104
+
105
+ ### `localssl-cli ci`
106
+ CI-only mode (`CI=true`):
107
+ - ephemeral CA/cert generation
108
+ - exports `NODE_EXTRA_CA_CERTS`, `SSL_CERT_FILE`, `REQUESTS_CA_BUNDLE`
109
+ - also exports `LOCALSSL_CERT_FILE`, `LOCALSSL_KEY_FILE`
110
+
111
+ ### `localssl-cli remove`
112
+ Best-effort cleanup:
113
+ - removes trust from OS/Firefox/Chrome/Edge NSS
114
+ - deletes `~/.localssl`
115
+ - deletes project `.localssl`
116
+
117
+ ---
118
+
119
+ ## Framework support
120
+
121
+ - **Vite**: injects HTTPS cert/key in `vite.config.*`
122
+ - **Next.js**: updates `dev` script with `--experimental-https` flags
123
+ - **Create React App**: writes HTTPS vars to `.env.local`
124
+ - **Express**: creates `localssl.js` helper exporting HTTPS options
125
+ - **Webpack Dev Server**: injects `devServer.https`
126
+ - **Generic**: prints manual cert/key usage hint
127
+
128
+ ---
129
+
130
+ ## Team sharing (`localssl.json`)
131
+
132
+ `localssl.json` is safe to commit.
133
+
134
+ It stores only:
135
+ - project hosts
136
+ - teammate machine metadata
137
+ - teammate **public** CA certificates
138
+
139
+ It never stores CA private keys.
140
+
141
+ ---
142
+
143
+ ## Security notes
144
+
145
+ - Private keys are written to project `.localssl/` and ignored by `.gitignore`
146
+ - Team file validation blocks private-key content in `localssl.json`
147
+ - Never share root CA private key files
148
+
149
+ ---
150
+
151
+ ## Troubleshooting
152
+
153
+ ### Windows `EPERM` when running `npx` inside this package source folder
154
+ Run from another directory, for example:
155
+ ```powershell
156
+ cd $env:TEMP
157
+ npx --yes localssl-cli --help
158
+ ```
159
+
160
+ ### Firefox/Chrome/Edge trust skipped
161
+ Install `certutil` (NSS tools), then rerun:
162
+ ```bash
163
+ localssl-cli init
164
+ ```
165
+
166
+ ### Rebuild certs
167
+ ```bash
168
+ localssl-cli renew
169
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "localssl-cli",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "One-command local HTTPS setup for teams",
5
5
  "type": "commonjs",
6
6
  "main": "src/index.js",
@@ -13,7 +13,8 @@
13
13
  },
14
14
  "scripts": {
15
15
  "start": "node bin/localssl.js",
16
- "test": "node -e \"console.log('No tests yet')\""
16
+ "test": "node -e \"console.log('No tests yet')\"",
17
+ "postinstall": "node src/postinstall.js"
17
18
  },
18
19
  "keywords": [
19
20
  "https",
package/src/bootstrap.js CHANGED
@@ -80,9 +80,9 @@ async function ensureMkcert() {
80
80
  return mkcertPath;
81
81
  }
82
82
 
83
- function execMkcert(mkcertPath, args) {
83
+ function execMkcert(mkcertPath, args, extraEnv = {}) {
84
84
  return new Promise((resolve, reject) => {
85
- execFile(mkcertPath, args, { env: { ...process.env, CAROOT: LOCALSSL_HOME } }, (error, stdout, stderr) => {
85
+ execFile(mkcertPath, args, { env: { ...process.env, CAROOT: LOCALSSL_HOME, ...extraEnv } }, (error, stdout, stderr) => {
86
86
  if (error) {
87
87
  reject(new Error(stderr || error.message));
88
88
  return;
@@ -144,7 +144,16 @@ async function initMachine({ quiet = false } = {}) {
144
144
  return { mkcertPath, initialized: false };
145
145
  }
146
146
 
147
- await execMkcert(mkcertPath, ['-install']);
147
+ try {
148
+ await execMkcert(mkcertPath, ['-install'], { TRUST_STORES: 'system,nss' });
149
+ } catch (error) {
150
+ const message = error.message || '';
151
+ const javaTrustError = /keytool|cacerts|access is denied/i.test(message);
152
+ if (!javaTrustError) {
153
+ throw error;
154
+ }
155
+ warn('Java trust store update skipped (no admin access). System/browser trust still configured.');
156
+ }
148
157
  const systemResult = await trustSystem(LOCALSSL_CA_PUBLIC);
149
158
  const firefoxResult = await trustInFirefox(LOCALSSL_CA_PUBLIC);
150
159
  const chromiumResult = await trustInChromium(LOCALSSL_CA_PUBLIC);
@@ -0,0 +1,60 @@
1
+ const path = require('path');
2
+ const fs = require('fs-extra');
3
+
4
+ function ensureHook(scripts, hookName, targetCommand, baseScriptName) {
5
+ if (!scripts[baseScriptName]) {
6
+ return false;
7
+ }
8
+
9
+ const current = scripts[hookName];
10
+ if (!current) {
11
+ scripts[hookName] = targetCommand;
12
+ return true;
13
+ }
14
+
15
+ if (current.includes('localssl-cli use') || current.includes('localssl use')) {
16
+ return false;
17
+ }
18
+
19
+ scripts[hookName] = `${targetCommand} && ${current}`;
20
+ return true;
21
+ }
22
+
23
+ async function run() {
24
+ if (process.env.LOCALSSL_SKIP_POSTINSTALL === '1') {
25
+ return;
26
+ }
27
+
28
+ const packageRoot = path.resolve(__dirname, '..');
29
+ const initCwd = path.resolve(process.env.INIT_CWD || process.cwd());
30
+ if (initCwd === packageRoot) {
31
+ return;
32
+ }
33
+
34
+ const targetPackageJsonPath = path.join(initCwd, 'package.json');
35
+ if (!(await fs.pathExists(targetPackageJsonPath))) {
36
+ return;
37
+ }
38
+
39
+ let targetPackage;
40
+ try {
41
+ targetPackage = await fs.readJson(targetPackageJsonPath);
42
+ } catch {
43
+ return;
44
+ }
45
+
46
+ targetPackage.scripts = targetPackage.scripts || {};
47
+
48
+ let changed = false;
49
+ changed = ensureHook(targetPackage.scripts, 'predev', 'localssl-cli use', 'dev') || changed;
50
+ changed = ensureHook(targetPackage.scripts, 'prestart', 'localssl-cli use', 'start') || changed;
51
+
52
+ if (!changed) {
53
+ return;
54
+ }
55
+
56
+ await fs.writeJson(targetPackageJsonPath, targetPackage, { spaces: 2 });
57
+ console.log('localssl-cli: added predev/prestart HTTPS setup hooks');
58
+ }
59
+
60
+ run().catch(() => {});