@fredlackey/devutils 0.0.1 → 0.0.2

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.
Files changed (257) hide show
  1. package/README.md +5 -5
  2. package/package.json +1 -1
  3. package/src/commands/install.js +374 -36
  4. package/src/installs/adobe-creative-cloud.js +527 -25
  5. package/src/installs/adobe-creative-cloud.md +605 -0
  6. package/src/installs/appcleaner.js +303 -26
  7. package/src/installs/appcleaner.md +699 -0
  8. package/src/installs/apt-transport-https.js +390 -0
  9. package/src/installs/apt-transport-https.md +678 -0
  10. package/src/installs/atomicparsley.js +624 -26
  11. package/src/installs/atomicparsley.md +795 -0
  12. package/src/installs/aws-cli.js +779 -26
  13. package/src/installs/aws-cli.md +727 -0
  14. package/src/installs/balena-etcher.js +688 -26
  15. package/src/installs/balena-etcher.md +761 -0
  16. package/src/installs/bambu-studio.js +912 -26
  17. package/src/installs/bambu-studio.md +780 -0
  18. package/src/installs/bash-completion.js +554 -23
  19. package/src/installs/bash-completion.md +833 -0
  20. package/src/installs/bash.js +399 -26
  21. package/src/installs/bash.md +993 -0
  22. package/src/installs/beyond-compare.js +585 -26
  23. package/src/installs/beyond-compare.md +813 -0
  24. package/src/installs/build-essential.js +511 -26
  25. package/src/installs/build-essential.md +977 -0
  26. package/src/installs/ca-certificates.js +618 -0
  27. package/src/installs/ca-certificates.md +937 -0
  28. package/src/installs/caffeine.js +490 -26
  29. package/src/installs/caffeine.md +839 -0
  30. package/src/installs/camtasia.js +577 -25
  31. package/src/installs/camtasia.md +762 -0
  32. package/src/installs/chatgpt.js +458 -26
  33. package/src/installs/chatgpt.md +814 -0
  34. package/src/installs/chocolatey.js +447 -0
  35. package/src/installs/chocolatey.md +661 -0
  36. package/src/installs/chrome-canary.js +472 -26
  37. package/src/installs/chrome-canary.md +641 -0
  38. package/src/installs/chromium.js +645 -26
  39. package/src/installs/chromium.md +838 -0
  40. package/src/installs/claude-code.js +558 -26
  41. package/src/installs/claude-code.md +1173 -0
  42. package/src/installs/curl.js +361 -26
  43. package/src/installs/curl.md +714 -0
  44. package/src/installs/cursor.js +561 -26
  45. package/src/installs/cursor.md +970 -0
  46. package/src/installs/dbschema.js +674 -26
  47. package/src/installs/dbschema.md +925 -0
  48. package/src/installs/dependencies.md +435 -0
  49. package/src/installs/development-tools.js +600 -0
  50. package/src/installs/development-tools.md +977 -0
  51. package/src/installs/docker.js +1010 -25
  52. package/src/installs/docker.md +1109 -0
  53. package/src/installs/drawio.js +1001 -26
  54. package/src/installs/drawio.md +795 -0
  55. package/src/installs/elmedia-player.js +328 -25
  56. package/src/installs/elmedia-player.md +556 -0
  57. package/src/installs/ffmpeg.js +870 -25
  58. package/src/installs/ffmpeg.md +852 -0
  59. package/src/installs/file.js +464 -0
  60. package/src/installs/file.md +987 -0
  61. package/src/installs/gemini-cli.js +793 -26
  62. package/src/installs/gemini-cli.md +1153 -0
  63. package/src/installs/git.js +382 -26
  64. package/src/installs/git.md +907 -0
  65. package/src/installs/gitego.js +931 -26
  66. package/src/installs/gitego.md +1172 -0
  67. package/src/installs/go.js +913 -26
  68. package/src/installs/go.md +958 -0
  69. package/src/installs/google-chrome.js +801 -25
  70. package/src/installs/google-chrome.md +862 -0
  71. package/src/installs/gpg.js +412 -73
  72. package/src/installs/gpg.md +1056 -0
  73. package/src/installs/homebrew.js +1015 -26
  74. package/src/installs/homebrew.md +988 -0
  75. package/src/installs/imageoptim.js +950 -26
  76. package/src/installs/imageoptim.md +1119 -0
  77. package/src/installs/installers.json +2297 -0
  78. package/src/installs/jq.js +382 -26
  79. package/src/installs/jq.md +809 -0
  80. package/src/installs/keyboard-maestro.js +701 -26
  81. package/src/installs/keyboard-maestro.md +825 -0
  82. package/src/installs/latex.js +771 -26
  83. package/src/installs/latex.md +1095 -0
  84. package/src/installs/lftp.js +338 -26
  85. package/src/installs/lftp.md +907 -0
  86. package/src/installs/lsb-release.js +346 -0
  87. package/src/installs/lsb-release.md +814 -0
  88. package/src/installs/messenger.js +829 -26
  89. package/src/installs/messenger.md +900 -0
  90. package/src/installs/microsoft-office.js +550 -26
  91. package/src/installs/microsoft-office.md +760 -0
  92. package/src/installs/microsoft-teams.js +782 -25
  93. package/src/installs/microsoft-teams.md +886 -0
  94. package/src/installs/node.js +886 -26
  95. package/src/installs/node.md +1153 -0
  96. package/src/installs/nordpass.js +698 -26
  97. package/src/installs/nordpass.md +921 -0
  98. package/src/installs/nvm.js +977 -26
  99. package/src/installs/nvm.md +1057 -0
  100. package/src/installs/openssh.js +734 -64
  101. package/src/installs/openssh.md +1056 -0
  102. package/src/installs/pandoc.js +644 -26
  103. package/src/installs/pandoc.md +1036 -0
  104. package/src/installs/pinentry.js +492 -26
  105. package/src/installs/pinentry.md +1142 -0
  106. package/src/installs/pngyu.js +851 -26
  107. package/src/installs/pngyu.md +896 -0
  108. package/src/installs/postman.js +781 -26
  109. package/src/installs/postman.md +940 -0
  110. package/src/installs/procps.js +425 -0
  111. package/src/installs/procps.md +851 -0
  112. package/src/installs/safari-tech-preview.js +355 -25
  113. package/src/installs/safari-tech-preview.md +533 -0
  114. package/src/installs/sfnt2woff.js +640 -26
  115. package/src/installs/sfnt2woff.md +795 -0
  116. package/src/installs/shellcheck.js +463 -26
  117. package/src/installs/shellcheck.md +1005 -0
  118. package/src/installs/slack.js +722 -25
  119. package/src/installs/slack.md +865 -0
  120. package/src/installs/snagit.js +566 -25
  121. package/src/installs/snagit.md +844 -0
  122. package/src/installs/software-properties-common.js +372 -0
  123. package/src/installs/software-properties-common.md +805 -0
  124. package/src/installs/spotify.js +858 -25
  125. package/src/installs/spotify.md +901 -0
  126. package/src/installs/studio-3t.js +803 -26
  127. package/src/installs/studio-3t.md +918 -0
  128. package/src/installs/sublime-text.js +780 -25
  129. package/src/installs/sublime-text.md +914 -0
  130. package/src/installs/superwhisper.js +687 -25
  131. package/src/installs/superwhisper.md +630 -0
  132. package/src/installs/tailscale.js +727 -26
  133. package/src/installs/tailscale.md +1100 -0
  134. package/src/installs/tar.js +389 -0
  135. package/src/installs/tar.md +946 -0
  136. package/src/installs/termius.js +780 -26
  137. package/src/installs/termius.md +844 -0
  138. package/src/installs/terraform.js +761 -26
  139. package/src/installs/terraform.md +899 -0
  140. package/src/installs/tidal.js +752 -25
  141. package/src/installs/tidal.md +864 -0
  142. package/src/installs/tmux.js +328 -26
  143. package/src/installs/tmux.md +1030 -0
  144. package/src/installs/tree.js +393 -26
  145. package/src/installs/tree.md +833 -0
  146. package/src/installs/unzip.js +460 -0
  147. package/src/installs/unzip.md +879 -0
  148. package/src/installs/vim.js +403 -26
  149. package/src/installs/vim.md +1040 -0
  150. package/src/installs/vlc.js +803 -26
  151. package/src/installs/vlc.md +927 -0
  152. package/src/installs/vscode.js +825 -26
  153. package/src/installs/vscode.md +1002 -0
  154. package/src/installs/wget.js +415 -0
  155. package/src/installs/wget.md +791 -0
  156. package/src/installs/whatsapp.js +710 -25
  157. package/src/installs/whatsapp.md +854 -0
  158. package/src/installs/winpty.js +352 -0
  159. package/src/installs/winpty.md +620 -0
  160. package/src/installs/woff2.js +535 -26
  161. package/src/installs/woff2.md +977 -0
  162. package/src/installs/wsl.js +572 -0
  163. package/src/installs/wsl.md +699 -0
  164. package/src/installs/xcode-clt.js +520 -0
  165. package/src/installs/xcode-clt.md +351 -0
  166. package/src/installs/xcode.js +542 -26
  167. package/src/installs/xcode.md +573 -0
  168. package/src/installs/yarn.js +806 -26
  169. package/src/installs/yarn.md +1074 -0
  170. package/src/installs/yq.js +636 -26
  171. package/src/installs/yq.md +944 -0
  172. package/src/installs/yt-dlp.js +683 -26
  173. package/src/installs/yt-dlp.md +946 -0
  174. package/src/installs/yum-utils.js +297 -0
  175. package/src/installs/yum-utils.md +648 -0
  176. package/src/installs/zoom.js +740 -25
  177. package/src/installs/zoom.md +884 -0
  178. package/src/scripts/README.md +567 -45
  179. package/src/scripts/STATUS.md +208 -0
  180. package/src/scripts/afk.js +395 -7
  181. package/src/scripts/backup-all.js +731 -9
  182. package/src/scripts/backup-source.js +711 -8
  183. package/src/scripts/brewd.js +373 -7
  184. package/src/scripts/brewi.js +505 -9
  185. package/src/scripts/brewr.js +512 -9
  186. package/src/scripts/brews.js +462 -9
  187. package/src/scripts/brewu.js +488 -7
  188. package/src/scripts/c.js +185 -7
  189. package/src/scripts/ccurl.js +325 -8
  190. package/src/scripts/certbot-crontab-init.js +488 -8
  191. package/src/scripts/certbot-init.js +641 -9
  192. package/src/scripts/ch.js +339 -7
  193. package/src/scripts/claude-danger.js +253 -8
  194. package/src/scripts/clean-dev.js +419 -8
  195. package/src/scripts/clear-dns-cache.js +525 -7
  196. package/src/scripts/clone.js +417 -7
  197. package/src/scripts/code-all.js +420 -7
  198. package/src/scripts/count-files.js +195 -8
  199. package/src/scripts/count-folders.js +195 -8
  200. package/src/scripts/count.js +248 -8
  201. package/src/scripts/d.js +203 -7
  202. package/src/scripts/datauri.js +373 -8
  203. package/src/scripts/delete-files.js +363 -7
  204. package/src/scripts/docker-clean.js +410 -8
  205. package/src/scripts/dp.js +426 -7
  206. package/src/scripts/e.js +375 -9
  207. package/src/scripts/empty-trash.js +497 -7
  208. package/src/scripts/evm.js +428 -9
  209. package/src/scripts/fetch-github-repos.js +441 -10
  210. package/src/scripts/get-channel.js +329 -8
  211. package/src/scripts/get-course.js +384 -11
  212. package/src/scripts/get-dependencies.js +290 -9
  213. package/src/scripts/get-folder.js +783 -10
  214. package/src/scripts/get-tunes.js +411 -10
  215. package/src/scripts/get-video.js +352 -9
  216. package/src/scripts/git-backup.js +561 -9
  217. package/src/scripts/git-clone.js +477 -9
  218. package/src/scripts/git-pup.js +303 -7
  219. package/src/scripts/git-push.js +380 -8
  220. package/src/scripts/h.js +607 -9
  221. package/src/scripts/hide-desktop-icons.js +483 -7
  222. package/src/scripts/hide-hidden-files.js +522 -7
  223. package/src/scripts/install-dependencies-from.js +440 -9
  224. package/src/scripts/ips.js +647 -10
  225. package/src/scripts/iso.js +354 -8
  226. package/src/scripts/killni.js +561 -7
  227. package/src/scripts/ll.js +451 -8
  228. package/src/scripts/local-ip.js +310 -8
  229. package/src/scripts/m.js +508 -8
  230. package/src/scripts/map.js +293 -8
  231. package/src/scripts/mkd.js +287 -7
  232. package/src/scripts/ncu-update-all.js +441 -8
  233. package/src/scripts/nginx-init.js +702 -12
  234. package/src/scripts/npmi.js +366 -7
  235. package/src/scripts/o.js +495 -8
  236. package/src/scripts/org-by-date.js +321 -7
  237. package/src/scripts/p.js +208 -7
  238. package/src/scripts/packages.js +313 -8
  239. package/src/scripts/path.js +209 -7
  240. package/src/scripts/ports.js +582 -8
  241. package/src/scripts/q.js +290 -8
  242. package/src/scripts/refresh-files.js +378 -10
  243. package/src/scripts/remove-smaller-files.js +500 -8
  244. package/src/scripts/rename-files-with-date.js +517 -9
  245. package/src/scripts/resize-image.js +523 -9
  246. package/src/scripts/rm-safe.js +653 -8
  247. package/src/scripts/s.js +525 -9
  248. package/src/scripts/set-git-public.js +349 -7
  249. package/src/scripts/show-desktop-icons.js +459 -7
  250. package/src/scripts/show-hidden-files.js +456 -7
  251. package/src/scripts/tpa.js +265 -8
  252. package/src/scripts/tpo.js +264 -7
  253. package/src/scripts/u.js +489 -7
  254. package/src/scripts/vpush.js +422 -8
  255. package/src/scripts/y.js +267 -7
  256. package/src/utils/common/os.js +94 -2
  257. package/src/utils/ubuntu/apt.js +13 -7
