phcdevworks_accounts_stytch 0.1.0.pre.1 → 0.2.0.pre.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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +43 -4
  3. data/app/controllers/concerns/error_handler.rb +19 -0
  4. data/app/controllers/concerns/handle_service_action.rb +17 -0
  5. data/app/controllers/concerns/organization_setter.rb +11 -0
  6. data/app/controllers/phcdevworks_accounts_stytch/b2b/authenticate_controller.rb +81 -0
  7. data/app/controllers/phcdevworks_accounts_stytch/b2b/magic_links_controller.rb +57 -0
  8. data/app/controllers/phcdevworks_accounts_stytch/b2b/passwords_controller.rb +95 -0
  9. data/app/controllers/phcdevworks_accounts_stytch/b2c/authenticate_controller.rb +99 -0
  10. data/app/controllers/phcdevworks_accounts_stytch/b2c/magic_links_controller.rb +90 -0
  11. data/app/controllers/phcdevworks_accounts_stytch/b2c/passwords_controller.rb +94 -0
  12. data/app/views/layouts/phcdevworks_accounts_stytch/application.html.erb +2 -0
  13. data/app/views/phcdevworks_accounts_stytch/b2b/magic_links/invite.html.erb +12 -0
  14. data/app/views/phcdevworks_accounts_stytch/b2b/magic_links/login_or_signup.html.erb +12 -0
  15. data/app/views/phcdevworks_accounts_stytch/b2b/passwords/reset_existing_password.html.erb +22 -0
  16. data/app/views/phcdevworks_accounts_stytch/b2b/passwords/reset_password.html.erb +17 -0
  17. data/app/views/phcdevworks_accounts_stytch/b2b/passwords/reset_start.html.erb +12 -0
  18. data/app/views/phcdevworks_accounts_stytch/b2b/passwords/reset_with_session.html.erb +17 -0
  19. data/app/views/phcdevworks_accounts_stytch/b2c/magic_links/invite.html.erb +12 -0
  20. data/app/views/phcdevworks_accounts_stytch/b2c/magic_links/login_or_signup.html.erb +12 -0
  21. data/app/views/phcdevworks_accounts_stytch/b2c/passwords/reset_existing_password.html.erb +22 -0
  22. data/app/views/phcdevworks_accounts_stytch/b2c/passwords/reset_password.html.erb +17 -0
  23. data/app/views/phcdevworks_accounts_stytch/b2c/passwords/reset_start.html.erb +12 -0
  24. data/app/views/phcdevworks_accounts_stytch/b2c/passwords/reset_with_session.html.erb +17 -0
  25. data/config/routes/b2b.rb +30 -0
  26. data/config/routes/b2c.rb +27 -0
  27. data/config/routes.rb +2 -4
  28. data/lib/phcdevworks_accounts_stytch/authentication/b2b/magic_link_service.rb +63 -0
  29. data/lib/phcdevworks_accounts_stytch/authentication/b2b/password_service.rb +80 -0
  30. data/lib/phcdevworks_accounts_stytch/authentication/b2c/magic_link_service.rb +55 -0
  31. data/lib/phcdevworks_accounts_stytch/authentication/b2c/password_service.rb +76 -0
  32. data/lib/phcdevworks_accounts_stytch/engine.rb +6 -0
  33. data/lib/phcdevworks_accounts_stytch/stytch/client.rb +45 -0
  34. data/lib/phcdevworks_accounts_stytch/stytch/error.rb +26 -0
  35. data/lib/phcdevworks_accounts_stytch/stytch/method_options.rb +21 -0
  36. data/lib/phcdevworks_accounts_stytch/stytch/organization.rb +51 -0
  37. data/lib/phcdevworks_accounts_stytch/stytch/response.rb +44 -0
  38. data/lib/phcdevworks_accounts_stytch/stytch/success.rb +19 -0
  39. data/lib/phcdevworks_accounts_stytch/version.rb +1 -1
  40. data/lib/phcdevworks_accounts_stytch.rb +3 -4
  41. metadata +37 -13
  42. data/app/controllers/phcdevworks_accounts_stytch/authentication/login_controller.rb +0 -26
  43. data/app/controllers/phcdevworks_accounts_stytch/authentication/processor_controller.rb +0 -36
  44. data/lib/phcdevworks_accounts_stytch/stytch_client.rb +0 -10
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PhcdevworksAccountsStytch
4
+ module Stytch
5
+ class Organization
6
+ def initialize
7
+ @client = PhcdevworksAccountsStytch::Stytch::Client.b2b_client
8
+ end
9
+
10
+ def find_organization_id_by_slug(slug)
11
+ response = search_organization_by_slug(slug)
12
+ extract_organization_id(response, slug)
13
+ rescue StandardError => e
14
+ handle_error(e)
15
+ end
16
+
17
+ private
18
+
19
+ def search_organization_by_slug(slug)
20
+ @client.organizations.search(
21
+ query: {
22
+ operator: 'OR',
23
+ operands: [
24
+ { filter_name: 'organization_slugs', filter_value: [slug] }
25
+ ]
26
+ }
27
+ )
28
+ end
29
+
30
+ def extract_organization_id(response, slug)
31
+ organizations = response['organizations']
32
+ if organizations&.any?
33
+ organization = organizations.first
34
+ organization['organization_id']
35
+ else
36
+ raise PhcdevworksAccountsStytch::Stytch::Error.new(
37
+ status_code: 404,
38
+ error_message: "Organization with slug '#{slug}' not found"
39
+ )
40
+ end
41
+ end
42
+
43
+ def handle_error(error)
44
+ raise PhcdevworksAccountsStytch::Stytch::Error.new(
45
+ status_code: error.respond_to?(:status_code) ? error.status_code : 500,
46
+ error_message: error.message
47
+ )
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PhcdevworksAccountsStytch
4
+ module Stytch
5
+ module Response
6
+ def self.handle_response(response)
7
+ response = response.is_a?(Hash) ? response : JSON.parse(response)
8
+
9
+ status_code = response['status_code'] || 500
10
+
11
+ if success_status?(status_code)
12
+ build_success_response(status_code, response)
13
+ else
14
+ build_error_response(response, status_code)
15
+ end
16
+ end
17
+
18
+ def self.success_status?(status_code)
19
+ status_code.between?(200, 299)
20
+ end
21
+
22
+ def self.build_success_response(status_code, response)
23
+ PhcdevworksAccountsStytch::Stytch::Success.new(
24
+ status_code: status_code,
25
+ message: "Successfully processed request with status code #{status_code}.",
26
+ data: response
27
+ )
28
+ end
29
+
30
+ def self.build_error_response(response, status_code)
31
+ error_code = response['error_type'] || 'unknown_error'
32
+ error_message = response['error_message'] || 'An unknown error occurred'
33
+
34
+ Rails.logger.error "Stytch API error: #{response.inspect}"
35
+
36
+ raise PhcdevworksAccountsStytch::Stytch::Error.new(
37
+ status_code: status_code,
38
+ error_code: error_code,
39
+ error_message: error_message
40
+ )
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PhcdevworksAccountsStytch
4
+ module Stytch
5
+ class Success
6
+ attr_reader :status_code, :message, :data
7
+
8
+ def initialize(status_code:, message: 'Action completed successfully.', data: {})
9
+ @status_code = status_code
10
+ @message = message
11
+ @data = data
12
+ end
13
+
14
+ def success?
15
+ true
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PhcdevworksAccountsStytch
4
- VERSION = '0.1.0.pre.1'
4
+ VERSION = '0.2.0.pre.1'
5
5
  end
