reivt 1.6.0 → 1.6.1

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.
data/lib/reivt/api.rb CHANGED
@@ -1,64 +1,64 @@
1
- require 'graphql/client'
2
- require 'graphql/client/http'
3
-
4
- require 'pp'
5
-
6
- # An extension of our main module Reivt
7
- #
8
- # @author [brwnrclse]
9
- #
10
- module Reivt
11
- # Intrface for rev API, connects local changes with our remote.
12
- #
13
- # @author [brwnrclse]
14
- #
15
- module RevAPI
16
- SCHEMA_PATH = "#{Dir.pwd}/lib/reivt/schema/schema.json".freeze
17
- ENDPOINT_URL = 'https://api.graph.cool/simple/v1/revwver'.freeze
18
- ENDPOINT = GraphQL::Client::HTTP.new(ENDPOINT_URL) do
19
- def headers(_context)
20
- auth_token = Reivt::REIVT_STORE.transaction do |store|
21
- store.fetch(:auth0_id, nil)
22
- end
23
-
24
- { 'Authorization': "Bearer #{auth_token}" }
25
- end
26
- end
27
-
28
- ID_TOKEN = Reivt::REIVT_STORE.transaction do |store|
29
- store.fetch(:user_id, nil)
30
- end
31
-
32
- unless File.exist?(SCHEMA_PATH)
33
- GraphQL::Client.dump_schema(ENDPOINT, SCHEMA_PATH)
34
- end
35
-
36
- SCHEMA = GraphQL::Client.load_schema(SCHEMA_PATH)
37
- CLIENT = GraphQL::Client.new(schema: SCHEMA, execute: ENDPOINT)
38
-
39
- # Raise any errors in the response data or simply return the data
40
- #
41
- # @param api_response [Obj] A nested object containing either data or errors
42
- #
43
- # @return [Array] A list containing the data and error object from the req
44
- #
45
- def self.retrieve(api_response)
46
- errors = api_response.errors
47
- data = api_response.data
48
-
49
- if data.nil?
50
- msg = errors.details[:data].map { |error| error['message'] }
51
- raise Reivt::GraphQLDataException, msg.join(",\n")
52
- else
53
- data
54
- end
55
- end
56
- end
57
- end
58
-
59
- require_relative 'api/mutations/document_create.mutation'
60
- require_relative 'api/mutations/document_delete.mutation'
61
- require_relative 'api/mutations/rev_create.mutation'
62
- require_relative 'api/mutations/rev_delete.mutation'
63
- require_relative 'api/mutations/user_create.mutation'
64
- require_relative 'api/mutations/user_signin.mutation'
1
+ require 'graphql/client'
2
+ require 'graphql/client/http'
3
+
4
+ require 'pp'
5
+
6
+ # An extension of our main module Reivt
7
+ #
8
+ # @author [brwnrclse]
9
+ #
10
+ module Reivt
11
+ # Intrface for rev API, connects local changes with our remote.
12
+ #
13
+ # @author [brwnrclse]
14
+ #
15
+ module RevAPI
16
+ SCHEMA_PATH = "#{Dir.pwd}/lib/reivt/schema/schema.json".freeze
17
+ ENDPOINT_URL = 'https://api.graph.cool/simple/v1/revwver'.freeze
18
+ ENDPOINT = GraphQL::Client::HTTP.new(ENDPOINT_URL) do
19
+ def headers(_context)
20
+ auth_token = Reivt::REIVT_STORE.transaction do |store|
21
+ store.fetch(:auth0_id, nil)
22
+ end
23
+
24
+ { 'Authorization': "Bearer #{auth_token}" }
25
+ end
26
+ end
27
+
28
+ ID_TOKEN = Reivt::REIVT_STORE.transaction do |store|
29
+ store.fetch(:user_id, nil)
30
+ end
31
+
32
+ unless File.exist?(SCHEMA_PATH)
33
+ GraphQL::Client.dump_schema(ENDPOINT, SCHEMA_PATH)
34
+ end
35
+
36
+ SCHEMA = GraphQL::Client.load_schema(SCHEMA_PATH)
37
+ CLIENT = GraphQL::Client.new(schema: SCHEMA, execute: ENDPOINT)
38
+
39
+ # Raise any errors in the response data or simply return the data
40
+ #
41
+ # @param api_response [Obj] A nested object containing either data or errors
42
+ #
43
+ # @return [Array] A list containing the data and error object from the req
44
+ #
45
+ def self.retrieve(api_response)
46
+ errors = api_response.errors
47
+ data = api_response.data
48
+
49
+ if data.nil?
50
+ msg = errors.details[:data].map { |error| error['message'] }
51
+ raise Reivt::GraphQLDataException, msg.join(",\n")
52
+ else
53
+ data
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ require_relative 'api/mutations/document_create.mutation'
60
+ require_relative 'api/mutations/document_delete.mutation'
61
+ require_relative 'api/mutations/rev_create.mutation'
62
+ require_relative 'api/mutations/rev_delete.mutation'
63
+ require_relative 'api/mutations/user_create.mutation'
64
+ require_relative 'api/mutations/user_signin.mutation'
data/lib/reivt/auth.rb CHANGED
@@ -1,96 +1,94 @@
1
- require 'base64'
2
- require 'bcrypt'
3
- require 'digest'
4
- require 'json'
5
- require 'net/http'
6
- require 'sysrandom'
7
- require 'uri'
8
-
9
- # An extension of our main module
10
- #
11
- # @author [brwnrclse]
12
- #
13
- module Reivt
14
- # Convience module for handling our authentication actions and talking to
15
- # Auth0
16
- #
17
- # @author [brwnrclse]
18
- #
19
- module Auth
20
- AUTH_CALLBACK_URL = 'https://rev.vaemoi.co/login_success'.freeze
21
- AUTH_CLIENT_ID = 'Q1fRDQ9u3oN33ok0ciIi9Vww5kV8U8MA'.freeze
22
- AUTH0_ID = Reivt::REIVT_STORE.transaction do
23
- Reivt::REIVT_STORE.fetch(:auth0_id, nil)
24
- end
25
- AUTH_STORE_ACCESS_TOKEN = Reivt::REIVT_STORE.transaction do
26
- Reivt::REIVT_STORE.fetch(:access_token, nil)
27
- end
28
- AUTH_URL = 'https://vaemoi.auth0.com'.freeze
29
- VERIFIER = Sysrandom.urlsafe_base64(32)
30
-
31
- # Provides the user with a means to obtain an authorization code for
32
- # accessing rev's api by opening a browser to our Auth0 login page
33
- #
34
- # @return [nil]
35
- #
36
- def self.auth_code_url
37
- verifier_challenge = Sysrandom.urlsafe_base64(
38
- Digest::SHA256.new.update(VERIFIER).digest.to_i
39
- )
40
-
41
- auth_code_url = AUTH_URL +
42
- '/authorize?response_type=code&scope=openid%20profile' \
43
- '&client_id=' + AUTH_CLIENT_ID +
44
- '&redirect_uri=' + AUTH_CALLBACK_URL +
45
- '&code_challenge=' + verifier_challenge +
46
- '&code_challenge_method=S256'
47
-
48
- auth_code_url
49
- end
50
-
51
- # Exchanges the auth code obtained for a token used to access rev's api
52
- #
53
- # @param auth_code [String] The auth code obtained from logging in
54
- #
55
- # @return [String] The auth token used for accessing rev's api
56
- #
57
- def self.auth_token(auth_code)
58
- auth_token_uri = URI.parse('https://vaemoi.auth0.com/oauth/token')
59
- body = {
60
- grant_type: 'authorization_code',
61
- client_id: AUTH_CLIENT_ID,
62
- code_verifier: VERIFIER,
63
- code: auth_code,
64
- redirect_uri: AUTH_CALLBACK_URL
65
- }
66
- http = Net::HTTP.new(auth_token_uri.host, auth_token_uri.port)
67
- http.use_ssl = true
68
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
69
- req = Net::HTTP::Post.new(auth_token_uri)
70
- req.content_type = 'application/json'
71
- req.body = body.to_json
72
-
73
- res = http.request(req)
74
- token = {}
75
- token[:access_token] = JSON.parse(res.body)['access_token']
76
- token[:auth0_id] = JSON.parse(res.body)['id_token']
77
- token[:expires] = Time.now.to_i + JSON.parse(res.body)['expires'].to_i
78
-
79
- token
80
- end
81
-
82
-
83
- # Checks if user has an auth token - if not, they're most likely not logged in
84
- #
85
- # @param N/A
86
- #
87
- # @return true if logged in
88
- #
89
- def self.logged_in
90
- if AUTH_STORE_ACCESS_TOKEN.nil?
91
- raise Reivt::LoginException
92
- end
93
- return true
94
- end
95
- end
96
- end
1
+ require 'base64'
2
+ require 'bcrypt'
3
+ require 'digest'
4
+ require 'json'
5
+ require 'net/http'
6
+ require 'sysrandom'
7
+ require 'uri'
8
+
9
+ # An extension of our main module
10
+ #
11
+ # @author [brwnrclse]
12
+ #
13
+ module Reivt
14
+ # Convience module for handling our authentication actions and talking to
15
+ # Auth0
16
+ #
17
+ # @author [brwnrclse]
18
+ #
19
+ module Auth
20
+ AUTH_CALLBACK_URL = 'https://rev.vaemoi.co/login_success'.freeze
21
+ AUTH_CLIENT_ID = 'Q1fRDQ9u3oN33ok0ciIi9Vww5kV8U8MA'.freeze
22
+ AUTH0_ID = Reivt::REIVT_STORE.transaction do
23
+ Reivt::REIVT_STORE.fetch(:auth0_id, nil)
24
+ end
25
+ AUTH_STORE_ACCESS_TOKEN = Reivt::REIVT_STORE.transaction do
26
+ Reivt::REIVT_STORE.fetch(:access_token, nil)
27
+ end
28
+ AUTH_URL = 'https://vaemoi.auth0.com'.freeze
29
+ VERIFIER = Sysrandom.urlsafe_base64(32)
30
+
31
+ # Provides the user with a means to obtain an authorization code for
32
+ # accessing rev's api by opening a browser to our Auth0 login page
33
+ #
34
+ # @return [nil]
35
+ #
36
+ def self.auth_code_url
37
+ verifier_challenge = Sysrandom.urlsafe_base64(
38
+ Digest::SHA256.new.update(VERIFIER).digest.to_i
39
+ )
40
+
41
+ auth_code_url = AUTH_URL +
42
+ '/authorize?response_type=code&scope=openid%20profile' \
43
+ '&client_id=' + AUTH_CLIENT_ID +
44
+ '&redirect_uri=' + AUTH_CALLBACK_URL +
45
+ '&code_challenge=' + verifier_challenge +
46
+ '&code_challenge_method=S256'
47
+
48
+ auth_code_url
49
+ end
50
+
51
+ # Exchanges the auth code obtained for a token used to access rev's api
52
+ #
53
+ # @param auth_code [String] The auth code obtained from logging in
54
+ #
55
+ # @return [String] The auth token used for accessing rev's api
56
+ #
57
+ def self.auth_token(auth_code)
58
+ auth_token_uri = URI.parse('https://vaemoi.auth0.com/oauth/token')
59
+ body = {
60
+ grant_type: 'authorization_code',
61
+ client_id: AUTH_CLIENT_ID,
62
+ code_verifier: VERIFIER,
63
+ code: auth_code,
64
+ redirect_uri: AUTH_CALLBACK_URL
65
+ }
66
+ http = Net::HTTP.new(auth_token_uri.host, auth_token_uri.port)
67
+ http.use_ssl = true
68
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
69
+ req = Net::HTTP::Post.new(auth_token_uri)
70
+ req.content_type = 'application/json'
71
+ req.body = body.to_json
72
+
73
+ res = http.request(req)
74
+ token = {}
75
+ token[:access_token] = JSON.parse(res.body)['access_token']
76
+ token[:auth0_id] = JSON.parse(res.body)['id_token']
77
+ token[:expires] = Time.now.to_i + JSON.parse(res.body)['expires'].to_i
78
+
79
+ token
80
+ end
81
+
82
+ # Checks if the user has an Authentication token for accessing the API
83
+ #
84
+ # @return [Bool] true if token found
85
+ # raises an exception otherwise
86
+ def self.logged_in
87
+ if AUTH_STORE_ACCESS_TOKEN.nil? || AUTH_STORE_ACCESS_TOKEN.empty?
88
+ raise Reivt::LoginException
89
+ end
90
+
91
+ true
92
+ end
93
+ end
94
+ end
data/lib/reivt/cli.rb CHANGED
@@ -1,167 +1,167 @@
1
- # rubocop: disable Metrics/AbcSize, Metrics/MethodLength, Metrics/ClassLength
2
- require 'paint'
3
- require 'thor'
4
- require 'tty-spinner'
5
-
6
- #
7
- # An extension of our main module
8
- #
9
- # @author [brwnrclse]
10
- #
11
- module Reivt
12
- #
13
- # Rev's cli
14
- #
15
- # @author [brwnrclse]
16
- #
17
- class CLI < Thor
18
- namespace :revit
19
-
20
- map %w(--version -v) => :__print_version
21
- desc '--version, -v', 'print the version'
22
- def __print_version
23
- puts VERSION
24
- end
25
-
26
- method_option :description, type: :string, aliases: '-d', lazy_default: '',
27
- desc: 'A short summary of the changes'
28
- method_option :list_files, type: :array, aliases: '-l',
29
- desc: 'A list of files to add to the rev'
30
- method_option :title, type: :string, aliases: '-t', lazy_default: '',
31
- desc: 'A title for the rev'
32
- desc 'create PATH', 'Make a new rev and populate with documents'
33
- long_desc <<-LONGDESC
34
- `Initiates a flow for creating a new rev. To bypass the prompts users can use the provided flags.
35
- If using git the title, description and files will be retrieved from git via the git repo name, latest commit msg and latest commit file list respectively.
36
-
37
- `revit create ./Bucket/repo` # Create a new rev from the provided path
38
- `revit create ./Bucket/repo --title, -t "Test Repo"` # Create a new revo with a title of Test Repo
39
- `revit create ./Bucket/repo --description, -d "A test repo."` # Create a new revo with a description of "a test repo"
40
- `revit create ./Bucket/repo --list_files, -l ~/Bucket/oneoffs/help.js` # Create a new rev with a list of files, ignoring the current folder
41
- LONGDESC
42
- def create(path)
43
- doc_set = Set.new
44
- doc_ids = Set.new
45
- paths = path.split
46
- paths += options[:list_files] if options[:list_files]
47
- rev_id = nil
48
- spinner = TTY::Spinner.new('[:spinner] :msg', format: :bouncing_ball)
49
-
50
- Reivt::Auth.logged_in
51
-
52
- spinner.update(msg: 'Creating a rev...')
53
- spinner.run do
54
- rev_id = RevAPI.create_rev(options[:title], options[:description])
55
- end
56
- spinner.success(Paint['rev created', :green])
57
-
58
- paths.each do |x|
59
- type = File.exist?(x) ? File.ftype(x) : 'other'
60
-
61
- if type == 'file'
62
- spinner.update(msg: "#{Paint['Adding', nil, '#e3b505']} #{x}")
63
- spinner.run do
64
- doc_set.add(Util.doc_from_path(x))
65
- end
66
- spinner.success(Paint['document created', :green])
67
- elsif type == 'directory'
68
- spinner.update(msg: "#{Paint['Adding', nil, '#e3b505']} docs from " \
69
- "#{Paint[path, '#2de1fc']}")
70
-
71
- if Dir.entries(x).include?('.git')
72
- spinner.run do
73
- doc_set.merge(Util.docs_from_repo(x, spinner))
74
- end
75
- spinner.success(Paint['repo docs created', :green])
76
- else
77
- spinner.run do
78
- doc_set.merge(Util.docs_from_dir(x))
79
- end
80
- spinner.success(Paint['dir docs created', :green])
81
- end
82
- else
83
- spinner.error("#{Paint['Unsupported file type:']} #{path}")
84
- end
85
- end
86
-
87
- spinner.update(msg: 'Uploading docs to rev api')
88
- spinner.run do
89
- doc_set.each do |doc|
90
- doc_id = RevAPI.create_doc(doc.blob, doc.content_type, doc.doc_name,
91
- doc.has_diff, rev_id)
92
- doc_ids.add(doc_id)
93
- end
94
- end
95
- spinner.success(Paint['docs uploaded to api', :green])
96
-
97
- Reivt::LOGGER.info(
98
- "Login at #{Paint['wver.vaemoi.co/home', :green]} to start your rev!"
99
- )
100
- rescue Errno::ECONNRESET, Errno::EINVAL, EOFError, Net::HTTPBadResponse,
101
- Net::HTTPHeaderSyntaxError, Net::OpenTimeout, Net::ProtocolError,
102
- Reivt::BaemptyException, Reivt::GraphQLDataException,
103
- Reivt::GraphQLValidationException => e
104
-
105
- Reivt::DEVLOGGER.error(e.message)
106
- Reivt::LOGGER.error(e.message)
107
-
108
- unless doc_ids.empty?
109
- doc_ids.each do |id|
110
- RevAPI.delete_doc(id)
111
- end
112
- end
113
-
114
- unless rev_id.nil?
115
- RevAPI.delete_rev(rev_id) unless rev_id.nil?
116
- end
117
- Reivt::LOGGER.info('Done!')
118
- end
119
-
120
- desc 'login', 'Get an auth token for accessing the rev api'
121
- long_desc <<-LONGDESC
122
- Sends a request for a valid auth token (jwt) to use for accessing the API.
123
- Refresh is handled automatically as along as the user keeps on using rev otherwise it'll expire after about a week.
124
-
125
- `rev login --username brwnrclse`
126
-
127
- `rev login -u brwnrclse`
128
- LONGDESC
129
- def login
130
- Reivt::LOGGER.info('Login here for your token:')
131
- Reivt::LOGGER.info(Paint[Auth.auth_code_url, :green])
132
-
133
- auth_code = Thor::Shell::Basic.new.ask("\nEnter your auth code => ")
134
- spinner = TTY::Spinner.new('[:spinner] :msg', format: :bouncing_ball)
135
-
136
- spinner.update(msg: 'Logging in')
137
- spinner.run do
138
- begin
139
- auth_token = Auth.auth_token(auth_code)
140
- user_id = RevAPI.signin_user(auth_token[:auth0_id])
141
-
142
- if user_id.nil?
143
- spinner.update(msg: 'User not found! Creating...')
144
- user_id = RevAPI.create_user(auth_token[:auth0_id])
145
- spinner.success(Paint['User created', :green])
146
- end
147
-
148
- Reivt::REIVT_STORE.transaction do |store|
149
- store[:access_token] = auth_token[:access_token].strip
150
- store[:expires] = auth_token[:expires]
151
- store[:auth0_id] = auth_token[:auth0_id].strip
152
- store[:user_id] = user_id
153
- end
154
- spinner.success(Paint['Login successful :)', :green])
155
- rescue Errno::ECONNRESET, Errno::EINVAL, EOFError,
156
- Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
157
- Net::OpenTimeout, Net::ProtocolError,
158
- Reivt::GraphQLDataException,
159
- Reivt::GraphQLValidationException => e
160
-
161
- Reivt::DEVLOGGER.error(e.message)
162
- Reivt::DEVLOGGER.error(e.message)
163
- end
164
- end
165
- end
166
- end
167
- end
1
+ # rubocop: disable Metrics/AbcSize, Metrics/MethodLength, Metrics/ClassLength
2
+ require 'paint'
3
+ require 'thor'
4
+ require 'tty-spinner'
5
+
6
+ #
7
+ # An extension of our main module
8
+ #
9
+ # @author [brwnrclse]
10
+ #
11
+ module Reivt
12
+ #
13
+ # Rev's cli
14
+ #
15
+ # @author [brwnrclse]
16
+ #
17
+ class CLI < Thor
18
+ namespace :revit
19
+
20
+ map %w(--version -v) => :__print_version
21
+ desc '--version, -v', 'print the version'
22
+ def __print_version
23
+ puts VERSION
24
+ end
25
+
26
+ method_option :description, type: :string, aliases: '-d', lazy_default: '',
27
+ desc: 'A short summary of the changes'
28
+ method_option :list_files, type: :array, aliases: '-l',
29
+ desc: 'A list of files to add to the rev'
30
+ method_option :title, type: :string, aliases: '-t', lazy_default: '',
31
+ desc: 'A title for the rev'
32
+ desc 'create PATH', 'Make a new rev and populate with documents'
33
+ long_desc <<-LONGDESC
34
+ `Initiates a flow for creating a new rev. To bypass the prompts users can use the provided flags.
35
+ If using git the title, description and files will be retrieved from git via the git repo name, latest commit msg and latest commit file list respectively.
36
+
37
+ `revit create ./Bucket/repo` # Create a new rev from the provided path
38
+ `revit create ./Bucket/repo --title, -t "Test Repo"` # Create a new revo with a title of Test Repo
39
+ `revit create ./Bucket/repo --description, -d "A test repo."` # Create a new revo with a description of "a test repo"
40
+ `revit create ./Bucket/repo --list_files, -l ~/Bucket/oneoffs/help.js` # Create a new rev with a list of files, ignoring the current folder
41
+ LONGDESC
42
+ def create(path)
43
+ doc_set = Set.new
44
+ doc_ids = Set.new
45
+ paths = path.split
46
+ paths += options[:list_files] if options[:list_files]
47
+ rev_id = nil
48
+ spinner = TTY::Spinner.new('[:spinner] :msg', format: :bouncing_ball)
49
+
50
+ Reivt::Auth.logged_in
51
+
52
+ spinner.update(msg: 'Creating a rev...')
53
+ spinner.run do
54
+ rev_id = RevAPI.create_rev(options[:title], options[:description])
55
+ end
56
+ spinner.success(Paint['rev created', :green])
57
+
58
+ paths.each do |x|
59
+ type = File.exist?(x) ? File.ftype(x) : 'other'
60
+
61
+ if type == 'file'
62
+ spinner.update(msg: "#{Paint['Adding', nil, '#e3b505']} #{x}")
63
+ spinner.run do
64
+ doc_set.add(Util.doc_from_path(x))
65
+ end
66
+ spinner.success(Paint['document created', :green])
67
+ elsif type == 'directory'
68
+ spinner.update(msg: "#{Paint['Adding', nil, '#e3b505']} docs from " \
69
+ "#{Paint[path, '#2de1fc']}")
70
+
71
+ if Dir.entries(x).include?('.git')
72
+ spinner.run do
73
+ doc_set.merge(Util.docs_from_repo(x, spinner))
74
+ end
75
+ spinner.success(Paint['repo docs created', :green])
76
+ else
77
+ spinner.run do
78
+ doc_set.merge(Util.docs_from_dir(x))
79
+ end
80
+ spinner.success(Paint['dir docs created', :green])
81
+ end
82
+ else
83
+ spinner.error("#{Paint['Unsupported file type:']} #{path}")
84
+ end
85
+ end
86
+
87
+ spinner.update(msg: 'Uploading docs to rev api')
88
+ spinner.run do
89
+ doc_set.each do |doc|
90
+ doc_id = RevAPI.create_doc(doc.blob, doc.content_type, doc.doc_name,
91
+ doc.has_diff, rev_id)
92
+ doc_ids.add(doc_id)
93
+ end
94
+ end
95
+ spinner.success(Paint['docs uploaded to api', :green])
96
+
97
+ Reivt::LOGGER.info(
98
+ "Login at #{Paint['wver.vaemoi.co/home', :green]} to start your rev!"
99
+ )
100
+ rescue Errno::ECONNRESET, Errno::EINVAL, EOFError, Net::HTTPBadResponse,
101
+ Net::HTTPHeaderSyntaxError, Net::OpenTimeout, Net::ProtocolError,
102
+ Reivt::BaemptyException, Reivt::GraphQLDataException,
103
+ Reivt::GraphQLValidationException => e
104
+
105
+ Reivt::DEVLOGGER.error(e.message)
106
+ Reivt::LOGGER.error(e.message)
107
+
108
+ unless doc_ids.empty?
109
+ doc_ids.each do |id|
110
+ RevAPI.delete_doc(id)
111
+ end
112
+ end
113
+
114
+ unless rev_id.nil?
115
+ RevAPI.delete_rev(rev_id) unless rev_id.nil?
116
+ end
117
+ Reivt::LOGGER.info('Done!')
118
+ end
119
+
120
+ desc 'login', 'Get an auth token for accessing the rev api'
121
+ long_desc <<-LONGDESC
122
+ Sends a request for a valid auth token (jwt) to use for accessing the API.
123
+ Refresh is handled automatically as along as the user keeps on using rev otherwise it'll expire after about a week.
124
+
125
+ `rev login --username brwnrclse`
126
+
127
+ `rev login -u brwnrclse`
128
+ LONGDESC
129
+ def login
130
+ Reivt::LOGGER.info('Login here for your token:')
131
+ Reivt::LOGGER.info(Paint[Auth.auth_code_url, :green])
132
+
133
+ auth_code = Thor::Shell::Basic.new.ask("\nEnter your auth code => ")
134
+ spinner = TTY::Spinner.new('[:spinner] :msg', format: :bouncing_ball)
135
+
136
+ spinner.update(msg: 'Logging in')
137
+ spinner.run do
138
+ begin
139
+ auth_token = Auth.auth_token(auth_code)
140
+ user_id = RevAPI.signin_user(auth_token[:auth0_id])
141
+
142
+ if user_id.nil?
143
+ spinner.update(msg: 'User not found! Creating...')
144
+ user_id = RevAPI.create_user(auth_token[:auth0_id])
145
+ spinner.success(Paint['User created', :green])
146
+ end
147
+
148
+ Reivt::REIVT_STORE.transaction do |store|
149
+ store[:access_token] = auth_token[:access_token].strip
150
+ store[:expires] = auth_token[:expires]
151
+ store[:auth0_id] = auth_token[:auth0_id].strip
152
+ store[:user_id] = user_id
153
+ end
154
+ spinner.success(Paint['Login successful :)', :green])
155
+ rescue Errno::ECONNRESET, Errno::EINVAL, EOFError,
156
+ Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
157
+ Net::OpenTimeout, Net::ProtocolError,
158
+ Reivt::GraphQLDataException,
159
+ Reivt::GraphQLValidationException => e
160
+
161
+ Reivt::DEVLOGGER.error(e.message)
162
+ Reivt::DEVLOGGER.error(e.message)
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end