react-native-nitro-auth 0.5.0 → 0.5.3
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 +374 -189
- package/android/src/main/cpp/PlatformAuth+Android.cpp +4 -1
- package/android/src/main/java/com/auth/AuthAdapter.kt +99 -182
- package/android/src/main/java/com/auth/GoogleSignInActivity.kt +2 -1
- package/android/src/main/java/com/auth/NitroAuthPackage.kt +2 -0
- package/app.plugin.js +2 -9
- package/cpp/AuthCache.cpp +12 -102
- package/cpp/HybridAuth.cpp +37 -61
- package/cpp/HybridAuth.hpp +2 -4
- package/ios/AuthAdapter.swift +21 -25
- package/lib/commonjs/Auth.web.js +433 -164
- package/lib/commonjs/Auth.web.js.map +1 -1
- package/lib/commonjs/index.js +0 -12
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +0 -12
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/js-storage-adapter.js +2 -0
- package/lib/commonjs/js-storage-adapter.js.map +1 -0
- package/lib/commonjs/service.js +7 -84
- package/lib/commonjs/service.js.map +1 -1
- package/lib/commonjs/service.web.js +1 -5
- package/lib/commonjs/service.web.js.map +1 -1
- package/lib/commonjs/ui/social-button.js +44 -29
- package/lib/commonjs/ui/social-button.js.map +1 -1
- package/lib/commonjs/ui/social-button.web.js +44 -29
- package/lib/commonjs/ui/social-button.web.js.map +1 -1
- package/lib/commonjs/use-auth.js +8 -2
- package/lib/commonjs/use-auth.js.map +1 -1
- package/lib/commonjs/utils/logger.js +12 -4
- package/lib/commonjs/utils/logger.js.map +1 -1
- package/lib/module/Auth.web.js +433 -164
- package/lib/module/Auth.web.js.map +1 -1
- package/lib/module/index.js +0 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +0 -1
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/js-storage-adapter.js +2 -0
- package/lib/module/js-storage-adapter.js.map +1 -0
- package/lib/module/service.js +7 -84
- package/lib/module/service.js.map +1 -1
- package/lib/module/service.web.js +1 -5
- package/lib/module/service.web.js.map +1 -1
- package/lib/module/ui/social-button.js +44 -29
- package/lib/module/ui/social-button.js.map +1 -1
- package/lib/module/ui/social-button.web.js +44 -29
- package/lib/module/ui/social-button.web.js.map +1 -1
- package/lib/module/use-auth.js +8 -2
- package/lib/module/use-auth.js.map +1 -1
- package/lib/module/utils/logger.js +12 -4
- package/lib/module/utils/logger.js.map +1 -1
- package/lib/typescript/commonjs/Auth.nitro.d.ts +5 -3
- package/lib/typescript/commonjs/Auth.nitro.d.ts.map +1 -1
- package/lib/typescript/commonjs/Auth.web.d.ts +18 -6
- package/lib/typescript/commonjs/Auth.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +1 -2
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.web.d.ts +0 -1
- package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/js-storage-adapter.d.ts +6 -0
- package/lib/typescript/commonjs/js-storage-adapter.d.ts.map +1 -0
- package/lib/typescript/commonjs/service.d.ts +1 -8
- package/lib/typescript/commonjs/service.d.ts.map +1 -1
- package/lib/typescript/commonjs/service.web.d.ts +1 -8
- package/lib/typescript/commonjs/service.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/social-button.d.ts +6 -6
- package/lib/typescript/commonjs/ui/social-button.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/social-button.web.d.ts +6 -6
- package/lib/typescript/commonjs/ui/social-button.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/use-auth.d.ts +4 -4
- package/lib/typescript/commonjs/use-auth.d.ts.map +1 -1
- package/lib/typescript/commonjs/utils/logger.d.ts +4 -4
- package/lib/typescript/commonjs/utils/logger.d.ts.map +1 -1
- package/lib/typescript/module/Auth.nitro.d.ts +5 -3
- package/lib/typescript/module/Auth.nitro.d.ts.map +1 -1
- package/lib/typescript/module/Auth.web.d.ts +18 -6
- package/lib/typescript/module/Auth.web.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +1 -2
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/index.web.d.ts +0 -1
- package/lib/typescript/module/index.web.d.ts.map +1 -1
- package/lib/typescript/module/js-storage-adapter.d.ts +6 -0
- package/lib/typescript/module/js-storage-adapter.d.ts.map +1 -0
- package/lib/typescript/module/service.d.ts +1 -8
- package/lib/typescript/module/service.d.ts.map +1 -1
- package/lib/typescript/module/service.web.d.ts +1 -8
- package/lib/typescript/module/service.web.d.ts.map +1 -1
- package/lib/typescript/module/ui/social-button.d.ts +6 -6
- package/lib/typescript/module/ui/social-button.d.ts.map +1 -1
- package/lib/typescript/module/ui/social-button.web.d.ts +6 -6
- package/lib/typescript/module/ui/social-button.web.d.ts.map +1 -1
- package/lib/typescript/module/use-auth.d.ts +4 -4
- package/lib/typescript/module/use-auth.d.ts.map +1 -1
- package/lib/typescript/module/utils/logger.d.ts +4 -4
- package/lib/typescript/module/utils/logger.d.ts.map +1 -1
- package/nitrogen/generated/android/NitroAuth+autolinking.cmake +0 -1
- package/nitrogen/generated/shared/c++/AuthTokens.hpp +5 -1
- package/nitrogen/generated/shared/c++/AuthUser.hpp +5 -1
- package/nitrogen/generated/shared/c++/HybridAuthSpec.cpp +0 -1
- package/nitrogen/generated/shared/c++/HybridAuthSpec.hpp +0 -5
- package/nitrogen/generated/shared/c++/LoginOptions.hpp +5 -1
- package/package.json +13 -10
- package/src/Auth.nitro.ts +6 -3
- package/src/Auth.web.ts +582 -202
- package/src/global.d.ts +0 -1
- package/src/index.ts +1 -2
- package/src/index.web.ts +0 -1
- package/src/js-storage-adapter.ts +5 -0
- package/src/service.ts +11 -104
- package/src/service.web.ts +0 -7
- package/src/ui/social-button.tsx +66 -43
- package/src/ui/social-button.web.tsx +67 -44
- package/src/use-auth.ts +18 -6
- package/src/utils/logger.ts +12 -4
- package/lib/commonjs/AuthStorage.nitro.js +0 -6
- package/lib/commonjs/AuthStorage.nitro.js.map +0 -1
- package/lib/module/AuthStorage.nitro.js +0 -4
- package/lib/module/AuthStorage.nitro.js.map +0 -1
- package/lib/typescript/commonjs/AuthStorage.nitro.d.ts +0 -26
- package/lib/typescript/commonjs/AuthStorage.nitro.d.ts.map +0 -1
- package/lib/typescript/module/AuthStorage.nitro.d.ts +0 -26
- package/lib/typescript/module/AuthStorage.nitro.d.ts.map +0 -1
- package/nitrogen/generated/shared/c++/HybridAuthStorageAdapterSpec.cpp +0 -23
- package/nitrogen/generated/shared/c++/HybridAuthStorageAdapterSpec.hpp +0 -65
- package/src/AuthStorage.nitro.ts +0 -26
package/cpp/AuthCache.cpp
CHANGED
|
@@ -13,91 +13,21 @@
|
|
|
13
13
|
namespace margelo::nitro::NitroAuth {
|
|
14
14
|
|
|
15
15
|
#ifdef __APPLE__
|
|
16
|
-
static
|
|
17
|
-
static CFStringRef kAccount = CFSTR("nitro_auth_user");
|
|
18
|
-
static CFStringRef kLegacyCacheKey = CFSTR("nitro_auth_user");
|
|
19
|
-
|
|
20
|
-
static CFMutableDictionaryRef createKeychainQuery() {
|
|
21
|
-
CFMutableDictionaryRef query = CFDictionaryCreateMutable(
|
|
22
|
-
kCFAllocatorDefault,
|
|
23
|
-
0,
|
|
24
|
-
&kCFTypeDictionaryKeyCallBacks,
|
|
25
|
-
&kCFTypeDictionaryValueCallBacks
|
|
26
|
-
);
|
|
27
|
-
CFDictionarySetValue(query, kSecClass, kSecClassGenericPassword);
|
|
28
|
-
CFDictionarySetValue(query, kSecAttrService, kService);
|
|
29
|
-
CFDictionarySetValue(query, kSecAttrAccount, kAccount);
|
|
30
|
-
return query;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
static std::optional<std::string> getLegacyUserJson() {
|
|
34
|
-
CFPropertyListRef value = CFPreferencesCopyAppValue(kLegacyCacheKey, kCFPreferencesCurrentApplication);
|
|
35
|
-
if (value && CFGetTypeID(value) == CFStringGetTypeID()) {
|
|
36
|
-
CFStringRef cfStr = static_cast<CFStringRef>(value);
|
|
37
|
-
char buffer[4096];
|
|
38
|
-
if (CFStringGetCString(cfStr, buffer, sizeof(buffer), kCFStringEncodingUTF8)) {
|
|
39
|
-
CFRelease(value);
|
|
40
|
-
return std::string(buffer);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
if (value) CFRelease(value);
|
|
44
|
-
return std::nullopt;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
static void clearLegacyUserJson() {
|
|
48
|
-
CFPreferencesSetAppValue(kLegacyCacheKey, nullptr, kCFPreferencesCurrentApplication);
|
|
49
|
-
CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
|
|
50
|
-
}
|
|
16
|
+
static std::string sInMemoryUserJson;
|
|
51
17
|
|
|
52
18
|
void AuthCache::setUserJson(const std::string& json) {
|
|
53
|
-
|
|
54
|
-
SecItemDelete(query);
|
|
55
|
-
|
|
56
|
-
CFDataRef data = CFDataCreate(
|
|
57
|
-
kCFAllocatorDefault,
|
|
58
|
-
reinterpret_cast<const UInt8*>(json.data()),
|
|
59
|
-
static_cast<CFIndex>(json.size())
|
|
60
|
-
);
|
|
61
|
-
CFDictionarySetValue(query, kSecValueData, data);
|
|
62
|
-
CFDictionarySetValue(query, kSecAttrAccessible, kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly);
|
|
63
|
-
|
|
64
|
-
SecItemAdd(query, nullptr);
|
|
65
|
-
CFRelease(data);
|
|
66
|
-
CFRelease(query);
|
|
19
|
+
sInMemoryUserJson = json;
|
|
67
20
|
}
|
|
68
21
|
|
|
69
22
|
std::optional<std::string> AuthCache::getUserJson() {
|
|
70
|
-
|
|
71
|
-
CFDictionarySetValue(query, kSecReturnData, kCFBooleanTrue);
|
|
72
|
-
CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitOne);
|
|
73
|
-
|
|
74
|
-
CFTypeRef result = nullptr;
|
|
75
|
-
OSStatus status = SecItemCopyMatching(query, &result);
|
|
76
|
-
CFRelease(query);
|
|
77
|
-
|
|
78
|
-
if (status != errSecSuccess || result == nullptr) {
|
|
79
|
-
if (result) CFRelease(result);
|
|
80
|
-
auto legacy = getLegacyUserJson();
|
|
81
|
-
if (legacy) {
|
|
82
|
-
AuthCache::setUserJson(*legacy);
|
|
83
|
-
clearLegacyUserJson();
|
|
84
|
-
return legacy;
|
|
85
|
-
}
|
|
23
|
+
if (sInMemoryUserJson.empty()) {
|
|
86
24
|
return std::nullopt;
|
|
87
25
|
}
|
|
88
|
-
|
|
89
|
-
CFDataRef data = static_cast<CFDataRef>(result);
|
|
90
|
-
const UInt8* bytes = CFDataGetBytePtr(data);
|
|
91
|
-
const CFIndex length = CFDataGetLength(data);
|
|
92
|
-
std::string value(reinterpret_cast<const char*>(bytes), static_cast<size_t>(length));
|
|
93
|
-
CFRelease(result);
|
|
94
|
-
return value;
|
|
26
|
+
return sInMemoryUserJson;
|
|
95
27
|
}
|
|
96
28
|
|
|
97
29
|
void AuthCache::clear() {
|
|
98
|
-
|
|
99
|
-
SecItemDelete(query);
|
|
100
|
-
CFRelease(query);
|
|
30
|
+
sInMemoryUserJson.clear();
|
|
101
31
|
}
|
|
102
32
|
#endif
|
|
103
33
|
|
|
@@ -108,26 +38,8 @@ struct JContext : JavaClass<JContext> {
|
|
|
108
38
|
static constexpr auto kJavaDescriptor = "Landroid/content/Context;";
|
|
109
39
|
};
|
|
110
40
|
|
|
111
|
-
struct JAuthAdapter : facebook::jni::JavaClass<JAuthAdapter> {
|
|
112
|
-
static constexpr auto kJavaDescriptor = "Lcom/auth/AuthAdapter;";
|
|
113
|
-
|
|
114
|
-
static void setUserJson(facebook::jni::alias_ref<jobject> context, const std::string& json) {
|
|
115
|
-
static auto method = javaClassStatic()->getStaticMethod<void(alias_ref<JContext>, jstring)>("setUserJson");
|
|
116
|
-
method(javaClassStatic(), static_ref_cast<JContext>(context), make_jstring(json).get());
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
static facebook::jni::local_ref<jstring> getUserJson(facebook::jni::alias_ref<jobject> context) {
|
|
120
|
-
static auto method = javaClassStatic()->getStaticMethod<jstring(alias_ref<JContext>)>("getUserJson");
|
|
121
|
-
return method(javaClassStatic(), static_ref_cast<JContext>(context));
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
static void clearUser(facebook::jni::alias_ref<jobject> context) {
|
|
125
|
-
static auto method = javaClassStatic()->getStaticMethod<void(alias_ref<JContext>)>("clearUser");
|
|
126
|
-
method(javaClassStatic(), static_ref_cast<JContext>(context));
|
|
127
|
-
}
|
|
128
|
-
};
|
|
129
|
-
|
|
130
41
|
static facebook::jni::global_ref<jobject> gContext;
|
|
42
|
+
static std::string sInMemoryUserJson;
|
|
131
43
|
|
|
132
44
|
void AuthCache::setAndroidContext(void* context) {
|
|
133
45
|
gContext = facebook::jni::make_global(static_cast<jobject>(context));
|
|
@@ -138,20 +50,18 @@ void* AuthCache::getAndroidContext() {
|
|
|
138
50
|
}
|
|
139
51
|
|
|
140
52
|
void AuthCache::setUserJson(const std::string& json) {
|
|
141
|
-
|
|
142
|
-
JAuthAdapter::setUserJson(gContext, json);
|
|
53
|
+
sInMemoryUserJson = json;
|
|
143
54
|
}
|
|
144
55
|
|
|
145
56
|
std::optional<std::string> AuthCache::getUserJson() {
|
|
146
|
-
if (
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
return
|
|
57
|
+
if (sInMemoryUserJson.empty()) {
|
|
58
|
+
return std::nullopt;
|
|
59
|
+
}
|
|
60
|
+
return sInMemoryUserJson;
|
|
150
61
|
}
|
|
151
62
|
|
|
152
63
|
void AuthCache::clear() {
|
|
153
|
-
|
|
154
|
-
JAuthAdapter::clearUser(gContext);
|
|
64
|
+
sInMemoryUserJson.clear();
|
|
155
65
|
}
|
|
156
66
|
#endif
|
|
157
67
|
|
package/cpp/HybridAuth.cpp
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
#include "HybridAuth.hpp"
|
|
2
|
-
#include "AuthCache.hpp"
|
|
3
|
-
#include "JSONSerializer.hpp"
|
|
4
2
|
#include "PlatformAuth.hpp"
|
|
5
3
|
#include <NitroModules/NitroLogger.hpp>
|
|
6
4
|
#include <chrono>
|
|
@@ -10,7 +8,7 @@ namespace margelo::nitro::NitroAuth {
|
|
|
10
8
|
bool HybridAuth::sLoggingEnabled = false;
|
|
11
9
|
|
|
12
10
|
HybridAuth::HybridAuth() : HybridObject(TAG) {
|
|
13
|
-
|
|
11
|
+
// In-memory only - no internal persistence.
|
|
14
12
|
}
|
|
15
13
|
|
|
16
14
|
std::optional<AuthUser> HybridAuth::getCurrentUser() {
|
|
@@ -27,41 +25,6 @@ bool HybridAuth::getHasPlayServices() {
|
|
|
27
25
|
return PlatformAuth::hasPlayServices();
|
|
28
26
|
}
|
|
29
27
|
|
|
30
|
-
void HybridAuth::loadFromCache() {
|
|
31
|
-
std::lock_guard<std::mutex> lock(_mutex);
|
|
32
|
-
std::optional<std::string> json;
|
|
33
|
-
|
|
34
|
-
if (_storageAdapter) {
|
|
35
|
-
json = _storageAdapter->load("nitro_auth_user");
|
|
36
|
-
} else {
|
|
37
|
-
json = AuthCache::getUserJson();
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (json) {
|
|
41
|
-
_currentUser = JSONSerializer::deserialize(*json);
|
|
42
|
-
if (_currentUser && _currentUser->scopes) {
|
|
43
|
-
_grantedScopes = *_currentUser->scopes;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
void HybridAuth::saveToCache(const std::optional<AuthUser>& user) {
|
|
49
|
-
if (user) {
|
|
50
|
-
auto json = JSONSerializer::serialize(*user);
|
|
51
|
-
if (_storageAdapter) {
|
|
52
|
-
_storageAdapter->save("nitro_auth_user", json);
|
|
53
|
-
} else {
|
|
54
|
-
AuthCache::setUserJson(json);
|
|
55
|
-
}
|
|
56
|
-
} else {
|
|
57
|
-
if (_storageAdapter) {
|
|
58
|
-
_storageAdapter->remove("nitro_auth_user");
|
|
59
|
-
} else {
|
|
60
|
-
AuthCache::clear();
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
28
|
void HybridAuth::notifyAuthStateChanged() {
|
|
66
29
|
std::optional<AuthUser> user;
|
|
67
30
|
std::vector<std::function<void(const std::optional<AuthUser>&)>> listeners;
|
|
@@ -104,7 +67,6 @@ void HybridAuth::logout() {
|
|
|
104
67
|
std::lock_guard<std::mutex> lock(_mutex);
|
|
105
68
|
_currentUser = std::nullopt;
|
|
106
69
|
_grantedScopes.clear();
|
|
107
|
-
saveToCache(std::nullopt);
|
|
108
70
|
}
|
|
109
71
|
PlatformAuth::logout();
|
|
110
72
|
notifyAuthStateChanged();
|
|
@@ -114,18 +76,27 @@ std::shared_ptr<Promise<void>> HybridAuth::silentRestore() {
|
|
|
114
76
|
auto promise = Promise<void>::create();
|
|
115
77
|
auto silentPromise = PlatformAuth::silentRestore();
|
|
116
78
|
silentPromise->addOnResolvedListener([this, promise](const std::optional<AuthUser>& user) {
|
|
117
|
-
|
|
79
|
+
{
|
|
118
80
|
std::lock_guard<std::mutex> lock(_mutex);
|
|
119
81
|
_currentUser = user;
|
|
120
|
-
if (user
|
|
121
|
-
|
|
82
|
+
if (user) {
|
|
83
|
+
if (user->scopes) {
|
|
84
|
+
_grantedScopes = *user->scopes;
|
|
85
|
+
} else {
|
|
86
|
+
_grantedScopes.clear();
|
|
87
|
+
}
|
|
88
|
+
} else {
|
|
89
|
+
_grantedScopes.clear();
|
|
90
|
+
}
|
|
122
91
|
}
|
|
92
|
+
// Always resolve - no session is not an error, just means user is logged out
|
|
123
93
|
notifyAuthStateChanged();
|
|
124
94
|
promise->resolve();
|
|
125
95
|
});
|
|
126
96
|
|
|
127
|
-
silentPromise->addOnRejectedListener([promise](const std::exception_ptr&
|
|
128
|
-
|
|
97
|
+
silentPromise->addOnRejectedListener([promise](const std::exception_ptr&) {
|
|
98
|
+
// Silently ignore errors during restore - user will be logged out
|
|
99
|
+
promise->resolve();
|
|
129
100
|
});
|
|
130
101
|
return promise;
|
|
131
102
|
}
|
|
@@ -138,11 +109,18 @@ std::shared_ptr<Promise<void>> HybridAuth::login(AuthProvider provider, const st
|
|
|
138
109
|
{
|
|
139
110
|
std::lock_guard<std::mutex> lock(_mutex);
|
|
140
111
|
_currentUser = user;
|
|
141
|
-
if (
|
|
112
|
+
if (user.scopes && !user.scopes->empty()) {
|
|
113
|
+
_grantedScopes = *user.scopes;
|
|
114
|
+
} else if (options && options->scopes && !options->scopes->empty()) {
|
|
142
115
|
_grantedScopes = *options->scopes;
|
|
116
|
+
} else {
|
|
117
|
+
_grantedScopes.clear();
|
|
118
|
+
}
|
|
119
|
+
if (_currentUser) {
|
|
120
|
+
_currentUser->scopes = _grantedScopes.empty()
|
|
121
|
+
? std::nullopt
|
|
122
|
+
: std::make_optional(_grantedScopes);
|
|
143
123
|
}
|
|
144
|
-
if (_currentUser) _currentUser->scopes = _grantedScopes;
|
|
145
|
-
saveToCache(_currentUser);
|
|
146
124
|
}
|
|
147
125
|
notifyAuthStateChanged();
|
|
148
126
|
promise->resolve();
|
|
@@ -167,7 +145,6 @@ std::shared_ptr<Promise<void>> HybridAuth::requestScopes(const std::vector<std::
|
|
|
167
145
|
}
|
|
168
146
|
}
|
|
169
147
|
if (_currentUser) _currentUser->scopes = _grantedScopes;
|
|
170
|
-
saveToCache(_currentUser);
|
|
171
148
|
}
|
|
172
149
|
notifyAuthStateChanged();
|
|
173
150
|
promise->resolve();
|
|
@@ -192,7 +169,6 @@ std::shared_ptr<Promise<void>> HybridAuth::revokeScopes(const std::vector<std::s
|
|
|
192
169
|
);
|
|
193
170
|
if (_currentUser) {
|
|
194
171
|
_currentUser->scopes = _grantedScopes;
|
|
195
|
-
saveToCache(_currentUser);
|
|
196
172
|
}
|
|
197
173
|
}
|
|
198
174
|
notifyAuthStateChanged();
|
|
@@ -239,9 +215,18 @@ std::shared_ptr<Promise<AuthTokens>> HybridAuth::refreshToken() {
|
|
|
239
215
|
{
|
|
240
216
|
std::lock_guard<std::mutex> lock(_mutex);
|
|
241
217
|
if (_currentUser) {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
218
|
+
if (tokens.accessToken.has_value()) {
|
|
219
|
+
_currentUser->accessToken = tokens.accessToken;
|
|
220
|
+
}
|
|
221
|
+
if (tokens.idToken.has_value()) {
|
|
222
|
+
_currentUser->idToken = tokens.idToken;
|
|
223
|
+
}
|
|
224
|
+
if (tokens.refreshToken.has_value()) {
|
|
225
|
+
_currentUser->refreshToken = tokens.refreshToken;
|
|
226
|
+
}
|
|
227
|
+
if (tokens.expirationTime.has_value()) {
|
|
228
|
+
_currentUser->expirationTime = tokens.expirationTime;
|
|
229
|
+
}
|
|
245
230
|
}
|
|
246
231
|
}
|
|
247
232
|
notifyTokensRefreshed(tokens);
|
|
@@ -259,15 +244,6 @@ void HybridAuth::setLoggingEnabled(bool enabled) {
|
|
|
259
244
|
sLoggingEnabled = enabled;
|
|
260
245
|
}
|
|
261
246
|
|
|
262
|
-
void HybridAuth::setStorageAdapter(const std::optional<std::shared_ptr<HybridAuthStorageAdapterSpec>>& adapter) {
|
|
263
|
-
std::lock_guard<std::mutex> lock(_mutex);
|
|
264
|
-
_storageAdapter = adapter.value_or(nullptr);
|
|
265
|
-
if (_storageAdapter) {
|
|
266
|
-
loadFromCache();
|
|
267
|
-
notifyAuthStateChanged();
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
247
|
void HybridAuth::notifyTokensRefreshed(const AuthTokens& tokens) {
|
|
272
248
|
std::vector<std::function<void(const AuthTokens&)>> listeners;
|
|
273
249
|
{
|
package/cpp/HybridAuth.hpp
CHANGED
|
@@ -31,11 +31,10 @@ public:
|
|
|
31
31
|
std::function<void()> onAuthStateChanged(const std::function<void(const std::optional<AuthUser>&)>& callback) override;
|
|
32
32
|
std::function<void()> onTokensRefreshed(const std::function<void(const AuthTokens&)>& callback) override;
|
|
33
33
|
void setLoggingEnabled(bool enabled) override;
|
|
34
|
-
|
|
34
|
+
// Note: setStorageAdapter is kept internally but not exposed in public API
|
|
35
|
+
// Storage is in-memory only by default
|
|
35
36
|
|
|
36
37
|
private:
|
|
37
|
-
void loadFromCache();
|
|
38
|
-
void saveToCache(const std::optional<AuthUser>& user);
|
|
39
38
|
void notifyAuthStateChanged();
|
|
40
39
|
void notifyTokensRefreshed(const AuthTokens& tokens);
|
|
41
40
|
|
|
@@ -45,7 +44,6 @@ private:
|
|
|
45
44
|
std::map<int, std::function<void(const std::optional<AuthUser>&)>> _listeners;
|
|
46
45
|
int _nextListenerId = 0;
|
|
47
46
|
|
|
48
|
-
std::shared_ptr<HybridAuthStorageAdapterSpec> _storageAdapter;
|
|
49
47
|
std::map<int, std::function<void(const AuthTokens&)>> _tokenListeners;
|
|
50
48
|
int _nextTokenListenerId = 0;
|
|
51
49
|
|
package/ios/AuthAdapter.swift
CHANGED
|
@@ -7,6 +7,11 @@ import CommonCrypto
|
|
|
7
7
|
|
|
8
8
|
@objc
|
|
9
9
|
public class AuthAdapter: NSObject {
|
|
10
|
+
private static let defaultMicrosoftScopes = ["openid", "email", "profile", "offline_access", "User.Read"]
|
|
11
|
+
private static var inMemoryMicrosoftRefreshToken: String?
|
|
12
|
+
private static var inMemoryMicrosoftScopes: [String] = defaultMicrosoftScopes
|
|
13
|
+
private static var inMemoryGoogleServerAuthCode: String?
|
|
14
|
+
|
|
10
15
|
@objc
|
|
11
16
|
public static func login(provider: String, scopes: [String], loginHint: String?, useSheet: Bool, forceAccountPicker: Bool = false, tenant: String? = nil, prompt: String? = nil, completion: @escaping (NSDictionary?, String?) -> Void) {
|
|
12
17
|
if provider == "google" {
|
|
@@ -258,9 +263,9 @@ public class AuthAdapter: NSObject {
|
|
|
258
263
|
let expirationTime = Date().timeIntervalSince1970 * 1000 + expiresIn * 1000
|
|
259
264
|
|
|
260
265
|
if !refreshToken.isEmpty {
|
|
261
|
-
|
|
266
|
+
inMemoryMicrosoftRefreshToken = refreshToken
|
|
262
267
|
}
|
|
263
|
-
|
|
268
|
+
inMemoryMicrosoftScopes = scopes.isEmpty ? defaultMicrosoftScopes : scopes
|
|
264
269
|
|
|
265
270
|
let resultData: [String: Any] = [
|
|
266
271
|
"provider": "microsoft",
|
|
@@ -313,6 +318,9 @@ public class AuthAdapter: NSObject {
|
|
|
313
318
|
return
|
|
314
319
|
}
|
|
315
320
|
|
|
321
|
+
let serverAuthCode = result?.serverAuthCode ?? ""
|
|
322
|
+
inMemoryGoogleServerAuthCode = serverAuthCode.isEmpty ? nil : serverAuthCode
|
|
323
|
+
|
|
316
324
|
let data: [String: Any] = [
|
|
317
325
|
"provider": "google",
|
|
318
326
|
"email": user.profile?.email ?? "",
|
|
@@ -320,7 +328,7 @@ public class AuthAdapter: NSObject {
|
|
|
320
328
|
"photo": user.profile?.imageURL(withDimension: 300)?.absoluteString ?? "",
|
|
321
329
|
"idToken": user.idToken?.tokenString ?? "",
|
|
322
330
|
"accessToken": user.accessToken.tokenString,
|
|
323
|
-
"serverAuthCode":
|
|
331
|
+
"serverAuthCode": serverAuthCode,
|
|
324
332
|
"expirationTime": (user.accessToken.expirationDate?.timeIntervalSince1970 ?? 0) * 1000,
|
|
325
333
|
"underlyingError": ""
|
|
326
334
|
]
|
|
@@ -353,12 +361,11 @@ public class AuthAdapter: NSObject {
|
|
|
353
361
|
}
|
|
354
362
|
return
|
|
355
363
|
}
|
|
356
|
-
guard
|
|
364
|
+
guard inMemoryMicrosoftRefreshToken != nil else {
|
|
357
365
|
completion(nil, "No user logged in")
|
|
358
366
|
return
|
|
359
367
|
}
|
|
360
|
-
let
|
|
361
|
-
let mergedScopes = Array(Set(storedScopes + scopes))
|
|
368
|
+
let mergedScopes = Array(Set(inMemoryMicrosoftScopes + scopes))
|
|
362
369
|
loginMicrosoft(scopes: mergedScopes, loginHint: nil, tenant: nil, prompt: nil, completion: completion)
|
|
363
370
|
}
|
|
364
371
|
|
|
@@ -399,7 +406,7 @@ public class AuthAdapter: NSObject {
|
|
|
399
406
|
"photo": user.profile?.imageURL(withDimension: 300)?.absoluteString ?? "",
|
|
400
407
|
"idToken": user.idToken?.tokenString ?? "",
|
|
401
408
|
"accessToken": user.accessToken.tokenString,
|
|
402
|
-
"serverAuthCode": "",
|
|
409
|
+
"serverAuthCode": inMemoryGoogleServerAuthCode ?? "",
|
|
403
410
|
"expirationTime": (user.accessToken.expirationDate?.timeIntervalSince1970 ?? 0) * 1000
|
|
404
411
|
]
|
|
405
412
|
completion(data as NSDictionary)
|
|
@@ -413,7 +420,7 @@ public class AuthAdapter: NSObject {
|
|
|
413
420
|
}
|
|
414
421
|
|
|
415
422
|
private static func tryMicrosoftSilentRefresh(completion: @escaping (NSDictionary?) -> Void) {
|
|
416
|
-
guard let refreshToken =
|
|
423
|
+
guard let refreshToken = inMemoryMicrosoftRefreshToken else {
|
|
417
424
|
completion(nil)
|
|
418
425
|
return
|
|
419
426
|
}
|
|
@@ -459,7 +466,7 @@ public class AuthAdapter: NSObject {
|
|
|
459
466
|
let expirationTime = Date().timeIntervalSince1970 * 1000 + expiresIn * 1000
|
|
460
467
|
|
|
461
468
|
if !newRefreshToken.isEmpty {
|
|
462
|
-
|
|
469
|
+
inMemoryMicrosoftRefreshToken = newRefreshToken
|
|
463
470
|
}
|
|
464
471
|
|
|
465
472
|
let resultData: [String: Any] = [
|
|
@@ -478,7 +485,7 @@ public class AuthAdapter: NSObject {
|
|
|
478
485
|
}
|
|
479
486
|
|
|
480
487
|
private static func tryMicrosoftRefreshForTokenRefresh(completion: @escaping (NSDictionary?, String?) -> Void) {
|
|
481
|
-
guard let refreshToken =
|
|
488
|
+
guard let refreshToken = inMemoryMicrosoftRefreshToken else {
|
|
482
489
|
completion(nil, "No user logged in")
|
|
483
490
|
return
|
|
484
491
|
}
|
|
@@ -523,7 +530,7 @@ public class AuthAdapter: NSObject {
|
|
|
523
530
|
let expiresIn = json["expires_in"] as? Double ?? 0
|
|
524
531
|
let expirationTime = Date().timeIntervalSince1970 * 1000 + expiresIn * 1000
|
|
525
532
|
if !newRefreshToken.isEmpty {
|
|
526
|
-
|
|
533
|
+
inMemoryMicrosoftRefreshToken = newRefreshToken
|
|
527
534
|
}
|
|
528
535
|
let tokensData: [String: Any] = [
|
|
529
536
|
"accessToken": accessToken,
|
|
@@ -551,20 +558,9 @@ public class AuthAdapter: NSObject {
|
|
|
551
558
|
@objc
|
|
552
559
|
public static func logout() {
|
|
553
560
|
GIDSignIn.sharedInstance.signOut()
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
private static func getStoredMicrosoftRefreshToken() -> String? {
|
|
559
|
-
if let token = KeychainStore.get("nitro_auth_microsoft_refresh_token") {
|
|
560
|
-
return token
|
|
561
|
-
}
|
|
562
|
-
if let legacy = UserDefaults.standard.string(forKey: "nitro_auth_microsoft_refresh_token") {
|
|
563
|
-
KeychainStore.set(legacy, for: "nitro_auth_microsoft_refresh_token")
|
|
564
|
-
UserDefaults.standard.removeObject(forKey: "nitro_auth_microsoft_refresh_token")
|
|
565
|
-
return legacy
|
|
566
|
-
}
|
|
567
|
-
return nil
|
|
561
|
+
inMemoryMicrosoftRefreshToken = nil
|
|
562
|
+
inMemoryMicrosoftScopes = defaultMicrosoftScopes
|
|
563
|
+
inMemoryGoogleServerAuthCode = nil
|
|
568
564
|
}
|
|
569
565
|
}
|
|
570
566
|
|