certops 1.0.10 → 1.0.11

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # certops
2
2
 
3
- CLI for managing and auto-renewing SSL certificates from the [SSL Pilot](https://ssl-manager.dcom.at) platform.
3
+ CLI for managing and auto-renewing SSL certificates from the [CertOps](https://ssl-manager.dcom.at) platform.
4
4
 
5
5
  ## Install
6
6
 
@@ -11,7 +11,7 @@ npm install -g certops
11
11
  ## Requirements
12
12
 
13
13
  - Node.js 18+
14
- - An SSL Pilot API key (`sslpilot_...`) from your dashboard
14
+ - An CertOps API key (`sslpilot_...`) from your dashboard
15
15
 
16
16
  ## Quick start
17
17
 
@@ -78,18 +78,18 @@ journalctl -u certops -f # follow logs
78
78
 
79
79
  ## Auto-renewal service
80
80
 
81
- The service polls your SSL Pilot account, checks local expiry state, and re-downloads certificates approaching expiry. Hook scripts in `/etc/certops/hooks/` run after each download.
81
+ The service polls your CertOps account, checks local expiry state, and re-downloads certificates approaching expiry. Hook scripts in `/etc/certops/hooks/` run after each download.
82
82
 
83
83
  **Hook environment variables:**
84
84
 
85
85
  | Variable | Value |
86
86
  |----------|-------|
87
- | `SSL_PILOT_CERT_NAME` | Certificate name |
88
- | `SSL_PILOT_DOMAIN` | Domain (certName from API) |
89
- | `SSL_PILOT_FULLCHAIN_PATH` | Path to `fullchain.pem` |
90
- | `SSL_PILOT_CERT_PATH` | Path to `cert.pem` |
91
- | `SSL_PILOT_CHAIN_PATH` | Path to `chain.pem` |
92
- | `SSL_PILOT_KEY_PATH` | Path to `privkey.pem` |
87
+ | `CERTOPS_CERT_NAME` | Certificate name |
88
+ | `CERTOPS_DOMAIN` | Domain (certName from API) |
89
+ | `CERTOPS_FULLCHAIN_PATH` | Path to `fullchain.pem` |
90
+ | `CERTOPS_CERT_PATH` | Path to `cert.pem` |
91
+ | `CERTOPS_CHAIN_PATH` | Path to `chain.pem` |
92
+ | `CERTOPS_KEY_PATH` | Path to `privkey.pem` |
93
93
 
94
94
  **Example hook** (`/etc/certops/hooks/example.com.sh`):
95
95
 
@@ -12,7 +12,7 @@ export const configureCommand = new Command('configure')
12
12
  process.exit(1);
13
13
  }
14
14
  const existing = await readConfig();
15
- console.log('\nSSL Pilot — Update Service Config\n');
15
+ console.log('\nCertOps — Update Service Config\n');
16
16
  console.log(' (API key is stored in the systemd unit, not changed here)\n');
17
17
  const intervalStr = await input({
18
18
  message: 'Check interval (hours):',
@@ -30,16 +30,16 @@ function requireRoot() {
30
30
  }
31
31
  }
32
32
  export const startCommand = new Command('start')
33
- .description('Start the SSL Pilot service')
33
+ .description('Start the CertOps service')
34
34
  .action(() => { requireRoot(); systemctl(['start', UNIT]); });
35
35
  export const stopCommand = new Command('stop')
36
- .description('Stop the SSL Pilot service')
36
+ .description('Stop the CertOps service')
37
37
  .action(() => { requireRoot(); systemctl(['stop', UNIT]); });
38
38
  export const restartCommand = new Command('restart')
39
39
  .description('Restart the service — picks up config.json changes immediately')
40
40
  .action(() => { requireRoot(); systemctl(['restart', UNIT]); });
41
41
  export const statusCommand = new Command('status')
42
- .description('Show SSL Pilot service status')
42
+ .description('Show CertOps service status')
43
43
  .action(() => { systemctl(['status', UNIT]); });
44
44
  export const checkCommand = new Command('check')
45
45
  .description('Run one renewal check cycle immediately (for testing)')
@@ -65,10 +65,10 @@ export const checkCommand = new Command('check')
65
65
  }
66
66
  });
67
67
  export const uninstallServiceCommand = new Command('uninstall')
