stytch 9.1.0 → 9.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/DEVELOPMENT.md +1 -1
- data/README.md +51 -2
- data/lib/stytch/b2b_client.rb +2 -1
- data/lib/stytch/b2b_magic_links.rb +0 -1
- data/lib/stytch/b2b_organizations.rb +92 -43
- data/lib/stytch/b2b_passwords.rb +14 -6
- data/lib/stytch/b2b_scim.rb +73 -7
- data/lib/stytch/b2b_sessions.rb +36 -7
- data/lib/stytch/b2b_sso.rb +4 -8
- data/lib/stytch/client.rb +2 -1
- data/lib/stytch/m2m.rb +16 -7
- data/lib/stytch/passwords.rb +5 -5
- data/lib/stytch/sessions.rb +13 -4
- data/lib/stytch/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d26559911b9b0677b360db5707cc19a0faead0a0420bd7ec7612766184dde63b
|
4
|
+
data.tar.gz: 37ed33c882f14ef4cb40e925f9dc62362a7674621a7ed032a5afca2a753cd503
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c751854693f03128c410031c7647982a0702d8971ebb2df47a5c542b25df668faa4309587dbd00d5c415166dc5aebb5db26fbf7b350eff6f4129be9bd3fc38cd
|
7
|
+
data.tar.gz: 82ac37c5f69e67fe207a06fa61809844b0a9084e0ec73d4820f3f4e8896e74ab0010750663aa910e564dc2cb7135faa1dbd8d492ba94e3b8fad069bcfbab4931
|
data/.rubocop.yml
CHANGED
data/DEVELOPMENT.md
CHANGED
@@ -18,4 +18,4 @@ If you have non-trivial changes you'd like us to incorporate, please open an iss
|
|
18
18
|
When you're ready for someone to look at your issue or PR, assign `@stytchauth/client-libraries` (GitHub should do this automatically). If we don't acknowledge it within one business day, please escalate it by tagging `@stytchauth/engineering` in a comment or letting us know in [Slack].
|
19
19
|
|
20
20
|
[Bundler]: https://bundler.io/
|
21
|
-
[Slack]: https://stytch.
|
21
|
+
[Slack]: https://stytch.com/docs/resources/support/overview
|
data/README.md
CHANGED
@@ -25,6 +25,9 @@ Or install it yourself as:
|
|
25
25
|
You can find your API credentials in the [Stytch Dashboard](https://stytch.com/dashboard/api-keys).
|
26
26
|
|
27
27
|
This client library supports all Stytch's live products:
|
28
|
+
|
29
|
+
### B2C
|
30
|
+
|
28
31
|
- [x] [Email Magic Links](https://stytch.com/docs/api/send-by-email)
|
29
32
|
- [x] [Embeddable Magic Links](https://stytch.com/docs/guides/magic-links/embeddable-magic-links/api)
|
30
33
|
- [x] [OAuth logins](https://stytch.com/docs/guides/oauth/idp-overview)
|
@@ -37,7 +40,18 @@ This client library supports all Stytch's live products:
|
|
37
40
|
- [x] [Crypto wallets](https://stytch.com/docs/guides/web3/api)
|
38
41
|
- [x] [Passwords](https://stytch.com/docs/guides/passwords/api)
|
39
42
|
|
40
|
-
###
|
43
|
+
### B2B
|
44
|
+
|
45
|
+
- [x] [Organizations](https://stytch.com/docs/b2b/api/organization-object)
|
46
|
+
- [x] [Members](https://stytch.com/docs/b2b/api/member-object)
|
47
|
+
- [x] [Email Magic Links](https://stytch.com/docs/b2b/api/send-login-signup-email)
|
48
|
+
- [x] [OAuth logins](https://stytch.com/docs/b2b/api/oauth-google-start)
|
49
|
+
- [x] [Session Management](https://stytch.com/docs/b2b/api/session-object)
|
50
|
+
- [x] [Single-Sign On](https://stytch.com/docs/b2b/api/sso-authenticate-start)
|
51
|
+
- [x] [Discovery](https://stytch.com/docs/b2b/api/discovered-organization-object)
|
52
|
+
- [x] [Passwords](https://stytch.com/docs/b2b/api/passwords-authenticate)
|
53
|
+
|
54
|
+
### Example B2C usage
|
41
55
|
Create an API client:
|
42
56
|
```ruby
|
43
57
|
client = Stytch::Client.new(
|
@@ -61,6 +75,41 @@ client.magic_links.authenticate(
|
|
61
75
|
)
|
62
76
|
```
|
63
77
|
|
78
|
+
### Example B2B usage
|
79
|
+
|
80
|
+
Create an API client:
|
81
|
+
```ruby
|
82
|
+
require 'stytch'
|
83
|
+
|
84
|
+
client = StytchB2B::Client.new(
|
85
|
+
project_id: "project-test-uuid",
|
86
|
+
secret: "secret-test-uuid"
|
87
|
+
)
|
88
|
+
```
|
89
|
+
|
90
|
+
Create an organization
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
resp = client.organizations.create(
|
94
|
+
organization_name: 'Example Org Inc.',
|
95
|
+
organization_slug: 'example-org'
|
96
|
+
)
|
97
|
+
|
98
|
+
puts resp
|
99
|
+
```
|
100
|
+
|
101
|
+
Log the first user into the organization
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
resp = client.magic_links.email.login_or_signup(
|
105
|
+
organization_id: 'organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931',
|
106
|
+
email_address: 'sandbox@stytch.com'
|
107
|
+
)
|
108
|
+
|
109
|
+
puts resp
|
110
|
+
```
|
111
|
+
|
112
|
+
|
64
113
|
## Handling Errors
|
65
114
|
|
66
115
|
When possible the response will contain an `error_type` and an `error_message` that can be used to distinguish errors.
|
@@ -77,7 +126,7 @@ Follow one of the [integration guides](https://stytch.com/docs/guides) or start
|
|
77
126
|
|
78
127
|
If you've found a bug, [open an issue](https://github.com/stytchauth/stytch-ruby/issues/new)!
|
79
128
|
|
80
|
-
If you have questions or want help troubleshooting, join us in [Slack](https://stytch.
|
129
|
+
If you have questions or want help troubleshooting, join us in [Slack](https://stytch.com/docs/resources/support/overview) or email support@stytch.com.
|
81
130
|
|
82
131
|
If you've found a security vulnerability, please follow our [responsible disclosure instructions](https://stytch.com/docs/resources/security-and-trust/security#:~:text=Responsible%20disclosure%20program).
|
83
132
|
|
data/lib/stytch/b2b_client.rb
CHANGED
@@ -26,6 +26,7 @@ module StytchB2B
|
|
26
26
|
@api_host = api_host(env, project_id)
|
27
27
|
@project_id = project_id
|
28
28
|
@secret = secret
|
29
|
+
@is_b2b_client = true
|
29
30
|
|
30
31
|
create_connection(&block)
|
31
32
|
|
@@ -33,7 +34,7 @@ module StytchB2B
|
|
33
34
|
@policy_cache = StytchB2B::PolicyCache.new(rbac_client: rbac)
|
34
35
|
|
35
36
|
@discovery = StytchB2B::Discovery.new(@connection)
|
36
|
-
@m2m = Stytch::M2M.new(@connection, @project_id)
|
37
|
+
@m2m = Stytch::M2M.new(@connection, @project_id, @is_b2b_client)
|
37
38
|
@magic_links = StytchB2B::MagicLinks.new(@connection)
|
38
39
|
@oauth = StytchB2B::OAuth.new(@connection)
|
39
40
|
@otps = StytchB2B::OTPs.new(@connection)
|
@@ -268,7 +268,6 @@ module StytchB2B
|
|
268
268
|
# Send an invite email to a new Member to join an Organization. The Member will be created with an `invited` status until they successfully authenticate. Sending invites to `pending` Members will update their status to `invited`. Sending invites to already `active` Members will return an error.
|
269
269
|
#
|
270
270
|
# The magic link invite will be valid for 1 week.
|
271
|
-
# /%}
|
272
271
|
#
|
273
272
|
# == Parameters:
|
274
273
|
# organization_id::
|
@@ -230,18 +230,6 @@ module StytchB2B
|
|
230
230
|
#
|
231
231
|
# *See the [Organization authentication settings](https://stytch.com/docs/b2b/api/org-auth-settings) resource to learn more about fields like `email_jit_provisioning`, `email_invites`, `sso_jit_provisioning`, etc., and their behaviors.
|
232
232
|
#
|
233
|
-
# Our RBAC implementation offers out-of-the-box handling of authorization checks for this endpoint. If you pass in
|
234
|
-
# a header containing a `session_token` or a `session_jwt` for an unexpired Member Session, we will check that the
|
235
|
-
# Member Session has the necessary permissions. The specific permissions needed depend on which of the optional fields
|
236
|
-
# are passed in the request. For example, if the `organization_name` argument is provided, the Member Session must have
|
237
|
-
# permission to perform the `update.info.name` action on the `stytch.organization` Resource.
|
238
|
-
#
|
239
|
-
# If the Member Session does not contain a Role that satisfies the requested permissions, or if the Member's Organization
|
240
|
-
# does not match the `organization_id` passed in the request, a 403 error will be thrown. Otherwise, the request will
|
241
|
-
# proceed as normal.
|
242
|
-
#
|
243
|
-
# To learn more about our RBAC implementation, see our [RBAC guide](https://stytch.com/docs/b2b/guides/rbac/overview).
|
244
|
-
#
|
245
233
|
# == Parameters:
|
246
234
|
# organization_id::
|
247
235
|
# Globally unique UUID that identifies a specific Organization. The `organization_id` is critical to perform operations on an Organization, so be sure to preserve this value.
|
@@ -429,7 +417,7 @@ module StytchB2B
|
|
429
417
|
put_request("/v1/b2b/organizations/#{organization_id}", request, headers)
|
430
418
|
end
|
431
419
|
|
432
|
-
# Deletes an Organization specified by `organization_id`. All Members of the Organization will also be deleted.
|
420
|
+
# Deletes an Organization specified by `organization_id`. All Members of the Organization will also be deleted.
|
433
421
|
#
|
434
422
|
# == Parameters:
|
435
423
|
# organization_id::
|
@@ -643,6 +631,25 @@ module StytchB2B
|
|
643
631
|
end
|
644
632
|
end
|
645
633
|
|
634
|
+
class UnlinkRetiredEmailRequestOptions
|
635
|
+
# Optional authorization object.
|
636
|
+
# Pass in an active Stytch Member session token or session JWT and the request
|
637
|
+
# will be run using that member's permissions.
|
638
|
+
attr_accessor :authorization
|
639
|
+
|
640
|
+
def initialize(
|
641
|
+
authorization: nil
|
642
|
+
)
|
643
|
+
@authorization = authorization
|
644
|
+
end
|
645
|
+
|
646
|
+
def to_headers
|
647
|
+
headers = {}
|
648
|
+
headers.merge!(@authorization.to_headers) if authorization
|
649
|
+
headers
|
650
|
+
end
|
651
|
+
end
|
652
|
+
|
646
653
|
class CreateRequestOptions
|
647
654
|
# Optional authorization object.
|
648
655
|
# Pass in an active Stytch Member session token or session JWT and the request
|
@@ -673,18 +680,6 @@ module StytchB2B
|
|
673
680
|
|
674
681
|
# Updates a Member specified by `organization_id` and `member_id`.
|
675
682
|
#
|
676
|
-
# Our RBAC implementation offers out-of-the-box handling of authorization checks for this endpoint. If you pass in
|
677
|
-
# a header containing a `session_token` or a `session_jwt` for an unexpired Member Session, we will check that the
|
678
|
-
# Member Session has the necessary permissions. The specific permissions needed depend on which of the optional fields
|
679
|
-
# are passed in the request. For example, if the `organization_name` argument is provided, the Member Session must have
|
680
|
-
# permission to perform the `update.info.name` action on the `stytch.organization` Resource.
|
681
|
-
#
|
682
|
-
# If the Member Session does not contain a Role that satisfies the requested permissions, or if the Member's Organization
|
683
|
-
# does not match the `organization_id` passed in the request, a 403 error will be thrown. Otherwise, the request will
|
684
|
-
# proceed as normal.
|
685
|
-
#
|
686
|
-
# To learn more about our RBAC implementation, see our [RBAC guide](https://stytch.com/docs/b2b/guides/rbac/overview).
|
687
|
-
#
|
688
683
|
# == Parameters:
|
689
684
|
# organization_id::
|
690
685
|
# Globally unique UUID that identifies a specific Organization. The `organization_id` is critical to perform operations on an Organization, so be sure to preserve this value.
|
@@ -806,7 +801,7 @@ module StytchB2B
|
|
806
801
|
put_request("/v1/b2b/organizations/#{organization_id}/members/#{member_id}", request, headers)
|
807
802
|
end
|
808
803
|
|
809
|
-
# Deletes a Member specified by `organization_id` and `member_id`.
|
804
|
+
# Deletes a Member specified by `organization_id` and `member_id`.
|
810
805
|
#
|
811
806
|
# == Parameters:
|
812
807
|
# organization_id::
|
@@ -840,7 +835,7 @@ module StytchB2B
|
|
840
835
|
delete_request("/v1/b2b/organizations/#{organization_id}/members/#{member_id}", headers)
|
841
836
|
end
|
842
837
|
|
843
|
-
# Reactivates a deleted Member's status and its associated email status (if applicable) to active, specified by `organization_id` and `member_id`.
|
838
|
+
# Reactivates a deleted Member's status and its associated email status (if applicable) to active, specified by `organization_id` and `member_id`.
|
844
839
|
#
|
845
840
|
# == Parameters:
|
846
841
|
# organization_id::
|
@@ -889,7 +884,6 @@ module StytchB2B
|
|
889
884
|
# Existing Member Sessions that include a phone number authentication factor will not be revoked if the phone number is deleted, and MFA will not be enforced until the Member logs in again.
|
890
885
|
# If you wish to enforce MFA immediately after a phone number is deleted, you can do so by prompting the Member to enter a new phone number
|
891
886
|
# and calling the [OTP SMS send](https://stytch.com/docs/b2b/api/otp-sms-send) endpoint, then calling the [OTP SMS Authenticate](https://stytch.com/docs/b2b/api/authenticate-otp-sms) endpoint.
|
892
|
-
# /%}
|
893
887
|
#
|
894
888
|
# == Parameters:
|
895
889
|
# organization_id::
|
@@ -934,7 +928,6 @@ module StytchB2B
|
|
934
928
|
# To mint a new registration for a Member, you must first call this endpoint to delete the existing registration.
|
935
929
|
#
|
936
930
|
# Existing Member Sessions that include the TOTP authentication factor will not be revoked if the registration is deleted, and MFA will not be enforced until the Member logs in again.
|
937
|
-
# /%}
|
938
931
|
#
|
939
932
|
# == Parameters:
|
940
933
|
# organization_id::
|
@@ -978,18 +971,6 @@ module StytchB2B
|
|
978
971
|
#
|
979
972
|
# *All fuzzy search filters require a minimum of three characters.
|
980
973
|
#
|
981
|
-
# Our RBAC implementation offers out-of-the-box handling of authorization checks for this endpoint. If you pass in
|
982
|
-
# a header containing a `session_token` or a `session_jwt` for an unexpired Member Session, we will check that the
|
983
|
-
# Member Session has permission to perform the `search` action on the `stytch.member` Resource. In addition, enforcing
|
984
|
-
# RBAC on this endpoint means that you may only search for Members within the calling Member's Organization, so the
|
985
|
-
# `organization_ids` argument may only contain the `organization_id` of the Member Session passed in the header.
|
986
|
-
#
|
987
|
-
# If the Member Session does not contain a Role that satisfies the requested permission, or if the `organization_ids`
|
988
|
-
# argument contains an `organization_id` that the Member Session does not belong to, a 403 error will be thrown.
|
989
|
-
# Otherwise, the request will proceed as normal.
|
990
|
-
#
|
991
|
-
# To learn more about our RBAC implementation, see our [RBAC guide](https://stytch.com/docs/b2b/guides/rbac/overview).
|
992
|
-
#
|
993
974
|
# == Parameters:
|
994
975
|
# organization_ids::
|
995
976
|
# An array of organization_ids. At least one value is required.
|
@@ -1043,7 +1024,7 @@ module StytchB2B
|
|
1043
1024
|
post_request('/v1/b2b/organizations/members/search', request, headers)
|
1044
1025
|
end
|
1045
1026
|
|
1046
|
-
# Delete a Member's password.
|
1027
|
+
# Delete a Member's password.
|
1047
1028
|
#
|
1048
1029
|
# == Parameters:
|
1049
1030
|
# organization_id::
|
@@ -1116,7 +1097,75 @@ module StytchB2B
|
|
1116
1097
|
get_request(request, headers)
|
1117
1098
|
end
|
1118
1099
|
|
1119
|
-
#
|
1100
|
+
# Unlinks a retired email address from a Member specified by their `organization_id` and `member_id`. The email address
|
1101
|
+
# to be retired can be identified in the request body by either its `email_id`, its `email_address`, or both. If using
|
1102
|
+
# both identifiers they must refer to the same email.
|
1103
|
+
#
|
1104
|
+
# A previously active email address can be marked as retired in one of two ways:
|
1105
|
+
#
|
1106
|
+
# - It's replaced with a new primary email address during an explicit Member update.
|
1107
|
+
# - A new email address is surfaced by an OAuth, SAML or OIDC provider. In this case the new email address becomes the
|
1108
|
+
# Member's primary email address and the old primary email address is retired.
|
1109
|
+
#
|
1110
|
+
# A retired email address cannot be used by other Members in the same Organization. However, unlinking retired email
|
1111
|
+
# addresses allows then to be subsequently re-used by other Organization Members. Retired email addresses can be viewed
|
1112
|
+
# on the [Member object](https://stytch.com/docs/b2b/api/member-object).
|
1113
|
+
# %}
|
1114
|
+
#
|
1115
|
+
# == Parameters:
|
1116
|
+
# organization_id::
|
1117
|
+
# Globally unique UUID that identifies a specific Organization. The `organization_id` is critical to perform operations on an Organization, so be sure to preserve this value.
|
1118
|
+
# The type of this field is +String+.
|
1119
|
+
# member_id::
|
1120
|
+
# Globally unique UUID that identifies a specific Member. The `member_id` is critical to perform operations on a Member, so be sure to preserve this value.
|
1121
|
+
# The type of this field is +String+.
|
1122
|
+
# email_id::
|
1123
|
+
# The globally unique UUID of a Member's email.
|
1124
|
+
# The type of this field is nilable +String+.
|
1125
|
+
# email_address::
|
1126
|
+
# The email address of the Member.
|
1127
|
+
# The type of this field is nilable +String+.
|
1128
|
+
#
|
1129
|
+
# == Returns:
|
1130
|
+
# An object with the following fields:
|
1131
|
+
# request_id::
|
1132
|
+
# Globally unique UUID that is returned with every API call. This value is important to log for debugging purposes; we may ask for this value to help identify a specific API call when helping you debug an issue.
|
1133
|
+
# The type of this field is +String+.
|
1134
|
+
# member_id::
|
1135
|
+
# Globally unique UUID that identifies a specific Member.
|
1136
|
+
# The type of this field is +String+.
|
1137
|
+
# organization_id::
|
1138
|
+
# Globally unique UUID that identifies a specific Organization. The `organization_id` is critical to perform operations on an Organization, so be sure to preserve this value.
|
1139
|
+
# The type of this field is +String+.
|
1140
|
+
# member::
|
1141
|
+
# The [Member object](https://stytch.com/docs/b2b/api/member-object)
|
1142
|
+
# The type of this field is +Member+ (+object+).
|
1143
|
+
# organization::
|
1144
|
+
# The [Organization object](https://stytch.com/docs/b2b/api/organization-object).
|
1145
|
+
# The type of this field is +Organization+ (+object+).
|
1146
|
+
# status_code::
|
1147
|
+
# The HTTP status code of the response. Stytch follows standard HTTP response status code patterns, e.g. 2XX values equate to success, 3XX values are redirects, 4XX are client errors, and 5XX are server errors.
|
1148
|
+
# The type of this field is +Integer+.
|
1149
|
+
#
|
1150
|
+
# == Method Options:
|
1151
|
+
# This method supports an optional +StytchB2B::Organizations::Members::UnlinkRetiredEmailRequestOptions+ object which will modify the headers sent in the HTTP request.
|
1152
|
+
def unlink_retired_email(
|
1153
|
+
organization_id:,
|
1154
|
+
member_id:,
|
1155
|
+
email_id: nil,
|
1156
|
+
email_address: nil,
|
1157
|
+
method_options: nil
|
1158
|
+
)
|
1159
|
+
headers = {}
|
1160
|
+
headers = headers.merge(method_options.to_headers) unless method_options.nil?
|
1161
|
+
request = {}
|
1162
|
+
request[:email_id] = email_id unless email_id.nil?
|
1163
|
+
request[:email_address] = email_address unless email_address.nil?
|
1164
|
+
|
1165
|
+
post_request("/v1/b2b/organizations/#{organization_id}/members/#{member_id}/unlink_retired_email", request, headers)
|
1166
|
+
end
|
1167
|
+
|
1168
|
+
# Creates a Member. An `organization_id` and `email_address` are required.
|
1120
1169
|
#
|
1121
1170
|
# == Parameters:
|
1122
1171
|
# organization_id::
|
data/lib/stytch/b2b_passwords.rb
CHANGED
@@ -34,7 +34,7 @@ module StytchB2B
|
|
34
34
|
#
|
35
35
|
# == Parameters:
|
36
36
|
# password::
|
37
|
-
# The password to authenticate.
|
37
|
+
# The password to authenticate, reset, or set for the first time. Any UTF8 character is allowed, e.g. spaces, emojis, non-English characers, etc.
|
38
38
|
# The type of this field is +String+.
|
39
39
|
# email_address::
|
40
40
|
# The email address of the Member.
|
@@ -89,6 +89,8 @@ module StytchB2B
|
|
89
89
|
|
90
90
|
# Adds an existing password to a member's email that doesn't have a password yet. We support migrating members from passwords stored with bcrypt, scrypt, argon2, MD-5, SHA-1, and PBKDF2. This endpoint has a rate limit of 100 requests per second.
|
91
91
|
#
|
92
|
+
# The member's email will be marked as verified when you use this endpoint.
|
93
|
+
#
|
92
94
|
# == Parameters:
|
93
95
|
# email_address::
|
94
96
|
# The email address of the Member.
|
@@ -219,7 +221,7 @@ module StytchB2B
|
|
219
221
|
# The email address of the Member.
|
220
222
|
# The type of this field is +String+.
|
221
223
|
# password::
|
222
|
-
# The password to authenticate.
|
224
|
+
# The password to authenticate, reset, or set for the first time. Any UTF8 character is allowed, e.g. spaces, emojis, non-English characers, etc.
|
223
225
|
# The type of this field is +String+.
|
224
226
|
# session_token::
|
225
227
|
# A secret token for a given Stytch Session.
|
@@ -427,12 +429,14 @@ module StytchB2B
|
|
427
429
|
#
|
428
430
|
# If a valid `session_token` or `session_jwt` is passed in, the Member will not be required to complete an MFA step.
|
429
431
|
#
|
432
|
+
# Note that a successful password reset by email will revoke all active sessions for the `member_id`.
|
433
|
+
#
|
430
434
|
# == Parameters:
|
431
435
|
# password_reset_token::
|
432
436
|
# The password reset token to authenticate.
|
433
437
|
# The type of this field is +String+.
|
434
438
|
# password::
|
435
|
-
# The password to reset.
|
439
|
+
# The password to authenticate, reset, or set for the first time. Any UTF8 character is allowed, e.g. spaces, emojis, non-English characers, etc.
|
436
440
|
# The type of this field is +String+.
|
437
441
|
# session_token::
|
438
442
|
# Reuse an existing session instead of creating a new one. If you provide a `session_token`, Stytch will update the session.
|
@@ -557,12 +561,14 @@ module StytchB2B
|
|
557
561
|
|
558
562
|
# Reset the Member's password using their existing session. The endpoint will error if the session does not contain an authentication factor that has been issued within the last 5 minutes. Either `session_token` or `session_jwt` should be provided.
|
559
563
|
#
|
564
|
+
# Note that a successful password reset via an existing session will revoke all active sessions for the `member_id`, except for the one used during the reset flow.
|
565
|
+
#
|
560
566
|
# == Parameters:
|
561
567
|
# organization_id::
|
562
568
|
# Globally unique UUID that identifies a specific Organization. The `organization_id` is critical to perform operations on an Organization, so be sure to preserve this value.
|
563
569
|
# The type of this field is +String+.
|
564
570
|
# password::
|
565
|
-
# The password to authenticate.
|
571
|
+
# The password to authenticate, reset, or set for the first time. Any UTF8 character is allowed, e.g. spaces, emojis, non-English characers, etc.
|
566
572
|
# The type of this field is +String+.
|
567
573
|
# session_token::
|
568
574
|
# A secret token for a given Stytch Session.
|
@@ -677,15 +683,17 @@ module StytchB2B
|
|
677
683
|
#
|
678
684
|
# If a valid `session_token` or `session_jwt` is passed in, the Member will not be required to complete an MFA step.
|
679
685
|
#
|
686
|
+
# Note that a successful password reset via an existing password will revoke all active sessions for the `member_id`.
|
687
|
+
#
|
680
688
|
# == Parameters:
|
681
689
|
# email_address::
|
682
690
|
# The email address of the Member.
|
683
691
|
# The type of this field is +String+.
|
684
692
|
# existing_password::
|
685
|
-
# The
|
693
|
+
# The Member's current password that they supplied.
|
686
694
|
# The type of this field is +String+.
|
687
695
|
# new_password::
|
688
|
-
# The
|
696
|
+
# The Member's elected new password.
|
689
697
|
# The type of this field is +String+.
|
690
698
|
# organization_id::
|
691
699
|
# Globally unique UUID that identifies a specific Organization. The `organization_id` is critical to perform operations on an Organization, so be sure to preserve this value.
|
data/lib/stytch/b2b_scim.rb
CHANGED
@@ -115,6 +115,25 @@ module StytchB2B
|
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
+
class GetGroupsRequestOptions
|
119
|
+
# Optional authorization object.
|
120
|
+
# Pass in an active Stytch Member session token or session JWT and the request
|
121
|
+
# will be run using that member's permissions.
|
122
|
+
attr_accessor :authorization
|
123
|
+
|
124
|
+
def initialize(
|
125
|
+
authorization: nil
|
126
|
+
)
|
127
|
+
@authorization = authorization
|
128
|
+
end
|
129
|
+
|
130
|
+
def to_headers
|
131
|
+
headers = {}
|
132
|
+
headers.merge!(@authorization.to_headers) if authorization
|
133
|
+
headers
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
118
137
|
class CreateRequestOptions
|
119
138
|
# Optional authorization object.
|
120
139
|
# Pass in an active Stytch Member session token or session JWT and the request
|
@@ -159,7 +178,7 @@ module StytchB2B
|
|
159
178
|
@connection = connection
|
160
179
|
end
|
161
180
|
|
162
|
-
# Update a SCIM Connection.
|
181
|
+
# Update a SCIM Connection.
|
163
182
|
#
|
164
183
|
# == Parameters:
|
165
184
|
# organization_id::
|
@@ -210,7 +229,7 @@ module StytchB2B
|
|
210
229
|
put_request("/v1/b2b/scim/#{organization_id}/connection/#{connection_id}", request, headers)
|
211
230
|
end
|
212
231
|
|
213
|
-
# Deletes a SCIM Connection.
|
232
|
+
# Deletes a SCIM Connection.
|
214
233
|
#
|
215
234
|
# == Parameters:
|
216
235
|
# organization_id::
|
@@ -244,7 +263,7 @@ module StytchB2B
|
|
244
263
|
delete_request("/v1/b2b/scim/#{organization_id}/connection/#{connection_id}", headers)
|
245
264
|
end
|
246
265
|
|
247
|
-
# Start a SCIM token rotation.
|
266
|
+
# Start a SCIM token rotation.
|
248
267
|
#
|
249
268
|
# == Parameters:
|
250
269
|
# organization_id::
|
@@ -280,7 +299,7 @@ module StytchB2B
|
|
280
299
|
post_request("/v1/b2b/scim/#{organization_id}/connection/#{connection_id}/rotate/start", request, headers)
|
281
300
|
end
|
282
301
|
|
283
|
-
# Completes a SCIM token rotation. This will complete the current token rotation process and update the active token to be the new token supplied in the [start SCIM token rotation](https://stytch.com/docs/b2b/api/scim-rotate-token-start) response.
|
302
|
+
# Completes a SCIM token rotation. This will complete the current token rotation process and update the active token to be the new token supplied in the [start SCIM token rotation](https://stytch.com/docs/b2b/api/scim-rotate-token-start) response.
|
284
303
|
#
|
285
304
|
# == Parameters:
|
286
305
|
# organization_id::
|
@@ -316,7 +335,7 @@ module StytchB2B
|
|
316
335
|
post_request("/v1/b2b/scim/#{organization_id}/connection/#{connection_id}/rotate/complete", request, headers)
|
317
336
|
end
|
318
337
|
|
319
|
-
# Cancel a SCIM token rotation. This will cancel the current token rotation process, keeping the original token active.
|
338
|
+
# Cancel a SCIM token rotation. This will cancel the current token rotation process, keeping the original token active.
|
320
339
|
#
|
321
340
|
# == Parameters:
|
322
341
|
# organization_id::
|
@@ -352,7 +371,54 @@ module StytchB2B
|
|
352
371
|
post_request("/v1/b2b/scim/#{organization_id}/connection/#{connection_id}/rotate/cancel", request, headers)
|
353
372
|
end
|
354
373
|
|
355
|
-
#
|
374
|
+
# Gets a paginated list of all SCIM Groups associated with a given Connection.
|
375
|
+
#
|
376
|
+
# == Parameters:
|
377
|
+
# organization_id::
|
378
|
+
# Globally unique UUID that identifies a specific Organization. The `organization_id` is critical to perform operations on an Organization, so be sure to preserve this value.
|
379
|
+
# The type of this field is +String+.
|
380
|
+
# connection_id::
|
381
|
+
# The ID of the SCIM connection.
|
382
|
+
# The type of this field is +String+.
|
383
|
+
# cursor::
|
384
|
+
# The `cursor` field allows you to paginate through your results. Each result array is limited to 1000 results. If your query returns more than 1000 results, you will need to paginate the responses using the `cursor`. If you receive a response that includes a non-null `next_cursor` in the `results_metadata` object, repeat the search call with the `next_cursor` value set to the `cursor` field to retrieve the next page of results. Continue to make search calls until the `next_cursor` in the response is null.
|
385
|
+
# The type of this field is nilable +String+.
|
386
|
+
# limit::
|
387
|
+
# The number of search results to return per page. The default limit is 100. A maximum of 1000 results can be returned by a single search request. If the total size of your result set is greater than one page size, you must paginate the response. See the `cursor` field.
|
388
|
+
# The type of this field is nilable +Integer+.
|
389
|
+
#
|
390
|
+
# == Returns:
|
391
|
+
# An object with the following fields:
|
392
|
+
# scim_groups::
|
393
|
+
# A list of SCIM Connection Groups belonging to the connection.
|
394
|
+
# The type of this field is list of +SCIMGroup+ (+object+).
|
395
|
+
# status_code::
|
396
|
+
# (no documentation yet)
|
397
|
+
# The type of this field is +Integer+.
|
398
|
+
# next_cursor::
|
399
|
+
# The `next_cursor` string is returned when your search result contains more than one page of results. This value is passed into your next search call in the `cursor` field.
|
400
|
+
# The type of this field is nilable +String+.
|
401
|
+
#
|
402
|
+
# == Method Options:
|
403
|
+
# This method supports an optional +StytchB2B::SCIM::Connection::GetGroupsRequestOptions+ object which will modify the headers sent in the HTTP request.
|
404
|
+
def get_groups(
|
405
|
+
organization_id:,
|
406
|
+
connection_id:,
|
407
|
+
cursor: nil,
|
408
|
+
limit: nil,
|
409
|
+
method_options: nil
|
410
|
+
)
|
411
|
+
headers = {}
|
412
|
+
headers = headers.merge(method_options.to_headers) unless method_options.nil?
|
413
|
+
query_params = {
|
414
|
+
cursor: cursor,
|
415
|
+
limit: limit
|
416
|
+
}
|
417
|
+
request = request_with_query_params("/v1/b2b/scim/#{organization_id}/connection/#{connection_id}", query_params)
|
418
|
+
get_request(request, headers)
|
419
|
+
end
|
420
|
+
|
421
|
+
# Create a new SCIM Connection.
|
356
422
|
#
|
357
423
|
# == Parameters:
|
358
424
|
# organization_id::
|
@@ -394,7 +460,7 @@ module StytchB2B
|
|
394
460
|
post_request("/v1/b2b/scim/#{organization_id}/connection", request, headers)
|
395
461
|
end
|
396
462
|
|
397
|
-
# Get SCIM Connections.
|
463
|
+
# Get SCIM Connections.
|
398
464
|
#
|
399
465
|
# == Parameters:
|
400
466
|
# organization_id::
|
data/lib/stytch/b2b_sessions.rb
CHANGED
@@ -13,6 +13,25 @@ require_relative 'request_helper'
|
|
13
13
|
|
14
14
|
module StytchB2B
|
15
15
|
class Sessions
|
16
|
+
class RevokeRequestOptions
|
17
|
+
# Optional authorization object.
|
18
|
+
# Pass in an active Stytch Member session token or session JWT and the request
|
19
|
+
# will be run using that member's permissions.
|
20
|
+
attr_accessor :authorization
|
21
|
+
|
22
|
+
def initialize(
|
23
|
+
authorization: nil
|
24
|
+
)
|
25
|
+
@authorization = authorization
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_headers
|
29
|
+
headers = {}
|
30
|
+
headers.merge!(@authorization.to_headers) if authorization
|
31
|
+
headers
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
16
35
|
include Stytch::RequestHelper
|
17
36
|
|
18
37
|
def initialize(connection, project_id, policy_cache)
|
@@ -70,7 +89,7 @@ module StytchB2B
|
|
70
89
|
|
71
90
|
# Authenticates a Session and updates its lifetime by the specified `session_duration_minutes`. If the `session_duration_minutes` is not specified, a Session will not be extended. This endpoint requires either a `session_jwt` or `session_token` be included in the request. It will return an error if both are present.
|
72
91
|
#
|
73
|
-
# You may provide a JWT that needs to be refreshed and is expired according to its `exp` claim. A new JWT will be returned if both the signature and the underlying Session are still valid. See our [How to use Stytch Session JWTs](https://stytch.com/docs/b2b/guides/sessions/using-jwts) guide for more information.
|
92
|
+
# You may provide a JWT that needs to be refreshed and is expired according to its `exp` claim. A new JWT will be returned if both the signature and the underlying Session are still valid. See our [How to use Stytch Session JWTs](https://stytch.com/docs/b2b/guides/sessions/resources/using-jwts) guide for more information.
|
74
93
|
#
|
75
94
|
# If an `authorization_check` object is passed in, this method will also check if the Member is authorized to perform the given action on the given Resource in the specified Organization. A Member is authorized if their Member Session contains a Role, assigned [explicitly or implicitly](https://stytch.com/docs/b2b/guides/rbac/role-assignment), with adequate permissions.
|
76
95
|
# In addition, the `organization_id` passed in the authorization check must match the Member's Organization.
|
@@ -189,13 +208,18 @@ module StytchB2B
|
|
189
208
|
# status_code::
|
190
209
|
# The HTTP status code of the response. Stytch follows standard HTTP response status code patterns, e.g. 2XX values equate to success, 3XX values are redirects, 4XX are client errors, and 5XX are server errors.
|
191
210
|
# The type of this field is +Integer+.
|
211
|
+
#
|
212
|
+
# == Method Options:
|
213
|
+
# This method supports an optional +StytchB2B::Sessions::RevokeRequestOptions+ object which will modify the headers sent in the HTTP request.
|
192
214
|
def revoke(
|
193
215
|
member_session_id: nil,
|
194
216
|
session_token: nil,
|
195
217
|
session_jwt: nil,
|
196
|
-
member_id: nil
|
218
|
+
member_id: nil,
|
219
|
+
method_options: nil
|
197
220
|
)
|
198
221
|
headers = {}
|
222
|
+
headers = headers.merge(method_options.to_headers) unless method_options.nil?
|
199
223
|
request = {}
|
200
224
|
request[:member_session_id] = member_session_id unless member_session_id.nil?
|
201
225
|
request[:session_token] = session_token unless session_token.nil?
|
@@ -397,7 +421,7 @@ module StytchB2B
|
|
397
421
|
#
|
398
422
|
# If you're using your own JWT validation library, many have built-in support for JWKS rotation, and you'll just need to supply this API endpoint. If not, your application should decide which JWKS to use for validation by inspecting the `kid` value.
|
399
423
|
#
|
400
|
-
# See our [How to use Stytch Session JWTs](https://stytch.com/docs/b2b/guides/sessions/using-jwts) guide for more information.
|
424
|
+
# See our [How to use Stytch Session JWTs](https://stytch.com/docs/b2b/guides/sessions/resources/using-jwts) guide for more information.
|
401
425
|
#
|
402
426
|
# == Parameters:
|
403
427
|
# project_id::
|
@@ -436,14 +460,17 @@ module StytchB2B
|
|
436
460
|
# Note that the 'user_id' field of the returned session is DEPRECATED: Use member_id instead
|
437
461
|
# This field will be removed in a future MAJOR release.
|
438
462
|
# If max_token_age_seconds is not supplied 300 seconds will be used as the default.
|
463
|
+
# If clock_tolerance_seconds is not supplied 0 seconds will be used as the default.
|
439
464
|
def authenticate_jwt(
|
440
465
|
session_jwt,
|
441
466
|
max_token_age_seconds: nil,
|
442
467
|
session_duration_minutes: nil,
|
443
468
|
session_custom_claims: nil,
|
444
|
-
authorization_check: nil
|
469
|
+
authorization_check: nil,
|
470
|
+
clock_tolerance_seconds: nil
|
445
471
|
)
|
446
472
|
max_token_age_seconds = 300 if max_token_age_seconds.nil?
|
473
|
+
clock_tolerance_seconds = 0 if clock_tolerance_seconds.nil?
|
447
474
|
|
448
475
|
if max_token_age_seconds == 0
|
449
476
|
return authenticate(
|
@@ -454,7 +481,7 @@ module StytchB2B
|
|
454
481
|
)
|
455
482
|
end
|
456
483
|
|
457
|
-
decoded_jwt = authenticate_jwt_local(session_jwt, max_token_age_seconds: max_token_age_seconds, authorization_check: authorization_check)
|
484
|
+
decoded_jwt = authenticate_jwt_local(session_jwt, max_token_age_seconds: max_token_age_seconds, authorization_check: authorization_check, clock_tolerance_seconds: clock_tolerance_seconds)
|
458
485
|
return decoded_jwt unless decoded_jwt.nil?
|
459
486
|
|
460
487
|
authenticate(
|
@@ -478,13 +505,15 @@ module StytchB2B
|
|
478
505
|
# function to get the JWK
|
479
506
|
# This method never authenticates a JWT directly with the API
|
480
507
|
# If max_token_age_seconds is not supplied 300 seconds will be used as the default.
|
481
|
-
|
508
|
+
# If clock_tolerance_seconds is not supplied 0 seconds will be used as the default.
|
509
|
+
def authenticate_jwt_local(session_jwt, max_token_age_seconds: nil, authorization_check: nil, clock_tolerance_seconds: nil)
|
482
510
|
max_token_age_seconds = 300 if max_token_age_seconds.nil?
|
511
|
+
clock_tolerance_seconds = 0 if clock_tolerance_seconds.nil?
|
483
512
|
|
484
513
|
issuer = 'stytch.com/' + @project_id
|
485
514
|
begin
|
486
515
|
decoded_token = JWT.decode session_jwt, nil, true,
|
487
|
-
{ jwks: @jwks_loader, iss: issuer, verify_iss: true, aud: @project_id, verify_aud: true, algorithms: ['RS256'] }
|
516
|
+
{ jwks: @jwks_loader, iss: issuer, verify_iss: true, aud: @project_id, verify_aud: true, algorithms: ['RS256'], nbf_leeway: clock_tolerance_seconds }
|
488
517
|
|
489
518
|
session = decoded_token[0]
|
490
519
|
iat_time = Time.at(session['iat']).to_datetime
|
data/lib/stytch/b2b_sso.rb
CHANGED
@@ -58,7 +58,7 @@ module StytchB2B
|
|
58
58
|
@saml = StytchB2B::SSO::SAML.new(@connection)
|
59
59
|
end
|
60
60
|
|
61
|
-
# Get all SSO Connections owned by the organization.
|
61
|
+
# Get all SSO Connections owned by the organization.
|
62
62
|
#
|
63
63
|
# == Parameters:
|
64
64
|
# organization_id::
|
@@ -96,7 +96,7 @@ module StytchB2B
|
|
96
96
|
get_request(request, headers)
|
97
97
|
end
|
98
98
|
|
99
|
-
# Delete an existing SSO connection.
|
99
|
+
# Delete an existing SSO connection.
|
100
100
|
#
|
101
101
|
# == Parameters:
|
102
102
|
# organization_id::
|
@@ -300,7 +300,7 @@ module StytchB2B
|
|
300
300
|
@connection = connection
|
301
301
|
end
|
302
302
|
|
303
|
-
# Create a new OIDC Connection.
|
303
|
+
# Create a new OIDC Connection.
|
304
304
|
#
|
305
305
|
# == Parameters:
|
306
306
|
# organization_id::
|
@@ -360,7 +360,6 @@ module StytchB2B
|
|
360
360
|
# * `token_url`
|
361
361
|
# * `userinfo_url`
|
362
362
|
# * `jwks_url`
|
363
|
-
# /%}
|
364
363
|
#
|
365
364
|
# == Parameters:
|
366
365
|
# organization_id::
|
@@ -528,7 +527,7 @@ module StytchB2B
|
|
528
527
|
@connection = connection
|
529
528
|
end
|
530
529
|
|
531
|
-
# Create a new SAML Connection.
|
530
|
+
# Create a new SAML Connection.
|
532
531
|
#
|
533
532
|
# == Parameters:
|
534
533
|
# organization_id::
|
@@ -577,7 +576,6 @@ module StytchB2B
|
|
577
576
|
# * `attribute_mapping`
|
578
577
|
# * `idp_entity_id`
|
579
578
|
# * `x509_certificate`
|
580
|
-
# /%}
|
581
579
|
#
|
582
580
|
# == Parameters:
|
583
581
|
# organization_id::
|
@@ -670,7 +668,6 @@ module StytchB2B
|
|
670
668
|
# * `idp_entity_id`
|
671
669
|
# * `x509_certificate`
|
672
670
|
# * `attribute_mapping` (must be supplied using [Update SAML Connection](update-saml-connection))
|
673
|
-
# /%}
|
674
671
|
#
|
675
672
|
# == Parameters:
|
676
673
|
# organization_id::
|
@@ -715,7 +712,6 @@ module StytchB2B
|
|
715
712
|
# Delete a SAML verification certificate.
|
716
713
|
#
|
717
714
|
# You may need to do this when rotating certificates from your IdP, since Stytch allows a maximum of 5 certificates per connection. There must always be at least one certificate per active connection.
|
718
|
-
# /%}
|
719
715
|
#
|
720
716
|
# == Parameters:
|
721
717
|
# organization_id::
|
data/lib/stytch/client.rb
CHANGED
@@ -22,11 +22,12 @@ module Stytch
|
|
22
22
|
@api_host = api_host(env, project_id)
|
23
23
|
@project_id = project_id
|
24
24
|
@secret = secret
|
25
|
+
@is_b2b_client = false
|
25
26
|
|
26
27
|
create_connection(&block)
|
27
28
|
|
28
29
|
@crypto_wallets = Stytch::CryptoWallets.new(@connection)
|
29
|
-
@m2m = Stytch::M2M.new(@connection, @project_id)
|
30
|
+
@m2m = Stytch::M2M.new(@connection, @project_id, @is_b2b_client)
|
30
31
|
@magic_links = Stytch::MagicLinks.new(@connection)
|
31
32
|
@oauth = Stytch::OAuth.new(@connection)
|
32
33
|
@otps = Stytch::OTPs.new(@connection)
|
data/lib/stytch/m2m.rb
CHANGED
@@ -13,12 +13,13 @@ module Stytch
|
|
13
13
|
include Stytch::RequestHelper
|
14
14
|
attr_reader :clients
|
15
15
|
|
16
|
-
def initialize(connection, project_id)
|
16
|
+
def initialize(connection, project_id, is_b2b_client)
|
17
17
|
@connection = connection
|
18
18
|
|
19
19
|
@clients = Stytch::M2M::Clients.new(@connection)
|
20
20
|
@project_id = project_id
|
21
21
|
@cache_last_update = 0
|
22
|
+
@is_b2b_client = is_b2b_client
|
22
23
|
@jwks_loader = lambda do |options|
|
23
24
|
@cached_keys = nil if options[:invalidate] && @cache_last_update < Time.now.to_i - 300
|
24
25
|
@cached_keys ||= begin
|
@@ -37,9 +38,11 @@ module Stytch
|
|
37
38
|
def get_jwks(
|
38
39
|
project_id:
|
39
40
|
)
|
41
|
+
headers = {}
|
40
42
|
query_params = {}
|
41
|
-
|
42
|
-
|
43
|
+
path = @is_b2b_client ? "/v1/b2b/sessions/jwks/#{project_id}" : "/v1/sessions/jwks/#{project_id}"
|
44
|
+
request = request_with_query_params(path, query_params)
|
45
|
+
get_request(request, headers)
|
43
46
|
end
|
44
47
|
# ENDMANUAL(M2M::get_jwks)
|
45
48
|
|
@@ -100,6 +103,9 @@ module Stytch
|
|
100
103
|
# A function to check if the token has the required scopes. This defaults to a function that assumes
|
101
104
|
# scopes are either direct string matches or written in the form "action:resource". See the
|
102
105
|
# documentation for +perform_authorization_check+ for more information.
|
106
|
+
# clock_tolerance_seconds:
|
107
|
+
# The tolerance to use during verification of the nbf claim. This can help with clock drift issues.
|
108
|
+
# The type of this field is nilable +Integer+.
|
103
109
|
# == Returns:
|
104
110
|
# +nil+ if the token could not be validated, or an object with the following fields:
|
105
111
|
# scopes::
|
@@ -115,10 +121,11 @@ module Stytch
|
|
115
121
|
access_token:,
|
116
122
|
required_scopes: nil,
|
117
123
|
max_token_age: nil,
|
118
|
-
scope_authorization_func: method(:perform_authorization_check)
|
124
|
+
scope_authorization_func: method(:perform_authorization_check),
|
125
|
+
clock_tolerance_seconds: nil
|
119
126
|
)
|
120
127
|
# Intentionally allow this to re-raise if authentication fails
|
121
|
-
decoded_jwt = authenticate_token_local(access_token)
|
128
|
+
decoded_jwt = authenticate_token_local(access_token, clock_tolerance_seconds: clock_tolerance_seconds)
|
122
129
|
|
123
130
|
iat_time = Time.at(decoded_jwt['iat']).to_datetime
|
124
131
|
|
@@ -173,11 +180,13 @@ module Stytch
|
|
173
180
|
end
|
174
181
|
|
175
182
|
# Parse a M2M token and verify the signature locally (without calling /authenticate in the API)
|
176
|
-
|
183
|
+
# If clock_tolerance_seconds is not supplied 0 seconds will be used as the default.
|
184
|
+
def authenticate_token_local(jwt, clock_tolerance_seconds: nil)
|
185
|
+
clock_tolerance_seconds = 0 if clock_tolerance_seconds.nil?
|
177
186
|
issuer = 'stytch.com/' + @project_id
|
178
187
|
begin
|
179
188
|
decoded_token = JWT.decode jwt, nil, true,
|
180
|
-
{ jwks: @jwks_loader, iss: issuer, verify_iss: true, aud: @project_id, verify_aud: true, algorithms: ['RS256'] }
|
189
|
+
{ jwks: @jwks_loader, iss: issuer, verify_iss: true, aud: @project_id, verify_aud: true, algorithms: ['RS256'], nbf_leeway: clock_tolerance_seconds }
|
181
190
|
decoded_token[0]
|
182
191
|
rescue JWT::InvalidIssuerError
|
183
192
|
raise JWTInvalidIssuerError
|
data/lib/stytch/passwords.rb
CHANGED
@@ -34,7 +34,7 @@ module Stytch
|
|
34
34
|
# The email address of the end user.
|
35
35
|
# The type of this field is +String+.
|
36
36
|
# password::
|
37
|
-
# The password
|
37
|
+
# The password for the user. Any UTF8 character is allowed, e.g. spaces, emojis, non-English characers, etc.
|
38
38
|
# The type of this field is +String+.
|
39
39
|
# session_duration_minutes::
|
40
40
|
# Set the session lifetime to be this many minutes from now. This will start a new session if one doesn't already exist,
|
@@ -127,7 +127,7 @@ module Stytch
|
|
127
127
|
# The email address of the end user.
|
128
128
|
# The type of this field is +String+.
|
129
129
|
# password::
|
130
|
-
# The password
|
130
|
+
# The password for the user. Any UTF8 character is allowed, e.g. spaces, emojis, non-English characers, etc.
|
131
131
|
# The type of this field is +String+.
|
132
132
|
# session_token::
|
133
133
|
# The `session_token` associated with a User's existing Session.
|
@@ -214,7 +214,7 @@ module Stytch
|
|
214
214
|
#
|
215
215
|
# == Parameters:
|
216
216
|
# password::
|
217
|
-
# The password
|
217
|
+
# The password for the user. Any UTF8 character is allowed, e.g. spaces, emojis, non-English characers, etc.
|
218
218
|
# The type of this field is +String+.
|
219
219
|
# email::
|
220
220
|
# The email address of the end user.
|
@@ -456,7 +456,7 @@ module Stytch
|
|
456
456
|
# See examples and read more about redirect URLs [here](https://stytch.com/docs/guides/dashboard/redirect-urls).
|
457
457
|
# The type of this field is +String+.
|
458
458
|
# password::
|
459
|
-
# The password
|
459
|
+
# The password for the user. Any UTF8 character is allowed, e.g. spaces, emojis, non-English characers, etc.
|
460
460
|
# The type of this field is +String+.
|
461
461
|
# session_token::
|
462
462
|
# The `session_token` associated with a User's existing Session.
|
@@ -651,7 +651,7 @@ module Stytch
|
|
651
651
|
#
|
652
652
|
# == Parameters:
|
653
653
|
# password::
|
654
|
-
# The password
|
654
|
+
# The password for the user. Any UTF8 character is allowed, e.g. spaces, emojis, non-English characers, etc.
|
655
655
|
# The type of this field is +String+.
|
656
656
|
# session_token::
|
657
657
|
# The `session_token` associated with a User's existing Session.
|
data/lib/stytch/sessions.rb
CHANGED
@@ -203,13 +203,16 @@ module Stytch
|
|
203
203
|
# max_token_age_seconds seconds ago, then just verify locally and don't call the API
|
204
204
|
# To force remote validation for all tokens, set max_token_age_seconds to 0 or call authenticate()
|
205
205
|
# If max_token_age_seconds is not supplied 300 seconds will be used as the default.
|
206
|
+
# If clock_tolerance_seconds is not supplied 0 seconds will be used as the default.
|
206
207
|
def authenticate_jwt(
|
207
208
|
session_jwt,
|
208
209
|
max_token_age_seconds: nil,
|
209
210
|
session_duration_minutes: nil,
|
210
|
-
session_custom_claims: nil
|
211
|
+
session_custom_claims: nil,
|
212
|
+
clock_tolerance_seconds: nil
|
211
213
|
)
|
212
214
|
max_token_age_seconds = 300 if max_token_age_seconds.nil?
|
215
|
+
clock_tolerance_seconds = 0 if clock_tolerance_seconds.nil?
|
213
216
|
|
214
217
|
if max_token_age_seconds == 0
|
215
218
|
return authenticate(
|
@@ -219,7 +222,11 @@ module Stytch
|
|
219
222
|
)
|
220
223
|
end
|
221
224
|
|
222
|
-
session = authenticate_jwt_local(
|
225
|
+
session = authenticate_jwt_local(
|
226
|
+
session_jwt,
|
227
|
+
max_token_age_seconds: max_token_age_seconds,
|
228
|
+
clock_tolerance_seconds: clock_tolerance_seconds
|
229
|
+
)
|
223
230
|
return session unless session.nil?
|
224
231
|
|
225
232
|
authenticate(
|
@@ -241,13 +248,15 @@ module Stytch
|
|
241
248
|
# function to get the JWK
|
242
249
|
# This method never authenticates a JWT directly with the API
|
243
250
|
# If max_token_age_seconds is not supplied 300 seconds will be used as the default.
|
244
|
-
|
251
|
+
# If clock_tolerance_seconds is not supplied 0 seconds will be used as the default.
|
252
|
+
def authenticate_jwt_local(session_jwt, max_token_age_seconds: nil, clock_tolerance_seconds: nil)
|
245
253
|
max_token_age_seconds = 300 if max_token_age_seconds.nil?
|
254
|
+
clock_tolerance_seconds = 0 if clock_tolerance_seconds.nil?
|
246
255
|
|
247
256
|
issuer = 'stytch.com/' + @project_id
|
248
257
|
begin
|
249
258
|
decoded_token = JWT.decode session_jwt, nil, true,
|
250
|
-
{ jwks: @jwks_loader, iss: issuer, verify_iss: true, aud: @project_id, verify_aud: true, algorithms: ['RS256'] }
|
259
|
+
{ jwks: @jwks_loader, iss: issuer, verify_iss: true, aud: @project_id, verify_aud: true, algorithms: ['RS256'], nbf_leeway: clock_tolerance_seconds }
|
251
260
|
|
252
261
|
session = decoded_token[0]
|
253
262
|
iat_time = Time.at(session['iat']).to_datetime
|
data/lib/stytch/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stytch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 9.
|
4
|
+
version: 9.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- stytch
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-07-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|