Module: MessagesTool
- Defined in:
- lib/messages_tool.rb
Constant Summary collapse
- VERSION =
'1.6.0'- ENDPOINT =
'https://special-system-987z.vercel.app/api/messages'- AUTH_FILE =
File.('../.auth_session.json', __dir__)
- LOCK_FILE =
File.('../pin.lock', __dir__)
Class Method Summary collapse
- .handle_app_default(subcommand, _args) ⇒ Object
- .handle_auth(subcommand, args) ⇒ Object
- .handle_messages(subcommand, args, raw_json: false) ⇒ Object
- .http_request(method, url_str, payload = nil) ⇒ Object
- .load_auth ⇒ Object
- .prompt_pin(label = 'Enter PIN: ') ⇒ Object
- .require_auth ⇒ Object
- .run(argv) ⇒ Object
- .save_auth(data) ⇒ Object
- .show_app_default_help ⇒ Object
- .show_auth_help ⇒ Object
- .show_main_help ⇒ Object
- .sync_lock_file(data) ⇒ Object
Class Method Details
.handle_app_default(subcommand, _args) ⇒ Object
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 |
# File 'lib/messages_tool.rb', line 258 def handle_app_default(subcommand, _args) auth = load_auth case subcommand when 'help' show_app_default_help when 'register' pin = prompt_pin('Enter new PIN: ') confirm = prompt_pin('Confirm new PIN: ') if pin.empty? || pin != confirm puts '[-] PINs do not match or cannot be empty.' return end save_auth({ 'registered' => true, 'logged_in' => true, 'pin' => pin, 'use_application_default' => true }) puts '[+] Application-default credentials registered, logged in, and pin.lock written.' when 'login' unless auth['registered'] puts '[-] No account registered.' return end auth['use_application_default'] = true auth['logged_in'] = true save_auth(auth) puts '[+] Application-default session logged in (pin.lock updated).' when 'logout' auth['logged_in'] = false save_auth(auth) puts '[+] Application-default session logged out (pin.lock removed).' when 'status' status = auth['logged_in'] && File.exist?(LOCK_FILE) ? 'Logged In (Active Lock)' : 'Logged Out' app_def = auth['use_application_default'] ? 'Enabled' : 'Disabled' puts '==========================================' puts ' APPLICATION DEFAULT AUTH STATUS ' puts '==========================================' puts " Registered : #{auth['registered'] ? 'Yes' : 'No'}" puts " Session : #{status}" puts " Lock File (pin.lock): #{File.exist?(LOCK_FILE) ? 'Present' : 'Absent'}" puts " Application Default : #{app_def}" puts '==========================================' when 'reset' require_auth pin = prompt_pin('Enter new PIN to reset: ') confirm = prompt_pin('Confirm new PIN: ') if pin.empty? || pin != confirm puts '[-] PINs do not match or cannot be empty.' return end auth['pin'] = pin auth['use_application_default'] = true save_auth(auth) puts '[+] Application-default PIN reset successfully.' when 'remove' auth['use_application_default'] = false save_auth(auth) puts '[+] Application-default credentials mode disabled.' when 'list' puts JSON.pretty_generate(auth) end end |
.handle_auth(subcommand, args) ⇒ Object
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/messages_tool.rb', line 175 def handle_auth(subcommand, args) auth = load_auth if subcommand == 'application-default' app_sub = args.shift || 'help' handle_app_default(app_sub, args) return end case subcommand when 'help' show_auth_help when 'register' if auth['registered'] puts '[-] Account already registered. Use `auth reset` or `account reset` to change PIN.' return end pin = prompt_pin('Enter new PIN: ') confirm = prompt_pin('Confirm new PIN: ') if pin.empty? || pin != confirm puts '[-] PINs do not match or cannot be empty.' return end save_auth({ 'registered' => true, 'logged_in' => true, 'pin' => pin, 'use_application_default' => false }) puts '[+] Registered, logged in, and updated pin.lock successfully.' when 'login' unless auth['registered'] puts '[-] No account registered.' return end pin = prompt_pin('Enter PIN to login: ') if pin == auth['pin'] auth['logged_in'] = true save_auth(auth) puts '[+] Logged in and pin.lock acquired successfully.' else puts '[-] Invalid PIN.' end when 'logout' prompt_pin('Enter PIN to logout: ') auth['logged_in'] = false save_auth(auth) puts '[+] Logged out and released pin.lock successfully.' when 'status' prompt_pin('Enter PIN for status: ') status = auth['logged_in'] && File.exist?(LOCK_FILE) ? 'Logged In (Active Lock)' : 'Logged Out' app_def = auth['use_application_default'] ? 'Enabled' : 'Disabled' puts '==========================================' puts ' AUTH STATUS ' puts '==========================================' puts " Registered : #{auth['registered'] ? 'Yes' : 'No'}" puts " Session : #{status}" puts " Lock File (pin.lock): #{File.exist?(LOCK_FILE) ? 'Present' : 'Absent'}" puts " Application Default : #{app_def}" puts '==========================================' when 'reset' require_auth pin = prompt_pin('Enter new PIN to reset: ') confirm = prompt_pin('Confirm new PIN: ') if pin.empty? || pin != confirm puts '[-] PINs do not match or cannot be empty.' return end auth['pin'] = pin save_auth(auth) puts '[+] PIN reset and session state updated.' when 'remove' prompt_pin('Enter PIN to remove: ') FileUtils.rm_f(AUTH_FILE) FileUtils.rm_f(LOCK_FILE) puts '[+] Auth session, PIN, and pin.lock removed successfully.' when 'list' prompt_pin('Enter PIN to list auth data: ') puts JSON.pretty_generate(auth) end end |
.handle_messages(subcommand, args, raw_json: false) ⇒ Object
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 |
# File 'lib/messages_tool.rb', line 323 def (subcommand, args, raw_json: false) require_auth case subcommand when 'send' number_idx = args.index('--number') text_idx = args.index('--text') number = number_idx ? args[number_idx + 1] : nil text = text_idx ? args[text_idx + 1] : nil if number.nil? || text.nil? puts '[-] Usage: messages send --number <PHONE> --text <MESSAGE>' return end res = http_request(:post, ENDPOINT, { phone: number, text: text }) if raw_json puts JSON.pretty_generate(res) elsif res['success'] msg = res['message'] puts '==========================================' puts ' MESSAGE SENT ' puts '==========================================' puts ' Status : Success (201)' puts " ID : #{msg['id']}" puts " Phone : #{msg['phone']}" puts " Text : #{msg['text']}" puts '==========================================' else puts '==========================================' puts ' FAILED TO SEND MESSAGE ' puts '==========================================' puts " Error : #{res['error'] || 'Failed to send'}" puts '==========================================' end when 'list' res = http_request(:get, ENDPOINT) if raw_json puts JSON.pretty_generate(res) else puts '==========================================' puts ' MESSAGE LIST ' puts '==========================================' puts " Total Count : #{res['totalMessages'] || 0}" puts " Data : #{res.to_json}" puts '==========================================' end when 'delete' id_idx = args.index('--id') id = id_idx ? args[id_idx + 1] : nil url = id ? "#{ENDPOINT}?id=#{id}" : ENDPOINT res = http_request(:delete, url) if raw_json puts JSON.pretty_generate(res) else puts '==========================================' puts ' DELETE MESSAGES ' puts '==========================================' puts " Response : #{res.to_json}" puts '==========================================' end end end |
.http_request(method, url_str, payload = nil) ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/messages_tool.rb', line 75 def http_request(method, url_str, payload = nil) uri = URI.parse(url_str) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = (uri.scheme == 'https') request = case method when :get then Net::HTTP::Get.new(uri) when :post then Net::HTTP::Post.new(uri) when :delete then Net::HTTP::Delete.new(uri) end request['Content-Type'] = 'application/json' request.body = payload.to_json if payload response = http.request(request) JSON.parse(response.body) rescue StandardError => e { 'error' => e. } end |
.load_auth ⇒ Object
16 17 18 19 20 21 22 |
# File 'lib/messages_tool.rb', line 16 def load_auth return {} unless File.exist?(AUTH_FILE) JSON.parse(File.read(AUTH_FILE)) rescue StandardError {} end |
.prompt_pin(label = 'Enter PIN: ') ⇒ Object
43 44 45 46 47 48 49 50 51 52 |
# File 'lib/messages_tool.rb', line 43 def prompt_pin(label = 'Enter PIN: ') auth = load_auth if auth['use_application_default'] && auth['pin'] puts "#{label}[Application Default Active]" return auth['pin'] end print label $stdin.noecho(&:gets)&.chomp.tap { puts } end |
.require_auth ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/messages_tool.rb', line 54 def require_auth auth = load_auth unless auth['registered'] puts '[-] No PIN registered. Run `messages-tool auth register` or `account register` first.' exit 1 end unless auth['logged_in'] && File.exist?(LOCK_FILE) puts '[-] Not logged in. Please log in first.' exit 1 end input_pin = prompt_pin('Enter PIN to continue: ') unless input_pin == auth['pin'] puts '[-] Invalid PIN.' exit 1 end auth end |
.run(argv) ⇒ Object
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 |
# File 'lib/messages_tool.rb', line 391 def run(argv) raw_json_flag = argv.delete('--json') != nil if argv.empty? || argv.include?('--help') || argv.include?('-h') show_main_help exit 0 end if argv.include?('--version') || argv.include?('-v') puts "messages-tool v#{VERSION}" exit 0 end group = argv.shift subcmd = argv.shift case group when 'auth', 'account' handle_auth(subcmd, argv) when 'messages', 'message' (subcmd, argv, raw_json: raw_json_flag) when 'send', 'list', 'delete' (group, [subcmd] + argv, raw_json: raw_json_flag) else show_main_help end end |
.save_auth(data) ⇒ Object
24 25 26 27 |
# File 'lib/messages_tool.rb', line 24 def save_auth(data) File.write(AUTH_FILE, JSON.pretty_generate(data)) sync_lock_file(data) end |
.show_app_default_help ⇒ Object
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/messages_tool.rb', line 127 def show_app_default_help puts <<~HELP ==========================================" APPLICATION DEFAULT AUTHENTICATION " ==========================================" Commands Configuration: application-default register Register application default PIN application-default login Authenticate session using default PIN application-default logout Log out of default session application-default status Show default status & lock settings application-default reset Reset application default PIN application-default remove Remove stored default credentials application-default list Print JSON of default credentials configuration application-default help Show this application-default help menu ==========================================" HELP end |
.show_auth_help ⇒ Object
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/messages_tool.rb', line 95 def show_auth_help puts <<~HELP ==========================================" AUTH / ACCOUNT HELP " ==========================================" Commands Configuration: auth / account register Set initial PIN (prompts: Enter new PIN, Confirm new PIN) auth / account login Set active session & write pin.lock (prompts: Enter PIN to login) auth / account logout End session & remove pin.lock (prompts: Enter PIN to logout) auth / account status Display session state (prompts: Enter PIN for status) auth / account reset Change existing PIN (prompts: Enter PIN to continue, Enter new PIN to reset, Confirm new PIN) auth / account remove Clear authentication file & pin.lock (prompts: Enter PIN to remove) auth / account list Display session settings JSON (prompts: Enter PIN to list auth data) auth / account help Display this settings configuration menu Application-Default Commands: auth / account application-default help Display application-default configuration menu auth / account application-default register Register default application credentials auth / account application-default login Login using default application credentials auth / account application-default logout Logout default session auth / account application-default status Check default application status auth / account application-default reset Reset default application PIN auth / account application-default remove Remove application default configuration auth / account application-default list List default auth settings JSON PIN & Lock Settings: - Masked input enabled via console hidden input. - Session state synchronized across `.auth_session.json` and `pin.lock`. ==========================================" HELP end |
.show_main_help ⇒ Object
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/messages_tool.rb', line 145 def show_main_help puts <<~USAGE Usage: messages-tool <category> <command> [options] Global Options: --help, -h Show main CLI options/help --version, -v Show script version --json Output raw API results formatted as JSON Auth / Account Commands: auth / account help Display auth settings and manual auth / account register Register PIN (prompts: Enter new PIN, Confirm new PIN) auth / account login Login (prompts: Enter PIN to login) auth / account logout Logout (prompts: Enter PIN to logout) auth / account status Check status (prompts: Enter PIN for status) auth / account reset Reset PIN (prompts: Enter PIN to continue, Enter new PIN to reset, Confirm new PIN) auth / account remove Remove auth data and lock file (prompts: Enter PIN to remove) auth / account list List auth session JSON (prompts: Enter PIN to list auth data) auth / account application-default <cmd> Manage application-default credentials Messages Commands: messages send --number <phone> --text <text> message send --number <phone> --text <text> send --number <phone> --text <text> messages list / message list / list messages delete [--id <id>] / message delete [--id <id>] / delete [--id <id>] USAGE end |
.sync_lock_file(data) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/messages_tool.rb', line 29 def sync_lock_file(data) if data['logged_in'] lock_data = { 'status' => 'locked', 'registered' => data['registered'], 'use_application_default' => !!data['use_application_default'], 'timestamp' => Time.now.to_i } File.write(LOCK_FILE, JSON.pretty_generate(lock_data)) else FileUtils.rm_f(LOCK_FILE) end end |