68
- .description('Stop, disable, and remove the SSL Pilot service unit')
68
+ .description('Stop, disable, and remove the CertOps service unit')
69
69
  .action(async () => {
70
70
  requireRoot();
71
- process.stdout.write('\nRemoving SSL Pilot service…\n\n');
71
+ process.stdout.write('\nRemoving CertOps service…\n\n');
72
72
  systemctl(['stop', UNIT], false);
73
73
  systemctl(['disable', UNIT], false);
74
74
  try {
@@ -24,7 +24,7 @@ async function tick() {
24
24
  export const daemonCommand = new Command('run')
25
25
  .description('Run the monitoring daemon (managed by systemd)')
26
26
  .action(async () => {
27
- log('SSL Pilot daemon starting.');
27
+ log('CertOps daemon starting.');
28
28
  process.on('SIGTERM', () => { log('SIGTERM — shutting down.'); process.exit(0); });
29
29
  process.on('SIGINT', () => { log('SIGINT — shutting down.'); process.exit(0); });
30
30
  while (true) {
@@ -4,7 +4,7 @@ import { configureCommand } from './configure.js';
4
4
  import { daemonCommand } from './daemon.js';
5
5
  import { startCommand, stopCommand, restartCommand, statusCommand, checkCommand, uninstallServiceCommand } from './control.js';
6
6
  export const serviceCommand = new Command('service')
7
- .description('Manage the SSL Pilot auto-renewal background service')
7
+ .description('Manage the CertOps auto-renewal background service')
8
8
  .addHelpText('after', `
9
9
  Commands:
10
10
  install Interactive setup — writes config, hooks, and installs systemd unit
@@ -2,13 +2,13 @@ import { Command } from 'commander';
2
2
  import input from '@inquirer/input';
3
3
  import { writeFile, mkdir } from 'fs/promises';
4
4
  import { spawnSync } from 'child_process';
5
- import { readConfig, writeConfig, SSL_PILOT_DIR, HOOKS_DIR } from '../../config.js';
5
+ import { readConfig, writeConfig, CERTOPS_DIR, HOOKS_DIR } from '../../config.js';
6
6
  import { domainHookPath, GLOBAL_HOOK } from '../../hooks.js';
7
7
  const UNIT_PATH = '/etc/systemd/system/certops.service';
8
8
  function buildUnitContent(apiKey) {
9
9
  return `\
10
10
  [Unit]
11
- Description=SSL Pilot Certificate Monitor
11
+ Description=CertOps Certificate Monitor
12
12
  After=network-online.target
13
13
  Wants=network-online.target
14
14
 
@@ -28,18 +28,18 @@ WantedBy=multi-user.target
28
28
  }
29
29
  const HOOK_TEMPLATE = `#!/usr/bin/env bash
30
30
  # Available env vars:
31
- # SSL_PILOT_CERT_NAME — certificate name (e.g. *.example.com)
32
- # SSL_PILOT_DOMAIN — domain name (certName from API)
33
- # SSL_PILOT_FULLCHAIN_PATH — path to fullchain.pem
34
- # SSL_PILOT_CERT_PATH — path to cert.pem
35
- # SSL_PILOT_CHAIN_PATH — path to chain.pem
36
- # SSL_PILOT_KEY_PATH — path to privkey.pem
31
+ # CERTOPS_CERT_NAME — certificate name (e.g. *.example.com)
32
+ # CERTOPS_DOMAIN — domain name (certName from API)
33
+ # CERTOPS_FULLCHAIN_PATH — path to fullchain.pem
34
+ # CERTOPS_CERT_PATH — path to cert.pem
35
+ # CERTOPS_CHAIN_PATH — path to chain.pem
36
+ # CERTOPS_KEY_PATH — path to privkey.pem
37
37
 
38
38
  # Example: reload nginx after cert update
39
39
  # systemctl reload nginx
40
40
  `;
41
41
  export const installCommand = new Command('install')
42
- .description('Install and configure the SSL Pilot background service')
42
+ .description('Install and configure the CertOps background service')
43
43
  .action(async () => {
44
44
  try {
45
45
  if (process.getuid?.() !== 0) {
@@ -47,7 +47,7 @@ export const installCommand = new Command('install')
47
47
  console.error('\n sudo -E sp service install\n');
48
48
  process.exit(1);
49
49
  }
50
- console.log('\nSSL Pilot Service Setup\n');
50
+ console.log('\nCertOps Service Setup\n');
51
51
  const existing = await readConfig();
52
52
  // API key — env takes precedence, otherwise prompt
53
53
  const apiKey = process.env['CERTOPS_API_KEY'] ?? await input({
@@ -82,7 +82,7 @@ export const installCommand = new Command('install')
82
82
  };
83
83
  // Write config + create directories
84
84
  await writeConfig(config);
85
- await mkdir(SSL_PILOT_DIR, { recursive: true });
85
+ await mkdir(CERTOPS_DIR, { recursive: true });
86
86
  await mkdir(HOOKS_DIR, { recursive: true });
87
87
  console.log('\n✓ Config written to /etc/certops/config.json');
88
88
  // Create hook stubs only if they don't exist yet
@@ -68,11 +68,11 @@ export async function runRenewalCycle(apiKey, log) {
68
68
  log(` key : ${paths.keyPath}`);
69
69
  await updateCertState(cert.certName, cert.expiryDate ?? '');
70
70
  await runHooks(cert.certName, {
71
- SSL_PILOT_DOMAIN: cert.certName,
72
- SSL_PILOT_FULLCHAIN_PATH: paths.fullchainPath,
73
- SSL_PILOT_CERT_PATH: paths.certPath,
74
- SSL_PILOT_CHAIN_PATH: paths.chainPath,
75
- SSL_PILOT_KEY_PATH: paths.keyPath,
71
+ CERTOPS_DOMAIN: cert.certName,
72
+ CERTOPS_FULLCHAIN_PATH: paths.fullchainPath,
73
+ CERTOPS_CERT_PATH: paths.certPath,
74
+ CERTOPS_CHAIN_PATH: paths.chainPath,
75
+ CERTOPS_KEY_PATH: paths.keyPath,
76
76
  }, log);
77
77
  downloaded++;
78
78
  lastError = undefined;
package/dist/config.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { readFile, writeFile, mkdir } from 'fs/promises';
2
2
  import { join } from 'path';
3
- export const SSL_PILOT_DIR = '/etc/certops';
4
- export const HOOKS_DIR = join(SSL_PILOT_DIR, 'hooks');
5
- const CONFIG_PATH = join(SSL_PILOT_DIR, 'config.json');
3
+ export const CERTOPS_DIR = '/etc/certops';
4
+ export const HOOKS_DIR = join(CERTOPS_DIR, 'hooks');
5
+ const CONFIG_PATH = join(CERTOPS_DIR, 'config.json');
6
6
  const DEFAULTS = {
7
7
  renewalThresholdDays: 5,
8
8
  checkIntervalHours: 12,
@@ -21,7 +21,7 @@ export async function readConfig() {
21
21
  }
22
22
  }
23
23
  export async function writeConfig(config) {
24
- await mkdir(SSL_PILOT_DIR, { recursive: true });
24
+ await mkdir(CERTOPS_DIR, { recursive: true });
25
25
  await writeFile(CONFIG_PATH, JSON.stringify(config, null, 2) + '\n', {
26
26
  encoding: 'utf8',
27
27
  mode: 0o600,
package/dist/files.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { mkdir, writeFile, chmod } from 'fs/promises';
2
2
  import { join } from 'path';
3
3
  import { unzipSync } from 'fflate';
4
- import { SSL_PILOT_DIR } from './config.js';
4
+ import { CERTOPS_DIR } from './config.js';
5
5
  export async function saveZip(certName, zipBuffer) {
6
6
  const zipDirName = certName.replace(/^\*\./, 'wildcard.');
7
- const dir = join(SSL_PILOT_DIR, zipDirName);
7
+ const dir = join(CERTOPS_DIR, zipDirName);
8
8
  let entries;
9
9
  try {
10
10
  entries = unzipSync(new Uint8Array(zipBuffer));
package/dist/hooks.js CHANGED
@@ -33,7 +33,7 @@ async function execHook(scriptPath, vars) {
33
33
  }
34
34
  export async function runHooks(certName, vars, log) {
35
35
  const domainHook = domainHookPath(certName);
36
- const hookVars = { ...vars, SSL_PILOT_CERT_NAME: certName };
36
+ const hookVars = { ...vars, CERTOPS_CERT_NAME: certName };
37
37
  if (await fileExists(domainHook)) {
38
38
  log(` Running domain hook: ${domainHook}`);
39
39
  try {
package/dist/state.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { readFile, writeFile, rename, mkdir } from 'fs/promises';
2
2
  import { join } from 'path';
3
3
  import { randomBytes } from 'crypto';
4
- import { SSL_PILOT_DIR } from './config.js';
5
- const STATE_PATH = join(SSL_PILOT_DIR, 'state.json');
4
+ import { CERTOPS_DIR } from './config.js';
5
+ const STATE_PATH = join(CERTOPS_DIR, 'state.json');
6
6
  export async function readState() {
7
7
  try {
8
8
  const raw = await readFile(STATE_PATH, 'utf8');
@@ -15,11 +15,11 @@ export async function readState() {
15
15
  }
16
16
  }
17
17
  export async function updateCertState(certName, expiryDate) {
18
- await mkdir(SSL_PILOT_DIR, { recursive: true });
18
+ await mkdir(CERTOPS_DIR, { recursive: true });
19
19
  const state = await readState();
20
20
  state[certName] = { expiryDate, downloadedAt: new Date().toISOString() };
21
21
  const content = JSON.stringify(state, null, 2) + '\n';
22
- const tmp = join(SSL_PILOT_DIR, `.state-${randomBytes(4).toString('hex')}.tmp`);
22
+ const tmp = join(CERTOPS_DIR, `.state-${randomBytes(4).toString('hex')}.tmp`);
23
23
  await writeFile(tmp, content, { encoding: 'utf8', mode: 0o600 });
24
24
  await rename(tmp, STATE_PATH);
25
25
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "certops",
3
- "version": "1.0.10",
3
+ "version": "1.0.11",
4
4
  "description": "SSL Pilot CLI — download and manage your SSL certificates",
5
5
  "type": "module",
6
6
  "files": [