@@ -1,25 +1,657 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * @fileoverview Install SSL certificates via certbot.
4
+ * certbot-init - Install SSL certificates using certbot for nginx
5
+ *
6
+ * Migrated from legacy dotfiles function.
7
+ * Original:
8
+ * certbot-init() {
9
+ * # Install SSL certificates using certbot for nginx.
10
+ * # Usage: certbot-init -d example.com -e admin@example.com
11
+ * # Installs certbot if not present, then runs certbot --nginx
12
+ * }
13
+ *
14
+ * This script automates the process of obtaining and installing SSL certificates
15
+ * from Let's Encrypt using certbot with nginx integration. It:
16
+ * 1. Validates domain and email arguments
17
+ * 2. Installs certbot if not already installed (using the appropriate package manager)
18
+ * 3. Runs certbot to obtain and install SSL certificates for the specified domains
19
+ * 4. Automatically configures nginx to use the certificates
20
+ *
5
21
  * @module scripts/certbot-init
6
22
  */
7
23
 
24
+ const os = require('../utils/common/os');
25
+ const { execSync, spawnSync } = require('child_process');
26
+
27
+ /**
28
+ * Display usage information and examples.
29
+ * Shows all available options and how to use them correctly.
30
+ */
31
+ function showUsage() {
32
+ console.log(`certbot-init - Install SSL certificates using certbot for nginx
33
+
34
+ USAGE:
35
+ certbot-init [OPTIONS]
36
+
37
+ OPTIONS:
38
+ -d, --domain Domain name for SSL certificate (can be used multiple times) (required)
39
+ -e, --email Email address for Let's Encrypt registration (required)
40
+ -h, --help Show this help message
41
+
42
+ EXAMPLES:
43
+ certbot-init -d example.com -e admin@example.com
44
+ certbot-init -d example.com -d www.example.com -e admin@example.com
45
+ certbot-init -d api.example.com -d www.api.example.com -e webmaster@example.com
46
+
47
+ NOTE:
48
+ This command will install certbot if not present and requires sudo access.
49
+ It configures nginx to use the SSL certificates automatically.
50
+ Certificates are valid for 90 days and can be renewed with 'certbot renew'.`);
51
+ }
52
+
53
+ /**
54
+ * Parse command line arguments into structured options.
55
+ * Handles -d/--domain (multiple allowed), -e/--email, and -h/--help flags.
56
+ *
57
+ * @param {string[]} args - Raw command line arguments
58
+ * @returns {{ domains: string[], email: string, help: boolean, error: string|null }}
59
+ */
60
+ function parseArgs(args) {
61
+ const result = {
62
+ domains: [],
63
+ email: '',
64
+ help: false,
65
+ error: null
66
+ };
67
+
68
+ let i = 0;
69
+ while (i < args.length) {
70
+ const arg = args[i];
71
+
72
+ if (arg === '-h' || arg === '--help') {
73
+ result.help = true;
74
+ return result;
75
+ }
76
+
77
+ if (arg === '-d' || arg === '--domain') {
78
+ // Check if next argument exists and is not another flag
79
+ if (i + 1 >= args.length || args[i + 1].startsWith('-')) {
80
+ result.error = 'Domain value required after -d/--domain';
81
+ return result;
82
+ }
83
+ result.domains.push(args[i + 1]);
84
+ i += 2;
85
+ continue;
86
+ }
87
+
88
+ if (arg === '-e' || arg === '--email') {
89
+ // Check if next argument exists and is not another flag
90
+ if (i + 1 >= args.length || args[i + 1].startsWith('-')) {
91
+ result.error = 'Email value required after -e/--email';
92
+ return result;
93
+ }
94
+ result.email = args[i + 1];
95
+ i += 2;
96
+ continue;
97
+ }
98
+
99
+ // Unknown option
100
+ result.error = `Unknown option: ${arg}`;
101
+ return result;
102
+ }
103
+
104
+ return result;
105
+ }
106
+
107
+ /**
108
+ * Validate that an email address has a valid format.
109
+ * Uses a basic regex that covers most common email formats.
110
+ *
111
+ * @param {string} email - The email address to validate
112
+ * @returns {boolean} True if the email format is valid
113
+ */
114
+ function isValidEmail(email) {
115
+ // Basic email validation regex
116
+ // Matches: user@domain.tld where tld is at least 2 characters
117
+ const emailRegex = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/;
118
+ return emailRegex.test(email);
119
+ }
120
+
121
+ /**
122
+ * Check if a command exists on the system.
123
+ * Uses 'which' on Unix-like systems to locate executables.
124
+ *
125
+ * @param {string} cmd - The command name to check
126
+ * @returns {boolean} True if the command exists in PATH
127
+ */
128
+ function isCommandAvailable(cmd) {
129
+ try {
130
+ execSync(`which ${cmd}`, { stdio: 'ignore' });
131
+ return true;
132
+ } catch {
133
+ return false;
134
+ }
135
+ }
136
+
137
+ /**
138
+ * Check if the current user has sudo access.
139
+ * First tries passwordless sudo, then validates sudo credentials.
140
+ *
141
+ * @returns {boolean} True if sudo access is available
142
+ */
143
+ function checkSudoAccess() {
144
+ try {
145
+ // Try passwordless sudo first
146
+ execSync('sudo -n true', { stdio: 'ignore' });
147
+ console.log('Using passwordless sudo');
148
+ return true;
149
+ } catch {
150
+ // Fall back to regular sudo (will prompt for password if needed)
151
+ console.log('Authenticating with sudo...');
152
+ try {
153
+ // sudo -v validates the user's credentials and extends the timeout
154
+ const result = spawnSync('sudo', ['-v'], { stdio: 'inherit' });
155
+ return result.status === 0;
156
+ } catch {
157
+ return false;
158
+ }
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Pure Node.js implementation - NOT APPLICABLE for this script.
164
+ *
165
+ * Certbot SSL certificate installation requires:
166
+ * 1. System package manager to install certbot
167
+ * 2. Root/sudo access to modify nginx configuration
168
+ * 3. Network access to Let's Encrypt ACME servers
169
+ * 4. certbot command-line tool interaction
170
+ *
171
+ * These operations cannot be done in pure Node.js and require
172
+ * platform-specific shell commands.
173
+ *
174
+ * @param {string[]} args - Command line arguments
175
+ * @returns {Promise<void>}
176
+ * @throws {Error} Always throws - this function should not be called directly
177
+ */
178
+ async function do_certbot_init_nodejs(args) {
179
+ throw new Error(
180
+ 'do_certbot_init_nodejs should not be called directly. ' +
181
+ 'SSL certificate installation requires OS-specific package managers and sudo access.'
182
+ );
183
+ }
184
+
185
+ /**
186
+ * Install certbot and SSL certificates on macOS using Homebrew.
187
+ *
188
+ * macOS requires:
189
+ * - Homebrew for package management
190
+ * - nginx to be installed and running
191
+ * - certbot and certbot-nginx plugin
192
+ *
193
+ * Note: macOS is typically used for development, not production servers,
194
+ * so SSL certificates are less commonly needed. However, for local HTTPS
195
+ * development or Mac mini servers, this is supported.
196
+ *
197
+ * @param {string[]} args - Command line arguments
198
+ * @returns {Promise<void>}
199
+ */
200
+ async function do_certbot_init_macos(args) {
201
+ // Parse and validate arguments
202
+ const options = parseArgs(args);
203
+
204
+ if (options.help) {
205
+ showUsage();
206
+ return;
207
+ }
208
+
209
+ if (options.error) {
210
+ console.error(`Error: ${options.error}`);
211
+ showUsage();
212
+ process.exit(1);
213
+ }
214
+
215
+ // Show usage if no arguments provided
216
+ if (args.length === 0) {
217
+ showUsage();
218
+ return;
219
+ }
220
+
221
+ // Validate required arguments
222
+ if (options.domains.length === 0) {
223
+ console.error('Error: At least one domain is required (-d or --domain)');
224
+ showUsage();
225
+ process.exit(1);
226
+ }
227
+
228
+ if (!options.email) {
229
+ console.error('Error: Email address is required (-e or --email)');
230
+ showUsage();
231
+ process.exit(1);
232
+ }
233
+
234
+ if (!isValidEmail(options.email)) {
235
+ console.error(`Error: Invalid email format: ${options.email}`);
236
+ process.exit(1);
237
+ }
238
+
239
+ // Check for Homebrew
240
+ if (!isCommandAvailable('brew')) {
241
+ console.error('Error: Homebrew is required but not installed.');
242
+ console.error('Install it from: https://brew.sh');
243
+ process.exit(1);
244
+ }
245
+
246
+ // Check sudo access
247
+ console.log('This command requires sudo access to configure SSL certificates');
248
+ if (!checkSudoAccess()) {
249
+ console.error('Error: sudo authentication failed');
250
+ process.exit(1);
251
+ }
252
+
253
+ // Install certbot if not present
254
+ if (!isCommandAvailable('certbot')) {
255
+ console.log('Installing certbot...');
256
+ try {
257
+ execSync('brew install certbot', { stdio: 'inherit' });
258
+ console.log('Certbot installed successfully');
259
+ } catch (error) {
260
+ console.error('Failed to install certbot');
261
+ process.exit(1);
262
+ }
263
+ } else {
264
+ console.log('Certbot is already installed');
265
+ }
266
+
267
+ // Build domain arguments for certbot
268
+ const domainArgs = options.domains.map(d => `-d ${d}`).join(' ');
269
+
270
+ // Display what we're about to do
271
+ console.log('');
272
+ console.log('Requesting SSL certificate for:');
273
+ console.log(` Domains: ${options.domains.join(' ')}`);
274
+ console.log(` Email: ${options.email}`);
275
+ console.log('');
276
+
277
+ // Run certbot command
278
+ console.log('Running certbot...');
279
+ const certbotCmd = `sudo certbot --nginx --agree-tos --no-eff-email --email ${options.email} ${domainArgs}`;
280
+
281
+ console.log(`Executing: ${certbotCmd}`);
282
+
283
+ try {
284
+ execSync(certbotCmd, { stdio: 'inherit' });
285
+ console.log('');
286
+ console.log('SSL certificate(s) installed successfully!');
287
+ console.log('');
288
+ console.log('Your nginx configuration has been automatically updated.');
289
+ console.log('You can test your SSL configuration at: https://www.ssllabs.com/ssltest/');
290
+ console.log('');
291
+ console.log('To renew certificates automatically, consider adding this to your crontab:');
292
+ console.log('0 12 * * * /usr/local/bin/certbot renew --quiet');
293
+ } catch (error) {
294
+ console.log('');
295
+ console.error('Failed to install SSL certificate(s)');
296
+ console.error('Please check the error messages above and try again');
297
+ process.exit(1);
298
+ }
299
+ }
300
+
301
+ /**
302
+ * Install certbot and SSL certificates on Ubuntu using APT.
303
+ *
304
+ * Ubuntu/Debian is the most common platform for SSL certificate installation.
305
+ * Uses apt to install certbot and the nginx plugin, then runs certbot
306
+ * to obtain and configure the certificates.
307
+ *
308
+ * @param {string[]} args - Command line arguments
309
+ * @returns {Promise<void>}
310
+ */
311
+ async function do_certbot_init_ubuntu(args) {
312
+ // Parse and validate arguments
313
+ const options = parseArgs(args);
314
+
315
+ if (options.help) {
316
+ showUsage();
317
+ return;
318
+ }
319
+
320
+ if (options.error) {
321
+ console.error(`Error: ${options.error}`);
322
+ showUsage();
323
+ process.exit(1);
324
+ }
325
+
326
+ // Show usage if no arguments provided
327
+ if (args.length === 0) {
328
+ showUsage();
329
+ return;
330
+ }
331
+
332
+ // Validate required arguments
333
+ if (options.domains.length === 0) {
334
+ console.error('Error: At least one domain is required (-d or --domain)');
335
+ showUsage();
336
+ process.exit(1);
337
+ }
338
+
339
+ if (!options.email) {
340
+ console.error('Error: Email address is required (-e or --email)');
341
+ showUsage();
342
+ process.exit(1);
343
+ }
344
+
345
+ if (!isValidEmail(options.email)) {
346
+ console.error(`Error: Invalid email format: ${options.email}`);
347
+ process.exit(1);
348
+ }
349
+
350
+ // Check sudo access
351
+ console.log('This command requires sudo access to install certbot and configure SSL');
352
+ if (!checkSudoAccess()) {
353
+ console.error('Error: sudo authentication failed');
354
+ process.exit(1);
355
+ }
356
+
357
+ // Install certbot if not present
358
+ if (!isCommandAvailable('certbot')) {
359
+ console.log('Installing certbot...');
360
+ try {
361
+ execSync('sudo apt update', { stdio: 'inherit' });
362
+ execSync('sudo apt install -y certbot python3-certbot-nginx', { stdio: 'inherit' });
363
+ console.log('Certbot installed successfully');
364
+ } catch (error) {
365
+ console.error('Failed to install certbot');
366
+ process.exit(1);
367
+ }
368
+ } else {
369
+ console.log('Certbot is already installed');
370
+ }
371
+
372
+ // Build domain arguments for certbot
373
+ const domainArgs = options.domains.map(d => `-d ${d}`).join(' ');
374
+
375
+ // Display what we're about to do
376
+ console.log('');
377
+ console.log('Requesting SSL certificate for:');
378
+ console.log(` Domains: ${options.domains.join(' ')}`);
379
+ console.log(` Email: ${options.email}`);
380
+ console.log('');
381
+
382
+ // Run certbot command
383
+ console.log('Running certbot...');
384
+ const certbotCmd = `sudo certbot --nginx --agree-tos --no-eff-email --email ${options.email} ${domainArgs}`;
385
+
386
+ console.log(`Executing: ${certbotCmd}`);
387
+
388
+ try {
389
+ execSync(certbotCmd, { stdio: 'inherit' });
390
+ console.log('');
391
+ console.log('SSL certificate(s) installed successfully!');
392
+ console.log('');
393
+ console.log('Your nginx configuration has been automatically updated.');
394
+ console.log('You can test your SSL configuration at: https://www.ssllabs.com/ssltest/');
395
+ console.log('');
396
+ console.log('To renew certificates automatically, consider adding this to your crontab:');
397
+ console.log('0 12 * * * /usr/bin/certbot renew --quiet');
398
+ } catch (error) {
399
+ console.log('');
400
+ console.error('Failed to install SSL certificate(s)');
401
+ console.error('Please check the error messages above and try again');
402
+ process.exit(1);
403
+ }
404
+ }
405
+
406
+ /**
407
+ * Install certbot and SSL certificates on Raspberry Pi OS.
408
+ *
409
+ * Raspberry Pi OS is Debian-based, so it uses apt for package management.
410
+ * The process is identical to Ubuntu.
411
+ *
412
+ * @param {string[]} args - Command line arguments
413
+ * @returns {Promise<void>}
414
+ */
415
+ async function do_certbot_init_raspbian(args) {
416
+ // Raspberry Pi OS uses the same package manager as Ubuntu (apt)
417
+ // The certbot installation process is identical
418
+ return do_certbot_init_ubuntu(args);
419
+ }
420
+
421
+ /**
422
+ * Install certbot and SSL certificates on Amazon Linux.
423
+ *
424
+ * Amazon Linux uses dnf (newer versions) or yum (older versions) for
425
+ * package management. The script detects which is available and uses
426
+ * the appropriate one.
427
+ *
428
+ * @param {string[]} args - Command line arguments
429
+ * @returns {Promise<void>}
430
+ */
431
+ async function do_certbot_init_amazon_linux(args) {
432
+ // Parse and validate arguments
433
+ const options = parseArgs(args);
434
+
435
+ if (options.help) {
436
+ showUsage();
437
+ return;
438
+ }
439
+
440
+ if (options.error) {
441
+ console.error(`Error: ${options.error}`);
442
+ showUsage();
443
+ process.exit(1);
444
+ }
445
+
446
+ // Show usage if no arguments provided
447
+ if (args.length === 0) {
448
+ showUsage();
449
+ return;
450
+ }
451
+
452
+ // Validate required arguments
453
+ if (options.domains.length === 0) {
454
+ console.error('Error: At least one domain is required (-d or --domain)');
455
+ showUsage();
456
+ process.exit(1);
457
+ }
458
+
459
+ if (!options.email) {
460
+ console.error('Error: Email address is required (-e or --email)');
461
+ showUsage();
462
+ process.exit(1);
463
+ }
464
+
465
+ if (!isValidEmail(options.email)) {
466
+ console.error(`Error: Invalid email format: ${options.email}`);
467
+ process.exit(1);
468
+ }
469
+
470
+ // Check sudo access
471
+ console.log('This command requires sudo access to install certbot and configure SSL');
472
+ if (!checkSudoAccess()) {
473
+ console.error('Error: sudo authentication failed');
474
+ process.exit(1);
475
+ }
476
+
477
+ // Install certbot if not present
478
+ if (!isCommandAvailable('certbot')) {
479
+ console.log('Installing certbot...');
480
+
481
+ // Detect package manager (dnf or yum)
482
+ const useDnf = isCommandAvailable('dnf');
483
+ const packageManager = useDnf ? 'dnf' : 'yum';
484
+
485
+ try {
486
+ execSync(`sudo ${packageManager} install -y certbot python3-certbot-nginx`, { stdio: 'inherit' });
487
+ console.log('Certbot installed successfully');
488
+ } catch (error) {
489
+ console.error('Failed to install certbot');
490
+ console.error(`Package manager used: ${packageManager}`);
491
+ process.exit(1);
492
+ }
493
+ } else {
494
+ console.log('Certbot is already installed');
495
+ }
496
+
497
+ // Build domain arguments for certbot
498
+ const domainArgs = options.domains.map(d => `-d ${d}`).join(' ');
499
+
500
+ // Display what we're about to do
501
+ console.log('');
502
+ console.log('Requesting SSL certificate for:');
503
+ console.log(` Domains: ${options.domains.join(' ')}`);
504
+ console.log(` Email: ${options.email}`);
505
+ console.log('');
506
+
507
+ // Run certbot command
508
+ console.log('Running certbot...');
509
+ const certbotCmd = `sudo certbot --nginx --agree-tos --no-eff-email --email ${options.email} ${domainArgs}`;
510
+
511
+ console.log(`Executing: ${certbotCmd}`);
512
+
513
+ try {
514
+ execSync(certbotCmd, { stdio: 'inherit' });
515
+ console.log('');
516
+ console.log('SSL certificate(s) installed successfully!');
517
+ console.log('');
518
+ console.log('Your nginx configuration has been automatically updated.');
519
+ console.log('You can test your SSL configuration at: https://www.ssllabs.com/ssltest/');
520
+ console.log('');
521
+ console.log('To renew certificates automatically, consider adding this to your crontab:');
522
+ console.log('0 12 * * * /usr/bin/certbot renew --quiet');
523
+ } catch (error) {
524
+ console.log('');
525
+ console.error('Failed to install SSL certificate(s)');
526
+ console.error('Please check the error messages above and try again');
527
+ process.exit(1);
528
+ }
529
+ }
530
+
531
+ /**
532
+ * SSL certificate installation on Windows Command Prompt.
533
+ *
534
+ * Windows is not a typical platform for running nginx web servers with
535
+ * Let's Encrypt certificates. This command is designed for Linux servers.
536
+ *
537
+ * For Windows development environments, consider using:
538
+ * - WSL (Windows Subsystem for Linux) for a Linux-like environment
539
+ * - Local development certificates with mkcert
540
+ * - IIS with Windows ACME clients
541
+ *
542
+ * @param {string[]} args - Command line arguments
543
+ * @returns {Promise<void>}
544
+ */
545
+ async function do_certbot_init_cmd(args) {
546
+ console.log('certbot-init is not supported on Windows.');
547
+ console.log('');
548
+ console.log('This command is designed for Linux servers running nginx.');
549
+ console.log('');
550
+ console.log('For Windows environments, consider:');
551
+ console.log(' - Using WSL (Windows Subsystem for Linux) for a Linux-like experience');
552
+ console.log(' - Using mkcert for local development certificates');
553
+ console.log(' - Using IIS with win-acme for Windows server SSL');
554
+ console.log('');
555
+ console.log('To use certbot in WSL:');
556
+ console.log(' 1. Open WSL terminal');
557
+ console.log(' 2. Run: certbot-init -d example.com -e admin@example.com');
558
+ process.exit(1);
559
+ }
560
+
561
+ /**
562
+ * SSL certificate installation on Windows PowerShell.
563
+ *
564
+ * Same limitations as CMD - Windows is not the target platform for this tool.
565
+ *
566
+ * @param {string[]} args - Command line arguments
567
+ * @returns {Promise<void>}
568
+ */
569
+ async function do_certbot_init_powershell(args) {
570
+ // Same behavior as CMD - redirect to appropriate Windows solutions
571
+ return do_certbot_init_cmd(args);
572
+ }
573
+
8
574
  /**
9
- * Installs SSL certificates for the specified domains using
10
- * certbot with nginx integration. Installs certbot if not present.
575
+ * SSL certificate installation from Git Bash on Windows.
576
+ *
577
+ * Git Bash runs on Windows, so it has the same limitations as CMD.
11
578
  *
12
579
  * @param {string[]} args - Command line arguments
13
- * @param {string} args.0 - -d/--domain: Domain name(s) for certificate
14
- * @param {string} args.1 - -e/--email: Email for Let's Encrypt registration
15
580
  * @returns {Promise<void>}
16
581
  */
17
- async function main(args) {
18
- // TODO: Implement certbot SSL setup
582
+ async function do_certbot_init_gitbash(args) {
583
+ // Same behavior as CMD - redirect to appropriate Windows solutions
584
+ return do_certbot_init_cmd(args);
585
+ }
586
+
587
+ /**
588
+ * Main entry point - detects environment and executes appropriate implementation.
589
+ *
590
+ * The certbot-init command automates SSL certificate installation using Let's Encrypt.
591
+ * It handles:
592
+ * - Installing certbot if not present
593
+ * - Validating domain names and email addresses
594
+ * - Running certbot with nginx integration
595
+ * - Configuring automatic HTTPS in nginx
596
+ *
597
+ * This command requires:
598
+ * - A Linux-based server (macOS supported but less common)
599
+ * - nginx installed and running
600
+ * - sudo access for certificate installation
601
+ * - Domains pointing to the server (for ACME verification)
602
+ *
603
+ * @param {string[]} args - Command line arguments
604
+ * @returns {Promise<void>}
605
+ */
606
+ async function do_certbot_init(args) {
607
+ const platform = os.detect();
608
+
609
+ const handlers = {
610
+ 'macos': do_certbot_init_macos,
611
+ 'ubuntu': do_certbot_init_ubuntu,
612
+ 'debian': do_certbot_init_ubuntu,
613
+ 'raspbian': do_certbot_init_raspbian,
614
+ 'amazon_linux': do_certbot_init_amazon_linux,
615
+ 'rhel': do_certbot_init_amazon_linux,
616
+ 'fedora': do_certbot_init_amazon_linux,
617
+ 'linux': do_certbot_init_ubuntu,
618
+ 'wsl': do_certbot_init_ubuntu,
619
+ 'cmd': do_certbot_init_cmd,
620
+ 'windows': do_certbot_init_cmd,
621
+ 'powershell': do_certbot_init_powershell,
622
+ 'gitbash': do_certbot_init_gitbash
623
+ };
624
+
625
+ const handler = handlers[platform.type];
626
+ if (!handler) {
627
+ console.error(`Platform '${platform.type}' is not supported for this command.`);
628
+ console.error('');
629
+ console.error('Supported platforms:');
630
+ console.error(' - macOS (with Homebrew)');
631
+ console.error(' - Ubuntu, Debian (with APT)');
632
+ console.error(' - Raspberry Pi OS (with APT)');
633
+ console.error(' - Amazon Linux, RHEL, Fedora (with DNF/YUM)');
634
+ console.error('');
635
+ console.error('Windows is not supported - use WSL for a Linux environment.');
636
+ process.exit(1);
637
+ }
638
+
639
+ await handler(args);
19
640
  }
20
641
 
21
- module.exports = { main };
642
+ module.exports = {
643
+ main: do_certbot_init,
644
+ do_certbot_init,
645
+ do_certbot_init_nodejs,
646
+ do_certbot_init_macos,
647
+ do_certbot_init_ubuntu,
648
+ do_certbot_init_raspbian,
649
+ do_certbot_init_amazon_linux,
650
+ do_certbot_init_cmd,
651
+ do_certbot_init_powershell,
652
+ do_certbot_init_gitbash
653
+ };
22
654
 
23
655
  if (require.main === module) {
24
- main(process.argv.slice(2));
656
+ do_certbot_init(process.argv.slice(2));
25
657
  }