@@ -1,10 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'phcdevworks_accounts_stytch/version'
3
+ require 'stytch'
4
4
  require 'phcdevworks_accounts_stytch/engine'
5
+ require 'phcdevworks_accounts_stytch/version'
6
+ require 'phcdevworks_accounts_stytch/stytch/client'
5
7
 
6
- # PhcdevworksAccountsStytch
7
- # This module serves as the namespace for the PhcdevworksAccountsStytch engine.
8
8
  module PhcdevworksAccountsStytch
9
- # Your code goes here...
10
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phcdevworks_accounts_stytch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre.1
4
+ version: 0.2.0.pre.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - PHCDevworks
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-07-15 00:00:00.000000000 Z
12
+ date: 2024-09-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -17,20 +17,14 @@ dependencies:
17
17
  requirements:
18
18
  - - "~>"
19
19
  - !ruby/object:Gem::Version
20
- version: '7.1'
21
- - - ">="
22
- - !ruby/object:Gem::Version
23
- version: 7.1.3.4
20
+ version: '7.2'
24
21
  type: :runtime
25
22
  prerelease: false
26
23
  version_requirements: !ruby/object:Gem::Requirement
27
24
  requirements:
28
25
  - - "~>"
29
26
  - !ruby/object:Gem::Version
30
- version: '7.1'
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: 7.1.3.4
27
+ version: '7.2'
34
28
  - !ruby/object:Gem::Dependency
