mobiscroll-connect 1.1.0 → 1.2.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 +7 -2
- data/lib/mobiscroll/connect/errors.rb +28 -1
- data/lib/mobiscroll/connect/models.rb +31 -3
- data/lib/mobiscroll/connect/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: b31a5377ff60ec4d4e5601e084d736e26bad0250ffb3c57f21e9763cbe32ce1f
|
|
4
|
+
data.tar.gz: ecaf0a97ba89509bd0ce3eba1f33d37024d0a3cdac5ff2e6cfbe85ec9bdd0395
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f98b8378045037ee79e53b5b5394beeb42b1ea92a0641cf0412e0598ec9bf92296568ebf8c46d625d260967e397e891110c204bd5fe6e69ae60e8d7e95cfccc2
|
|
7
|
+
data.tar.gz: 9a92b7c19a5dada68228e6d2533b996352e74b104089f3cac3676db05e9d877b08eaedc207e268067710ca81b9ea6ce85f6952086f156c047ffe59b5852a5c8b
|
data/README.md
CHANGED
|
@@ -35,7 +35,7 @@ client = Mobiscroll::Connect::Client.new(
|
|
|
35
35
|
```ruby
|
|
36
36
|
url = client.auth.generate_auth_url(
|
|
37
37
|
user_id: 'user-123',
|
|
38
|
-
lng: 'es', # optional: Connect page language
|
|
38
|
+
lng: 'es', # optional: Connect page language, see https://mobiscroll.com/docs/connect/localization#supported-languages
|
|
39
39
|
providers: [
|
|
40
40
|
Mobiscroll::Connect::Provider::GOOGLE,
|
|
41
41
|
Mobiscroll::Connect::Provider::MICROSOFT
|
|
@@ -69,7 +69,12 @@ client.set_credentials(
|
|
|
69
69
|
```ruby
|
|
70
70
|
status = client.auth.get_connection_status
|
|
71
71
|
status.connections.each do |provider, accounts|
|
|
72
|
-
accounts.each
|
|
72
|
+
accounts.each do |a|
|
|
73
|
+
puts "#{provider}: #{a.display}"
|
|
74
|
+
# Google's consent screen lets the user untick the calendar permission and still
|
|
75
|
+
# finish signing in. Such an account is connected but lists no calendars.
|
|
76
|
+
puts " #{a.id} must reconnect and allow calendar access" if a.calendar_permission_granted == false
|
|
77
|
+
end
|
|
73
78
|
end
|
|
74
79
|
```
|
|
75
80
|
|
|
@@ -17,6 +17,25 @@ module Mobiscroll
|
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
# Raised when no connected account has the calendar access the request needs.
|
|
21
|
+
#
|
|
22
|
+
# The user completed sign-in but did not grant the calendar permission — Google's
|
|
23
|
+
# consent screen presents it as a separate checkbox. This cannot be repaired
|
|
24
|
+
# server-side, because providers only issue permissions at consent time: the
|
|
25
|
+
# accounts in +accounts+ have to run the connect flow again and allow access.
|
|
26
|
+
#
|
|
27
|
+
# Subclasses AuthenticationError, so existing rescue clauses keep working.
|
|
28
|
+
class CalendarPermissionError < AuthenticationError
|
|
29
|
+
# Array of BlockedAccount structs that must reconnect.
|
|
30
|
+
attr_reader :accounts
|
|
31
|
+
|
|
32
|
+
def initialize(message = 'No connected account has calendar access', accounts: [])
|
|
33
|
+
super(message)
|
|
34
|
+
@code = 'CALENDAR_PERMISSION_REQUIRED'
|
|
35
|
+
@accounts = accounts
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
20
39
|
class NotFoundError < Error
|
|
21
40
|
def initialize(message = 'Resource not found')
|
|
22
41
|
super(message, code: 'NOT_FOUND_ERROR')
|
|
@@ -67,7 +86,15 @@ module Mobiscroll
|
|
|
67
86
|
|
|
68
87
|
case status
|
|
69
88
|
when 401, 403
|
|
70
|
-
|
|
89
|
+
# A 403 the caller can act on: the account connected but never granted
|
|
90
|
+
# calendar access, so it is raised as its own type naming the accounts.
|
|
91
|
+
hash = body.is_a?(Hash) ? body : {}
|
|
92
|
+
if status == 403 && (hash['code'] || hash[:code]) == 'calendar_permission_required'
|
|
93
|
+
raw = hash['accounts'] || hash[:accounts]
|
|
94
|
+
CalendarPermissionError.new(message, accounts: Array(raw).filter_map { |a| BlockedAccount.from_h(a) })
|
|
95
|
+
else
|
|
96
|
+
AuthenticationError.new(message)
|
|
97
|
+
end
|
|
71
98
|
when 404
|
|
72
99
|
NotFoundError.new(message)
|
|
73
100
|
when 400, 422
|
|
@@ -35,12 +35,40 @@ module Mobiscroll
|
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
#
|
|
39
|
-
|
|
38
|
+
# A connected account that withheld calendar access on its provider's consent screen.
|
|
39
|
+
BlockedAccount = Struct.new(:provider, :account, keyword_init: true) do
|
|
40
40
|
def self.from_h(hash)
|
|
41
41
|
return nil if hash.nil?
|
|
42
42
|
|
|
43
|
-
new(
|
|
43
|
+
new(
|
|
44
|
+
provider: hash['provider'] || hash[:provider],
|
|
45
|
+
account: hash['account'] || hash[:account]
|
|
46
|
+
)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# One connected calendar account.
|
|
51
|
+
#
|
|
52
|
+
# `granted_scopes` are the scopes the provider actually granted, which are not
|
|
53
|
+
# necessarily the ones Connect asked for: Google's consent screen lets the user untick
|
|
54
|
+
# the calendar permission and still complete sign-in.
|
|
55
|
+
#
|
|
56
|
+
# `calendar_permission_granted` is false for exactly those accounts — connected, but
|
|
57
|
+
# no calendars can be read from them until the user reconnects and allows access. It
|
|
58
|
+
# is nil when the question does not apply (Apple and CalDav authenticate with a
|
|
59
|
+
# username and app password) or no scopes were recorded for the account.
|
|
60
|
+
ConnectedAccount = Struct.new(:id, :display, :granted_scopes, :calendar_permission_granted, keyword_init: true) do
|
|
61
|
+
def self.from_h(hash)
|
|
62
|
+
return nil if hash.nil?
|
|
63
|
+
|
|
64
|
+
key = 'calendarPermissionGranted'
|
|
65
|
+
granted = hash.key?(key) ? hash[key] : hash[key.to_sym]
|
|
66
|
+
new(
|
|
67
|
+
id: hash['id'] || hash[:id],
|
|
68
|
+
display: hash['display'] || hash[:display],
|
|
69
|
+
granted_scopes: Array(hash['grantedScopes'] || hash[:grantedScopes]),
|
|
70
|
+
calendar_permission_granted: granted
|
|
71
|
+
)
|
|
44
72
|
end
|
|
45
73
|
end
|
|
46
74
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mobiscroll-connect
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mobiscroll
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-08-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: base64
|