vortex-ruby-sdk 1.0.0 → 1.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 +4 -4
- data/README.md +64 -21
- data/examples/basic_usage.rb +19 -13
- data/examples/rails_app.rb +10 -11
- data/examples/sinatra_app.rb +10 -11
- data/lib/vortex/client.rb +39 -15
- data/lib/vortex/rails.rb +56 -7
- data/lib/vortex/types.rb +74 -0
- data/lib/vortex/version.rb +1 -1
- metadata +7 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e7f6c2f423b5aa8099f7ccce759daaf6dcdd114c6052f1ffb9d9f5072d505916
|
|
4
|
+
data.tar.gz: 46755e0df9a92907219042a2f2373f6f067aa46f57a1409159cc215ae14823f3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 55c8a0671bcad40614d75363ef1b0aaf7b2323f47e9dd717940f59fd026b449c64d79b6c7b9bbed6493199c4c3d1beaac97c3e728409407339bb41363c93b1f9
|
|
7
|
+
data.tar.gz: fcce54f801ef8115f7567cded83704409fb8436f34056aa296c77210099e0519dd59d8b51f29ff8eb05669acefb088e5cdf4a8a7f2603033f84de1767192b025
|
data/README.md
CHANGED
|
@@ -5,6 +5,8 @@ A Ruby SDK for the Vortex invitation system, providing seamless integration with
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- **JWT Generation**: Identical algorithm to other SDKs for complete compatibility
|
|
8
|
+
- **Simplified JWT Format**: New streamlined payload with `userEmail` and `adminScopes`
|
|
9
|
+
- **Backward Compatible**: Legacy JWT format still supported
|
|
8
10
|
- **Complete API Coverage**: All invitation management operations
|
|
9
11
|
- **Framework Integration**: Built-in Rails and Sinatra helpers
|
|
10
12
|
- **Same Route Structure**: Ensures React provider compatibility
|
|
@@ -39,13 +41,15 @@ require 'vortex'
|
|
|
39
41
|
# Initialize the client
|
|
40
42
|
client = Vortex::Client.new(ENV['VORTEX_API_KEY'])
|
|
41
43
|
|
|
42
|
-
#
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
# Create a user object
|
|
45
|
+
user = {
|
|
46
|
+
id: 'user-123',
|
|
47
|
+
email: 'user@example.com',
|
|
48
|
+
admin_scopes: ['autojoin'] # Optional - included as adminScopes array in JWT
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
# Generate JWT
|
|
52
|
+
jwt = client.generate_jwt(user: user)
|
|
49
53
|
|
|
50
54
|
# Get invitations by target
|
|
51
55
|
invitations = client.get_invitations_by_target('email', 'user@example.com')
|
|
@@ -57,6 +61,22 @@ client.accept_invitations(['inv1', 'inv2'], { type: 'email', value: 'user@exampl
|
|
|
57
61
|
group_invitations = client.get_invitations_by_group('team', 'team1')
|
|
58
62
|
```
|
|
59
63
|
|
|
64
|
+
### Generate JWT with Additional Properties
|
|
65
|
+
|
|
66
|
+
```ruby
|
|
67
|
+
user = {
|
|
68
|
+
id: 'user-123',
|
|
69
|
+
email: 'user@example.com'
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
extra = {
|
|
73
|
+
role: 'admin',
|
|
74
|
+
department: 'Engineering'
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
jwt = client.generate_jwt(user: user, extra: extra)
|
|
78
|
+
```
|
|
79
|
+
|
|
60
80
|
## Rails Integration
|
|
61
81
|
|
|
62
82
|
Create a controller with Vortex routes:
|
|
@@ -70,13 +90,13 @@ class VortexController < ApplicationController
|
|
|
70
90
|
|
|
71
91
|
def authenticate_vortex_user
|
|
72
92
|
# Return user data hash or nil
|
|
93
|
+
admin_scopes = []
|
|
94
|
+
admin_scopes << 'autojoin' if current_user.admin?
|
|
95
|
+
|
|
73
96
|
{
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
{ id: team.id, type: 'team', name: team.name }
|
|
78
|
-
},
|
|
79
|
-
role: current_user.role
|
|
97
|
+
id: current_user.id,
|
|
98
|
+
email: current_user.email,
|
|
99
|
+
admin_scopes: admin_scopes
|
|
80
100
|
}
|
|
81
101
|
end
|
|
82
102
|
|
|
@@ -86,7 +106,7 @@ class VortexController < ApplicationController
|
|
|
86
106
|
when 'JWT', 'GET_INVITATIONS'
|
|
87
107
|
true
|
|
88
108
|
when 'REVOKE_INVITATION'
|
|
89
|
-
user[:
|
|
109
|
+
user[:admin_scopes]&.include?('autojoin')
|
|
90
110
|
else
|
|
91
111
|
false
|
|
92
112
|
end
|
|
@@ -134,10 +154,9 @@ class MyApp < Sinatra::Base
|
|
|
134
154
|
return nil unless user_id
|
|
135
155
|
|
|
136
156
|
{
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
role: 'user'
|
|
157
|
+
id: user_id,
|
|
158
|
+
email: 'user@example.com',
|
|
159
|
+
admin_scopes: [] # Optional
|
|
141
160
|
}
|
|
142
161
|
end
|
|
143
162
|
|
|
@@ -153,9 +172,13 @@ end
|
|
|
153
172
|
All methods match the functionality of other Vortex SDKs:
|
|
154
173
|
|
|
155
174
|
### JWT Generation
|
|
156
|
-
|
|
175
|
+
|
|
176
|
+
- `generate_jwt(user:, extra: nil)` - Generate JWT token
|
|
177
|
+
- `user`: Hash with `:id`, `:email`, and optional `:admin_scopes` array
|
|
178
|
+
- `extra`: Optional hash with additional properties to include in JWT payload
|
|
157
179
|
|
|
158
180
|
### Invitation Management
|
|
181
|
+
|
|
159
182
|
- `get_invitations_by_target(target_type, target_value)` - Get invitations by target
|
|
160
183
|
- `get_invitation(invitation_id)` - Get specific invitation
|
|
161
184
|
- `revoke_invitation(invitation_id)` - Revoke invitation
|
|
@@ -177,13 +200,33 @@ The SDK provides these routes (same as other SDKs for React provider compatibili
|
|
|
177
200
|
- `DELETE /api/vortex/invitations/by-group/:type/:id`
|
|
178
201
|
- `POST /api/vortex/invitations/:id/reinvite`
|
|
179
202
|
|
|
203
|
+
## JWT Payload Structure
|
|
204
|
+
|
|
205
|
+
The SDK generates JWTs with the following payload structure:
|
|
206
|
+
|
|
207
|
+
```ruby
|
|
208
|
+
{
|
|
209
|
+
userId: 'user-123',
|
|
210
|
+
userEmail: 'user@example.com',
|
|
211
|
+
adminScopes: ['autojoin'], # Full array included if admin_scopes provided
|
|
212
|
+
expires: 1234567890
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Additional properties from the `extra` parameter are merged into the payload.
|
|
217
|
+
|
|
180
218
|
## Error Handling
|
|
181
219
|
|
|
182
220
|
All methods raise `Vortex::VortexError` on failures:
|
|
183
221
|
|
|
184
222
|
```ruby
|
|
185
223
|
begin
|
|
186
|
-
jwt = client.generate_jwt(
|
|
224
|
+
jwt = client.generate_jwt(
|
|
225
|
+
user: {
|
|
226
|
+
id: 'user-123',
|
|
227
|
+
email: 'user@example.com'
|
|
228
|
+
}
|
|
229
|
+
)
|
|
187
230
|
rescue Vortex::VortexError => e
|
|
188
231
|
logger.error "Vortex error: #{e.message}"
|
|
189
232
|
end
|
|
@@ -201,4 +244,4 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/vortex
|
|
|
201
244
|
|
|
202
245
|
## License
|
|
203
246
|
|
|
204
|
-
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
247
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/examples/basic_usage.rb
CHANGED
|
@@ -13,29 +13,35 @@ require 'vortex'
|
|
|
13
13
|
API_KEY = ENV['VORTEX_API_KEY'] || 'your-api-key-here'
|
|
14
14
|
client = Vortex::Client.new(API_KEY)
|
|
15
15
|
|
|
16
|
-
# Example user data
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
16
|
+
# Example user data
|
|
17
|
+
user = {
|
|
18
|
+
id: 'user123',
|
|
19
|
+
email: 'user@example.com',
|
|
20
|
+
admin_scopes: ['autojoin'] # Optional - included as adminScopes array in JWT
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
# Additional properties (optional)
|
|
24
|
+
extra = {
|
|
25
|
+
role: 'admin',
|
|
26
|
+
department: 'Engineering'
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
begin
|
|
30
30
|
puts "=== Vortex Ruby SDK Example ==="
|
|
31
31
|
puts
|
|
32
32
|
|
|
33
|
-
# 1. Generate JWT
|
|
33
|
+
# 1. Generate JWT for user
|
|
34
34
|
puts "1. Generating JWT for user..."
|
|
35
|
-
jwt = client.generate_jwt(
|
|
35
|
+
jwt = client.generate_jwt(user: user)
|
|
36
36
|
puts "JWT generated: #{jwt[0..50]}..."
|
|
37
37
|
puts
|
|
38
38
|
|
|
39
|
+
# 1b. Generate JWT with additional properties
|
|
40
|
+
puts "1b. Generating JWT with additional properties..."
|
|
41
|
+
jwt_with_extra = client.generate_jwt(user: user, extra: extra)
|
|
42
|
+
puts "JWT with extra generated: #{jwt_with_extra[0..50]}..."
|
|
43
|
+
puts
|
|
44
|
+
|
|
39
45
|
# 2. Get invitations by target
|
|
40
46
|
puts "2. Getting invitations by email target..."
|
|
41
47
|
invitations = client.get_invitations_by_target('email', 'user@example.com')
|
data/examples/rails_app.rb
CHANGED
|
@@ -32,16 +32,15 @@ class VortexController < ActionController::Base
|
|
|
32
32
|
user_id = session[:user_id] || request.headers['X-User-ID']
|
|
33
33
|
return nil unless user_id
|
|
34
34
|
|
|
35
|
-
#
|
|
35
|
+
# Build admin_scopes array
|
|
36
|
+
admin_scopes = []
|
|
37
|
+
admin_scopes << 'autojoin' if session[:user_role] == 'admin'
|
|
38
|
+
|
|
39
|
+
# Return user data
|
|
36
40
|
{
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
],
|
|
41
|
-
groups: [
|
|
42
|
-
{ id: 'team1', type: 'team', name: 'Engineering' }
|
|
43
|
-
],
|
|
44
|
-
role: session[:user_role] || 'user'
|
|
41
|
+
id: user_id,
|
|
42
|
+
email: session[:user_email] || 'user@example.com',
|
|
43
|
+
admin_scopes: admin_scopes
|
|
45
44
|
}
|
|
46
45
|
end
|
|
47
46
|
|
|
@@ -56,9 +55,9 @@ class VortexController < ActionController::Base
|
|
|
56
55
|
when 'ACCEPT_INVITATIONS'
|
|
57
56
|
true # Everyone can accept invitations
|
|
58
57
|
when 'REVOKE_INVITATION', 'DELETE_GROUP_INVITATIONS'
|
|
59
|
-
user[:
|
|
58
|
+
user[:admin_scopes]&.include?('autojoin') # Only admins can delete
|
|
60
59
|
when 'GET_GROUP_INVITATIONS', 'REINVITE'
|
|
61
|
-
user[:
|
|
60
|
+
user[:admin_scopes]&.include?('autojoin') # Only admins can manage groups
|
|
62
61
|
else
|
|
63
62
|
false
|
|
64
63
|
end
|
data/examples/sinatra_app.rb
CHANGED
|
@@ -25,16 +25,15 @@ class VortexSinatraApp < Sinatra::Base
|
|
|
25
25
|
user_id = request.env['HTTP_X_USER_ID'] || 'demo-user'
|
|
26
26
|
return nil unless user_id
|
|
27
27
|
|
|
28
|
-
#
|
|
28
|
+
# Build admin_scopes array
|
|
29
|
+
admin_scopes = []
|
|
30
|
+
admin_scopes << 'autojoin' if request.env['HTTP_X_USER_ROLE'] == 'admin'
|
|
31
|
+
|
|
32
|
+
# Return user data
|
|
29
33
|
{
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
],
|
|
34
|
-
groups: [
|
|
35
|
-
{ id: 'team1', type: 'team', name: 'Engineering' }
|
|
36
|
-
],
|
|
37
|
-
role: request.env['HTTP_X_USER_ROLE'] || 'user'
|
|
34
|
+
id: user_id,
|
|
35
|
+
email: request.env['HTTP_X_USER_EMAIL'] || 'demo@example.com',
|
|
36
|
+
admin_scopes: admin_scopes
|
|
38
37
|
}
|
|
39
38
|
end
|
|
40
39
|
|
|
@@ -48,9 +47,9 @@ class VortexSinatraApp < Sinatra::Base
|
|
|
48
47
|
when 'ACCEPT_INVITATIONS'
|
|
49
48
|
true # Everyone can accept invitations
|
|
50
49
|
when 'REVOKE_INVITATION', 'DELETE_GROUP_INVITATIONS'
|
|
51
|
-
user[:
|
|
50
|
+
user[:admin_scopes]&.include?('autojoin') # Only admins can delete
|
|
52
51
|
when 'GET_GROUP_INVITATIONS', 'REINVITE'
|
|
53
|
-
user[:
|
|
52
|
+
user[:admin_scopes]&.include?('autojoin') # Only admins can manage groups
|
|
54
53
|
else
|
|
55
54
|
false
|
|
56
55
|
end
|
data/lib/vortex/client.rb
CHANGED
|
@@ -23,18 +23,31 @@ module Vortex
|
|
|
23
23
|
@connection = build_connection
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
# Generate a JWT for
|
|
26
|
+
# Generate a JWT token for a user
|
|
27
27
|
#
|
|
28
|
-
#
|
|
29
|
-
# complete compatibility across all platforms.
|
|
30
|
-
#
|
|
31
|
-
# @param user_id [String] Unique identifier for the user
|
|
32
|
-
# @param identifiers [Array<Hash>] Array of identifier hashes with :type and :value
|
|
33
|
-
# @param groups [Array<Hash>] Array of group hashes with :id, :type, and :name
|
|
34
|
-
# @param role [String, nil] Optional user role
|
|
28
|
+
# @param params [Hash] JWT parameters with :user (required) and optional :attributes
|
|
35
29
|
# @return [String] JWT token
|
|
36
30
|
# @raise [VortexError] If API key is invalid or JWT generation fails
|
|
37
|
-
|
|
31
|
+
#
|
|
32
|
+
# @example Simple usage
|
|
33
|
+
# client = Vortex::Client.new(ENV['VORTEX_API_KEY'])
|
|
34
|
+
# jwt = client.generate_jwt({
|
|
35
|
+
# user: {
|
|
36
|
+
# id: 'user-123',
|
|
37
|
+
# email: 'user@example.com',
|
|
38
|
+
# admin_scopes: ['autojoin']
|
|
39
|
+
# }
|
|
40
|
+
# })
|
|
41
|
+
#
|
|
42
|
+
# @example With additional attributes
|
|
43
|
+
# jwt = client.generate_jwt({
|
|
44
|
+
# user: { id: 'user-123', email: 'user@example.com' },
|
|
45
|
+
# attributes: { role: 'admin', department: 'Engineering' }
|
|
46
|
+
# })
|
|
47
|
+
def generate_jwt(params)
|
|
48
|
+
user = params[:user]
|
|
49
|
+
attributes = params[:attributes]
|
|
50
|
+
|
|
38
51
|
# Parse API key - same format as Node.js SDK
|
|
39
52
|
prefix, encoded_id, key = @api_key.split('.')
|
|
40
53
|
|
|
@@ -52,7 +65,7 @@ module Vortex
|
|
|
52
65
|
# Step 1: Derive signing key from API key + ID (same as Node.js)
|
|
53
66
|
signing_key = OpenSSL::HMAC.digest('sha256', key, id)
|
|
54
67
|
|
|
55
|
-
# Step 2: Build header + payload
|
|
68
|
+
# Step 2: Build header + payload
|
|
56
69
|
header = {
|
|
57
70
|
iat: Time.now.to_i,
|
|
58
71
|
alg: 'HS256',
|
|
@@ -60,14 +73,23 @@ module Vortex
|
|
|
60
73
|
kid: id
|
|
61
74
|
}
|
|
62
75
|
|
|
76
|
+
# Build payload - start with required fields
|
|
63
77
|
payload = {
|
|
64
|
-
userId:
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
expires: expires,
|
|
68
|
-
identifiers: identifiers
|
|
78
|
+
userId: user[:id],
|
|
79
|
+
userEmail: user[:email],
|
|
80
|
+
expires: expires
|
|
69
81
|
}
|
|
70
82
|
|
|
83
|
+
# Add adminScopes if present
|
|
84
|
+
if user[:admin_scopes]
|
|
85
|
+
payload[:adminScopes] = user[:admin_scopes]
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Add any additional properties from attributes
|
|
89
|
+
if attributes && !attributes.empty?
|
|
90
|
+
payload.merge!(attributes)
|
|
91
|
+
end
|
|
92
|
+
|
|
71
93
|
# Step 3: Base64URL encode (same as Node.js)
|
|
72
94
|
header_b64 = base64url_encode(JSON.generate(header))
|
|
73
95
|
payload_b64 = base64url_encode(JSON.generate(payload))
|
|
@@ -81,6 +103,8 @@ module Vortex
|
|
|
81
103
|
raise VortexError, "JWT generation failed: #{e.message}"
|
|
82
104
|
end
|
|
83
105
|
|
|
106
|
+
public
|
|
107
|
+
|
|
84
108
|
# Get invitations by target
|
|
85
109
|
#
|
|
86
110
|
# @param target_type [String] Type of target (email, sms)
|
data/lib/vortex/rails.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'logger'
|
|
3
4
|
require 'vortex/client'
|
|
4
5
|
require 'vortex/error'
|
|
5
6
|
|
|
@@ -28,6 +29,17 @@ module Vortex
|
|
|
28
29
|
# @vortex_client ||= Vortex::Client.new(ENV['VORTEX_API_KEY'])
|
|
29
30
|
# end
|
|
30
31
|
# end
|
|
32
|
+
#
|
|
33
|
+
# Configure logging:
|
|
34
|
+
# Vortex::Rails.logger = MyLogger.new
|
|
35
|
+
class << self
|
|
36
|
+
attr_writer :logger
|
|
37
|
+
|
|
38
|
+
def logger
|
|
39
|
+
@logger ||= defined?(::Rails) ? ::Rails.logger : Logger.new(nil)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
31
43
|
module Controller
|
|
32
44
|
extend ActiveSupport::Concern
|
|
33
45
|
|
|
@@ -39,28 +51,54 @@ module Vortex
|
|
|
39
51
|
# Generate JWT for authenticated user
|
|
40
52
|
# POST /api/vortex/jwt
|
|
41
53
|
def generate_jwt
|
|
54
|
+
Vortex::Rails.logger.debug("Vortex::Rails::Controller#generate_jwt invoked")
|
|
55
|
+
|
|
42
56
|
user = authenticate_vortex_user
|
|
43
57
|
return render_unauthorized('Authentication required') unless user
|
|
44
58
|
|
|
45
59
|
unless authorize_vortex_operation('JWT', user)
|
|
60
|
+
Vortex::Rails.logger.warn("Vortex JWT authorization failed for user #{user[:user_id]}")
|
|
46
61
|
return render_forbidden('Not authorized to generate JWT')
|
|
47
62
|
end
|
|
48
63
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
64
|
+
# Extract email from identifiers for the user hash
|
|
65
|
+
email = user[:identifiers]&.find { |i| i[:type] == 'email' }&.dig(:value)
|
|
66
|
+
|
|
67
|
+
# Build the JWT
|
|
68
|
+
jwt_params = {
|
|
69
|
+
user: {
|
|
70
|
+
id: user[:user_id],
|
|
71
|
+
email: email
|
|
72
|
+
}
|
|
73
|
+
}
|
|
55
74
|
|
|
75
|
+
# Add adminScopes if present
|
|
76
|
+
if user[:admin_scopes]&.any?
|
|
77
|
+
jwt_params[:user][:admin_scopes] = user[:admin_scopes]
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Add attributes if present
|
|
81
|
+
if user[:attributes]
|
|
82
|
+
jwt_params[:attributes] = user[:attributes]
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
jwt = vortex_client.generate_jwt(jwt_params)
|
|
86
|
+
|
|
87
|
+
Vortex::Rails.logger.debug("Vortex JWT generated successfully for user #{user[:user_id]}")
|
|
56
88
|
render json: { jwt: jwt }
|
|
57
89
|
rescue Vortex::VortexError => e
|
|
90
|
+
Vortex::Rails.logger.error("Vortex error generating JWT: #{e.message}")
|
|
58
91
|
render_server_error("Failed to generate JWT: #{e.message}")
|
|
92
|
+
rescue StandardError => e
|
|
93
|
+
Vortex::Rails.logger.error("Unexpected error generating JWT: #{e.class} - #{e.message}")
|
|
94
|
+
render_server_error("Unexpected error: #{e.message}")
|
|
59
95
|
end
|
|
60
96
|
|
|
61
97
|
# Get invitations by target
|
|
62
98
|
# GET /api/vortex/invitations?targetType=email&targetValue=user@example.com
|
|
63
99
|
def get_invitations_by_target
|
|
100
|
+
Vortex::Rails.logger.debug("Vortex::Rails::Controller#get_invitations_by_target invoked")
|
|
101
|
+
|
|
64
102
|
user = authenticate_vortex_user
|
|
65
103
|
return render_unauthorized('Authentication required') unless user
|
|
66
104
|
|
|
@@ -82,6 +120,8 @@ module Vortex
|
|
|
82
120
|
# Get specific invitation by ID
|
|
83
121
|
# GET /api/vortex/invitations/:invitation_id
|
|
84
122
|
def get_invitation
|
|
123
|
+
Vortex::Rails.logger.debug("Vortex::Rails::Controller#get_invitation invoked")
|
|
124
|
+
|
|
85
125
|
user = authenticate_vortex_user
|
|
86
126
|
return render_unauthorized('Authentication required') unless user
|
|
87
127
|
|
|
@@ -99,6 +139,8 @@ module Vortex
|
|
|
99
139
|
# Revoke (delete) invitation
|
|
100
140
|
# DELETE /api/vortex/invitations/:invitation_id
|
|
101
141
|
def revoke_invitation
|
|
142
|
+
Vortex::Rails.logger.debug("Vortex::Rails::Controller#revoke_invitation invoked")
|
|
143
|
+
|
|
102
144
|
user = authenticate_vortex_user
|
|
103
145
|
return render_unauthorized('Authentication required') unless user
|
|
104
146
|
|
|
@@ -116,6 +158,8 @@ module Vortex
|
|
|
116
158
|
# Accept invitations
|
|
117
159
|
# POST /api/vortex/invitations/accept
|
|
118
160
|
def accept_invitations
|
|
161
|
+
Vortex::Rails.logger.debug("Vortex::Rails::Controller#accept_invitations invoked")
|
|
162
|
+
|
|
119
163
|
user = authenticate_vortex_user
|
|
120
164
|
return render_unauthorized('Authentication required') unless user
|
|
121
165
|
|
|
@@ -139,6 +183,8 @@ module Vortex
|
|
|
139
183
|
# Get invitations by group
|
|
140
184
|
# GET /api/vortex/invitations/by-group/:group_type/:group_id
|
|
141
185
|
def get_invitations_by_group
|
|
186
|
+
Vortex::Rails.logger.debug("Vortex::Rails::Controller#get_invitations_by_group invoked")
|
|
187
|
+
|
|
142
188
|
user = authenticate_vortex_user
|
|
143
189
|
return render_unauthorized('Authentication required') unless user
|
|
144
190
|
|
|
@@ -158,6 +204,8 @@ module Vortex
|
|
|
158
204
|
# Delete invitations by group
|
|
159
205
|
# DELETE /api/vortex/invitations/by-group/:group_type/:group_id
|
|
160
206
|
def delete_invitations_by_group
|
|
207
|
+
Vortex::Rails.logger.debug("Vortex::Rails::Controller#delete_invitations_by_group invoked")
|
|
208
|
+
|
|
161
209
|
user = authenticate_vortex_user
|
|
162
210
|
return render_unauthorized('Authentication required') unless user
|
|
163
211
|
|
|
@@ -177,6 +225,8 @@ module Vortex
|
|
|
177
225
|
# Reinvite user
|
|
178
226
|
# POST /api/vortex/invitations/:invitation_id/reinvite
|
|
179
227
|
def reinvite
|
|
228
|
+
Vortex::Rails.logger.debug("Vortex::Rails::Controller#reinvite invoked")
|
|
229
|
+
|
|
180
230
|
user = authenticate_vortex_user
|
|
181
231
|
return render_unauthorized('Authentication required') unless user
|
|
182
232
|
|
|
@@ -228,7 +278,6 @@ module Vortex
|
|
|
228
278
|
end
|
|
229
279
|
|
|
230
280
|
def handle_vortex_error(error)
|
|
231
|
-
Rails.logger.error("Vortex error: #{error.message}")
|
|
232
281
|
render_server_error(error.message)
|
|
233
282
|
end
|
|
234
283
|
end
|
data/lib/vortex/types.rb
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Vortex
|
|
4
|
+
# Type documentation for Vortex SDK responses
|
|
5
|
+
# Ruby uses dynamic typing with Hashes, but this documents the expected structure
|
|
6
|
+
module Types
|
|
7
|
+
# Group structure for JWT generation (input)
|
|
8
|
+
# @example
|
|
9
|
+
# {
|
|
10
|
+
# type: 'workspace',
|
|
11
|
+
# id: 'workspace-123', # Legacy field (deprecated, use groupId)
|
|
12
|
+
# groupId: 'workspace-123', # Preferred field
|
|
13
|
+
# name: 'My Workspace'
|
|
14
|
+
# }
|
|
15
|
+
GROUP_INPUT = {
|
|
16
|
+
type: String, # Required: Group type (e.g., "workspace", "team")
|
|
17
|
+
id: String, # Optional: Legacy field (deprecated, use groupId)
|
|
18
|
+
groupId: String, # Optional: Preferred - Customer's group ID
|
|
19
|
+
name: String # Required: Group name
|
|
20
|
+
}.freeze
|
|
21
|
+
|
|
22
|
+
# InvitationGroup structure from API responses
|
|
23
|
+
# This matches the MemberGroups table structure from the API
|
|
24
|
+
# @example
|
|
25
|
+
# {
|
|
26
|
+
# id: '550e8400-e29b-41d4-a716-446655440000',
|
|
27
|
+
# accountId: '6ba7b810-9dad-11d1-80b4-00c04fd430c8',
|
|
28
|
+
# groupId: 'workspace-123',
|
|
29
|
+
# type: 'workspace',
|
|
30
|
+
# name: 'My Workspace',
|
|
31
|
+
# createdAt: '2025-01-27T12:00:00.000Z'
|
|
32
|
+
# }
|
|
33
|
+
INVITATION_GROUP = {
|
|
34
|
+
id: String, # Vortex internal UUID
|
|
35
|
+
accountId: String, # Vortex account ID
|
|
36
|
+
groupId: String, # Customer's group ID (the ID they provided to Vortex)
|
|
37
|
+
type: String, # Group type (e.g., "workspace", "team")
|
|
38
|
+
name: String, # Group name
|
|
39
|
+
createdAt: String # ISO 8601 timestamp when the group was created
|
|
40
|
+
}.freeze
|
|
41
|
+
|
|
42
|
+
# Invitation structure from API responses
|
|
43
|
+
# @example
|
|
44
|
+
# {
|
|
45
|
+
# id: '550e8400-e29b-41d4-a716-446655440000',
|
|
46
|
+
# accountId: '6ba7b810-9dad-11d1-80b4-00c04fd430c8',
|
|
47
|
+
# groups: [INVITATION_GROUP, ...],
|
|
48
|
+
# # ... other fields
|
|
49
|
+
# }
|
|
50
|
+
INVITATION = {
|
|
51
|
+
id: String,
|
|
52
|
+
accountId: String,
|
|
53
|
+
clickThroughs: Integer,
|
|
54
|
+
configurationAttributes: Hash,
|
|
55
|
+
attributes: Hash,
|
|
56
|
+
createdAt: String,
|
|
57
|
+
deactivated: :boolean,
|
|
58
|
+
deliveryCount: Integer,
|
|
59
|
+
deliveryTypes: Array, # of String
|
|
60
|
+
foreignCreatorId: String,
|
|
61
|
+
invitationType: String,
|
|
62
|
+
modifiedAt: String,
|
|
63
|
+
status: String,
|
|
64
|
+
target: Array, # of { type: String, value: String }
|
|
65
|
+
views: Integer,
|
|
66
|
+
widgetConfigurationId: String,
|
|
67
|
+
projectId: String,
|
|
68
|
+
groups: Array, # of INVITATION_GROUP structures
|
|
69
|
+
accepts: Array, # of acceptance structures
|
|
70
|
+
expired: :boolean,
|
|
71
|
+
expires: String # ISO 8601 timestamp (optional)
|
|
72
|
+
}.freeze
|
|
73
|
+
end
|
|
74
|
+
end
|
data/lib/vortex/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: vortex-ruby-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vortex Software
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-12-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
@@ -156,6 +156,7 @@ files:
|
|
|
156
156
|
- lib/vortex/error.rb
|
|
157
157
|
- lib/vortex/rails.rb
|
|
158
158
|
- lib/vortex/sinatra.rb
|
|
159
|
+
- lib/vortex/types.rb
|
|
159
160
|
- lib/vortex/version.rb
|
|
160
161
|
- vortex-ruby-sdk.gemspec
|
|
161
162
|
homepage: https://github.com/vortexsoftware/vortex-ruby-sdk
|
|
@@ -166,7 +167,7 @@ metadata:
|
|
|
166
167
|
homepage_uri: https://github.com/vortexsoftware/vortex-ruby-sdk
|
|
167
168
|
source_code_uri: https://github.com/vortexsoftware/vortex-ruby-sdk
|
|
168
169
|
changelog_uri: https://github.com/vortexsoftware/vortex-ruby-sdk/blob/main/CHANGELOG.md
|
|
169
|
-
post_install_message:
|
|
170
|
+
post_install_message:
|
|
170
171
|
rdoc_options: []
|
|
171
172
|
require_paths:
|
|
172
173
|
- lib
|
|
@@ -181,8 +182,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
181
182
|
- !ruby/object:Gem::Version
|
|
182
183
|
version: '0'
|
|
183
184
|
requirements: []
|
|
184
|
-
rubygems_version: 3.
|
|
185
|
-
signing_key:
|
|
185
|
+
rubygems_version: 3.4.19
|
|
186
|
+
signing_key:
|
|
186
187
|
specification_version: 4
|
|
187
188
|
summary: Ruby SDK for Vortex invitation system
|
|
188
189
|
test_files: []
|