35
29
  name: stytch
36
30
  requirement: !ruby/object:Gem::Requirement
@@ -58,18 +52,48 @@ files:
58
52
  - Rakefile
59
53
  - app/assets/config/phcdevworks_accounts_stytch_manifest.js
60
54
  - app/assets/stylesheets/phcdevworks_accounts_stytch/application.css
55
+ - app/controllers/concerns/error_handler.rb
56
+ - app/controllers/concerns/handle_service_action.rb
57
+ - app/controllers/concerns/organization_setter.rb
61
58
  - app/controllers/phcdevworks_accounts_stytch/application_controller.rb
62
- - app/controllers/phcdevworks_accounts_stytch/authentication/login_controller.rb
63
- - app/controllers/phcdevworks_accounts_stytch/authentication/processor_controller.rb
59
+ - app/controllers/phcdevworks_accounts_stytch/b2b/authenticate_controller.rb
60
+ - app/controllers/phcdevworks_accounts_stytch/b2b/magic_links_controller.rb
61
+ - app/controllers/phcdevworks_accounts_stytch/b2b/passwords_controller.rb
62
+ - app/controllers/phcdevworks_accounts_stytch/b2c/authenticate_controller.rb
63
+ - app/controllers/phcdevworks_accounts_stytch/b2c/magic_links_controller.rb
64
+ - app/controllers/phcdevworks_accounts_stytch/b2c/passwords_controller.rb
64
65
  - app/helpers/phcdevworks_accounts_stytch/application_helper.rb
65
66
  - app/jobs/phcdevworks_accounts_stytch/application_job.rb
66
67
  - app/mailers/phcdevworks_accounts_stytch/application_mailer.rb
67
68
  - app/models/phcdevworks_accounts_stytch/application_record.rb
68
69
  - app/views/layouts/phcdevworks_accounts_stytch/application.html.erb
70
+ - app/views/phcdevworks_accounts_stytch/b2b/magic_links/invite.html.erb
71
+ - app/views/phcdevworks_accounts_stytch/b2b/magic_links/login_or_signup.html.erb
72
+ - app/views/phcdevworks_accounts_stytch/b2b/passwords/reset_existing_password.html.erb
73
+ - app/views/phcdevworks_accounts_stytch/b2b/passwords/reset_password.html.erb
74
+ - app/views/phcdevworks_accounts_stytch/b2b/passwords/reset_start.html.erb
75
+ - app/views/phcdevworks_accounts_stytch/b2b/passwords/reset_with_session.html.erb
76
+ - app/views/phcdevworks_accounts_stytch/b2c/magic_links/invite.html.erb
77
+ - app/views/phcdevworks_accounts_stytch/b2c/magic_links/login_or_signup.html.erb
78
+ - app/views/phcdevworks_accounts_stytch/b2c/passwords/reset_existing_password.html.erb
79
+ - app/views/phcdevworks_accounts_stytch/b2c/passwords/reset_password.html.erb
80
+ - app/views/phcdevworks_accounts_stytch/b2c/passwords/reset_start.html.erb
81
+ - app/views/phcdevworks_accounts_stytch/b2c/passwords/reset_with_session.html.erb
69
82
  - config/routes.rb
