react-native-nitro-auth 0.5.5 → 0.5.6
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.
- package/README.md +22 -17
- package/android/proguard-rules.pro +7 -1
- package/android/src/main/AndroidManifest.xml +12 -0
- package/android/src/main/cpp/PlatformAuth+Android.cpp +260 -67
- package/android/src/main/java/com/auth/AuthAdapter.kt +217 -146
- package/android/src/main/java/com/auth/GoogleSignInActivity.kt +9 -5
- package/cpp/HybridAuth.cpp +79 -64
- package/cpp/HybridAuth.hpp +9 -7
- package/cpp/JSONSerializer.hpp +3 -0
- package/ios/AuthAdapter.swift +173 -60
- package/ios/PlatformAuth+iOS.mm +10 -3
- package/lib/commonjs/Auth.web.js +50 -10
- package/lib/commonjs/Auth.web.js.map +1 -1
- package/lib/commonjs/index.web.js +30 -12
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/service.js +9 -7
- package/lib/commonjs/service.js.map +1 -1
- package/lib/commonjs/service.web.js +65 -13
- package/lib/commonjs/service.web.js.map +1 -1
- package/lib/commonjs/ui/social-button.js +19 -14
- package/lib/commonjs/ui/social-button.js.map +1 -1
- package/lib/commonjs/ui/social-button.web.js +16 -10
- package/lib/commonjs/ui/social-button.web.js.map +1 -1
- package/lib/commonjs/use-auth.js +13 -5
- package/lib/commonjs/use-auth.js.map +1 -1
- package/lib/commonjs/utils/logger.js +1 -0
- package/lib/commonjs/utils/logger.js.map +1 -1
- package/lib/module/Auth.web.js +50 -10
- package/lib/module/Auth.web.js.map +1 -1
- package/lib/module/global.d.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +2 -1
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/service.js +9 -7
- package/lib/module/service.js.map +1 -1
- package/lib/module/service.web.js +65 -13
- package/lib/module/service.web.js.map +1 -1
- package/lib/module/ui/social-button.js +19 -14
- package/lib/module/ui/social-button.js.map +1 -1
- package/lib/module/ui/social-button.web.js +16 -10
- package/lib/module/ui/social-button.web.js.map +1 -1
- package/lib/module/use-auth.js +13 -5
- package/lib/module/use-auth.js.map +1 -1
- package/lib/module/utils/logger.js +1 -0
- package/lib/module/utils/logger.js.map +1 -1
- package/lib/typescript/commonjs/Auth.web.d.ts +5 -1
- package/lib/typescript/commonjs/Auth.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +1 -1
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.web.d.ts +2 -1
- package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/service.d.ts.map +1 -1
- package/lib/typescript/commonjs/service.web.d.ts +2 -18
- package/lib/typescript/commonjs/service.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/social-button.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/social-button.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/use-auth.d.ts.map +1 -1
- package/lib/typescript/commonjs/utils/logger.d.ts.map +1 -1
- package/lib/typescript/module/Auth.web.d.ts +5 -1
- package/lib/typescript/module/Auth.web.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +1 -1
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/index.web.d.ts +2 -1
- package/lib/typescript/module/index.web.d.ts.map +1 -1
- package/lib/typescript/module/service.d.ts.map +1 -1
- package/lib/typescript/module/service.web.d.ts +2 -18
- package/lib/typescript/module/service.web.d.ts.map +1 -1
- package/lib/typescript/module/ui/social-button.d.ts.map +1 -1
- package/lib/typescript/module/ui/social-button.web.d.ts.map +1 -1
- package/lib/typescript/module/use-auth.d.ts.map +1 -1
- package/lib/typescript/module/utils/logger.d.ts.map +1 -1
- package/package.json +2 -4
- package/src/Auth.web.ts +77 -11
- package/src/global.d.ts +0 -11
- package/src/index.ts +5 -1
- package/src/index.web.ts +6 -1
- package/src/service.ts +9 -7
- package/src/service.web.ts +84 -15
- package/src/ui/social-button.tsx +21 -9
- package/src/ui/social-button.web.tsx +17 -4
- package/src/use-auth.ts +35 -8
- package/src/utils/logger.ts +1 -0
|
@@ -21,13 +21,15 @@ class GoogleSignInActivity : ComponentActivity() {
|
|
|
21
21
|
private const val EXTRA_SCOPES = "scopes"
|
|
22
22
|
private const val EXTRA_LOGIN_HINT = "login_hint"
|
|
23
23
|
private const val EXTRA_FORCE_PICKER = "force_picker"
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
private const val EXTRA_ORIGIN = "origin"
|
|
25
|
+
|
|
26
|
+
fun createIntent(context: Context, clientId: String, scopes: Array<String>, loginHint: String?, forcePicker: Boolean = false, origin: String = "login"): Intent {
|
|
26
27
|
return Intent(context, GoogleSignInActivity::class.java).apply {
|
|
27
28
|
putExtra(EXTRA_CLIENT_ID, clientId)
|
|
28
29
|
putExtra(EXTRA_SCOPES, scopes)
|
|
29
30
|
putExtra(EXTRA_LOGIN_HINT, loginHint)
|
|
30
31
|
putExtra(EXTRA_FORCE_PICKER, forcePicker)
|
|
32
|
+
putExtra(EXTRA_ORIGIN, origin)
|
|
31
33
|
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
32
34
|
}
|
|
33
35
|
}
|
|
@@ -36,13 +38,14 @@ class GoogleSignInActivity : ComponentActivity() {
|
|
|
36
38
|
private val signInLauncher = registerForActivityResult(
|
|
37
39
|
ActivityResultContracts.StartActivityForResult()
|
|
38
40
|
) { result ->
|
|
41
|
+
val origin = intent.getStringExtra(EXTRA_ORIGIN) ?: "login"
|
|
39
42
|
try {
|
|
40
43
|
val task = GoogleSignIn.getSignedInAccountFromIntent(result.data)
|
|
41
44
|
val account = task.getResult(ApiException::class.java)
|
|
42
45
|
val scopes = intent.getStringArrayExtra(EXTRA_SCOPES)?.toList() ?: emptyList()
|
|
43
|
-
AuthAdapter.onSignInSuccess(account, scopes)
|
|
46
|
+
AuthAdapter.onSignInSuccess(account, scopes, origin)
|
|
44
47
|
} catch (e: ApiException) {
|
|
45
|
-
AuthAdapter.onSignInError(e.statusCode, e.message)
|
|
48
|
+
AuthAdapter.onSignInError(e.statusCode, e.message, origin)
|
|
46
49
|
}
|
|
47
50
|
finish()
|
|
48
51
|
}
|
|
@@ -54,8 +57,9 @@ class GoogleSignInActivity : ComponentActivity() {
|
|
|
54
57
|
val loginHint = intent.getStringExtra(EXTRA_LOGIN_HINT)
|
|
55
58
|
val forcePicker = intent.getBooleanExtra(EXTRA_FORCE_PICKER, false)
|
|
56
59
|
|
|
60
|
+
val origin = intent.getStringExtra(EXTRA_ORIGIN) ?: "login"
|
|
57
61
|
if (clientId == null) {
|
|
58
|
-
AuthAdapter.onSignInError(8, "Missing client ID")
|
|
62
|
+
AuthAdapter.onSignInError(8, "Missing client ID", origin)
|
|
59
63
|
finish()
|
|
60
64
|
return
|
|
61
65
|
}
|
package/cpp/HybridAuth.cpp
CHANGED
|
@@ -1,23 +1,21 @@
|
|
|
1
1
|
#include "HybridAuth.hpp"
|
|
2
2
|
#include "PlatformAuth.hpp"
|
|
3
|
-
#include <
|
|
3
|
+
#include <algorithm>
|
|
4
4
|
#include <chrono>
|
|
5
5
|
|
|
6
6
|
namespace margelo::nitro::NitroAuth {
|
|
7
|
-
|
|
8
|
-
bool HybridAuth::sLoggingEnabled = false;
|
|
9
7
|
|
|
10
8
|
HybridAuth::HybridAuth() : HybridObject(TAG) {
|
|
11
9
|
// In-memory only - no internal persistence.
|
|
12
10
|
}
|
|
13
11
|
|
|
14
12
|
std::optional<AuthUser> HybridAuth::getCurrentUser() {
|
|
15
|
-
std::lock_guard<std::
|
|
13
|
+
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
|
16
14
|
return _currentUser;
|
|
17
15
|
}
|
|
18
16
|
|
|
19
17
|
std::vector<std::string> HybridAuth::getGrantedScopes() {
|
|
20
|
-
std::lock_guard<std::
|
|
18
|
+
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
|
21
19
|
return _grantedScopes;
|
|
22
20
|
}
|
|
23
21
|
|
|
@@ -29,7 +27,7 @@ void HybridAuth::notifyAuthStateChanged() {
|
|
|
29
27
|
std::optional<AuthUser> user;
|
|
30
28
|
std::vector<std::function<void(const std::optional<AuthUser>&)>> listeners;
|
|
31
29
|
{
|
|
32
|
-
std::lock_guard<std::
|
|
30
|
+
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
|
33
31
|
user = _currentUser;
|
|
34
32
|
for (auto const& [id, listener] : _listeners) {
|
|
35
33
|
listeners.push_back(listener);
|
|
@@ -41,30 +39,38 @@ void HybridAuth::notifyAuthStateChanged() {
|
|
|
41
39
|
}
|
|
42
40
|
|
|
43
41
|
std::function<void()> HybridAuth::onAuthStateChanged(const std::function<void(const std::optional<AuthUser>&)>& callback) {
|
|
44
|
-
std::lock_guard<std::
|
|
45
|
-
|
|
42
|
+
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
|
43
|
+
uint64_t id = _nextListenerId++;
|
|
46
44
|
_listeners[id] = callback;
|
|
47
45
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
auto weak = weak_from_this();
|
|
47
|
+
return [weak, id]() {
|
|
48
|
+
auto self = weak.lock();
|
|
49
|
+
if (!self) return;
|
|
50
|
+
auto* auth = dynamic_cast<HybridAuth*>(self.get());
|
|
51
|
+
std::lock_guard<std::recursive_mutex> lock(auth->_mutex);
|
|
52
|
+
auth->_listeners.erase(id);
|
|
51
53
|
};
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
std::function<void()> HybridAuth::onTokensRefreshed(const std::function<void(const AuthTokens&)>& callback) {
|
|
55
|
-
std::lock_guard<std::
|
|
56
|
-
|
|
57
|
+
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
|
58
|
+
uint64_t id = _nextTokenListenerId++;
|
|
57
59
|
_tokenListeners[id] = callback;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
|
|
61
|
+
auto weak = weak_from_this();
|
|
62
|
+
return [weak, id]() {
|
|
63
|
+
auto self = weak.lock();
|
|
64
|
+
if (!self) return;
|
|
65
|
+
auto* auth = dynamic_cast<HybridAuth*>(self.get());
|
|
66
|
+
std::lock_guard<std::recursive_mutex> lock(auth->_mutex);
|
|
67
|
+
auth->_tokenListeners.erase(id);
|
|
62
68
|
};
|
|
63
69
|
}
|
|
64
70
|
|
|
65
71
|
void HybridAuth::logout() {
|
|
66
72
|
{
|
|
67
|
-
std::lock_guard<std::
|
|
73
|
+
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
|
68
74
|
_currentUser = std::nullopt;
|
|
69
75
|
_grantedScopes.clear();
|
|
70
76
|
}
|
|
@@ -75,22 +81,24 @@ void HybridAuth::logout() {
|
|
|
75
81
|
std::shared_ptr<Promise<void>> HybridAuth::silentRestore() {
|
|
76
82
|
auto promise = Promise<void>::create();
|
|
77
83
|
auto silentPromise = PlatformAuth::silentRestore();
|
|
78
|
-
|
|
84
|
+
auto self = shared_from_this();
|
|
85
|
+
silentPromise->addOnResolvedListener([self, promise](const std::optional<AuthUser>& user) {
|
|
86
|
+
auto* auth = dynamic_cast<HybridAuth*>(self.get());
|
|
79
87
|
{
|
|
80
|
-
std::lock_guard<std::
|
|
81
|
-
_currentUser = user;
|
|
88
|
+
std::lock_guard<std::recursive_mutex> lock(auth->_mutex);
|
|
89
|
+
auth->_currentUser = user;
|
|
82
90
|
if (user) {
|
|
83
91
|
if (user->scopes) {
|
|
84
|
-
_grantedScopes = *user->scopes;
|
|
92
|
+
auth->_grantedScopes = *user->scopes;
|
|
85
93
|
} else {
|
|
86
|
-
_grantedScopes.clear();
|
|
94
|
+
auth->_grantedScopes.clear();
|
|
87
95
|
}
|
|
88
96
|
} else {
|
|
89
|
-
_grantedScopes.clear();
|
|
97
|
+
auth->_grantedScopes.clear();
|
|
90
98
|
}
|
|
91
99
|
}
|
|
92
100
|
// Always resolve - no session is not an error, just means user is logged out
|
|
93
|
-
notifyAuthStateChanged();
|
|
101
|
+
auth->notifyAuthStateChanged();
|
|
94
102
|
promise->resolve();
|
|
95
103
|
});
|
|
96
104
|
|
|
@@ -104,25 +112,27 @@ std::shared_ptr<Promise<void>> HybridAuth::silentRestore() {
|
|
|
104
112
|
std::shared_ptr<Promise<void>> HybridAuth::login(AuthProvider provider, const std::optional<LoginOptions>& options) {
|
|
105
113
|
auto promise = Promise<void>::create();
|
|
106
114
|
|
|
115
|
+
auto self = shared_from_this();
|
|
107
116
|
auto loginPromise = PlatformAuth::login(provider, options);
|
|
108
|
-
loginPromise->addOnResolvedListener([
|
|
117
|
+
loginPromise->addOnResolvedListener([self, promise, options](const AuthUser& user) {
|
|
118
|
+
auto* auth = dynamic_cast<HybridAuth*>(self.get());
|
|
109
119
|
{
|
|
110
|
-
std::lock_guard<std::
|
|
111
|
-
_currentUser = user;
|
|
120
|
+
std::lock_guard<std::recursive_mutex> lock(auth->_mutex);
|
|
121
|
+
auth->_currentUser = user;
|
|
112
122
|
if (user.scopes && !user.scopes->empty()) {
|
|
113
|
-
_grantedScopes = *user.scopes;
|
|
123
|
+
auth->_grantedScopes = *user.scopes;
|
|
114
124
|
} else if (options && options->scopes && !options->scopes->empty()) {
|
|
115
|
-
_grantedScopes = *options->scopes;
|
|
125
|
+
auth->_grantedScopes = *options->scopes;
|
|
116
126
|
} else {
|
|
117
|
-
_grantedScopes.clear();
|
|
127
|
+
auth->_grantedScopes.clear();
|
|
118
128
|
}
|
|
119
|
-
if (_currentUser) {
|
|
120
|
-
_currentUser->scopes = _grantedScopes.empty()
|
|
129
|
+
if (auth->_currentUser) {
|
|
130
|
+
auth->_currentUser->scopes = auth->_grantedScopes.empty()
|
|
121
131
|
? std::nullopt
|
|
122
|
-
: std::make_optional(_grantedScopes);
|
|
132
|
+
: std::make_optional(auth->_grantedScopes);
|
|
123
133
|
}
|
|
124
134
|
}
|
|
125
|
-
notifyAuthStateChanged();
|
|
135
|
+
auth->notifyAuthStateChanged();
|
|
126
136
|
promise->resolve();
|
|
127
137
|
});
|
|
128
138
|
|
|
@@ -134,19 +144,21 @@ std::shared_ptr<Promise<void>> HybridAuth::login(AuthProvider provider, const st
|
|
|
134
144
|
|
|
135
145
|
std::shared_ptr<Promise<void>> HybridAuth::requestScopes(const std::vector<std::string>& scopes) {
|
|
136
146
|
auto promise = Promise<void>::create();
|
|
147
|
+
auto self = shared_from_this();
|
|
137
148
|
auto requestPromise = PlatformAuth::requestScopes(scopes);
|
|
138
|
-
requestPromise->addOnResolvedListener([
|
|
149
|
+
requestPromise->addOnResolvedListener([self, promise, scopes](const AuthUser& user) {
|
|
150
|
+
auto* auth = dynamic_cast<HybridAuth*>(self.get());
|
|
139
151
|
{
|
|
140
|
-
std::lock_guard<std::
|
|
141
|
-
_currentUser = user;
|
|
152
|
+
std::lock_guard<std::recursive_mutex> lock(auth->_mutex);
|
|
153
|
+
auth->_currentUser = user;
|
|
142
154
|
for (const auto& scope : scopes) {
|
|
143
|
-
if (std::find(_grantedScopes.begin(), _grantedScopes.end(), scope) == _grantedScopes.end()) {
|
|
144
|
-
_grantedScopes.push_back(scope);
|
|
155
|
+
if (std::find(auth->_grantedScopes.begin(), auth->_grantedScopes.end(), scope) == auth->_grantedScopes.end()) {
|
|
156
|
+
auth->_grantedScopes.push_back(scope);
|
|
145
157
|
}
|
|
146
158
|
}
|
|
147
|
-
if (_currentUser) _currentUser->scopes = _grantedScopes;
|
|
159
|
+
if (auth->_currentUser) auth->_currentUser->scopes = auth->_grantedScopes;
|
|
148
160
|
}
|
|
149
|
-
notifyAuthStateChanged();
|
|
161
|
+
auth->notifyAuthStateChanged();
|
|
150
162
|
promise->resolve();
|
|
151
163
|
});
|
|
152
164
|
|
|
@@ -159,7 +171,7 @@ std::shared_ptr<Promise<void>> HybridAuth::requestScopes(const std::vector<std::
|
|
|
159
171
|
std::shared_ptr<Promise<void>> HybridAuth::revokeScopes(const std::vector<std::string>& scopes) {
|
|
160
172
|
auto promise = Promise<void>::create();
|
|
161
173
|
{
|
|
162
|
-
std::lock_guard<std::
|
|
174
|
+
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
|
163
175
|
_grantedScopes.erase(
|
|
164
176
|
std::remove_if(_grantedScopes.begin(), _grantedScopes.end(),
|
|
165
177
|
[&scopes](const std::string& s) {
|
|
@@ -180,7 +192,7 @@ std::shared_ptr<Promise<std::optional<std::string>>> HybridAuth::getAccessToken(
|
|
|
180
192
|
auto promise = Promise<std::optional<std::string>>::create();
|
|
181
193
|
bool needsRefresh = false;
|
|
182
194
|
{
|
|
183
|
-
std::lock_guard<std::
|
|
195
|
+
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
|
184
196
|
if (_currentUser && _currentUser->accessToken) {
|
|
185
197
|
if (_currentUser->expirationTime) {
|
|
186
198
|
auto now = std::chrono::system_clock::now().time_since_epoch() / std::chrono::milliseconds(1);
|
|
@@ -211,7 +223,7 @@ std::shared_ptr<Promise<std::optional<std::string>>> HybridAuth::getAccessToken(
|
|
|
211
223
|
std::shared_ptr<Promise<AuthTokens>> HybridAuth::refreshToken() {
|
|
212
224
|
std::shared_ptr<Promise<AuthTokens>> promise;
|
|
213
225
|
{
|
|
214
|
-
std::lock_guard<std::
|
|
226
|
+
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
|
215
227
|
if (_refreshInFlight) {
|
|
216
228
|
return _refreshInFlight;
|
|
217
229
|
}
|
|
@@ -219,38 +231,41 @@ std::shared_ptr<Promise<AuthTokens>> HybridAuth::refreshToken() {
|
|
|
219
231
|
_refreshInFlight = promise;
|
|
220
232
|
}
|
|
221
233
|
|
|
234
|
+
auto self = shared_from_this();
|
|
222
235
|
auto refreshPromise = PlatformAuth::refreshToken();
|
|
223
|
-
refreshPromise->addOnResolvedListener([
|
|
236
|
+
refreshPromise->addOnResolvedListener([self, promise](const AuthTokens& tokens) {
|
|
237
|
+
auto* auth = dynamic_cast<HybridAuth*>(self.get());
|
|
224
238
|
{
|
|
225
|
-
std::lock_guard<std::
|
|
226
|
-
if (_currentUser) {
|
|
239
|
+
std::lock_guard<std::recursive_mutex> lock(auth->_mutex);
|
|
240
|
+
if (auth->_currentUser) {
|
|
227
241
|
if (tokens.accessToken.has_value()) {
|
|
228
|
-
_currentUser->accessToken = tokens.accessToken;
|
|
242
|
+
auth->_currentUser->accessToken = tokens.accessToken;
|
|
229
243
|
}
|
|
230
244
|
if (tokens.idToken.has_value()) {
|
|
231
|
-
_currentUser->idToken = tokens.idToken;
|
|
245
|
+
auth->_currentUser->idToken = tokens.idToken;
|
|
232
246
|
}
|
|
233
247
|
if (tokens.refreshToken.has_value()) {
|
|
234
|
-
_currentUser->refreshToken = tokens.refreshToken;
|
|
248
|
+
auth->_currentUser->refreshToken = tokens.refreshToken;
|
|
235
249
|
}
|
|
236
250
|
if (tokens.expirationTime.has_value()) {
|
|
237
|
-
_currentUser->expirationTime = tokens.expirationTime;
|
|
251
|
+
auth->_currentUser->expirationTime = tokens.expirationTime;
|
|
238
252
|
}
|
|
239
253
|
}
|
|
240
|
-
if (_refreshInFlight == promise) {
|
|
241
|
-
_refreshInFlight = nullptr;
|
|
254
|
+
if (auth->_refreshInFlight == promise) {
|
|
255
|
+
auth->_refreshInFlight = nullptr;
|
|
242
256
|
}
|
|
243
257
|
}
|
|
244
|
-
notifyTokensRefreshed(tokens);
|
|
245
|
-
notifyAuthStateChanged();
|
|
258
|
+
auth->notifyTokensRefreshed(tokens);
|
|
259
|
+
auth->notifyAuthStateChanged();
|
|
246
260
|
promise->resolve(tokens);
|
|
247
261
|
});
|
|
248
|
-
|
|
249
|
-
refreshPromise->addOnRejectedListener([
|
|
262
|
+
|
|
263
|
+
refreshPromise->addOnRejectedListener([self, promise](const std::exception_ptr& error) {
|
|
264
|
+
auto* auth = dynamic_cast<HybridAuth*>(self.get());
|
|
250
265
|
{
|
|
251
|
-
std::lock_guard<std::
|
|
252
|
-
if (_refreshInFlight == promise) {
|
|
253
|
-
_refreshInFlight = nullptr;
|
|
266
|
+
std::lock_guard<std::recursive_mutex> lock(auth->_mutex);
|
|
267
|
+
if (auth->_refreshInFlight == promise) {
|
|
268
|
+
auth->_refreshInFlight = nullptr;
|
|
254
269
|
}
|
|
255
270
|
}
|
|
256
271
|
promise->reject(error);
|
|
@@ -258,14 +273,14 @@ std::shared_ptr<Promise<AuthTokens>> HybridAuth::refreshToken() {
|
|
|
258
273
|
return promise;
|
|
259
274
|
}
|
|
260
275
|
|
|
261
|
-
void HybridAuth::setLoggingEnabled(bool enabled) {
|
|
262
|
-
|
|
276
|
+
void HybridAuth::setLoggingEnabled(bool /* enabled */) {
|
|
277
|
+
// Reserved for future use — logging not yet implemented in C++ layer
|
|
263
278
|
}
|
|
264
279
|
|
|
265
280
|
void HybridAuth::notifyTokensRefreshed(const AuthTokens& tokens) {
|
|
266
281
|
std::vector<std::function<void(const AuthTokens&)>> listeners;
|
|
267
282
|
{
|
|
268
|
-
std::lock_guard<std::
|
|
283
|
+
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
|
269
284
|
for (auto const& [id, listener] : _tokenListeners) {
|
|
270
285
|
listeners.push_back(listener);
|
|
271
286
|
}
|
package/cpp/HybridAuth.hpp
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
#include "AuthUser.hpp"
|
|
5
5
|
#include "LoginOptions.hpp"
|
|
6
6
|
#include "AuthTokens.hpp"
|
|
7
|
+
#include <cstdint>
|
|
7
8
|
#include <optional>
|
|
8
9
|
#include <mutex>
|
|
9
10
|
#include <memory>
|
|
@@ -41,17 +42,18 @@ private:
|
|
|
41
42
|
private:
|
|
42
43
|
std::optional<AuthUser> _currentUser;
|
|
43
44
|
std::vector<std::string> _grantedScopes;
|
|
44
|
-
std::map<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
std::map<
|
|
48
|
-
|
|
45
|
+
std::map<uint64_t, std::function<void(const std::optional<AuthUser>&)>> _listeners;
|
|
46
|
+
uint64_t _nextListenerId = 0;
|
|
47
|
+
|
|
48
|
+
std::map<uint64_t, std::function<void(const AuthTokens&)>> _tokenListeners;
|
|
49
|
+
uint64_t _nextTokenListenerId = 0;
|
|
49
50
|
std::shared_ptr<Promise<AuthTokens>> _refreshInFlight;
|
|
50
51
|
|
|
51
|
-
|
|
52
|
+
// recursive_mutex: listeners resolved inside a lock scope may re-enter Auth methods
|
|
53
|
+
// that also acquire _mutex, causing deadlock with a non-recursive mutex.
|
|
54
|
+
std::recursive_mutex _mutex;
|
|
52
55
|
|
|
53
56
|
static constexpr auto TAG = "Auth";
|
|
54
|
-
static bool sLoggingEnabled;
|
|
55
57
|
};
|
|
56
58
|
|
|
57
59
|
} // namespace margelo::nitro::NitroAuth
|
package/cpp/JSONSerializer.hpp
CHANGED