vpn_tool 0.1.0
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.
- checksums.yaml +7 -0
- data/bin/vpn_tool +69 -0
- data/lib/vpn_tool.rb +170 -0
- metadata +40 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: e0f2ab4755d2efd79993ca2048d7dd98b05d7d96f060a47a8bdd70494923ae04
|
|
4
|
+
data.tar.gz: 274dcdcc32359ad7a03d326fb5390477f366136b885f92504893a8cadd65c126
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: c261527554e4ed208789c663aa76a4cb2d001c2428b30ca5ad8e518d3b0c238ab61f9b7b9be8e5f61b1a0d1bdafd2107acf44c9e635d2aeb3c2273e2d80dbb61
|
|
7
|
+
data.tar.gz: cbeab84005e708ebb6f20e1dd1b22c2391319aac3efc0f215b9a63392247591cd657664c1ff8bf0a9f160ec9c593e9bf59e3a81917593857bfbb16b387a0be62
|
data/bin/vpn_tool
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require_relative "../lib/vpn_tool"
|
|
4
|
+
require "json"
|
|
5
|
+
|
|
6
|
+
VERSION = "0.1.0"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
if ARGV.include?("--version")
|
|
10
|
+
puts "vpn_tool #{VERSION}"
|
|
11
|
+
exit 0
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
case ARGV.shift
|
|
16
|
+
|
|
17
|
+
when "auth"
|
|
18
|
+
|
|
19
|
+
case ARGV.shift
|
|
20
|
+
when "register"
|
|
21
|
+
VpnTool.register_pin
|
|
22
|
+
when "login"
|
|
23
|
+
VpnTool.login_pin
|
|
24
|
+
else
|
|
25
|
+
puts "vpn_tool auth register"
|
|
26
|
+
puts "vpn_tool auth login"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
when "connect"
|
|
31
|
+
|
|
32
|
+
VpnTool.login_pin
|
|
33
|
+
|
|
34
|
+
country = ARGV[1]
|
|
35
|
+
|
|
36
|
+
unless ARGV[0] == "--country" && country
|
|
37
|
+
puts "Usage: vpn_tool connect --country US"
|
|
38
|
+
exit 1
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
puts JSON.pretty_generate(
|
|
42
|
+
VpnTool.connect(country)
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
when "countries"
|
|
47
|
+
|
|
48
|
+
VpnTool.login_pin
|
|
49
|
+
puts JSON.pretty_generate(VpnTool.countries)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
when "status"
|
|
53
|
+
|
|
54
|
+
VpnTool.login_pin
|
|
55
|
+
puts JSON.pretty_generate(VpnTool.status)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
when "disconnect"
|
|
59
|
+
|
|
60
|
+
VpnTool.login_pin
|
|
61
|
+
puts JSON.pretty_generate(VpnTool.disconnect)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
else
|
|
65
|
+
|
|
66
|
+
puts "vpn_tool #{VERSION}"
|
|
67
|
+
puts "Use --version to verify"
|
|
68
|
+
|
|
69
|
+
end
|
data/lib/vpn_tool.rb
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
require "net/http"
|
|
2
|
+
require "json"
|
|
3
|
+
require "uri"
|
|
4
|
+
require "time"
|
|
5
|
+
|
|
6
|
+
module VpnTool
|
|
7
|
+
|
|
8
|
+
API = "https://vpn-connect-status--fudhhhhfhfhdjjc.replit.app"
|
|
9
|
+
|
|
10
|
+
PIN_FILE = File.expand_path("../../pin.lock", __FILE__)
|
|
11
|
+
ATTEMPTS_FILE = File.expand_path("../../attempts.lock", __FILE__)
|
|
12
|
+
LOCK_FILE = File.expand_path("../../pin.lockout", __FILE__)
|
|
13
|
+
|
|
14
|
+
MAX_ATTEMPTS = 3
|
|
15
|
+
LOCK_MINUTES = 5
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def self.lock_check
|
|
19
|
+
return unless File.exist?(LOCK_FILE)
|
|
20
|
+
|
|
21
|
+
locked_time = Time.parse(File.read(LOCK_FILE))
|
|
22
|
+
remaining = (locked_time + LOCK_MINUTES * 60) - Time.now
|
|
23
|
+
|
|
24
|
+
if remaining > 0
|
|
25
|
+
minutes = (remaining / 60).floor
|
|
26
|
+
seconds = (remaining % 60).floor
|
|
27
|
+
|
|
28
|
+
puts "Too many failed attempts"
|
|
29
|
+
puts "Try again in #{minutes} minutes #{seconds} seconds"
|
|
30
|
+
puts "Exiting..."
|
|
31
|
+
exit 1
|
|
32
|
+
else
|
|
33
|
+
File.delete(LOCK_FILE)
|
|
34
|
+
File.write(ATTEMPTS_FILE, "0")
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def self.register_pin
|
|
40
|
+
print "Enter new PIN: "
|
|
41
|
+
pin = STDIN.gets.chomp
|
|
42
|
+
|
|
43
|
+
print "Confirm new PIN: "
|
|
44
|
+
confirm = STDIN.gets.chomp
|
|
45
|
+
|
|
46
|
+
if pin != confirm
|
|
47
|
+
puts "PIN mismatch"
|
|
48
|
+
exit 1
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
File.write(PIN_FILE, pin)
|
|
52
|
+
File.write(ATTEMPTS_FILE, "0")
|
|
53
|
+
|
|
54
|
+
puts "PIN registered successfully"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def self.login_pin
|
|
59
|
+
|
|
60
|
+
lock_check
|
|
61
|
+
|
|
62
|
+
unless File.exist?(PIN_FILE)
|
|
63
|
+
puts "Not registered"
|
|
64
|
+
puts "Please register"
|
|
65
|
+
puts "Exiting..."
|
|
66
|
+
exit 1
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
print "Enter PIN: "
|
|
70
|
+
pin = STDIN.gets.chomp
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
if pin == File.read(PIN_FILE)
|
|
74
|
+
|
|
75
|
+
File.write(ATTEMPTS_FILE, "0")
|
|
76
|
+
puts "Login successful"
|
|
77
|
+
return
|
|
78
|
+
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
attempts =
|
|
83
|
+
File.exist?(ATTEMPTS_FILE) ?
|
|
84
|
+
File.read(ATTEMPTS_FILE).to_i : 0
|
|
85
|
+
|
|
86
|
+
attempts += 1
|
|
87
|
+
|
|
88
|
+
File.write(
|
|
89
|
+
ATTEMPTS_FILE,
|
|
90
|
+
attempts.to_s
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
if attempts >= MAX_ATTEMPTS
|
|
95
|
+
|
|
96
|
+
File.write(
|
|
97
|
+
LOCK_FILE,
|
|
98
|
+
Time.now.iso8601
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
puts "Too many failed attempts"
|
|
102
|
+
puts "Try again in #{LOCK_MINUTES} minutes"
|
|
103
|
+
else
|
|
104
|
+
puts "Wrong PIN"
|
|
105
|
+
puts "#{MAX_ATTEMPTS - attempts} attempts remaining"
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
puts "Not logged in"
|
|
109
|
+
puts "Exiting..."
|
|
110
|
+
exit 1
|
|
111
|
+
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def self.request(method, path, body=nil)
|
|
116
|
+
|
|
117
|
+
uri = URI(API + path)
|
|
118
|
+
|
|
119
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
120
|
+
http.use_ssl = true
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
request =
|
|
124
|
+
if method == :get
|
|
125
|
+
Net::HTTP::Get.new(uri)
|
|
126
|
+
else
|
|
127
|
+
r = Net::HTTP::Post.new(uri)
|
|
128
|
+
r["Content-Type"] = "application/json"
|
|
129
|
+
r.body = body.to_json
|
|
130
|
+
r
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
response = http.request(request)
|
|
135
|
+
|
|
136
|
+
JSON.parse(response.body)
|
|
137
|
+
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def self.countries
|
|
142
|
+
request(:get, "/api/vpn/countries")
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def self.connect(country)
|
|
147
|
+
request(
|
|
148
|
+
:post,
|
|
149
|
+
"/api/vpn/connect",
|
|
150
|
+
{
|
|
151
|
+
countryCode: country
|
|
152
|
+
}
|
|
153
|
+
)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def self.status
|
|
158
|
+
request(:get, "/api/vpn/status")
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def self.disconnect
|
|
163
|
+
request(
|
|
164
|
+
:post,
|
|
165
|
+
"/api/vpn/disconnect",
|
|
166
|
+
{}
|
|
167
|
+
)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: vpn_tool
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- dodi66412
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2026-07-09 00:00:00.000000000 Z
|
|
11
|
+
dependencies: []
|
|
12
|
+
email:
|
|
13
|
+
- dodi66412@gmail.com
|
|
14
|
+
executables:
|
|
15
|
+
- vpn_tool
|
|
16
|
+
extensions: []
|
|
17
|
+
extra_rdoc_files: []
|
|
18
|
+
files:
|
|
19
|
+
- bin/vpn_tool
|
|
20
|
+
- lib/vpn_tool.rb
|
|
21
|
+
licenses: []
|
|
22
|
+
metadata: {}
|
|
23
|
+
rdoc_options: []
|
|
24
|
+
require_paths:
|
|
25
|
+
- lib
|
|
26
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
27
|
+
requirements:
|
|
28
|
+
- - ">="
|
|
29
|
+
- !ruby/object:Gem::Version
|
|
30
|
+
version: '0'
|
|
31
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
32
|
+
requirements:
|
|
33
|
+
- - ">="
|
|
34
|
+
- !ruby/object:Gem::Version
|
|
35
|
+
version: '0'
|
|
36
|
+
requirements: []
|
|
37
|
+
rubygems_version: 3.6.2
|
|
38
|
+
specification_version: 4
|
|
39
|
+
summary: VPN API CLI with PIN authentication
|
|
40
|
+
test_files: []
|