83
+ - config/routes/b2b.rb
84
+ - config/routes/b2c.rb
70
85
  - lib/phcdevworks_accounts_stytch.rb
86
+ - lib/phcdevworks_accounts_stytch/authentication/b2b/magic_link_service.rb
87
+ - lib/phcdevworks_accounts_stytch/authentication/b2b/password_service.rb
88
+ - lib/phcdevworks_accounts_stytch/authentication/b2c/magic_link_service.rb
89
+ - lib/phcdevworks_accounts_stytch/authentication/b2c/password_service.rb
71
90
  - lib/phcdevworks_accounts_stytch/engine.rb
72
- - lib/phcdevworks_accounts_stytch/stytch_client.rb
91
+ - lib/phcdevworks_accounts_stytch/stytch/client.rb
92
+ - lib/phcdevworks_accounts_stytch/stytch/error.rb
93
+ - lib/phcdevworks_accounts_stytch/stytch/method_options.rb
94
+ - lib/phcdevworks_accounts_stytch/stytch/organization.rb
95
+ - lib/phcdevworks_accounts_stytch/stytch/response.rb
96
+ - lib/phcdevworks_accounts_stytch/stytch/success.rb
73
97
  - lib/phcdevworks_accounts_stytch/version.rb
74
98
  - lib/tasks/phcdevworks_accounts_stytch_tasks.rake
75
99
  homepage: https://phcdevworks.com/
@@ -1,26 +0,0 @@
1
- # app/controllers/phcdevworks_accounts_stytch/authentication/login_controller.rb
2
- # frozen_string_literal: true
3
-
4
- require 'phcdevworks_accounts_stytch/stytch_client'
5
-
6
- module PhcdevworksAccountsStytch
7
- module Authentication
8
- class LoginController < ApplicationController
9
- include StytchClient
10
-
11
- def create
12
- email = params[:email]
13
- response = send_magic_link(email)
14
- render json: response
15
- rescue StandardError => e
16
- render json: { error: e.message }, status: :internal_server_error
17
- end
18
-
19
- private
20
-
21
- def send_magic_link(email)
22
- stytch_client.magic_links.email.discovery.send(email_address: email)
23
- end
24
- end
25
- end
26
- end
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module PhcdevworksAccountsStytch
4
- module Authentication
5
- class ProcessorController < ApplicationController
6
- include StytchClient
7
-
8
- def create
9
- token = params[:token]
10
- response = authenticate_token(token)
11
- render_success(response)
12
- rescue StandardError => e
13
- render_error(e)
14
- end
15
-
16
- private
17
-
18
- def authenticate_token(token)
19
- stytch_client.magic_links.discovery.authenticate(discovery_magic_links_token: token)
20
- end
21
-
22
- def render_success(response)
23
- render plain: success_message(response)
24
- end
25
-
26
- def render_error(error)
27
- render plain: error.message, status: :unauthorized
28
- end
29
-
30
- def success_message(response)
31
- "Hello, #{response.email_address}! Complete the Discovery flow by creating an " \
32
- "Organization with your intermediate session token: #{response.intermediate_session_token}."
33
- end
34
- end
35
- end
36
- end
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module StytchClient
4
- def stytch_client
5
- @stytch_client ||= StytchB2B::Client.new(
6
- project_id: StytchClientConfig.project_id,
7
- secret: StytchClientConfig.secret
8
- )
9
- end
10
- end